Skip to content

Commit

Permalink
Host: Small cache of blocks by hash (#1738)
Browse files Browse the repository at this point in the history
  • Loading branch information
BedrockSquirrel authored Jan 9, 2024
1 parent 3103eca commit f72e986
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 21 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.4.2
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/mattn/go-sqlite3 v1.14.16
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
github.com/pkg/errors v0.9.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
Expand Down
61 changes: 40 additions & 21 deletions go/ethadapter/geth_rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,37 @@ import (
"math/big"
"time"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
gethlog "github.com/ethereum/go-ethereum/log"

"github.com/ten-protocol/go-ten/contracts/generated/ManagementContract"
"github.com/ten-protocol/go-ten/go/common/retry"

"github.com/ten-protocol/go-ten/go/common/log"
lru "github.com/hashicorp/golang-lru/v2"

"github.com/ten-protocol/go-ten/contracts/generated/ManagementContract"
"github.com/ten-protocol/go-ten/go/common"

"github.com/ethereum/go-ethereum"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ten-protocol/go-ten/go/common/log"
"github.com/ten-protocol/go-ten/go/common/retry"
)

const (
connRetryMaxWait = 10 * time.Minute // after this duration, we will stop retrying to connect and return the failure
connRetryInterval = 500 * time.Millisecond
_maxRetryPriceIncreases = 5
_retryPriceMultiplier = 1.2
_defaultBlockCacheSize = 51 // enough for 50 request batch size and one for previous block
)

// gethRPCClient implements the EthClient interface and allows connection to a real ethereum node
type gethRPCClient struct {
client *ethclient.Client // the underlying eth rpc client
l2ID gethcommon.Address // the address of the Obscuro node this client is dedicated to
timeout time.Duration // the timeout for connecting to, or communicating with, the L1 node
logger gethlog.Logger
rpcURL string
client *ethclient.Client // the underlying eth rpc client
l2ID gethcommon.Address // the address of the Obscuro node this client is dedicated to
timeout time.Duration // the timeout for connecting to, or communicating with, the L1 node
logger gethlog.Logger
rpcURL string
blockCache *lru.Cache[gethcommon.Hash, *types.Block]
}

// NewEthClientFromURL instantiates a new ethadapter.EthClient that connects to an ethereum node
Expand All @@ -49,12 +49,20 @@ func NewEthClientFromURL(rpcURL string, timeout time.Duration, l2ID gethcommon.A
}

logger.Trace(fmt.Sprintf("Initialized eth node connection - addr: %s", rpcURL))

// cache recent blocks to avoid re-fetching them (they are often re-used for checking for forks etc.)
blkCache, err := lru.New[gethcommon.Hash, *types.Block](_defaultBlockCacheSize)
if err != nil {
return nil, fmt.Errorf("unable to initialize block cache - %w", err)
}

return &gethRPCClient{
client: client,
l2ID: l2ID,
timeout: timeout,
logger: logger,
rpcURL: rpcURL,
client: client,
l2ID: l2ID,
timeout: timeout,
logger: logger,
rpcURL: rpcURL,
blockCache: blkCache,
}, nil
}

Expand Down Expand Up @@ -181,10 +189,21 @@ func (e *gethRPCClient) BlockByNumber(n *big.Int) (*types.Block, error) {
}

func (e *gethRPCClient) BlockByHash(hash gethcommon.Hash) (*types.Block, error) {
block, found := e.blockCache.Get(hash)
if found {
return block, nil
}

// not in cache, fetch from RPC
ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
defer cancel()

return e.client.BlockByHash(ctx, hash)
block, err := e.client.BlockByHash(ctx, hash)
if err != nil {
return nil, err
}
e.blockCache.Add(hash, block)
return block, nil
}

func (e *gethRPCClient) CallContract(msg ethereum.CallMsg) ([]byte, error) {
Expand Down

0 comments on commit f72e986

Please sign in to comment.