@@ -2,8 +2,11 @@ package raw
22
33import (
44 "context"
5+ "encoding/json"
6+ "fmt"
57 "math/big"
68 "net/http"
9+ "net/http/httptest"
710 "os"
811 "testing"
912
@@ -14,6 +17,7 @@ import (
1417
1518 "github.com/gobitfly/beaconchain/pkg/commons/db2/database"
1619 "github.com/gobitfly/beaconchain/pkg/commons/db2/database/databasetest"
20+ "github.com/gobitfly/beaconchain/pkg/commons/types/geth"
1721)
1822
1923const (
@@ -72,9 +76,8 @@ func TestBigTableClientRealCondition(t *testing.T) {
7276 if len (block .Transactions ()) != 0 && len (receipts ) == 0 {
7377 t .Errorf ("receipts should not be empty" )
7478 }
75-
76- var traces []GethTraceCallResultWrapper
77- if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (block .Number ()), gethTracerArg ); err != nil {
79+ var traces []geth.Trace
80+ if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (block .Number ()), geth .Tracer ); err != nil {
7881 t .Fatalf ("debug_traceBlockByNumber() error = %v" , err )
7982 }
8083 if len (block .Transactions ()) != 0 && len (traces ) == 0 {
@@ -84,72 +87,6 @@ func TestBigTableClientRealCondition(t *testing.T) {
8487 }
8588}
8689
87- func benchmarkBlockRetrieval (b * testing.B , ethClient * ethclient.Client , rpcClient * rpc.Client ) {
88- b .ResetTimer ()
89- for j := 0 ; j < b .N ; j ++ {
90- blockTestNumber := int64 (20978000 + b .N )
91- _ , err := ethClient .BlockByNumber (context .Background (), big .NewInt (blockTestNumber ))
92- if err != nil {
93- b .Fatalf ("BlockByNumber() error = %v" , err )
94- }
95-
96- if _ , err := ethClient .BlockReceipts (context .Background (), rpc .BlockNumberOrHashWithNumber (rpc .BlockNumber (blockTestNumber ))); err != nil {
97- b .Fatalf ("BlockReceipts() error = %v" , err )
98- }
99-
100- var traces []GethTraceCallResultWrapper
101- if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (big .NewInt (blockTestNumber )), gethTracerArg ); err != nil {
102- b .Fatalf ("debug_traceBlockByNumber() error = %v" , err )
103- }
104- }
105- }
106-
107- func BenchmarkErigonNode (b * testing.B ) {
108- node := os .Getenv ("ETH1_ERIGON_ENDPOINT" )
109- if node == "" {
110- b .Skip ("skipping test, please set ETH1_ERIGON_ENDPOINT" )
111- }
112-
113- rpcClient , err := rpc .DialOptions (context .Background (), node )
114- if err != nil {
115- b .Fatal (err )
116- }
117-
118- benchmarkBlockRetrieval (b , ethclient .NewClient (rpcClient ), rpcClient )
119- }
120-
121- func BenchmarkRawBigTable (b * testing.B ) {
122- project := os .Getenv ("BIGTABLE_PROJECT" )
123- instance := os .Getenv ("BIGTABLE_INSTANCE" )
124- if project == "" || instance == "" {
125- b .Skip ("skipping test, set BIGTABLE_PROJECT and BIGTABLE_INSTANCE" )
126- }
127-
128- bt , err := database .NewBigTable (project , instance , nil )
129- if err != nil {
130- b .Fatal (err )
131- }
132-
133- rawStore := WithCache (NewStore (database .Wrap (bt , Table )))
134- rpcClient , err := rpc .DialOptions (context .Background (), "https://foo.bar" , rpc .WithHTTPClient (& http.Client {
135- Transport : NewBigTableEthRaw (rawStore , chainID ),
136- }))
137- if err != nil {
138- b .Fatal (err )
139- }
140-
141- benchmarkBlockRetrieval (b , ethclient .NewClient (rpcClient ), rpcClient )
142- }
143-
144- func BenchmarkAll (b * testing.B ) {
145- b .Run ("BenchmarkErigonNode" , func (b * testing.B ) {
146- BenchmarkErigonNode (b )
147- })
148- b .Run ("BenchmarkRawBigTable" , func (b * testing.B ) {
149- BenchmarkRawBigTable (b )
150- })
151- }
152-
15390func TestBigTableClient (t * testing.T ) {
15491 tests := []struct {
15592 name string
@@ -202,8 +139,8 @@ func TestBigTableClient(t *testing.T) {
202139 t .Errorf ("receipts should not be empty" )
203140 }
204141
205- var traces []GethTraceCallResultWrapper
206- if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (block .Number ()), gethTracerArg ); err != nil {
142+ var traces []geth. Trace
143+ if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (block .Number ()), geth . Tracer ); err != nil {
207144 t .Fatalf ("debug_traceBlockByNumber() error = %v" , err )
208145 }
209146 if len (block .Transactions ()) != 0 && len (traces ) == 0 {
@@ -213,7 +150,71 @@ func TestBigTableClient(t *testing.T) {
213150 }
214151}
215152
216- func TestBigTableClientWithFallback (t * testing.T ) {
153+ func TestWithFallback (t * testing.T ) {
154+ tests := []struct {
155+ name string
156+ err error
157+ expectedErr bool
158+ }{
159+ {
160+ name : "fallback with json.SyntaxError" ,
161+ err : & json.SyntaxError {},
162+ },
163+ {
164+ name : "fallback with ErrNotFoundInCache" ,
165+ err : ErrNotFoundInCache ,
166+ },
167+ {
168+ name : "fallback with ErrMethodNotSupported" ,
169+ err : ErrMethodNotSupported ,
170+ },
171+ {
172+ name : "fallback with database.ErrNotFound" ,
173+ err : database .ErrNotFound ,
174+ },
175+ {
176+ name : "return err for other" ,
177+ err : fmt .Errorf ("some error" ),
178+ expectedErr : true ,
179+ },
180+ }
181+ for _ , tt := range tests {
182+ t .Run (tt .name , func (t * testing.T ) {
183+ roundTripper := NewWithFallback (
184+ stubRoundTripper {err : tt .err },
185+ stubRoundTripper {resp : & http.Response {StatusCode : http .StatusOK }},
186+ )
187+ resp , err := roundTripper .RoundTrip (httptest .NewRequest (http .MethodGet , "/" , nil ))
188+ if tt .expectedErr {
189+ if err == nil {
190+ t .Fatal ("expecting error, got none" )
191+ }
192+ return
193+ }
194+ if err != nil {
195+ t .Fatal (err )
196+ }
197+ if resp .StatusCode != http .StatusOK {
198+ t .Errorf ("got %v, want %v" , resp .StatusCode , http .StatusOK )
199+ }
200+ })
201+ }
202+
203+ }
204+
205+ type stubRoundTripper struct {
206+ err error
207+ resp * http.Response
208+ }
209+
210+ func (stub stubRoundTripper ) RoundTrip (* http.Request ) (* http.Response , error ) {
211+ if stub .err != nil {
212+ return nil , stub .err
213+ }
214+ return stub .resp , nil
215+ }
216+
217+ func TestBigTableClientWithFallbackRealCondition (t * testing.T ) {
217218 node := os .Getenv ("ETH1_ERIGON_ENDPOINT" )
218219 if node == "" {
219220 t .Skip ("skipping test, set ETH1_ERIGON_ENDPOINT" )
@@ -271,8 +272,8 @@ func TestBigTableClientWithFallback(t *testing.T) {
271272 t .Errorf ("receipts should not be empty" )
272273 }
273274
274- var traces []GethTraceCallResultWrapper
275- if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (block .Number ()), gethTracerArg ); err != nil {
275+ var traces []geth. Trace
276+ if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (block .Number ()), geth . Tracer ); err != nil {
276277 t .Fatalf ("debug_traceBlockByNumber() error = %v" , err )
277278 }
278279 if len (block .Transactions ()) != 0 && len (traces ) == 0 {
@@ -282,26 +283,68 @@ func TestBigTableClientWithFallback(t *testing.T) {
282283 }
283284}
284285
285- // TODO import those 3 from somewhere
286- var gethTracerArg = map [string ]string {
287- "tracer" : "callTracer" ,
286+ func benchmarkBlockRetrieval (b * testing.B , ethClient * ethclient.Client , rpcClient * rpc.Client ) {
287+ b .ResetTimer ()
288+ for j := 0 ; j < b .N ; j ++ {
289+ blockTestNumber := int64 (20978000 + b .N )
290+ _ , err := ethClient .BlockByNumber (context .Background (), big .NewInt (blockTestNumber ))
291+ if err != nil {
292+ b .Fatalf ("BlockByNumber() error = %v" , err )
293+ }
294+
295+ if _ , err := ethClient .BlockReceipts (context .Background (), rpc .BlockNumberOrHashWithNumber (rpc .BlockNumber (blockTestNumber ))); err != nil {
296+ b .Fatalf ("BlockReceipts() error = %v" , err )
297+ }
298+
299+ var traces []geth.Trace
300+ if err := rpcClient .Call (& traces , "debug_traceBlockByNumber" , hexutil .EncodeBig (big .NewInt (blockTestNumber )), geth .Tracer ); err != nil {
301+ b .Fatalf ("debug_traceBlockByNumber() error = %v" , err )
302+ }
303+ }
304+ }
305+
306+ func BenchmarkErigonNode (b * testing.B ) {
307+ node := os .Getenv ("ETH1_ERIGON_ENDPOINT" )
308+ if node == "" {
309+ b .Skip ("skipping test, please set ETH1_ERIGON_ENDPOINT" )
310+ }
311+
312+ rpcClient , err := rpc .DialOptions (context .Background (), node )
313+ if err != nil {
314+ b .Fatal (err )
315+ }
316+
317+ benchmarkBlockRetrieval (b , ethclient .NewClient (rpcClient ), rpcClient )
288318}
289319
290- type GethTraceCallResultWrapper struct {
291- Result * GethTraceCallResult `json:"result,omitempty"`
320+ func BenchmarkRawBigTable (b * testing.B ) {
321+ project := os .Getenv ("BIGTABLE_PROJECT" )
322+ instance := os .Getenv ("BIGTABLE_INSTANCE" )
323+ if project == "" || instance == "" {
324+ b .Skip ("skipping test, set BIGTABLE_PROJECT and BIGTABLE_INSTANCE" )
325+ }
326+
327+ bt , err := database .NewBigTable (project , instance , nil )
328+ if err != nil {
329+ b .Fatal (err )
330+ }
331+
332+ rawStore := WithCache (NewStore (database .Wrap (bt , Table )))
333+ rpcClient , err := rpc .DialOptions (context .Background (), "https://foo.bar" , rpc .WithHTTPClient (& http.Client {
334+ Transport : NewBigTableEthRaw (rawStore , chainID ),
335+ }))
336+ if err != nil {
337+ b .Fatal (err )
338+ }
339+
340+ benchmarkBlockRetrieval (b , ethclient .NewClient (rpcClient ), rpcClient )
292341}
293342
294- type GethTraceCallResult struct {
295- TransactionPosition int `json:"transaction_position,omitempty"`
296- Time string `json:"time,omitempty"`
297- GasUsed string `json:"gas_used,omitempty"`
298- From common.Address `json:"from,omitempty"`
299- To common.Address `json:"to,omitempty"`
300- Value string `json:"value,omitempty"`
301- Gas string `json:"gas,omitempty"`
302- Input string `json:"input,omitempty"`
303- Output string `json:"output,omitempty"`
304- Error string `json:"error,omitempty"`
305- Type string `json:"type,omitempty"`
306- Calls []* GethTraceCallResult `json:"calls,omitempty"`
343+ func BenchmarkAll (b * testing.B ) {
344+ b .Run ("BenchmarkErigonNode" , func (b * testing.B ) {
345+ BenchmarkErigonNode (b )
346+ })
347+ b .Run ("BenchmarkRawBigTable" , func (b * testing.B ) {
348+ BenchmarkRawBigTable (b )
349+ })
307350}
0 commit comments