Skip to content

Commit

Permalink
add builder and batch support
Browse files Browse the repository at this point in the history
  • Loading branch information
augustbleeds committed Mar 15, 2024
1 parent 4c4ec8d commit e0dc340
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 66 deletions.
60 changes: 53 additions & 7 deletions relayer/pkg/starknet/chain_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,40 @@ type FinalizedBlock = starknetrpc.Block

// used to create batch requests
type StarknetBatchBuilder interface {
RequestBlockByHash(ctx context.Context, h *felt.Felt) (*StarknetBatchBuilder, error)
RequestBlockByNumber(ctx context.Context, id uint64) (*StarknetBatchBuilder, error)
RequestLatestPendingBlock(ctx context.Context) (*StarknetBatchBuilder, error)
LatestBlockHashAndNumber(ctx context.Context) (*StarknetBatchBuilder, error)
EventsByFilter(ctx context.Context, f starknetrpc.EventFilter) (*StarknetBatchBuilder, error)
TxReceiptByHash(ctx context.Context, h *felt.Felt) (*StarknetBatchBuilder, error)
RequestBlockByHash(h *felt.Felt) (StarknetBatchBuilder, error)
// RequestBlockByNumber(id uint64) (StarknetBatchBuilder, error)
// RequestLatestPendingBlock() (StarknetBatchBuilder, error)
// RequestLatestBlockHashAndNumber() (StarknetBatchBuilder, error)
// RequestEventsByFilter(f starknetrpc.EventFilter) (StarknetBatchBuilder, error)
// RequestTxReceiptByHash(h *felt.Felt) (StarknetBatchBuilder, error)
Build() []gethrpc.BatchElem
}

var _ StarknetBatchBuilder = (*batchBuilder)(nil)

type batchBuilder struct {
args []gethrpc.BatchElem
}

func NewBatchBuilder() StarknetBatchBuilder {
return &batchBuilder{
args: make([]gethrpc.BatchElem, 0),
}
}

func (b *batchBuilder) RequestBlockByHash(h *felt.Felt) (StarknetBatchBuilder, error) {
b.args = append(b.args, gethrpc.BatchElem{
Method: "starknet_getBlockWithTxs",
Args: []interface{}{
starknetrpc.BlockID{Hash: h},
},
Result: &FinalizedBlock{},
})
return b, nil
}

func (b *batchBuilder) Build() []gethrpc.BatchElem {
return b.args
}

type StarknetChainClient interface {
Expand All @@ -34,7 +62,7 @@ type StarknetChainClient interface {
// get block logs, event logs, etc.
EventsByFilter(ctx context.Context, f starknetrpc.EventFilter) ([]starknetrpc.EmittedEvent, error)
TxReceiptByHash(ctx context.Context, h *felt.Felt) (starknetrpc.TransactionReceipt, error)
Batch(builder *StarknetBatchBuilder) ([]gethrpc.BatchElem, error)
Batch(builder StarknetBatchBuilder) ([]gethrpc.BatchElem, error)
}

func (c *Client) BlockByHash(ctx context.Context, h *felt.Felt) (FinalizedBlock, error) {
Expand All @@ -58,3 +86,21 @@ func (c *Client) BlockByHash(ctx context.Context, h *felt.Felt) (FinalizedBlock,

return *finalizedBlock, nil
}

func (c *Client) Batch(ctx context.Context, builder StarknetBatchBuilder) ([]gethrpc.BatchElem, error) {
if c.defaultTimeout != 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout)
defer cancel()
}

args := builder.Build()

err := c.EthClient.BatchCallContext(ctx, args)

if err != nil {
return nil, fmt.Errorf("error in Batch: %w", err)
}

return args, nil
}
144 changes: 87 additions & 57 deletions relayer/pkg/starknet/chain_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,53 @@ import (
)

var (
myChainID = "SN_SEPOLIA"
myTimeout = 10 * time.Second
myChainID = "SN_SEPOLIA"
myTimeout = 10 * time.Second
blockHash, _ = new(felt.Felt).SetString("0x725407fcc3bd43e50884f50f1e0ef32aa9f814af3da475411934a7dbd4b41a")
blockResponse = []byte(`
"result": {
"status": "ACCEPTED_ON_L2",
"block_hash": "0x725407fcc3bd43e50884f50f1e0ef32aa9f814af3da475411934a7dbd4b41a",
"parent_hash": "0x5ac8b4099a26e9331a015f8437feadf56fa7fb447e8183aa1bdb3bf541a2cbb",
"block_number": 48719,
"new_root": "0x624f0f3cf2fbbd5951b0d90e4e1fc858f3d77cf34303781fcf3e4dc3afaf666",
"timestamp": 1710445796,
"sequencer_address": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8",
"l1_gas_price": {
"price_in_fri": "0x1d1a94a20000",
"price_in_wei": "0x4a817c800"
},
"starknet_version": "0.13.1",
"transactions": [
{
"transaction_hash": "0x27a9a9bc927efc37658acfb9c27b1fc56e7cfcf7a30db1ecdd9820bb2dddf0c",
"type": "INVOKE",
"version": "0x1",
"nonce": "0x62b",
"max_fee": "0x271963aac565a",
"sender_address": "0x42db30408353b25c5a0b3dd798bfe98eba08956786374e961cc5dbb9811ec6e",
"signature": [
"0x66f70855f35096c6aea45be365617bc70fca65808bb85332dd3c2f6f4a86071",
"0x43c09cab9be65cdc59b29b8018c201c1eb42d51529cb9b5dd64859652bf827f"
],
"calldata": [
"0x1",
"0x517567ac7026ce129c950e6e113e437aa3c83716cd61481c6bb8c5057e6923e",
"0xcaffbd1bd76bd7f24a3fa1d69d1b2588a86d1f9d2359b13f6a84b7e1cbd126",
"0xa",
"0x53616d706c654465706f7369745374617274",
"0x8",
"0x4",
"0x18343d00000001",
"0x1",
"0x5",
"0x469",
"0x2",
"0x1",
"0x4eb"
]
}]
}`)
)

func TestChainClient(t *testing.T) {
Expand All @@ -32,64 +77,37 @@ func TestChainClient(t *testing.T) {
type Call struct {
Method string `json:"method"`
Params []json.RawMessage `json:"params"`
Id uint `json:"id,omitempty"`
}

call := Call{}
require.NoError(t, json.Unmarshal(req, &call))

switch call.Method {
case "starknet_getBlockWithTxs":
out = []byte(fmt.Sprintf(`
{
"result": {
"status": "ACCEPTED_ON_L2",
"block_hash": "0x725407fcc3bd43e50884f50f1e0ef32aa9f814af3da475411934a7dbd4b41a",
"parent_hash": "0x5ac8b4099a26e9331a015f8437feadf56fa7fb447e8183aa1bdb3bf541a2cbb",
"block_number": 48719,
"new_root": "0x624f0f3cf2fbbd5951b0d90e4e1fc858f3d77cf34303781fcf3e4dc3afaf666",
"timestamp": 1710445796,
"sequencer_address": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8",
"l1_gas_price": {
"price_in_fri": "0x1d1a94a20000",
"price_in_wei": "0x4a817c800"
},
"starknet_version": "0.13.1",
"transactions": [
{
"transaction_hash": "0x27a9a9bc927efc37658acfb9c27b1fc56e7cfcf7a30db1ecdd9820bb2dddf0c",
"type": "INVOKE",
"version": "0x1",
"nonce": "0x62b",
"max_fee": "0x271963aac565a",
"sender_address": "0x42db30408353b25c5a0b3dd798bfe98eba08956786374e961cc5dbb9811ec6e",
"signature": [
"0x66f70855f35096c6aea45be365617bc70fca65808bb85332dd3c2f6f4a86071",
"0x43c09cab9be65cdc59b29b8018c201c1eb42d51529cb9b5dd64859652bf827f"
],
"calldata": [
"0x1",
"0x517567ac7026ce129c950e6e113e437aa3c83716cd61481c6bb8c5057e6923e",
"0xcaffbd1bd76bd7f24a3fa1d69d1b2588a86d1f9d2359b13f6a84b7e1cbd126",
"0xa",
"0x53616d706c654465706f7369745374617274",
"0x8",
"0x4",
"0x18343d00000001",
"0x1",
"0x5",
"0x469",
"0x2",
"0x1",
"0x4eb"
]
}]
errMarshal := json.Unmarshal(req, &call)
if errMarshal == nil {
switch call.Method {
case "starknet_getBlockWithTxs":
out = []byte(fmt.Sprintf(`{ %s }`, blockResponse))
case "starknet_blockNumber":
out = []byte(`{"result": 1}`)
default:
require.False(t, true, "unsupported RPC method %s", call.Method)
}
} else {
// batch method
var batchCall []Call
errBatchMarshal := json.Unmarshal(req, &batchCall)
assert.NoError(t, errBatchMarshal)

out = []byte(fmt.Sprintf(`
[
{
"jsonrpc": "2.0",
"id": %d,
%s
}
}`))
case "starknet_blockNumber":
out = []byte(`{"result": 1}`)
default:
require.False(t, true, "unsupported RPC method %s", call.Method)
]`, batchCall[0].Id, blockResponse))

}

_, err := w.Write(out)
require.NoError(t, err)
}))
Expand All @@ -101,11 +119,23 @@ func TestChainClient(t *testing.T) {
assert.Equal(t, myTimeout, client.defaultTimeout)

t.Run("get BlockByHash", func(t *testing.T) {
blockHash, err := new(felt.Felt).SetString("0x725407fcc3bd43e50884f50f1e0ef32aa9f814af3da475411934a7dbd4b41a")
block, err := client.BlockByHash(context.TODO(), blockHash)
require.NoError(t, err)
assert.Equal(t, blockHash, block.BlockHash)
})

block, err := client.BlockByHash(context.TODO(), blockHash)
t.Run("get Batch", func(t *testing.T) {
builder := NewBatchBuilder()
builder.RequestBlockByHash(blockHash)

results, err := client.Batch(context.TODO(), builder)
require.NoError(t, err)

assert.Equal(t, "starknet_getBlockWithTxs", results[0].Method)
assert.Nil(t, results[0].Error)

block, ok := results[0].Result.(*FinalizedBlock)
assert.True(t, ok)
assert.Equal(t, blockHash, block.BlockHash)
})
}
6 changes: 4 additions & 2 deletions relayer/pkg/starknet/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ var _ ReaderWriter = (*Client)(nil)

type Client struct {
Provider starknetrpc.RpcProvider
EthClient *ethrpc.Client
lggr logger.Logger
defaultTimeout time.Duration
}
Expand All @@ -56,8 +57,9 @@ func NewClient(_chainID string, baseURL string, lggr logger.Logger, timeout *tim
}

client := &Client{
Provider: starknetrpc.NewProvider(c),
lggr: lggr,
Provider: starknetrpc.NewProvider(c),
EthClient: c,
lggr: lggr,
}

// make copy to preserve value
Expand Down

0 comments on commit e0dc340

Please sign in to comment.