@@ -22,7 +22,7 @@ import { expect } from 'chai';
22
22
import { ethers } from 'ethers' ;
23
23
24
24
import { ConfigServiceTestHelper } from '../../../config-service/tests/configServiceTestHelper' ;
25
- import { withOverriddenEnvsInMochaTest } from '../../../relay/tests/helpers' ;
25
+ import { overrideEnvsInMochaDescribe , withOverriddenEnvsInMochaTest } from '../../../relay/tests/helpers' ;
26
26
import basicContract from '../../tests/contracts/Basic.json' ;
27
27
import RelayCalls from '../../tests/helpers/constants' ;
28
28
import MirrorClient from '../clients/mirrorClient' ;
@@ -32,6 +32,7 @@ import basicContractJson from '../contracts/Basic.json';
32
32
import logsContractJson from '../contracts/Logs.json' ;
33
33
// Local resources from contracts directory
34
34
import parentContractJson from '../contracts/Parent.json' ;
35
+ import reverterContractJson from '../contracts/Reverter.json' ;
35
36
// Assertions from local resources
36
37
import Assertions from '../helpers/assertions' ;
37
38
import { Utils } from '../helpers/utils' ;
@@ -765,6 +766,287 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () {
765
766
type : 1 ,
766
767
} ;
767
768
769
+ describe ( 'Transaction Pool feature' , async ( ) => {
770
+ describe ( 'ENABLE_TX_POOL = true' , async ( ) => {
771
+ overrideEnvsInMochaDescribe ( { ENABLE_TX_POOL : true } ) ;
772
+ it ( 'should have equal nonces (pending and latest) after successful validated transaction' , async ( ) => {
773
+ const tx = {
774
+ ...defaultLondonTransactionData ,
775
+ to : accounts [ 2 ] . address ,
776
+ nonce : await relay . getAccountNonce ( accounts [ 1 ] . address ) ,
777
+ } ;
778
+ const signedTx = await accounts [ 1 ] . wallet . signTransaction ( tx ) ;
779
+ const txHash = await relay . sendRawTransaction ( signedTx ) ;
780
+ await relay . pollForValidTransactionReceipt ( txHash ) ;
781
+
782
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
783
+ const noncePending = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
784
+
785
+ expect ( nonceLatest ) . to . equal ( noncePending ) ;
786
+ } ) ;
787
+
788
+ it ( 'should have equal nonces (pending and latest) after CN reverted transaction' , async ( ) => {
789
+ const tx = {
790
+ ...defaultLondonTransactionData ,
791
+ to : null ,
792
+ data : '0x' + '00' . repeat ( 5121 ) ,
793
+ nonce : await relay . getAccountNonce ( accounts [ 1 ] . address ) ,
794
+ gasLimit : 41484 ,
795
+ } ;
796
+ const signedTx = await accounts [ 1 ] . wallet . signTransaction ( tx ) ;
797
+ const txHash = await relay . sendRawTransaction ( signedTx ) ;
798
+ await relay . pollForValidTransactionReceipt ( txHash ) ;
799
+ const mnResult = await mirrorNode . get ( `/contracts/results/${ txHash } ` ) ;
800
+
801
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
802
+ const noncePending = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
803
+
804
+ expect ( mnResult . result ) . to . equal ( 'INSUFFICIENT_GAS' ) ;
805
+ expect ( nonceLatest ) . to . equal ( noncePending ) ;
806
+ } ) ;
807
+
808
+ it ( 'should have equal nonces (pending and latest) after multiple CN reverted transactions' , async ( ) => {
809
+ const accountNonce = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
810
+ const tx1 = {
811
+ ...defaultLondonTransactionData ,
812
+ to : null ,
813
+ data : '0x' + '00' . repeat ( 5121 ) ,
814
+ nonce : accountNonce ,
815
+ gasLimit : 41484 ,
816
+ } ;
817
+ const tx2 = {
818
+ ...defaultLondonTransactionData ,
819
+ to : accounts [ 2 ] . address ,
820
+ nonce : accountNonce ,
821
+ gasLimit : 21000 ,
822
+ } ;
823
+ const tx3 = {
824
+ ...defaultLondonTransactionData ,
825
+ to : null ,
826
+ data : '0x' + '00' . repeat ( 5121 ) ,
827
+ nonce : accountNonce + 1 ,
828
+ gasLimit : 41484 ,
829
+ } ;
830
+ const signedTx1 = await accounts [ 1 ] . wallet . signTransaction ( tx1 ) ;
831
+ const signedTx2 = await accounts [ 1 ] . wallet . signTransaction ( tx2 ) ;
832
+ const signedTx3 = await accounts [ 1 ] . wallet . signTransaction ( tx3 ) ;
833
+
834
+ const txHash1 = await relay . sendRawTransaction ( signedTx1 ) ;
835
+ await new Promise ( ( r ) => setTimeout ( r , 100 ) ) ;
836
+ const txHash2 = await relay . sendRawTransaction ( signedTx2 ) ;
837
+ await new Promise ( ( r ) => setTimeout ( r , 100 ) ) ;
838
+ const txHash3 = await relay . sendRawTransaction ( signedTx3 ) ;
839
+
840
+ await Promise . all ( [
841
+ relay . pollForValidTransactionReceipt ( txHash1 ) ,
842
+ relay . pollForValidTransactionReceipt ( txHash2 ) ,
843
+ relay . pollForValidTransactionReceipt ( txHash3 ) ,
844
+ ] ) ;
845
+
846
+ const [ mnResult1 , mnResult2 , mnResult3 ] = await Promise . all ( [
847
+ mirrorNode . get ( `/contracts/results/${ txHash1 } ` ) ,
848
+ mirrorNode . get ( `/contracts/results/${ txHash2 } ` ) ,
849
+ mirrorNode . get ( `/contracts/results/${ txHash3 } ` ) ,
850
+ ] ) ;
851
+
852
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
853
+ const noncePending = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
854
+
855
+ expect ( mnResult1 . result ) . to . equal ( 'INSUFFICIENT_GAS' ) ;
856
+ expect ( mnResult2 . result ) . to . equal ( 'SUCCESS' ) ;
857
+ expect ( mnResult3 . result ) . to . equal ( 'INSUFFICIENT_GAS' ) ;
858
+ expect ( nonceLatest ) . to . equal ( noncePending ) ;
859
+ } ) ;
860
+
861
+ it ( 'should have equal nonces (pending and latest_ for contract reverted transaction' , async ( ) => {
862
+ const reverterContract = await Utils . deployContract (
863
+ reverterContractJson . abi ,
864
+ reverterContractJson . bytecode ,
865
+ accounts [ 0 ] . wallet ,
866
+ ) ;
867
+
868
+ const tx = {
869
+ ...defaultLondonTransactionData ,
870
+ to : reverterContract . target ,
871
+ data : '0xd0efd7ef' ,
872
+ nonce : await relay . getAccountNonce ( accounts [ 1 ] . address ) ,
873
+ value : ONE_TINYBAR ,
874
+ } ;
875
+ const signedTx = await accounts [ 1 ] . wallet . signTransaction ( tx ) ;
876
+ const txHash = await relay . sendRawTransaction ( signedTx ) ;
877
+ await relay . pollForValidTransactionReceipt ( txHash ) ;
878
+ const mnResult = await mirrorNode . get ( `/contracts/results/${ txHash } ` ) ;
879
+
880
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
881
+ const noncePending = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
882
+
883
+ expect ( mnResult . result ) . to . equal ( 'CONTRACT_REVERT_EXECUTED' ) ;
884
+ expect ( nonceLatest ) . to . equal ( noncePending ) ;
885
+ } ) ;
886
+
887
+ it ( 'scenario #5' , async ( ) => { } ) ;
888
+
889
+ it ( 'should have difference between pending and latest nonce when a single transaction has been sent' , async ( ) => {
890
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
891
+ const signedTx1 = await accounts [ 1 ] . wallet . signTransaction ( {
892
+ ...defaultLondonTransactionData ,
893
+ to : accounts [ 2 ] . address ,
894
+ nonce : nonceLatest ,
895
+ gasLimit : 21000 ,
896
+ } ) ;
897
+ const txHash1 = await relay . sendRawTransaction ( signedTx1 ) ;
898
+
899
+ const noncePending = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
900
+ const signedTx2 = await accounts [ 1 ] . wallet . signTransaction ( {
901
+ ...defaultLondonTransactionData ,
902
+ to : accounts [ 2 ] . address ,
903
+ nonce : noncePending ,
904
+ gasLimit : 21000 ,
905
+ } ) ;
906
+ const txHash2 = await relay . sendRawTransaction ( signedTx2 ) ;
907
+
908
+ const [ receipt1 , receipt2 ] = await Promise . all ( [
909
+ relay . pollForValidTransactionReceipt ( txHash1 ) ,
910
+ relay . pollForValidTransactionReceipt ( txHash2 ) ,
911
+ ] ) ;
912
+
913
+ expect ( receipt1 . status ) . to . equal ( '0x1' ) ;
914
+ expect ( receipt2 . status ) . to . equal ( '0x1' ) ;
915
+ expect ( nonceLatest ) . to . be . lessThan ( noncePending ) ;
916
+ } ) ;
917
+
918
+ it ( 'should have difference between pending and latest nonce when multiple transactions have been sent simultaneously' , async ( ) => {
919
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
920
+ const signedTx1 = await accounts [ 1 ] . wallet . signTransaction ( {
921
+ ...defaultLondonTransactionData ,
922
+ to : accounts [ 2 ] . address ,
923
+ nonce : nonceLatest ,
924
+ gasLimit : 21000 ,
925
+ } ) ;
926
+ const txHash1 = await relay . sendRawTransaction ( signedTx1 ) ;
927
+
928
+ const noncePendingTx2 = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
929
+ const signedTx2 = await accounts [ 1 ] . wallet . signTransaction ( {
930
+ ...defaultLondonTransactionData ,
931
+ to : accounts [ 2 ] . address ,
932
+ nonce : noncePendingTx2 ,
933
+ gasLimit : 21000 ,
934
+ } ) ;
935
+ const txHash2 = await relay . sendRawTransaction ( signedTx2 ) ;
936
+
937
+ const noncePendingTx3 = await relay . getAccountNonce ( accounts [ 1 ] . address , 'pending' ) ;
938
+ const signedTx3 = await accounts [ 1 ] . wallet . signTransaction ( {
939
+ ...defaultLondonTransactionData ,
940
+ to : accounts [ 2 ] . address ,
941
+ nonce : noncePendingTx3 ,
942
+ gasLimit : 21000 ,
943
+ } ) ;
944
+ const txHash3 = await relay . sendRawTransaction ( signedTx3 ) ;
945
+
946
+ const [ receipt1 , receipt2 , receipt3 ] = await Promise . all ( [
947
+ relay . pollForValidTransactionReceipt ( txHash1 ) ,
948
+ relay . pollForValidTransactionReceipt ( txHash2 ) ,
949
+ relay . pollForValidTransactionReceipt ( txHash3 ) ,
950
+ ] ) ;
951
+
952
+ expect ( receipt1 . status ) . to . equal ( '0x1' ) ;
953
+ expect ( receipt2 . status ) . to . equal ( '0x1' ) ;
954
+ expect ( receipt3 . status ) . to . equal ( '0x1' ) ;
955
+ expect ( nonceLatest ) . to . be . lessThan ( noncePendingTx2 ) ;
956
+ expect ( noncePendingTx2 ) . to . be . lessThan ( noncePendingTx3 ) ;
957
+ } ) ;
958
+ } ) ;
959
+
960
+ describe ( 'ENABLE_TX_POOL = false' , async ( ) => {
961
+ overrideEnvsInMochaDescribe ( { ENABLE_TX_POOL : false } ) ;
962
+ it ( 'should return latest nonce after transaction has been sent ' , async ( ) => {
963
+ const nonce = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
964
+ const tx = {
965
+ ...defaultLondonTransactionData ,
966
+ to : accounts [ 2 ] . address ,
967
+ nonce,
968
+ } ;
969
+ const signedTx = await accounts [ 1 ] . wallet . signTransaction ( tx ) ;
970
+ const txHash = await relay . sendRawTransaction ( signedTx ) ;
971
+ await relay . pollForValidTransactionReceipt ( txHash ) ;
972
+
973
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
974
+
975
+ expect ( nonce ) . to . not . equal ( nonceLatest ) ;
976
+ expect ( nonce ) . to . be . lessThan ( nonceLatest ) ;
977
+ } ) ;
978
+
979
+ it ( 'should return equal nonces (pending and latest) when transaction has been sent' , async ( ) => {
980
+ const nonce = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
981
+ const tx = {
982
+ ...defaultLondonTransactionData ,
983
+ to : accounts [ 2 ] . address ,
984
+ nonce,
985
+ } ;
986
+ const signedTx = await accounts [ 1 ] . wallet . signTransaction ( tx ) ;
987
+ await relay . sendRawTransaction ( signedTx ) ;
988
+
989
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
990
+ const noncePending = await relay . getAccountNonce ( accounts [ 1 ] . address , Constants . BLOCK_PENDING ) ;
991
+
992
+ expect ( nonceLatest ) . to . equal ( noncePending ) ;
993
+ } ) ;
994
+
995
+ it ( 'should fail with WRONG_NONCE when multiple transactions have been sent simultaneously' , async ( ) => {
996
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
997
+
998
+ const txs = [ ] ;
999
+ for ( let i = 0 ; i < 10 ; i ++ ) {
1000
+ txs . push (
1001
+ relay . sendRawTransaction (
1002
+ await accounts [ 1 ] . wallet . signTransaction ( {
1003
+ ...defaultLondonTransactionData ,
1004
+ to : accounts [ 2 ] . address ,
1005
+ nonce : nonceLatest + i ,
1006
+ } ) ,
1007
+ ) ,
1008
+ ) ;
1009
+ }
1010
+ const txHashes = await Promise . all ( txs ) ;
1011
+
1012
+ // wait for at least one block time
1013
+ await new Promise ( ( r ) => setTimeout ( r , 2100 ) ) ;
1014
+
1015
+ // currently, there is no way to fetch WRONG_NONCE transactions via MN or on `eth_getTransactionReceipt` by evm hash
1016
+ // eth_sendRawTransaction returns always an evm hash, so as end-users we don't have the transaction id
1017
+
1018
+ // the WRONG_NONCE transactions are filtered out from MN /api/v1/contract/results/<evm_tx_hash>
1019
+ // and /api/v1/transactions/<evm_hash> doesn't exist (only /api/v1/transactions/<transaction_id>
1020
+
1021
+ // the only thing we can rely on right now is the "not found" status that is returned on /api/v1/contracts/results/<evm_hash> by evm tx hash
1022
+ const receipts = await Promise . allSettled (
1023
+ txHashes . map ( ( hash ) => mirrorNode . get ( `/contracts/results/${ hash } ` ) ) ,
1024
+ ) ;
1025
+ const rejected = receipts . filter ( ( receipt ) => receipt . status === 'rejected' ) ;
1026
+ expect ( rejected ) . to . not . be . empty ;
1027
+ rejected . forEach ( ( reject ) => expect ( reject . reason . response . status ) . to . equal ( 404 ) ) ;
1028
+ } ) ;
1029
+ } ) ;
1030
+
1031
+ it ( 'should fail with WRONG_NONCE when a transaction with very high nonce has been sent' , async ( ) => {
1032
+ const nonceLatest = await relay . getAccountNonce ( accounts [ 1 ] . address ) ;
1033
+ const txHash = await relay . sendRawTransaction (
1034
+ await accounts [ 1 ] . wallet . signTransaction ( {
1035
+ ...defaultLondonTransactionData ,
1036
+ to : accounts [ 2 ] . address ,
1037
+ nonce : nonceLatest + 100 ,
1038
+ } ) ,
1039
+ ) ;
1040
+
1041
+ // wait for at least one block time
1042
+ await new Promise ( ( r ) => setTimeout ( r , 2100 ) ) ;
1043
+
1044
+ await expect ( mirrorNode . get ( `/contracts/results/${ txHash } ` ) ) . to . eventually . be . rejected . and . satisfy (
1045
+ ( err : any ) => err . response . status === 404 ,
1046
+ ) ;
1047
+ } ) ;
1048
+ } ) ;
1049
+
768
1050
it ( '@release should execute "eth_getTransactionByBlockHashAndIndex"' , async function ( ) {
769
1051
const response = await relay . call ( RelayCalls . ETH_ENDPOINTS . ETH_GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX , [
770
1052
mirrorContractDetails . block_hash . substring ( 0 , 66 ) ,
0 commit comments