From 3b63840e7e8151bb17c56d46849a6c935193e2e7 Mon Sep 17 00:00:00 2001 From: Brad Hart Date: Wed, 18 Nov 2020 15:52:09 -0500 Subject: [PATCH 1/3] Adjusting code to use new get_block_info and more efficient Tapos --- src/eosjs-api.ts | 21 +++++++++++++++------ src/eosjs-jsonrpc.ts | 19 +++++++++++++++---- src/eosjs-rpc-interfaces.ts | 23 +++++++++++++++++++++++ src/tests/eosjs-api.test.ts | 2 +- src/tests/eosjs-jsonrpc.test.ts | 19 +++++++++++++++++++ src/tests/node.js | 4 ++-- src/tests/web.html | 4 ++-- 7 files changed, 77 insertions(+), 15 deletions(-) diff --git a/src/eosjs-api.ts b/src/eosjs-api.ts index c80703e25..192485bb2 100644 --- a/src/eosjs-api.ts +++ b/src/eosjs-api.ts @@ -393,8 +393,11 @@ export class Api { { sign, requiredKeys, authorization = [] }: QueryConfig ): Promise { const info = await this.rpc.get_info(); - // TODO: replace get_block; needs rodeos changes - const refBlock = await this.rpc.get_block(info.last_irreversible_block_num); + const refBlock = { + block_num: info.last_irreversible_block_num, + id: info.last_irreversible_block_id, + timestamp: info.last_irreversible_block_time, + }; const queryBuffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder }); ser.serializeQuery(queryBuffer, query); @@ -483,13 +486,19 @@ export class Api { if (!info) { info = await this.rpc.get_info(); } + if (useLastIrreversible) { + return { ...ser.transactionHeader({ + block_num: info.last_irreversible_block_num, + id: info.last_irreversible_block_id, + timestamp: info.last_irreversible_block_time, + }, expireSeconds), ...transaction }; + } - const taposBlockNumber: number = useLastIrreversible - ? info.last_irreversible_block_num : info.head_block_num - blocksBehind; + const taposBlockNumber: number = info.head_block_num - blocksBehind; const refBlock: GetBlockHeaderStateResult | GetBlockResult = taposBlockNumber <= info.last_irreversible_block_num - ? await this.rpc.get_block(taposBlockNumber) + ? await this.rpc.get_block_info(taposBlockNumber) : await this.tryGetBlockHeaderState(taposBlockNumber); return { ...ser.transactionHeader(refBlock, expireSeconds), ...transaction }; @@ -505,7 +514,7 @@ export class Api { try { return await this.rpc.get_block_header_state(taposBlockNumber); } catch (error) { - return await this.rpc.get_block(taposBlockNumber); + return await this.rpc.get_block_info(taposBlockNumber); } } diff --git a/src/eosjs-jsonrpc.ts b/src/eosjs-jsonrpc.ts index ef9848014..3edd1c122 100644 --- a/src/eosjs-jsonrpc.ts +++ b/src/eosjs-jsonrpc.ts @@ -7,10 +7,12 @@ import { AbiProvider, AuthorityProvider, AuthorityProviderArgs, BinaryAbi } from import { base64ToBinary, convertLegacyPublicKeys } from './eosjs-numeric'; import { GetAbiResult, + GetBlockInfoResult, GetBlockResult, GetCodeResult, GetInfoResult, GetRawCodeAndAbiResult, + GetRawAbiResult, PushTransactionArgs, GetBlockHeaderStateResult } from './eosjs-rpc-interfaces'; @@ -88,6 +90,11 @@ export class JsonRpc implements AuthorityProvider, AbiProvider { return await this.fetch('/v1/chain/get_block_header_state', { block_num_or_id: blockNumOrId }); } + /** Raw call to `/v1/chain/get_block_info` */ + public async get_block_info(blockNum: number): Promise { + return await this.fetch('/v1/chain/get_block_info', { block_num: blockNum }); + } + /** Raw call to `/v1/chain/get_block` */ public async get_block(blockNumOrId: number | string): Promise { return await this.fetch('/v1/chain/get_block', { block_num_or_id: blockNumOrId }); @@ -132,11 +139,15 @@ export class JsonRpc implements AuthorityProvider, AbiProvider { } /** calls `/v1/chain/get_raw_code_and_abi` and pulls out unneeded raw wasm code */ - // TODO: use `/v1/chain/get_raw_abi` directly when it becomes available public async getRawAbi(accountName: string): Promise { - const rawCodeAndAbi = await this.get_raw_code_and_abi(accountName); - const abi = base64ToBinary(rawCodeAndAbi.abi); - return { accountName: rawCodeAndAbi.account_name, abi }; + const rawAbi = await this.get_raw_abi(accountName); + const abi = base64ToBinary(rawAbi.abi); + return { accountName: rawAbi.account_name, abi }; + } + + /** Raw call to `/v1/chain/get_raw_abi` */ + public async get_raw_abi(accountName: string): Promise { + return await this.fetch('/v1/chain/get_raw_abi', { account_name: accountName }); } /** Raw call to `/v1/chain/get_scheduled_transactions` */ diff --git a/src/eosjs-rpc-interfaces.ts b/src/eosjs-rpc-interfaces.ts index 7169a9e1f..80162e867 100644 --- a/src/eosjs-rpc-interfaces.ts +++ b/src/eosjs-rpc-interfaces.ts @@ -38,6 +38,21 @@ export interface GetAbiResult { abi: Abi; } +/** Return value of `/v1/chain/get_block_info` */ +export interface GetBlockInfoResult { + timestamp: string; + producer: string; + confirmed: number; + previous: string; + transaction_mroot: string; + action_mroot: string; + schedule_version: number; + producer_signature: string; + id: string; + block_num: number; + ref_block_prefix: number; +} + /** Return value of `/v1/chain/get_block` */ export interface GetBlockResult { timestamp: string; @@ -101,6 +116,7 @@ export interface GetInfoResult { head_block_num: number; last_irreversible_block_num: number; last_irreversible_block_id: string; + last_irreversible_block_time: string; head_block_id: string; head_block_time: string; head_block_producer: string; @@ -117,6 +133,13 @@ export interface GetRawCodeAndAbiResult { abi: string; } +export interface GetRawAbiResult { + account_name: string; + code_hash: string; + abi_hash: string; + abi: string; +} + /** Arguments for `push_transaction` */ export interface PushTransactionArgs { signatures: string[]; diff --git a/src/tests/eosjs-api.test.ts b/src/tests/eosjs-api.test.ts index aad792a7a..8fbe961e8 100644 --- a/src/tests/eosjs-api.test.ts +++ b/src/tests/eosjs-api.test.ts @@ -136,7 +136,7 @@ describe('eosjs-api', () => { const fetch = async (input: any, init: any): Promise => ({ ok: true, json: async () => { - if (input === '/v1/chain/get_raw_code_and_abi') { + if (input === '/v1/chain/get_raw_abi') { return { account_name: 'testeostoken', abi: 'DmVvc2lvOjphYmkvMS4wAQxhY2NvdW50X25hbWUEbmFtZQUIdHJhbnNmZXIABARmcm9tDGFjY291bnRfbmFtZQJ0bwxhY2NvdW50X25hbWUIcXVhbnRpdHkFYXNzZXQEbWVtbwZzdHJpbmcGY3JlYXRlAAIGaXNzdWVyDGFjY291bnRfbmFtZQ5tYXhpbXVtX3N1cHBseQVhc3NldAVpc3N1ZQADAnRvDGFjY291bnRfbmFtZQhxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwdhY2NvdW50AAEHYmFsYW5jZQVhc3NldA5jdXJyZW5jeV9zdGF0cwADBnN1cHBseQVhc3NldAptYXhfc3VwcGx5BWFzc2V0Bmlzc3VlcgxhY2NvdW50X25hbWUDAAAAVy08zc0IdHJhbnNmZXLnBSMjIFRyYW5zZmVyIFRlcm1zICYgQ29uZGl0aW9ucwoKSSwge3tmcm9tfX0sIGNlcnRpZnkgdGhlIGZvbGxvd2luZyB0byBiZSB0cnVlIHRvIHRoZSBiZXN0IG9mIG15IGtub3dsZWRnZToKCjEuIEkgY2VydGlmeSB0aGF0IHt7cXVhbnRpdHl9fSBpcyBub3QgdGhlIHByb2NlZWRzIG9mIGZyYXVkdWxlbnQgb3IgdmlvbGVudCBhY3Rpdml0aWVzLgoyLiBJIGNlcnRpZnkgdGhhdCwgdG8gdGhlIGJlc3Qgb2YgbXkga25vd2xlZGdlLCB7e3RvfX0gaXMgbm90IHN1cHBvcnRpbmcgaW5pdGlhdGlvbiBvZiB2aW9sZW5jZSBhZ2FpbnN0IG90aGVycy4KMy4gSSBoYXZlIGRpc2Nsb3NlZCBhbnkgY29udHJhY3R1YWwgdGVybXMgJiBjb25kaXRpb25zIHdpdGggcmVzcGVjdCB0byB7e3F1YW50aXR5fX0gdG8ge3t0b319LgoKSSB1bmRlcnN0YW5kIHRoYXQgZnVuZHMgdHJhbnNmZXJzIGFyZSBub3QgcmV2ZXJzaWJsZSBhZnRlciB0aGUge3t0cmFuc2FjdGlvbi5kZWxheX19IHNlY29uZHMgb3Igb3RoZXIgZGVsYXkgYXMgY29uZmlndXJlZCBieSB7e2Zyb219fSdzIHBlcm1pc3Npb25zLgoKSWYgdGhpcyBhY3Rpb24gZmFpbHMgdG8gYmUgaXJyZXZlcnNpYmx5IGNvbmZpcm1lZCBhZnRlciByZWNlaXZpbmcgZ29vZHMgb3Igc2VydmljZXMgZnJvbSAne3t0b319JywgSSBhZ3JlZSB0byBlaXRoZXIgcmV0dXJuIHRoZSBnb29kcyBvciBzZXJ2aWNlcyBvciByZXNlbmQge3txdWFudGl0eX19IGluIGEgdGltZWx5IG1hbm5lci4KAAAAAAClMXYFaXNzdWUAAAAAAKhs1EUGY3JlYXRlAAIAAAA4T00RMgNpNjQBCGN1cnJlbmN5AQZ1aW50NjQHYWNjb3VudAAAAAAAkE3GA2k2NAEIY3VycmVuY3kBBnVpbnQ2NA5jdXJyZW5jeV9zdGF0cwAAAA===', // eslint-disable-line diff --git a/src/tests/eosjs-jsonrpc.test.ts b/src/tests/eosjs-jsonrpc.test.ts index c57d6527b..3b02645e7 100644 --- a/src/tests/eosjs-jsonrpc.test.ts +++ b/src/tests/eosjs-jsonrpc.test.ts @@ -140,6 +140,25 @@ describe('JSON RPC', () => { expect(fetch).toBeCalledWith(endpoint + expPath, expParams); }); + it('calls get_block_info', async () => { + const expPath = '/v1/chain/get_block_info'; + const blockNum = 1234; + const expReturn = { data: '12345' }; + const expParams = { + body: JSON.stringify({ + block_num: blockNum, + }), + method: 'POST', + }; + + fetchMock.once(JSON.stringify(expReturn)); + + const response = await jsonRpc.get_block_info(blockNum); + + expect(response).toEqual(expReturn); + expect(fetch).toBeCalledWith(endpoint + expPath, expParams); + }); + it('calls get_block', async () => { const expPath = '/v1/chain/get_block'; const blockNumOrId = 1234; diff --git a/src/tests/node.js b/src/tests/node.js index 38cc6289a..072bade18 100644 --- a/src/tests/node.js +++ b/src/tests/node.js @@ -64,7 +64,7 @@ const transactWithConfig = async (config, memo, from = 'bob', to = 'alice') => { const transactWithoutConfig = async () => { const transactionResponse = await transactWithConfig({ blocksBehind: 3, expireSeconds: 30}, 'transactWithoutConfig'); - const blockInfo = await rpc.get_block(transactionResponse.processed.block_num - 3); + const blockInfo = await rpc.get_block_info(transactionResponse.processed.block_num - 3); const currentDate = new Date(); const timePlusTen = currentDate.getTime() + 10000; const timeInISOString = (new Date(timePlusTen)).toISOString(); @@ -242,7 +242,7 @@ const transactShouldFail = async () => await api.transact({ }] }); -const rpcShouldFail = async () => await rpc.get_block(-1); +const rpcShouldFail = async () => await rpc.get_block_info(-1); module.exports = { transactWithConfig, diff --git a/src/tests/web.html b/src/tests/web.html index f8749785b..bc279120e 100644 --- a/src/tests/web.html +++ b/src/tests/web.html @@ -130,7 +130,7 @@ const transactWithoutConfig = async () => { const transactionResponse = await transactWithConfig({ blocksBehind: 3, expireSeconds: 30 }, 'transactWithoutConfig'); - const blockInfo = await rpc.get_block(transactionResponse.processed.block_num - 3); + const blockInfo = await rpc.get_block_info(transactionResponse.processed.block_num - 3); const currentDate = new Date(); const timePlusTen = currentDate.getTime() + 10000; const timeInISOString = (new Date(timePlusTen)).toISOString(); @@ -620,7 +620,7 @@ return false; } - const rpcShouldFail = async () => await rpc.get_block(-1); + const rpcShouldFail = async () => await rpc.get_block_info(-1); const testRpcShouldFail = async (e) => { resultsLabel = e.target; From 0ee094477b2493bc8af172e027f94c8ef824e6e5 Mon Sep 17 00:00:00 2001 From: "Block.one DevOps" Date: Thu, 19 Nov 2020 22:04:38 +0000 Subject: [PATCH 2/3] Updating package.json and yarn.lock --- package.json | 2 +- yarn.lock | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index b74453455..f25506299 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@blockone/eslint-config-blockone": "^3.0.0", "@types/elliptic": "^6.4.12", "@types/jest": "^26.0.15", - "@types/node": "^14.14.8", + "@types/node": "^14.14.9", "@types/pako": "^1.0.1", "cypress": "^4.12.1", "eosjs-ecc": "^4.0.7", diff --git a/yarn.lock b/yarn.lock index 6d2041a49..82ad91740 100644 --- a/yarn.lock +++ b/yarn.lock @@ -641,10 +641,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== -"@types/node@*", "@types/node@^14.14.8": - version "14.14.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.8.tgz#2127bd81949a95c8b7d3240f3254352d72563aec" - integrity sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA== +"@types/node@*", "@types/node@^14.14.9": + version "14.14.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6" + integrity sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2026,16 +2026,16 @@ debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: ms "2.0.0" debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -4611,9 +4611,9 @@ ospath@^1.2.2: integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= p-each-series@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" - integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== p-finally@^1.0.0: version "1.0.0" From 6611d9cfa7a46bc1a546b3868c452e123aa77154 Mon Sep 17 00:00:00 2001 From: Brad Hart Date: Fri, 20 Nov 2020 01:33:42 -0500 Subject: [PATCH 3/3] Adding compatibility --- src/eosjs-api.ts | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/eosjs-api.ts b/src/eosjs-api.ts index 8b1560bcb..d8e69293b 100644 --- a/src/eosjs-api.ts +++ b/src/eosjs-api.ts @@ -23,9 +23,11 @@ import { import { JsonRpc } from './eosjs-jsonrpc'; import { Abi, + BlockTaposInfo, GetInfoResult, PushTransactionArgs, GetBlockHeaderStateResult, + GetBlockInfoResult, GetBlockResult } from './eosjs-rpc-interfaces'; import * as ser from './eosjs-serialize'; @@ -349,11 +351,7 @@ export class Api { { sign, requiredKeys, authorization = [] }: QueryConfig ): Promise { const info = await this.rpc.get_info(); - const refBlock = { - block_num: info.last_irreversible_block_num, - id: info.last_irreversible_block_id, - timestamp: info.last_irreversible_block_time, - }; + const refBlock = await this.tryRefBlockFromGetInfo(info); const queryBuffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder }); ser.serializeQuery(queryBuffer, query); @@ -443,18 +441,15 @@ export class Api { info = await this.rpc.get_info(); } if (useLastIrreversible) { - return { ...ser.transactionHeader({ - block_num: info.last_irreversible_block_num, - id: info.last_irreversible_block_id, - timestamp: info.last_irreversible_block_time, - }, expireSeconds), ...transaction }; + const block = await this.tryRefBlockFromGetInfo(info); + return { ...ser.transactionHeader(block, expireSeconds), ...transaction }; } const taposBlockNumber: number = info.head_block_num - blocksBehind; const refBlock: GetBlockHeaderStateResult | GetBlockResult = taposBlockNumber <= info.last_irreversible_block_num - ? await this.rpc.get_block_info(taposBlockNumber) + ? await this.tryGetBlockInfo(taposBlockNumber) : await this.tryGetBlockHeaderState(taposBlockNumber); return { ...ser.transactionHeader(refBlock, expireSeconds), ...transaction }; @@ -470,7 +465,36 @@ export class Api { try { return await this.rpc.get_block_header_state(taposBlockNumber); } catch (error) { - return await this.rpc.get_block_info(taposBlockNumber); + return await this.tryGetBlockInfo(taposBlockNumber); + } + } + + private async tryGetBlockInfo(blockNumber: number): Promise { + try { + return await this.rpc.get_block_info(blockNumber); + } catch (error) { + return await this.rpc.get_block(blockNumber); + } + } + + private async tryRefBlockFromGetInfo(info: GetInfoResult): Promise { + if ( + info.hasOwnProperty('last_irreversible_block_id') && + info.hasOwnProperty('last_irreversible_block_num') && + info.hasOwnProperty('last_irreversible_block_time') + ) { + return { + block_num: info.last_irreversible_block_num, + id: info.last_irreversible_block_id, + timestamp: info.last_irreversible_block_time, + }; + } else { + const block = await this.tryGetBlockInfo(info.last_irreversible_block_num); + return { + block_num: block.block_num, + id: block.id, + timestamp: block.timestamp, + }; } }