Skip to content

Commit

Permalink
use latest for pending tag (#908)
Browse files Browse the repository at this point in the history
* use latest for pending tag

* update tests

* type polish

* fix
  • Loading branch information
shunjizhan authored Dec 21, 2023
1 parent d1f2660 commit 6d5fbe5
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 44 deletions.
1 change: 0 additions & 1 deletion packages/eth-providers/src/base-provider-dd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const TRACE_METHODS = [
'getBalance',
'getTransactionCount',
'getEvmTransactionCount',
'getSubstrateNonce',
'getCode',
'call',
'_ethCall',
Expand Down
49 changes: 9 additions & 40 deletions packages/eth-providers/src/base-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,36 +758,12 @@ export abstract class BaseProvider extends AbstractProvider {
return minedNonce + pendingNonce;
};

getSubstrateNonce = async (
addressOrName: string | Promise<string>,
blockTag?: BlockTag | Promise<BlockTag>
): Promise<number> => {
const resolvedBlockTag = await blockTag;

const address = await addressOrName;
const [substrateAddress, blockHash] = await Promise.all([
this.getSubstrateAddress(address),
this._getBlockHash(blockTag),
]);

if (resolvedBlockTag === 'pending') {
const idx = await this.api.rpc.system.accountNextIndex(substrateAddress);
return idx.toNumber();
}

const accountInfo = await this.queryStorage('system.account', [substrateAddress], blockHash);

return accountInfo.nonce.toNumber();
};

getCode = async (
addressOrName: string | Promise<string>,
_blockTag?: BlockTag | Promise<BlockTag> | Eip1898BlockTag
): Promise<string> => {
const blockTag = await this._ensureSafeModeBlockTagFinalization(await parseBlockTag(_blockTag));

if (blockTag === 'pending') return '0x';

const [address, blockHash] = await Promise.all([
addressOrName,
this._getBlockHash(blockTag),
Expand Down Expand Up @@ -944,7 +920,7 @@ export abstract class BaseProvider extends AbstractProvider {
*/
estimateGas = async (
transaction: Deferrable<TransactionRequest>,
blockTag?: BlockTag | Promise<BlockTag>
blockTag?: BlockTag,
): Promise<BigNumber> => {
const blockHash = blockTag && blockTag !== 'latest'
? await this._getBlockHash(blockTag)
Expand Down Expand Up @@ -1186,7 +1162,7 @@ export abstract class BaseProvider extends AbstractProvider {
};
};

getSubstrateAddress = async (addressOrName: string, blockTag?: BlockTag | Promise<BlockTag>): Promise<string> => {
getSubstrateAddress = async (addressOrName: string, blockTag?: BlockTag): Promise<string> => {
const [address, blockHash] = await Promise.all([
addressOrName,
this._getBlockHash(blockTag),
Expand All @@ -1197,7 +1173,7 @@ export abstract class BaseProvider extends AbstractProvider {
return substrateAccount.isEmpty ? computeDefaultSubstrateAddress(address) : substrateAccount.toString();
};

getEvmAddress = async (substrateAddress: string, blockTag?: BlockTag | Promise<BlockTag>): Promise<string> => {
getEvmAddress = async (substrateAddress: string, blockTag?: BlockTag): Promise<string> => {
const blockHash = await this._getBlockHash(blockTag);
const evmAddress = await this.queryStorage<Option<H160>>('evmAccounts.evmAddresses', [substrateAddress], blockHash);

Expand All @@ -1208,10 +1184,7 @@ export abstract class BaseProvider extends AbstractProvider {
addressOrName: string | Promise<string>,
_blockTag?: BlockTag | Promise<BlockTag> | Eip1898BlockTag
): Promise<Option<EvmAccountInfo>> => {
let blockTag = await this._ensureSafeModeBlockTagFinalization(await parseBlockTag(_blockTag));
if (blockTag === 'pending') {
blockTag = 'latest';
}
const blockTag = await this._ensureSafeModeBlockTagFinalization(await parseBlockTag(_blockTag));

const [address, blockHash] = await Promise.all([
addressOrName,
Expand Down Expand Up @@ -1502,9 +1475,7 @@ export abstract class BaseProvider extends AbstractProvider {

_getBlockNumber = async (blockTag: BlockTag): Promise<number> => {
switch (blockTag) {
case 'pending': {
return logger.throwError('pending tag not implemented', Logger.errors.UNSUPPORTED_OPERATION);
}
case 'pending':
case 'latest': {
return this.getBlockNumber();
}
Expand All @@ -1531,13 +1502,11 @@ export abstract class BaseProvider extends AbstractProvider {
}
};

_getBlockHash = async (_blockTag?: BlockTag | Promise<BlockTag>): Promise<string> => {
const blockTag = (await _blockTag) || 'latest';
_getBlockHash = async (_blockTag?: BlockTag): Promise<string> => {
const blockTag = _blockTag ?? 'latest';

switch (blockTag) {
case 'pending': {
return logger.throwError('pending tag not supported', Logger.errors.UNSUPPORTED_OPERATION);
}
case 'pending':
case 'latest': {
return this.safeMode ? this.finalizedBlockHash : this.bestBlockHash;
}
Expand Down Expand Up @@ -1638,7 +1607,7 @@ export abstract class BaseProvider extends AbstractProvider {
};

_getBlockHeader = async (blockTag?: BlockTag | Promise<BlockTag>): Promise<Header> => {
const blockHash = await this._getBlockHash(blockTag);
const blockHash = await this._getBlockHash(await blockTag);

try {
const header = await this.api.rpc.chain.getHeader(blockHash);
Expand Down
19 changes: 16 additions & 3 deletions packages/eth-rpc-adapter/src/__tests__/e2e/endpoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1911,48 +1911,56 @@ describe('endpoint', () => {
});
});

describe('finalized blocktag', () => {
describe('finalized/safe/pending blocktag', () => {
/* ----------
latest block <=> finalized block in local setup
---------- */
it('eth_getTransactionCount', async () => {
const res = (await eth_getTransactionCount([ADDRESS_ALICE, 'latest'])).data.result;
const resF = (await eth_getTransactionCount([ADDRESS_ALICE, 'finalized'])).data.result;
const resS = (await eth_getTransactionCount([ADDRESS_ALICE, 'safe'])).data.result;
const resP = (await eth_getTransactionCount([ADDRESS_ALICE, 'pending'])).data.result;

expect(parseInt(res)).to.greaterThan(0);
expect(res).to.equal(resF);
expect(res).to.equal(resS);
expect(res).to.equal(resP); // no pending in local setup
});

it('eth_getCode', async () => {
const res = (await eth_getCode([DETERMINISTIC_SETUP_DEX_ADDRESS, 'latest'])).data.result;
const resF = (await eth_getCode([DETERMINISTIC_SETUP_DEX_ADDRESS, 'finalized'])).data.result;
const resS = (await eth_getCode([DETERMINISTIC_SETUP_DEX_ADDRESS, 'safe'])).data.result;
const resP = (await eth_getCode([DETERMINISTIC_SETUP_DEX_ADDRESS, 'pending'])).data.result;

expect(res).not.to.be.undefined;
expect(res).to.equal(resF);
expect(res).to.equal(resS);
expect(res).to.equal(resP);
});

it('eth_getBalance', async () => {
const res = (await eth_getBalance([ADDRESS_ALICE, 'latest'])).data.result;
const resF = (await eth_getBalance([ADDRESS_ALICE, 'finalized'])).data.result;
const resS = (await eth_getBalance([ADDRESS_ALICE, 'safe'])).data.result;
const resP = (await eth_getBalance([ADDRESS_ALICE, 'pending'])).data.result;

expect(parseInt(res)).to.greaterThan(0);
expect(res).to.equal(resF);
expect(res).to.equal(resS);
expect(res).to.equal(resP);
});

it('eth_getBlockByNumber', async () => {
const res = (await eth_getBlockByNumber(['latest', false])).data.result;
const resF = (await eth_getBlockByNumber(['finalized', false])).data.result;
const resS = (await eth_getBlockByNumber(['safe', false])).data.result;
const resP = (await eth_getBlockByNumber(['pending', false])).data.result;

expect(res).not.to.be.undefined;
expect(res).to.deep.equal(resF);
expect(res).to.deep.equal(resS);
expect(res).to.deep.equal(resP);
});

it('eth_isBlockFinalized', async () => {
Expand Down Expand Up @@ -1994,8 +2002,13 @@ describe('endpoint', () => {
const { gasLimit } = await estimateGas(tx);
const bbb = (gasLimit.toNumber() % 100000) / 100;

const { gasLimit: gasLimitWithBlockTag } = await estimateGas(tx, 'latest');
expect(gasLimitWithBlockTag.toBigInt()).to.equal(gasLimit.toBigInt());
/* ---------- should work with latest and pending tag ---------- */
const { gasLimit: gasLimitLatest } = await estimateGas(tx, 'latest');
const { gasLimit: gasLimitPending } = await estimateGas(tx, 'pending');

expect(gasLimitLatest.toBigInt()).to.equal(gasLimit.toBigInt());
expect(gasLimitPending.toBigInt()).to.equal(gasLimit.toBigInt());
/* -------------------------------------------------------------- */

// should be passing gasLimit instead of usedGas
expect(bbb).to.gt(GAS_MONSTER_GAS_REQUIRED / 30000);
Expand Down

0 comments on commit 6d5fbe5

Please sign in to comment.