Skip to content

Commit b00865f

Browse files
feat: backfill provider scaffolder (#19)
* feat: metafiller scaffolder * feat: metafiller scaffolder * update gitignore * block cutoff config * fix tests * breakout get function * remove block cutooff * remove block cutooff * nits * rename to NewBackFillerProvider * lowercase backfill * add tests * add TODOs
1 parent 2dc6fc9 commit b00865f

File tree

13 files changed

+173
-12
lines changed

13 files changed

+173
-12
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
.env
1919

2020
# Build files
21-
op-translator
2221
bin/
2322
generated/
2423
openapi/

op-translator/internal/config/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type Config struct {
3131
SettlementChainRPCURL string `koanf:"settlement_chain_rpc_url"`
3232
SequencingChainRPCURL string `koanf:"sequencing_chain_rpc_url"`
3333
MetaBasedChainRPCURL string `koanf:"meta_based_chain_rpc_url"`
34+
MetafillerURL string `koanf:"metafiller_url"`
3435
SequencingContractAddress string `koanf:"sequencing_contract_address"`
3536
BatcherAddress string `koanf:"batcher_address"`
3637
BatchInboxAddress string `koanf:"batch_inbox_address"`
@@ -51,6 +52,7 @@ func setCLIFlags(f *pflag.FlagSet) {
5152
f.String("settlement_chain_rpc_url", "https://sepolia.base.org", "Settlement chain address")
5253
f.String("sequencing_chain_rpc_url", "https://sepolia.base.org", "Sequencing chain address")
5354
f.String("meta_based_chain_rpc_url", "https://sepolia.base.org", "Meta based chain address")
55+
f.String("metafiller_url", "http://localhost:8080", "Metafiller URL")
5456
f.String("log_level", constants.Info.String(), "Log level for the app")
5557
f.Int("frame_size", defaultFrameSize, "Size of each frame in bytes. Max is 1,000,000")
5658
f.Bool("pretty", false, "Pretty print JSON log responses")
@@ -70,6 +72,7 @@ func hydrateFromConfMap(config *Config) {
7072
config.SettlementChainRPCURL = k.String("settlement_chain_rpc_url")
7173
config.SequencingChainRPCURL = k.String("sequencing_chain_rpc_url")
7274
config.MetaBasedChainRPCURL = k.String("meta_based_chain_rpc_url")
75+
config.MetafillerURL = k.String("metafiller_url")
7376
config.FrameSize = k.Int("frame_size")
7477
config.LogLevel = k.String("log_level")
7578
config.Pretty = k.Bool("pretty")
@@ -151,6 +154,11 @@ func ValidateConfigValues(config *Config) (result error) {
151154
result = multierror.Append(result, fmt.Errorf("invalid URL for meta based chain address: %w", err))
152155
}
153156

157+
_, err = url.ParseRequestURI(config.MetafillerURL)
158+
if err != nil {
159+
result = multierror.Append(result, fmt.Errorf("invalid URL for metafiller: %w", err))
160+
}
161+
154162
if !constants.IsValidLogLevel(config.LogLevel) {
155163
result = multierror.Append(result, errors.New("invalid log level"))
156164
}

op-translator/internal/config/config_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func validConfig() config.Config {
1818
SequencingChainRPCURL: "http://example.com",
1919
SettlementChainRPCURL: "https://example.org",
2020
MetaBasedChainRPCURL: "https://example.io",
21+
MetafillerURL: "https://metafiller.io",
2122
LogLevel: constants.Info.String(),
2223
Pretty: false,
2324
SequencingContractAddress: "0x0000000000000000000000000000000000000000",

op-translator/mocks/config_mock.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var DefaultTestingConfig = &config.Config{
3333
SettlementChainRPCURL: "http://localhost:8545",
3434
SequencingChainRPCURL: "http://localhost:8545",
3535
MetaBasedChainRPCURL: "http://localhost:8545",
36+
MetafillerURL: "http://localhost:8080",
3637
BatchInboxAddress: TestingBatchInboxAddress,
3738
BatcherAddress: TestingBatcherAddress,
3839
SettlementChainID: TestingSettlementChainID,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package mocks
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/stretchr/testify/mock"
7+
)
8+
9+
type HTTPClientMock struct {
10+
mock.Mock
11+
}
12+
13+
func (m *HTTPClientMock) Do(req *http.Request) (*http.Response, error) {
14+
args := m.Called(req)
15+
return args.Get(0).(*http.Response), args.Error(1)
16+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package backfill
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
10+
"github.com/SyndicateProtocol/metabased-rollup/op-translator/internal/config"
11+
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/types"
12+
"github.com/ethereum/go-ethereum/common"
13+
)
14+
15+
// TODO SEQ-141: spike: performant Go HTTP/JSON-RPC lib
16+
type HTTPClient interface {
17+
Do(req *http.Request) (*http.Response, error)
18+
}
19+
20+
type BackfillProvider struct {
21+
Client HTTPClient
22+
MetafillerURL string
23+
}
24+
25+
func NewBackfillerProvider(cfg *config.Config) *BackfillProvider {
26+
return &BackfillProvider{
27+
MetafillerURL: cfg.MetafillerURL,
28+
Client: &http.Client{},
29+
}
30+
}
31+
32+
type BackfillData struct {
33+
Data string `json:"data"` // Hex format
34+
EpochHash common.Hash `json:"epochHash"`
35+
}
36+
37+
func (b *BackfillProvider) GetBackfillData(ctx context.Context, epochNumber string) (*BackfillData, error) {
38+
fullURL := b.MetafillerURL + "/" + epochNumber
39+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, http.NoBody)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
resp, err := b.Client.Do(req)
45+
if err != nil {
46+
return nil, err
47+
}
48+
defer resp.Body.Close()
49+
50+
body, err := io.ReadAll(resp.Body)
51+
fmt.Println("BODY", body)
52+
if err != nil {
53+
return nil, err
54+
}
55+
// TODO SEQ-209: Think most optimal way to send/receive this data
56+
var data *BackfillData
57+
err = json.Unmarshal(body, &data)
58+
if err != nil {
59+
return nil, err
60+
}
61+
return data, nil
62+
}
63+
64+
func (b *BackfillProvider) GetBackfillFrames(ctx context.Context, epochNumber string) ([]*types.Frame, error) {
65+
backfillData, err := b.GetBackfillData(ctx, epochNumber)
66+
if err != nil {
67+
return nil, err
68+
}
69+
70+
frames, err := types.ToFrames([]byte(backfillData.Data), config.MaxFrameSize, backfillData.EpochHash)
71+
if err != nil {
72+
return nil, err
73+
}
74+
75+
return frames, nil
76+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package backfill_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"io"
8+
"net/http"
9+
"testing"
10+
11+
"github.com/SyndicateProtocol/metabased-rollup/op-translator/mocks"
12+
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/backfill"
13+
"github.com/ethereum/go-ethereum/common"
14+
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/mock"
16+
)
17+
18+
func TestGetBackfillFrames(t *testing.T) {
19+
mockHTTPClient := new(mocks.HTTPClientMock)
20+
jsonData, err := json.Marshal(backfill.BackfillData{
21+
Data: "data",
22+
EpochHash: common.HexToHash("0x123"),
23+
})
24+
assert.NoError(t, err)
25+
mockHTTPClient.On("Do", mock.Anything).Return(&http.Response{
26+
StatusCode: http.StatusOK,
27+
Body: io.NopCloser(bytes.NewBuffer(jsonData)),
28+
Header: make(http.Header),
29+
}, nil)
30+
31+
ctx := context.Background()
32+
backfillProvider := backfill.BackfillProvider{
33+
Client: mockHTTPClient,
34+
MetafillerURL: "http://metafiller.io",
35+
}
36+
epoch := "0x1"
37+
frames, err := backfillProvider.GetBackfillFrames(ctx, epoch)
38+
39+
assert.NoError(t, err)
40+
assert.Len(t, frames, 1)
41+
42+
frame := frames[0]
43+
assert.NotNil(t, frame.ID)
44+
assert.Equal(t, uint16(0), frame.FrameNumber)
45+
assert.Equal(t, []byte("data"), frame.Data)
46+
assert.Equal(t, true, frame.IsLast)
47+
}

op-translator/pkg/translator/translator.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55

66
"github.com/SyndicateProtocol/metabased-rollup/op-translator/internal/config"
7+
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/backfill"
78
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/rpc-clients"
89
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/types"
910
"github.com/ethereum/go-ethereum/common"
@@ -30,6 +31,7 @@ var _ IRPCClient = (*rpc.RPCClient)(nil)
3031
type OPTranslator struct {
3132
SettlementChain IRPCClient
3233
BatchProvider IBatchProvider
34+
BackfillProvider *backfill.BackfillProvider
3335
Signer Signer
3436
BatcherInboxAddress common.Address
3537
BatcherAddress common.Address
@@ -43,12 +45,14 @@ func Init(cfg *config.Config) *OPTranslator {
4345

4446
metaBasedBatchProvider := InitMetaBasedBatchProvider(cfg)
4547
signer := NewSigner(cfg)
48+
backfillProvider := backfill.NewBackfillerProvider(cfg)
4649

4750
return &OPTranslator{
4851
SettlementChain: settlementChain,
4952
BatcherInboxAddress: common.HexToAddress(cfg.BatchInboxAddress),
5053
BatcherAddress: common.HexToAddress(cfg.BatcherAddress),
5154
BatchProvider: metaBasedBatchProvider,
55+
BackfillProvider: backfillProvider,
5256
Signer: *signer,
5357
}
5458
}
@@ -63,7 +67,9 @@ func (t *OPTranslator) translateBlock(ctx context.Context, block types.Block) (t
6367
return nil, err
6468
}
6569

66-
frames, err := batch.ToFrames(config.MaxFrameSize)
70+
// TODO SEQ-209: Write logic for switching between backfill and regular data fetching
71+
frames, err := batch.GetFrames(config.MaxFrameSize)
72+
6773
if err != nil {
6874
return nil, err
6975
}

op-translator/pkg/translator/translator_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/SyndicateProtocol/metabased-rollup/op-translator/mocks"
8+
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/backfill"
89
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/translator"
910
"github.com/SyndicateProtocol/metabased-rollup/op-translator/pkg/types"
1011

@@ -25,9 +26,10 @@ func TestGetBlockByNumber(t *testing.T) {
2526

2627
mockClient.On("GetBlockByNumber", ctx, number, true).Return(settlementBlock, nil)
2728
translatorMock := &translator.OPTranslator{
28-
SettlementChain: mockClient,
29-
BatchProvider: &mocks.MockBatchProvider{},
30-
Signer: *translator.NewSigner(mockConfig),
29+
SettlementChain: mockClient,
30+
BatchProvider: &mocks.MockBatchProvider{},
31+
Signer: *translator.NewSigner(mockConfig),
32+
BackfillProvider: backfill.NewBackfillerProvider(mockConfig),
3133
}
3234

3335
block, err := translatorMock.GetBlockByNumber(ctx, number, true)
@@ -50,6 +52,7 @@ func TestGetBlockByNumber(t *testing.T) {
5052

5153
func TestGetBlockByHash(t *testing.T) {
5254
mockClient := new(mocks.MockRPCClient)
55+
mockConfig := mocks.DefaultTestingConfig
5356
number := "0x1"
5457
settlementBlock := types.Block{
5558
"number": number,
@@ -61,9 +64,10 @@ func TestGetBlockByHash(t *testing.T) {
6164

6265
mockClient.On("GetBlockByHash", ctx, hash, true).Return(settlementBlock, nil)
6366
translatorMock := &translator.OPTranslator{
64-
SettlementChain: mockClient,
65-
BatchProvider: &mocks.MockBatchProvider{},
66-
Signer: *translator.NewSigner(mocks.DefaultTestingConfig),
67+
SettlementChain: mockClient,
68+
BatchProvider: &mocks.MockBatchProvider{},
69+
Signer: *translator.NewSigner(mockConfig),
70+
BackfillProvider: backfill.NewBackfillerProvider(mockConfig),
6771
}
6872

6973
block, err := translatorMock.GetBlockByHash(ctx, hash, true)

op-translator/pkg/types/batch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (b *Batch) Encode() ([]byte, error) {
6363
return buf.Bytes(), nil
6464
}
6565

66-
func (b *Batch) ToFrames(frameSize int) ([]*Frame, error) {
66+
func (b *Batch) GetFrames(frameSize int) ([]*Frame, error) {
6767
encodedBatch, err := b.Encode()
6868
if err != nil {
6969
return nil, err

0 commit comments

Comments
 (0)