@@ -75,6 +75,10 @@ const ONE_TINYBAR = ethers.utils.parseUnits('1', 10);
7575const ONE_WEIBAR = ethers . utils . parseUnits ( '1' , 18 ) ;
7676
7777const NON_EXISTING_ADDRESS = '0x5555555555555555555555555555555555555555' ;
78+ const NON_EXISTING_TX_HASH = '0x5555555555555555555555555555555555555555555555555555555555555555' ;
79+ const NON_EXISTING_BLOCK_HASH = '0x555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555' ;
80+ const NON_EXISTING_BLOCK_NUMBER = 99999999 ;
81+ const NON_EXISTING_INDEX = 999999 ;
7882
7983describe ( 'RPC Server Acceptance Tests' , function ( ) {
8084 this . timeout ( 240 * 1000 ) ; // 240 seconds
@@ -124,31 +128,106 @@ describe('RPC Server Acceptance Tests', function() {
124128 describe ( 'Block related RPC calls' , ( ) => {
125129
126130 let mirrorBlock ;
131+ let mirrorContractResults ;
132+ let mirrorTransactions : any [ ] = [ ] ;
127133
128134 before ( async ( ) => {
129135 mirrorBlock = ( await mirrorNode . get ( `/blocks?block.number=${ mirrorContractDetails . block_number } ` ) ) . blocks [ 0 ] ;
136+ const timestampQuery = `timestamp=gte:${ mirrorBlock . timestamp . from } ×tamp=lte:${ mirrorBlock . timestamp . to } ` ;
137+ mirrorContractResults = ( await mirrorNode . get ( `/contracts/results?${ timestampQuery } ` ) ) . results ;
138+
139+ for ( let i = 0 ; i < mirrorContractResults . length ; i ++ ) {
140+ const res = mirrorContractResults [ i ] ;
141+ mirrorTransactions . push ( ( await mirrorNode . get ( `/contracts/${ res . contract_id } /results/${ res . timestamp } ` ) ) ) ;
142+ }
143+
144+ } ) ;
145+
146+ it ( 'should execute "eth_getBlockByHash", hydrated transactions not specified' , async function ( ) {
147+ const blockResult = await relay . call ( 'eth_getBlockByHash' , [ mirrorBlock . hash ] ) ;
148+ Assertions . block ( blockResult , mirrorBlock , mirrorTransactions , false ) ;
149+ } ) ;
150+
151+ it ( 'should execute "eth_getBlockByHash", hydrated transactions = false' , async function ( ) {
152+ const blockResult = await relay . call ( 'eth_getBlockByHash' , [ mirrorBlock . hash , false ] ) ;
153+ Assertions . block ( blockResult , mirrorBlock , mirrorTransactions , false ) ;
154+ } ) ;
155+
156+ it ( 'should execute "eth_getBlockByHash", hydrated transactions = true' , async function ( ) {
157+ const blockResult = await relay . call ( 'eth_getBlockByHash' , [ mirrorBlock . hash , true ] ) ;
158+ Assertions . block ( blockResult , mirrorBlock , mirrorTransactions , true ) ;
130159 } ) ;
131160
132- it ( 'should execute "eth_getBlockByHash"' , async function ( ) {
133- const relayBlock = await relay . call ( 'eth_getBlockByHash' , [ mirrorBlock . hash , 'true' ] ) ;
134- Assertions . block ( relayBlock , mirrorBlock ) ;
161+ it ( 'should execute "eth_getBlockByHash" for non-existing block hash and hydrated transactions = false ' , async function ( ) {
162+ const blockResult = await relay . call ( 'eth_getBlockByHash' , [ NON_EXISTING_BLOCK_HASH , false ] ) ;
163+ expect ( blockResult ) . to . be . null ;
135164 } ) ;
136165
137- it ( 'should execute "eth_getBlockByNumber"' , async function ( ) {
166+ it ( 'should execute "eth_getBlockByHash" for non-existing block hash and hydrated transactions = true' , async function ( ) {
167+ const blockResult = await relay . call ( 'eth_getBlockByHash' , [ NON_EXISTING_BLOCK_HASH , true ] ) ;
168+ expect ( blockResult ) . to . be . null ;
169+ } ) ;
170+
171+ it ( 'should execute "eth_getBlockByNumber", hydrated transactions not specified' , async function ( ) {
172+ const blockResult = await relay . call ( 'eth_getBlockByNumber' , [ mirrorBlock . number ] ) ;
173+ Assertions . block ( blockResult , mirrorBlock , mirrorTransactions , false ) ;
174+ } ) ;
175+
176+ it ( 'should execute "eth_getBlockByNumber", hydrated transactions = false' , async function ( ) {
177+ const blockResult = await relay . call ( 'eth_getBlockByNumber' , [ mirrorBlock . number , false ] ) ;
178+ Assertions . block ( blockResult , mirrorBlock , mirrorTransactions , false ) ;
179+ } ) ;
180+
181+ it ( 'should execute "eth_getBlockByNumber", hydrated transactions = true' , async function ( ) {
138182 const blockResult = await relay . call ( 'eth_getBlockByNumber' , [ mirrorBlock . number , true ] ) ;
139- Assertions . block ( blockResult , mirrorBlock ) ;
183+ Assertions . block ( blockResult , mirrorBlock , mirrorTransactions , true ) ;
184+ } ) ;
185+
186+ it ( 'should execute "eth_getBlockByNumber" for non existing block number and hydrated transactions = true' , async function ( ) {
187+ const blockResult = await relay . call ( 'eth_getBlockByNumber' , [ NON_EXISTING_BLOCK_NUMBER , true ] ) ;
188+ expect ( blockResult ) . to . be . null ;
189+ } ) ;
190+
191+ it ( 'should execute "eth_getBlockByNumber" for non existing block number and hydrated transactions = false' , async function ( ) {
192+ const blockResult = await relay . call ( 'eth_getBlockByNumber' , [ NON_EXISTING_BLOCK_NUMBER , false ] ) ;
193+ expect ( blockResult ) . to . be . null ;
140194 } ) ;
141195
142196 it ( 'should execute "eth_getBlockTransactionCountByHash"' , async function ( ) {
143197 const res = await relay . call ( 'eth_getBlockTransactionCountByHash' , [ mirrorBlock . hash ] ) ;
144198 expect ( res ) . to . be . equal ( mirrorBlock . count ) ;
145199 } ) ;
146200
201+ it ( 'should execute "eth_getBlockTransactionCountByHash" for non-existing block hash' , async function ( ) {
202+ const res = await relay . call ( 'eth_getBlockTransactionCountByHash' , [ NON_EXISTING_BLOCK_HASH ] ) ;
203+ expect ( res ) . to . be . null ;
204+ } ) ;
205+
147206 it ( 'should execute "eth_getBlockTransactionCountByNumber"' , async function ( ) {
148207 const res = await relay . call ( 'eth_getBlockTransactionCountByNumber' , [ mirrorBlock . number ] ) ;
149208 expect ( res ) . to . be . equal ( mirrorBlock . count ) ;
150209 } ) ;
151210
211+ it ( 'should execute "eth_getBlockTransactionCountByNumber" for non-existing block number' , async function ( ) {
212+ const res = await relay . call ( 'eth_getBlockTransactionCountByNumber' , [ NON_EXISTING_BLOCK_NUMBER ] ) ;
213+ expect ( res ) . to . be . null ;
214+ } ) ;
215+
216+ it ( 'should execute "eth_blockNumber"' , async function ( ) {
217+
218+ const mirrorBlocks = await mirrorNode . get ( `blocks` ) ;
219+ expect ( mirrorBlocks ) . to . have . property ( 'blocks' ) ;
220+ expect ( mirrorBlocks . blocks . length ) . to . gt ( 0 ) ;
221+ const mirrorBlockNumber = mirrorBlocks . blocks [ 0 ] . number ;
222+
223+ const res = await relay . call ( 'eth_blockNumber' , [ ] ) ;
224+ const blockNumber = Number ( res ) ;
225+ expect ( blockNumber ) . to . exist ;
226+
227+ // In some rare occasions, the relay block might be equal to the mirror node block + 1
228+ // due to the mirror node block updating after it was retrieved and before the relay.call completes
229+ expect ( blockNumber ) . to . be . oneOf ( [ mirrorBlockNumber , mirrorBlockNumber + 1 ] ) ;
230+ } ) ;
152231 } ) ;
153232
154233 describe ( 'Transaction related RPC Calls' , ( ) => {
@@ -187,11 +266,33 @@ describe('RPC Server Acceptance Tests', function() {
187266 Assertions . transaction ( response , mirrorContractDetails ) ;
188267 } ) ;
189268
269+ it ( 'should execute "eth_getTransactionByBlockHashAndIndex" for invalid block hash' , async function ( ) {
270+ const response = await relay . call ( 'eth_getTransactionByBlockHashAndIndex' ,
271+ [ NON_EXISTING_BLOCK_HASH , mirrorContractDetails . transaction_index ] ) ;
272+ expect ( response ) . to . be . null ;
273+ } ) ;
274+
275+ it ( 'should execute "eth_getTransactionByBlockHashAndIndex" for invalid index' , async function ( ) {
276+ const response = await relay . call ( 'eth_getTransactionByBlockHashAndIndex' ,
277+ [ mirrorContractDetails . block_hash , NON_EXISTING_INDEX ] ) ;
278+ expect ( response ) . to . be . null ;
279+ } ) ;
280+
190281 it ( 'should execute "eth_getTransactionByBlockNumberAndIndex"' , async function ( ) {
191282 const response = await relay . call ( 'eth_getTransactionByBlockNumberAndIndex' , [ mirrorContractDetails . block_number , mirrorContractDetails . transaction_index ] ) ;
192283 Assertions . transaction ( response , mirrorContractDetails ) ;
193284 } ) ;
194285
286+ it ( 'should execute "eth_getTransactionByBlockNumberAndIndex" for invalid index' , async function ( ) {
287+ const response = await relay . call ( 'eth_getTransactionByBlockNumberAndIndex' , [ mirrorContractDetails . block_number , NON_EXISTING_INDEX ] ) ;
288+ expect ( response ) . to . be . null ;
289+ } ) ;
290+
291+ it ( 'should execute "eth_getTransactionByBlockNumberAndIndex" for non-exising block number' , async function ( ) {
292+ const response = await relay . call ( 'eth_getTransactionByBlockNumberAndIndex' , [ NON_EXISTING_BLOCK_NUMBER , mirrorContractDetails . transaction_index ] ) ;
293+ expect ( response ) . to . be . null ;
294+ } ) ;
295+
195296 it ( 'should execute "eth_getTransactionReceipt" for hash of legacy transaction' , async function ( ) {
196297 const transaction = {
197298 ...default155TransactionData ,
@@ -202,11 +303,11 @@ describe('RPC Server Acceptance Tests', function() {
202303 const legacyTxHash = await relay . sendRawTransaction ( signedTx ) ;
203304 // Since the transactionId is not available in this context
204305 // Wait for the transaction to be processed and imported in the mirror node with axios-retry
205- await mirrorNode . get ( `contracts/results/${ legacyTxHash } ` ) ;
306+ const mirrorResult = await mirrorNode . get ( `contracts/results/${ legacyTxHash } ` ) ;
206307
207308 const res = await relay . call ( 'eth_getTransactionReceipt' , [ legacyTxHash ] ) ;
208309 // FIXME here we must assert that the alias address is the `from` / `to` and not the `0x` prefixed one
209- Assertions . transactionReceipt ( res , transaction , { from : Utils . idToEvmAddress ( accounts [ 2 ] . accountId . toString ( ) ) } ) ;
310+ Assertions . transactionReceipt ( res , mirrorResult ) ;
210311 } ) ;
211312
212313 it ( 'should execute "eth_getTransactionReceipt" for hash of London transaction' , async function ( ) {
@@ -219,16 +320,15 @@ describe('RPC Server Acceptance Tests', function() {
219320 const transactionHash = await relay . sendRawTransaction ( signedTx ) ;
220321 // Since the transactionId is not available in this context
221322 // Wait for the transaction to be processed and imported in the mirror node with axios-retry
222- await mirrorNode . get ( `contracts/results/${ transactionHash } ` ) ;
323+ const mirrorResult = await mirrorNode . get ( `contracts/results/${ transactionHash } ` ) ;
223324
224325 const res = await relay . call ( 'eth_getTransactionReceipt' , [ transactionHash ] ) ;
225326 // FIXME here we must assert that the alias address is the `from` / `to` and not the `0x` prefixed one
226- Assertions . transactionReceipt ( res , transaction , { from : Utils . idToEvmAddress ( accounts [ 2 ] . accountId . toString ( ) ) } ) ;
327+ Assertions . transactionReceipt ( res , mirrorResult ) ;
227328 } ) ;
228329
229330 it ( 'should execute "eth_getTransactionReceipt" for non-existing hash' , async function ( ) {
230- const nonExistingTxHash = '0x5555555555555555555555555555555555555555555555555555555555555555' ;
231- const res = await relay . call ( 'eth_getTransactionReceipt' , [ nonExistingTxHash ] ) ;
331+ const res = await relay . call ( 'eth_getTransactionReceipt' , [ NON_EXISTING_TX_HASH ] ) ;
232332 expect ( res ) . to . be . null ;
233333 } ) ;
234334
@@ -321,7 +421,7 @@ describe('RPC Server Acceptance Tests', function() {
321421 } ) ;
322422
323423 it ( 'should execute "eth_getTransactionCount" for account with non-zero nonce' , async function ( ) {
324- const account = await servicesNode . createAliasAccount ( 10 ) ;
424+ const account = await servicesNode . createAliasAccount ( ) ;
325425 // Wait for account creation to propagate
326426 await mirrorNode . get ( `/accounts/${ account . accountId } ` ) ;
327427 const transaction = {
@@ -339,6 +439,25 @@ describe('RPC Server Acceptance Tests', function() {
339439 const res = await relay . call ( 'eth_getTransactionCount' , [ account . address , 'latest' ] ) ;
340440 expect ( res ) . to . be . equal ( '0x1' ) ;
341441 } ) ;
442+
443+ it ( 'should execute "eth_getTransactionByHash" for existing transaction' , async function ( ) {
444+ const transaction = {
445+ ...defaultLondonTransactionData ,
446+ to : mirrorContract . evm_address ,
447+ nonce : await relay . getAccountNonce ( accounts [ 2 ] . address )
448+ } ;
449+ const signedTx = await accounts [ 2 ] . wallet . signTransaction ( transaction ) ;
450+ const transactionHash = await relay . sendRawTransaction ( signedTx ) ;
451+ const mirrorTransaction = await mirrorNode . get ( `/contracts/results/${ transactionHash } ` ) ;
452+
453+ const res = await relay . call ( 'eth_getTransactionByHash' , [ transactionHash ] ) ;
454+ Assertions . transaction ( res , mirrorTransaction ) ;
455+ } ) ;
456+
457+ it ( 'should execute "eth_getTransactionByHash" for non-existing transaction and return null' , async function ( ) {
458+ const res = await relay . call ( 'eth_getTransactionByHash' , [ NON_EXISTING_TX_HASH ] ) ;
459+ expect ( res ) . to . be . null ;
460+ } ) ;
342461 } ) ;
343462
344463 it ( 'should execute "eth_estimateGas"' , async function ( ) {
@@ -381,6 +500,11 @@ describe('RPC Server Acceptance Tests', function() {
381500 } ) ;
382501
383502 describe ( 'Hardcoded RPC Endpoints' , ( ) => {
503+ let mirrorBlock ;
504+
505+ before ( async ( ) => {
506+ mirrorBlock = ( await mirrorNode . get ( `/blocks?block.number=${ mirrorContractDetails . block_number } ` ) ) . blocks [ 0 ] ;
507+ } ) ;
384508
385509 it ( 'should execute "eth_chainId"' , async function ( ) {
386510 const res = await relay . call ( 'eth_chainId' , [ null ] ) ;
@@ -398,12 +522,22 @@ describe('RPC Server Acceptance Tests', function() {
398522 } ) ;
399523
400524 it ( 'should execute "eth_getUncleByBlockHashAndIndex"' , async function ( ) {
401- const res = await relay . call ( 'eth_getUncleByBlockHashAndIndex' , [ ] ) ;
525+ const res = await relay . call ( 'eth_getUncleByBlockHashAndIndex' , [ mirrorBlock . hash , 0 ] ) ;
526+ expect ( res ) . to . be . null ;
527+ } ) ;
528+
529+ it ( 'should execute "eth_getUncleByBlockHashAndIndex" for non-existing block hash and index=0' , async function ( ) {
530+ const res = await relay . call ( 'eth_getUncleByBlockHashAndIndex' , [ NON_EXISTING_BLOCK_HASH , 0 ] ) ;
402531 expect ( res ) . to . be . null ;
403532 } ) ;
404533
405534 it ( 'should execute "eth_getUncleByBlockNumberAndIndex"' , async function ( ) {
406- const res = await relay . call ( 'eth_getUncleByBlockNumberAndIndex' , [ ] ) ;
535+ const res = await relay . call ( 'eth_getUncleByBlockNumberAndIndex' , [ mirrorBlock . number , 0 ] ) ;
536+ expect ( res ) . to . be . null ;
537+ } ) ;
538+
539+ it ( 'should execute "eth_getUncleByBlockNumberAndIndex" for non-existing block number and index=0' , async function ( ) {
540+ const res = await relay . call ( 'eth_getUncleByBlockNumberAndIndex' , [ NON_EXISTING_BLOCK_NUMBER , 0 ] ) ;
407541 expect ( res ) . to . be . null ;
408542 } ) ;
409543
0 commit comments