From 88a4e0d8112b1ebe74a70be2f8c06a6b94150e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Petruni=C4=87?= Date: Thu, 24 Oct 2024 14:57:20 +0200 Subject: [PATCH] feat: separate archive and standard beacon clients (#44) --- .env.example | 2 ++ chains/evm/config/config.go | 1 + chains/evm/config/config_test.go | 2 ++ chains/evm/proof/root.go | 35 ++++++++++++--------- chains/evm/proof/root_test.go | 10 +++--- main.go | 13 +++++++- mock/root.go | 53 +++++++++++++++++++++++--------- 7 files changed, 81 insertions(+), 35 deletions(-) diff --git a/.env.example b/.env.example index cf3bbe6..41d58b5 100644 --- a/.env.example +++ b/.env.example @@ -7,6 +7,7 @@ INCLUSION_PROVER_DOMAINS_1_ROUTER="0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" INCLUSION_PROVER_DOMAINS_1_HASHI="0xa4D8c6AD5BCE909A84453fd2E5c392223634Bc3E" INCLUSION_PROVER_DOMAINS_1_YAHO="0x21eAB033C7D2DF6A67AeF6C5Bda9A7F151eB9f52" INCLUSION_PROVER_DOMAINS_1_BEACON_ENDPOINT="http://beacon-stub:8882" +INCLUSION_PROVER_DOMAINS_1_ARCHIVE_BEACON_ENDPOINT="http://beacon-stub:8882" INCLUSION_PROVER_DOMAINS_1_STATE_ROOT_ADDRESSES="0xCfEB869F69431e42cdB54A4F4f105C19C080A601" INCLUSION_PROVER_DOMAINS_1_ENDPOINT="http://evm1:8545" INCLUSION_PROVER_DOMAINS_1_SLOT_INDEX="1" @@ -20,6 +21,7 @@ INCLUSION_PROVER_DOMAINS_2_ROUTER="0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" INCLUSION_PROVER_DOMAINS_2_HASHI="0xa4D8c6AD5BCE909A84453fd2E5c392223634Bc3E" INCLUSION_PROVER_DOMAINS_2_YAHO="0x21eAB033C7D2DF6A67AeF6C5Bda9A7F151eB9f52" INCLUSION_PROVER_DOMAINS_2_BEACON_ENDPOINT="http://beacon-stub:8882" +INCLUSION_PROVER_DOMAINS_2_ARCHIVE_BEACON_ENDPOINT="http://beacon-stub:8882" INCLUSION_PROVER_DOMAINS_2_ENDPOINT="http://evm2:8545" INCLUSION_PROVER_DOMAINS_2_STATE_ROOT_ADDRESSES="0xCfEB869F69431e42cdB54A4F4f105C19C080A601" INCLUSION_PROVER_DOMAINS_2_SLOT_INDEX="1" diff --git a/chains/evm/config/config.go b/chains/evm/config/config.go index a0895dc..f63df2c 100644 --- a/chains/evm/config/config.go +++ b/chains/evm/config/config.go @@ -20,6 +20,7 @@ const ( type EVMConfig struct { config.BaseNetworkConfig BeaconEndpoint string `split_words:"true"` + ArchiveBeaconEndpoint string `split_words:"true"` Router string Executor string Hashi string diff --git a/chains/evm/config/config_test.go b/chains/evm/config/config_test.go index 5aa7b21..e65177b 100644 --- a/chains/evm/config/config_test.go +++ b/chains/evm/config/config_test.go @@ -89,6 +89,7 @@ func (s *EVMConfigTestSuite) Test_LoadEVMConfig_SuccessfulLoad() { os.Setenv("INCLUSION_PROVER_DOMAINS_1_YAHO", "yaho") os.Setenv("INCLUSION_PROVER_DOMAINS_1_HASHI", "hashi") os.Setenv("INCLUSION_PROVER_DOMAINS_1_BEACON_ENDPOINT", "endpoint") + os.Setenv("INCLUSION_PROVER_DOMAINS_1_ARCHIVE_BEACON_ENDPOINT", "archive") os.Setenv("INCLUSION_PROVER_DOMAINS_1_MAX_GAS_PRICE", "1000") os.Setenv("INCLUSION_PROVER_DOMAINS_1_BLOCK_INTERVAL", "10") os.Setenv("INCLUSION_PROVER_DOMAINS_1_BLOCK_RETRY_INTERVAL", "10") @@ -118,6 +119,7 @@ func (s *EVMConfigTestSuite) Test_LoadEVMConfig_SuccessfulLoad() { GasIncreasePercentage: 20, MaxGasPrice: 1000, BeaconEndpoint: "endpoint", + ArchiveBeaconEndpoint: "archive", StateRootAddresses: []string{"0x1", "0x2"}, SlotIndex: 1, BlockConfirmations: 15, diff --git a/chains/evm/proof/root.go b/chains/evm/proof/root.go index aa75395..d40eb92 100644 --- a/chains/evm/proof/root.go +++ b/chains/evm/proof/root.go @@ -27,19 +27,22 @@ const ( SLOTS_PER_HISTORICAL_LIMIT = 8192 ) -type BeaconClient interface { - BeaconBlockHeader( +type BeaconStateFetcher interface { + BeaconState( ctx context.Context, - opts *api.BeaconBlockHeaderOpts, + opts *api.BeaconStateOpts, ) ( - *api.Response[*apiv1.BeaconBlockHeader], + *api.Response[*spec.VersionedBeaconState], error, ) - BeaconState( +} + +type BeaconClient interface { + BeaconBlockHeader( ctx context.Context, - opts *api.BeaconStateOpts, + opts *api.BeaconBlockHeaderOpts, ) ( - *api.Response[*spec.VersionedBeaconState], + *api.Response[*apiv1.BeaconBlockHeader], error, ) SignedBeaconBlock(ctx context.Context, @@ -51,16 +54,18 @@ type BeaconClient interface { } type ReceiptRootProver struct { - beaconClient BeaconClient - spec config.Spec - stateCache *cache.Cache + beaconClient BeaconClient + beaconStateFetcher BeaconStateFetcher + spec config.Spec + stateCache *cache.Cache } -func NewReceiptRootProver(beaconClient BeaconClient, spec config.Spec) *ReceiptRootProver { +func NewReceiptRootProver(beaconClient BeaconClient, beaconStateFetcher BeaconStateFetcher, spec config.Spec) *ReceiptRootProver { return &ReceiptRootProver{ - beaconClient: beaconClient, - spec: spec, - stateCache: cache.New(time.Minute*5, time.Minute*5), + beaconClient: beaconClient, + beaconStateFetcher: beaconStateFetcher, + spec: spec, + stateCache: cache.New(time.Minute*5, time.Minute*5), } } @@ -124,7 +129,7 @@ func (p *ReceiptRootProver) beaconState(ctx context.Context, slot *big.Int) (*ap return cachedState.(*api.Response[*spec.VersionedBeaconState]), nil } - state, err := p.beaconClient.BeaconState(ctx, &api.BeaconStateOpts{ + state, err := p.beaconStateFetcher.BeaconState(ctx, &api.BeaconStateOpts{ State: strconv.FormatUint(slot.Uint64(), 10), }) if err != nil { diff --git a/chains/evm/proof/root_test.go b/chains/evm/proof/root_test.go index 1db53ca..87e939b 100644 --- a/chains/evm/proof/root_test.go +++ b/chains/evm/proof/root_test.go @@ -24,8 +24,9 @@ import ( type ReceiptRootProofTestSuite struct { suite.Suite - prover *proof.ReceiptRootProver - mockBeaconClient *mock.MockBeaconClient + prover *proof.ReceiptRootProver + mockBeaconClient *mock.MockBeaconClient + mockArchiveBeaconClient *mock.MockBeaconStateFetcher } func TestRunReceiptRootProofTestSuite(t *testing.T) { @@ -35,6 +36,7 @@ func TestRunReceiptRootProofTestSuite(t *testing.T) { func (s *ReceiptRootProofTestSuite) SetupTest() { ctrl := gomock.NewController(s.T()) s.mockBeaconClient = mock.NewMockBeaconClient(ctrl) + s.mockArchiveBeaconClient = mock.NewMockBeaconStateFetcher(ctrl) beaconState := &spec.VersionedBeaconState{ Deneb: &deneb.BeaconState{}, @@ -44,7 +46,7 @@ func (s *ReceiptRootProofTestSuite) SetupTest() { panic(err) } _ = beaconState.Deneb.UnmarshalJSON(beaconBytes) - s.mockBeaconClient.EXPECT().BeaconState(gomock.Any(), gomock.Any()).Return(&api.Response[*spec.VersionedBeaconState]{ + s.mockArchiveBeaconClient.EXPECT().BeaconState(gomock.Any(), gomock.Any()).Return(&api.Response[*spec.VersionedBeaconState]{ Data: beaconState, }, nil).AnyTimes() @@ -70,7 +72,7 @@ func (s *ReceiptRootProofTestSuite) SetupTest() { Data: beaconBlockHeader, }, nil).AnyTimes() - s.prover = proof.NewReceiptRootProver(s.mockBeaconClient, config.MainnetSpec) + s.prover = proof.NewReceiptRootProver(s.mockBeaconClient, s.mockArchiveBeaconClient, config.MainnetSpec) } func (s *ReceiptRootProofTestSuite) Test_ReceiptRootProof_SlotDifferent() { diff --git a/main.go b/main.go index 7c9012e..48d46b3 100644 --- a/main.go +++ b/main.go @@ -140,8 +140,19 @@ func main() { panic(err) } beaconProvider := beaconClient.(*http.Service) + + archiveBeaconClinet, err := http.New(ctx, + http.WithAddress(config.ArchiveBeaconEndpoint), + http.WithLogLevel(logLevel), + http.WithTimeout(time.Minute*30), + http.WithEnforceJSON(false), + ) + if err != nil { + panic(err) + } + archiveBeaconProvider := archiveBeaconClinet.(*http.Service) receiptProver := proof.NewReceiptProver(client) - rootProver := proof.NewReceiptRootProver(beaconProvider, config.Spec) + rootProver := proof.NewReceiptRootProver(beaconProvider, archiveBeaconProvider, config.Spec) stateRootEventHandlers := make([]evmMessage.EventHandler, 0) if config.Yaho != "" { diff --git a/mock/root.go b/mock/root.go index bad3aeb..b34f356 100644 --- a/mock/root.go +++ b/mock/root.go @@ -18,6 +18,44 @@ import ( gomock "go.uber.org/mock/gomock" ) +// MockBeaconStateFetcher is a mock of BeaconStateFetcher interface. +type MockBeaconStateFetcher struct { + ctrl *gomock.Controller + recorder *MockBeaconStateFetcherMockRecorder +} + +// MockBeaconStateFetcherMockRecorder is the mock recorder for MockBeaconStateFetcher. +type MockBeaconStateFetcherMockRecorder struct { + mock *MockBeaconStateFetcher +} + +// NewMockBeaconStateFetcher creates a new mock instance. +func NewMockBeaconStateFetcher(ctrl *gomock.Controller) *MockBeaconStateFetcher { + mock := &MockBeaconStateFetcher{ctrl: ctrl} + mock.recorder = &MockBeaconStateFetcherMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBeaconStateFetcher) EXPECT() *MockBeaconStateFetcherMockRecorder { + return m.recorder +} + +// BeaconState mocks base method. +func (m *MockBeaconStateFetcher) BeaconState(ctx context.Context, opts *api.BeaconStateOpts) (*api.Response[*spec.VersionedBeaconState], error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeaconState", ctx, opts) + ret0, _ := ret[0].(*api.Response[*spec.VersionedBeaconState]) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeaconState indicates an expected call of BeaconState. +func (mr *MockBeaconStateFetcherMockRecorder) BeaconState(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconState", reflect.TypeOf((*MockBeaconStateFetcher)(nil).BeaconState), ctx, opts) +} + // MockBeaconClient is a mock of BeaconClient interface. type MockBeaconClient struct { ctrl *gomock.Controller @@ -56,21 +94,6 @@ func (mr *MockBeaconClientMockRecorder) BeaconBlockHeader(ctx, opts any) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconBlockHeader", reflect.TypeOf((*MockBeaconClient)(nil).BeaconBlockHeader), ctx, opts) } -// BeaconState mocks base method. -func (m *MockBeaconClient) BeaconState(ctx context.Context, opts *api.BeaconStateOpts) (*api.Response[*spec.VersionedBeaconState], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BeaconState", ctx, opts) - ret0, _ := ret[0].(*api.Response[*spec.VersionedBeaconState]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// BeaconState indicates an expected call of BeaconState. -func (mr *MockBeaconClientMockRecorder) BeaconState(ctx, opts any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconState", reflect.TypeOf((*MockBeaconClient)(nil).BeaconState), ctx, opts) -} - // SignedBeaconBlock mocks base method. func (m *MockBeaconClient) SignedBeaconBlock(ctx context.Context, opts *api.SignedBeaconBlockOpts) (*api.Response[*spec.VersionedSignedBeaconBlock], error) { m.ctrl.T.Helper()