@@ -11,6 +11,7 @@ import (
11
11
"github.com/NethermindEth/juno/core"
12
12
"github.com/NethermindEth/juno/core/felt"
13
13
"github.com/NethermindEth/juno/db"
14
+ "github.com/NethermindEth/juno/jsonrpc"
14
15
"github.com/NethermindEth/juno/mocks"
15
16
rpccore "github.com/NethermindEth/juno/rpc/rpccore"
16
17
rpc "github.com/NethermindEth/juno/rpc/v6"
@@ -587,6 +588,243 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
587
588
})
588
589
}
589
590
591
+ func TestTransactionReceiptByHash (t * testing.T ) {
592
+ t .Run ("internal error when returning tx by hash from DB" , func (t * testing.T ) {
593
+ mockCtrl := gomock .NewController (t )
594
+ t .Cleanup (mockCtrl .Finish )
595
+
596
+ mockReader := mocks .NewMockReader (mockCtrl )
597
+ handler := rpc .New (mockReader , nil , nil , "" , & utils .Sepolia , nil )
598
+
599
+ mockReader .EXPECT ().TransactionByHash (gomock .Any ()).Return (nil , errors .New ("some internal error" ))
600
+
601
+ txHash := new (felt.Felt ).SetBytes ([]byte ("some tx hash" ))
602
+ tx , rpcErr := handler .TransactionReceiptByHash (* txHash )
603
+
604
+ assert .Nil (t , tx )
605
+ assert .Equal (t , rpccore .ErrInternal .CloneWithData (errors .New ("some internal error" )), rpcErr )
606
+ })
607
+
608
+ t .Run ("not found if pending block nil" , func (t * testing.T ) {
609
+ mockCtrl := gomock .NewController (t )
610
+ t .Cleanup (mockCtrl .Finish )
611
+
612
+ mockReader := mocks .NewMockReader (mockCtrl )
613
+ mockSyncReader := mocks .NewMockSyncReader (mockCtrl )
614
+ handler := rpc .New (mockReader , mockSyncReader , nil , "" , & utils .Sepolia , nil )
615
+
616
+ mockReader .EXPECT ().TransactionByHash (gomock .Any ()).Return (nil , db .ErrKeyNotFound )
617
+ mockSyncReader .EXPECT ().PendingBlock ().Return (nil )
618
+
619
+ txHash := new (felt.Felt ).SetBytes ([]byte ("some tx hash" ))
620
+ tx , rpcErr := handler .TransactionReceiptByHash (* txHash )
621
+
622
+ assert .Nil (t , tx )
623
+ assert .Equal (t , rpccore .ErrTxnHashNotFound , rpcErr )
624
+ })
625
+
626
+ t .Run ("not found in non-nil pending block" , func (t * testing.T ) {
627
+ mockCtrl := gomock .NewController (t )
628
+ t .Cleanup (mockCtrl .Finish )
629
+
630
+ mockReader := mocks .NewMockReader (mockCtrl )
631
+ mockSyncReader := mocks .NewMockSyncReader (mockCtrl )
632
+ n := & utils .Sepolia
633
+ handler := rpc .New (mockReader , mockSyncReader , nil , "" , n , nil )
634
+
635
+ mockReader .EXPECT ().TransactionByHash (gomock .Any ()).Return (nil , db .ErrKeyNotFound )
636
+
637
+ client := feeder .NewTestClient (t , n )
638
+ gateway := adaptfeeder .New (client )
639
+ mockSyncReader .EXPECT ().PendingBlock ().DoAndReturn (func () * core.Block {
640
+ block , err := gateway .BlockByNumber (context .Background (), 4850 )
641
+ require .NoError (t , err )
642
+
643
+ return block
644
+ })
645
+
646
+ unexistingTxHashInBlock := utils .HexToFelt (t , "0x123" )
647
+ tx , rpcErr := handler .TransactionReceiptByHash (* unexistingTxHashInBlock )
648
+
649
+ assert .Nil (t , tx )
650
+ assert .Equal (t , rpccore .ErrTxnHashNotFound , rpcErr )
651
+ })
652
+
653
+ t .Run ("receipt not found (even though tx is found)" , func (t * testing.T ) {
654
+ mockCtrl := gomock .NewController (t )
655
+ t .Cleanup (mockCtrl .Finish )
656
+
657
+ mockReader := mocks .NewMockReader (mockCtrl )
658
+ mockSyncReader := mocks .NewMockSyncReader (mockCtrl )
659
+ n := & utils .Sepolia
660
+ handler := rpc .New (mockReader , mockSyncReader , nil , "" , n , nil )
661
+
662
+ client := feeder .NewTestClient (t , n )
663
+ gateway := adaptfeeder .New (client )
664
+ block , err := gateway .BlockByNumber (context .Background (), 4850 )
665
+ require .NoError (t , err )
666
+
667
+ tx0HashInBlock4850 := utils .HexToFelt (t , "0x236102aee88702cfa0546d84e54967e3de1ec6b784bc27364bbbdd25931140c" )
668
+
669
+ mockReader .EXPECT ().TransactionByHash (tx0HashInBlock4850 ).Return (block .Transactions [0 ], nil )
670
+ mockReader .EXPECT ().Receipt (tx0HashInBlock4850 ).Return (nil , nil , uint64 (0 ), errors .New ("some error" ))
671
+
672
+ txReceipt , rpcErr := handler .TransactionReceiptByHash (* tx0HashInBlock4850 )
673
+
674
+ assert .Nil (t , txReceipt )
675
+ assert .Equal (t , rpccore .ErrTxnHashNotFound , rpcErr )
676
+ })
677
+
678
+ t .Run ("internal error when verifying finality status" , func (t * testing.T ) {
679
+ mockCtrl := gomock .NewController (t )
680
+ t .Cleanup (mockCtrl .Finish )
681
+
682
+ mockReader := mocks .NewMockReader (mockCtrl )
683
+ mockSyncReader := mocks .NewMockSyncReader (mockCtrl )
684
+ n := & utils .Sepolia
685
+ handler := rpc .New (mockReader , mockSyncReader , nil , "" , n , nil )
686
+
687
+ client := feeder .NewTestClient (t , n )
688
+ gateway := adaptfeeder .New (client )
689
+ block , err := gateway .BlockByNumber (context .Background (), 4850 )
690
+ require .NoError (t , err )
691
+
692
+ tx0HashInBlock4850 := utils .HexToFelt (t , "0x236102aee88702cfa0546d84e54967e3de1ec6b784bc27364bbbdd25931140c" )
693
+
694
+ mockReader .EXPECT ().TransactionByHash (tx0HashInBlock4850 ).Return (block .Transactions [0 ], nil )
695
+ mockReader .EXPECT ().Receipt (tx0HashInBlock4850 ).Return (block .Receipts [0 ], block .Hash , block .Number , nil )
696
+ mockReader .EXPECT ().L1Head ().Return (nil , errors .New ("some internal error" ))
697
+
698
+ txReceipt , rpcErr := handler .TransactionReceiptByHash (* tx0HashInBlock4850 )
699
+
700
+ assert .Nil (t , txReceipt )
701
+ assert .Equal (t , jsonrpc .Err (jsonrpc .InternalError , "some internal error" ), rpcErr )
702
+ })
703
+
704
+ t .Run ("found in pending block" , func (t * testing.T ) {
705
+ mockCtrl := gomock .NewController (t )
706
+ t .Cleanup (mockCtrl .Finish )
707
+
708
+ mockReader := mocks .NewMockReader (mockCtrl )
709
+ mockSyncReader := mocks .NewMockSyncReader (mockCtrl )
710
+ n := & utils .Sepolia
711
+ handler := rpc .New (mockReader , mockSyncReader , nil , "" , n , nil )
712
+
713
+ mockReader .EXPECT ().TransactionByHash (gomock .Any ()).Return (nil , db .ErrKeyNotFound )
714
+
715
+ client := feeder .NewTestClient (t , n )
716
+ gateway := adaptfeeder .New (client )
717
+ mockSyncReader .EXPECT ().PendingBlock ().DoAndReturn (func () * core.Block {
718
+ block , err := gateway .BlockByNumber (context .Background (), 4850 )
719
+ require .NoError (t , err )
720
+
721
+ return block
722
+ })
723
+
724
+ tx0HashInBlock4850 := utils .HexToFelt (t , "0x236102aee88702cfa0546d84e54967e3de1ec6b784bc27364bbbdd25931140c" )
725
+ txReceipt , rpcErr := handler .TransactionReceiptByHash (* tx0HashInBlock4850 )
726
+
727
+ expectedReceipt := rpc.TransactionReceipt {
728
+ FinalityStatus : rpc .TxnAcceptedOnL2 ,
729
+ ExecutionStatus : rpc .TxnSuccess ,
730
+ Type : rpc .TxnInvoke ,
731
+ Hash : tx0HashInBlock4850 ,
732
+ ActualFee : & rpc.FeePayment {
733
+ Amount : utils .HexToFelt (t , "0x4e7f9f784c0" ),
734
+ Unit : rpc .WEI ,
735
+ },
736
+ // nil because pending block
737
+ BlockHash : nil ,
738
+ BlockNumber : nil ,
739
+ MessagesSent : []* rpc.MsgToL1 {},
740
+ Events : []* rpc.Event {{
741
+ From : utils .HexToFelt (t , "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" ),
742
+ Keys : []* felt.Felt {
743
+ utils .HexToFelt (t , "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ),
744
+ },
745
+ Data : []* felt.Felt {
746
+ utils .HexToFelt (t , "0x60664b576dae484dc3430ed3b1036e7879712e2c2c2728f568b8dbcbbc0f655" ),
747
+ utils .HexToFelt (t , "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8" ),
748
+ utils .HexToFelt (t , "0x4e7f9f784c0" ),
749
+ utils .HexToFelt (t , "0x0" ),
750
+ },
751
+ }},
752
+ ExecutionResources : & rpc.ExecutionResources {
753
+ ComputationResources : rpc.ComputationResources {
754
+ Steps : 6172 ,
755
+ Pedersen : 16 ,
756
+ RangeCheck : 208 ,
757
+ Ecdsa : 1 ,
758
+ },
759
+ },
760
+ }
761
+
762
+ assert .Nil (t , rpcErr )
763
+ assert .Equal (t , & expectedReceipt , txReceipt )
764
+ })
765
+
766
+ t .Run ("found in (non-pending) block" , func (t * testing.T ) {
767
+ mockCtrl := gomock .NewController (t )
768
+ t .Cleanup (mockCtrl .Finish )
769
+
770
+ mockReader := mocks .NewMockReader (mockCtrl )
771
+ mockSyncReader := mocks .NewMockSyncReader (mockCtrl )
772
+ n := & utils .Sepolia
773
+ handler := rpc .New (mockReader , mockSyncReader , nil , "" , n , nil )
774
+
775
+ client := feeder .NewTestClient (t , n )
776
+ gateway := adaptfeeder .New (client )
777
+ block , err := gateway .BlockByNumber (context .Background (), 4850 )
778
+ require .NoError (t , err )
779
+
780
+ tx0HashInBlock4850 := utils .HexToFelt (t , "0x236102aee88702cfa0546d84e54967e3de1ec6b784bc27364bbbdd25931140c" )
781
+
782
+ mockReader .EXPECT ().TransactionByHash (tx0HashInBlock4850 ).Return (block .Transactions [0 ], nil )
783
+ mockReader .EXPECT ().Receipt (tx0HashInBlock4850 ).Return (block .Receipts [0 ], block .Hash , block .Number , nil )
784
+ mockReader .EXPECT ().L1Head ().Return (& core.L1Head {BlockNumber : 4851 }, nil ) // block number not very important here
785
+
786
+ txReceipt , rpcErr := handler .TransactionReceiptByHash (* tx0HashInBlock4850 )
787
+
788
+ expectedBlockNumber := uint64 (4850 )
789
+ expectedReceipt := rpc.TransactionReceipt {
790
+ FinalityStatus : rpc .TxnAcceptedOnL1 ,
791
+ ExecutionStatus : rpc .TxnSuccess ,
792
+ Type : rpc .TxnInvoke ,
793
+ Hash : tx0HashInBlock4850 ,
794
+ ActualFee : & rpc.FeePayment {
795
+ Amount : utils .HexToFelt (t , "0x4e7f9f784c0" ),
796
+ Unit : rpc .WEI ,
797
+ },
798
+ BlockHash : utils .HexToFelt (t , "0x410dfca0f99545e62aef946e228329ce3a906f6785f5e6f97389f30ad1c1088" ),
799
+ BlockNumber : & expectedBlockNumber ,
800
+ MessagesSent : []* rpc.MsgToL1 {},
801
+ Events : []* rpc.Event {{
802
+ From : utils .HexToFelt (t , "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" ),
803
+ Keys : []* felt.Felt {
804
+ utils .HexToFelt (t , "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ),
805
+ },
806
+ Data : []* felt.Felt {
807
+ utils .HexToFelt (t , "0x60664b576dae484dc3430ed3b1036e7879712e2c2c2728f568b8dbcbbc0f655" ),
808
+ utils .HexToFelt (t , "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8" ),
809
+ utils .HexToFelt (t , "0x4e7f9f784c0" ),
810
+ utils .HexToFelt (t , "0x0" ),
811
+ },
812
+ }},
813
+ ExecutionResources : & rpc.ExecutionResources {
814
+ ComputationResources : rpc.ComputationResources {
815
+ Steps : 6172 ,
816
+ Pedersen : 16 ,
817
+ RangeCheck : 208 ,
818
+ Ecdsa : 1 ,
819
+ },
820
+ },
821
+ }
822
+
823
+ assert .Nil (t , rpcErr )
824
+ assert .Equal (t , & expectedReceipt , txReceipt )
825
+ })
826
+ }
827
+
590
828
//nolint:dupl
591
829
func TestLegacyTransactionReceiptByHash (t * testing.T ) {
592
830
t .Skip ()
@@ -1295,8 +1533,10 @@ func TestTransactionStatus(t *testing.T) {
1295
1533
for description , notFoundTest := range notFoundTests {
1296
1534
t .Run (description , func (t * testing.T ) {
1297
1535
mockReader := mocks .NewMockReader (mockCtrl )
1536
+ syncReader := mocks .NewMockSyncReader (mockCtrl )
1298
1537
mockReader .EXPECT ().TransactionByHash (notFoundTest .hash ).Return (nil , db .ErrKeyNotFound ).Times (2 )
1299
- handler := rpc .New (mockReader , nil , nil , "" , test .network , nil )
1538
+ syncReader .EXPECT ().PendingBlock ().Return (nil ).Times (2 )
1539
+ handler := rpc .New (mockReader , syncReader , nil , "" , test .network , nil )
1300
1540
_ , err := handler .TransactionStatus (ctx , * notFoundTest .hash )
1301
1541
require .Equal (t , rpccore .ErrTxnHashNotFound .Code , err .Code )
1302
1542
@@ -1309,11 +1549,12 @@ func TestTransactionStatus(t *testing.T) {
1309
1549
}
1310
1550
})
1311
1551
1312
- // transaction no† found in db and feeder
1313
- t .Run ("transaction not found in db and feeder " , func (t * testing.T ) {
1552
+ t .Run ("transaction not found in db and feeder" , func (t * testing.T ) {
1314
1553
mockReader := mocks .NewMockReader (mockCtrl )
1554
+ syncReader := mocks .NewMockSyncReader (mockCtrl )
1315
1555
mockReader .EXPECT ().TransactionByHash (test .notFoundTxHash ).Return (nil , db .ErrKeyNotFound )
1316
- handler := rpc .New (mockReader , nil , nil , "" , test .network , nil ).WithFeeder (client )
1556
+ syncReader .EXPECT ().PendingBlock ().Return (nil )
1557
+ handler := rpc .New (mockReader , syncReader , nil , "" , test .network , nil ).WithFeeder (client )
1317
1558
1318
1559
_ , err := handler .TransactionStatus (ctx , * test .notFoundTxHash )
1319
1560
require .NotNil (t , err )
0 commit comments