Skip to content

Commit

Permalink
Scaffolding to support Arbitrum Nitro EVM stacks.
Browse files Browse the repository at this point in the history
preparatory work to support Arbitrum Nitro RPC nodes
  • Loading branch information
msf committed Jul 23, 2024
1 parent e491b73 commit 5ace847
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 16 deletions.
44 changes: 44 additions & 0 deletions client/jsonrpc/arbitrum_nitro.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package jsonrpc

import (
"context"
"errors"
"log/slog"
"time"

"github.com/duneanalytics/blockchain-ingester/models"
)

type ArbitrumNitroClient struct {
rpcClient
}

var _ BlockchainClient = &ArbitrumNitroClient{}

func NewArbitrumNitroClient(log *slog.Logger, cfg Config) (*ArbitrumNitroClient, error) {
rpcClient, err := newClient(log.With("module", "jsonrpc"), cfg)
if err != nil {
return nil, err
}
return &ArbitrumNitroClient{*rpcClient}, nil
}

// BlockByNumber returns the block with the given blockNumber.
// it uses 3 different methods to get the block:
// 1. eth_getBlockByNumber
// 2. debug_traceBlockByNumber with tracer "callTracer"
// TODO: this method should be optional
// 2. call to eth_getTransactionReceipt for each Tx present in the Block
//
// We encode the payload in NDJSON, and use a header line to indicate how many Tx are present in the block
func (c *ArbitrumNitroClient) BlockByNumber(_ context.Context, blockNumber int64) (models.RPCBlock, error) {
tStart := time.Now()
defer func() {
c.log.Debug("BlockByNumber", "blockNumber", blockNumber, "duration", time.Since(tStart))
}()
// TODO: lets not implement this yet
return models.RPCBlock{
BlockNumber: blockNumber,
Error: errors.New("not implemented"),
}, errors.New("not implemented")
}
13 changes: 12 additions & 1 deletion client/jsonrpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,18 @@ type rpcClient struct {
httpHeaders map[string]string
}

func NewClient(log *slog.Logger, cfg Config) (*rpcClient, error) { // revive:disable-line:unexported-return
func NewClient(logger *slog.Logger, cfg Config) (BlockchainClient, error) {
switch cfg.EVMStack {
case models.OpStack:
return NewOpStackClient(logger, cfg)
case models.ArbitrumNitro:
return NewArbitrumNitroClient(logger, cfg)
default:
return nil, fmt.Errorf("unsupported EVM stack: %s", cfg.EVMStack)
}
}

func newClient(log *slog.Logger, cfg Config) (*rpcClient, error) { // revive:disable-line:unexported-return
client := retryablehttp.NewClient()
client.RetryMax = MaxRetries
client.Logger = log
Expand Down
3 changes: 3 additions & 0 deletions client/jsonrpc/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package jsonrpc

import (
"time"

"github.com/duneanalytics/blockchain-ingester/models"
)

type Config struct {
URL string
PollInterval time.Duration
HTTPHeaders map[string]string
EVMStack models.EVMStack
}
7 changes: 2 additions & 5 deletions client/jsonrpc/opstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type OpStackClient struct {
var _ BlockchainClient = &OpStackClient{}

func NewOpStackClient(log *slog.Logger, cfg Config) (*OpStackClient, error) {
rpcClient, err := NewClient(log.With("module", "jsonrpc"), cfg)
rpcClient, err := newClient(log.With("module", "jsonrpc"), cfg)
if err != nil {
return nil, err
}
Expand All @@ -37,10 +37,7 @@ func NewOpStackClient(log *slog.Logger, cfg Config) (*OpStackClient, error) {
func (c *OpStackClient) BlockByNumber(ctx context.Context, blockNumber int64) (models.RPCBlock, error) {
tStart := time.Now()
defer func() {
c.log.Debug("BlockByNumber",
"blockNumber", blockNumber,
"duration", time.Since(tStart),
)
c.log.Debug("BlockByNumber", "blockNumber", blockNumber, "duration", time.Since(tStart))
}()
blockNumberHex := fmt.Sprintf("0x%x", blockNumber)

Expand Down
14 changes: 5 additions & 9 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,11 @@ func main() {
logger.Info("Adding extra HTTP header to RPC requests", "key", key, "value", value)
rpcHTTPHeaders[key] = value
}
switch cfg.RPCStack {
case models.OpStack:
rpcClient, err = jsonrpc.NewOpStackClient(logger, jsonrpc.Config{
URL: cfg.RPCNode.NodeURL,
HTTPHeaders: rpcHTTPHeaders,
})
default:
stdlog.Fatalf("unsupported RPC stack: %s", cfg.RPCStack)
}
rpcClient, err = jsonrpc.NewClient(logger, jsonrpc.Config{
URL: cfg.RPCNode.NodeURL,
HTTPHeaders: rpcHTTPHeaders,
EVMStack: cfg.RPCStack,
})
if err != nil {
stdlog.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion models/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ type EVMStack string

const (
OpStack EVMStack = "opstack"
ArbitrumNitro EVMStack = "arbitrumnitro"
ArbitrumNitro EVMStack = "arbitrum-nitro"
)

func (e EVMStack) String() string {
Expand Down

0 comments on commit 5ace847

Please sign in to comment.