@@ -3,12 +3,14 @@ package etherman
33import (
44 "context"
55 "fmt"
6+ "math/big"
67 "os"
78 "testing"
89
910 ethermanconfig "github.com/agglayer/aggkit/etherman/config"
1011 aggkittypes "github.com/agglayer/aggkit/types"
1112 "github.com/agglayer/aggkit/types/mocks"
13+ "github.com/ethereum/go-ethereum/core/types"
1214 "github.com/stretchr/testify/mock"
1315 "github.com/stretchr/testify/require"
1416)
@@ -36,60 +38,100 @@ func TestDefaultEthClientExploratory(t *testing.T) {
3638}
3739
3840func TestDefaultEthClient_CustomHeaderByNumber (t * testing.T ) {
41+
3942 mockEthClient := mocks .NewEthereumClienter (t )
4043 mockRPCClient := mocks .NewRPCClienter (t )
4144
4245 client := NewDefaultEthClient (mockEthClient , mockRPCClient , nil )
43- client .HashFromJSON = true
44- bn , err := aggkittypes .NewBlockNumberFinality ("FinalizedBlock/5" )
46+ bnFinalized5 , err := aggkittypes .NewBlockNumberFinality ("FinalizedBlock/5" )
4547 require .NoError (t , err )
4648 ctx := t .Context ()
47- // Setup mock for rpcGetBlockByNumber
48- // Call to resolve finalized block
49- mockRPCClient .
50- EXPECT ().
51- CallContext (
52- ctx ,
53- mock .Anything ,
54- "eth_getBlockByNumber" ,
55- "finalized" ,
56- false ,
57- ).
58- Return (nil ).
59- Run (func (ctx context.Context , result interface {}, method string , args ... interface {}) {
60- rawEth , ok := result .(* * blockRawEth )
61- require .True (t , ok )
62- * rawEth = & blockRawEth {
63- Number : "0x5f" , // 95 in hex
64- Hash : "0xabc123" ,
65- Timestamp : "1234" ,
66- }
67- })
49+ blockRaw95 := & blockRawEth {
50+ Number : "0x5f" , // 95 in hex
51+ Hash : "0xabc123" ,
52+ Timestamp : "1234" ,
53+ }
6854
69- mockRPCClient .
70- EXPECT ().
71- CallContext (
72- ctx ,
73- mock .Anything ,
74- "eth_getBlockByNumber" ,
75- "0x64" ,
76- false ,
77- ).
78- Return (nil ).
79- Run (func (ctx context.Context , result interface {}, method string , args ... interface {}) {
80- rawEth , ok := result .(* * blockRawEth )
81- require .True (t , ok )
82- * rawEth = & blockRawEth {
83- Number : "0x64" , // 100 in hex
84- Hash : "0xabc123" ,
85- Timestamp : "1234" ,
86- }
87- })
88- // Call CustomHeaderByNumber
89- header , err := client .CustomHeaderByNumber (ctx , bn )
90- require .NoError (t , err )
91- require .NotNil (t , header )
92- require .Equal (t , uint64 (100 ), header .Number )
93- require .Equal (t , "0x0000000000000000000000000000000000000000000000000000000000abc123" , header .Hash .Hex ())
94- require .Equal (t , bn , header .RequestedBlock )
55+ blockRaw100 := & blockRawEth {
56+ Number : "0x64" , // 100 in hex
57+ Hash : "0xabc123" ,
58+ Timestamp : "1234" ,
59+ }
60+
61+ t .Run ("FinalizedBlock with offset" , func (t * testing.T ) {
62+ client .HashFromJSON = true
63+ // Setup mock for rpcGetBlockByNumber
64+ // Call to resolve finalized block
65+ mockRPCClient .
66+ EXPECT ().
67+ CallContext (
68+ ctx ,
69+ mock .Anything ,
70+ "eth_getBlockByNumber" ,
71+ "finalized" ,
72+ false ,
73+ ).
74+ Return (nil ).
75+ Run (func (ctx context.Context , result interface {}, method string , args ... interface {}) {
76+ rawEth , ok := result .(* * blockRawEth )
77+ require .True (t , ok )
78+ * rawEth = blockRaw95
79+ })
80+
81+ mockRPCClient .
82+ EXPECT ().
83+ CallContext (ctx , mock .Anything , "eth_getBlockByNumber" , "0x64" , false ).
84+ Return (nil ).
85+ Run (func (ctx context.Context , result interface {}, method string , args ... interface {}) {
86+ rawEth , ok := result .(* * blockRawEth )
87+ require .True (t , ok )
88+ * rawEth = blockRaw100
89+ })
90+ // Call CustomHeaderByNumber
91+ header , err := client .CustomHeaderByNumber (ctx , bnFinalized5 )
92+ require .NoError (t , err )
93+ require .NotNil (t , header )
94+ require .Equal (t , uint64 (100 ), header .Number )
95+ require .Equal (t , "0x0000000000000000000000000000000000000000000000000000000000abc123" , header .Hash .Hex ())
96+ require .Equal (t , bnFinalized5 , header .RequestedBlock )
97+ })
98+
99+ t .Run ("Latest block" , func (t * testing.T ) {
100+ client .HashFromJSON = true
101+ ctx := t .Context ()
102+
103+ mockRPCClient .
104+ EXPECT ().
105+ CallContext (ctx , mock .Anything , "eth_getBlockByNumber" , "latest" , false ).
106+ Return (nil ).
107+ Run (func (ctx context.Context , result interface {}, method string , args ... interface {}) {
108+ rawEth , ok := result .(* * blockRawEth )
109+ require .True (t , ok )
110+ * rawEth = blockRaw95
111+ })
112+ header , err := client .CustomHeaderByNumber (ctx , nil )
113+ require .NoError (t , err )
114+ require .NotNil (t , header )
115+ require .Equal (t , uint64 (95 ), header .Number )
116+ })
117+
118+ t .Run ("failed to find blockNumber for tag block" , func (t * testing.T ) {
119+ mockRPCClient .
120+ EXPECT ().CallContext (ctx , mock .Anything , "eth_getBlockByNumber" , "finalized" , false ).
121+ Return (fmt .Errorf ("rpc error" ))
122+ _ , err := client .CustomHeaderByNumber (ctx , bnFinalized5 )
123+ require .Error (t , err )
124+ })
125+
126+ t .Run ("use HashFromJSON=false (geth call)" , func (t * testing.T ) {
127+ client .HashFromJSON = false
128+ mockEthClient .EXPECT ().
129+ HeaderByNumber (ctx , (* big .Int )(nil )).
130+ Return (& types.Header {
131+ Number : big .NewInt (100 ),
132+ }, nil ).Once ()
133+ header , err := client .CustomHeaderByNumber (ctx , nil )
134+ require .NoError (t , err )
135+ require .NotNil (t , header )
136+ })
95137}
0 commit comments