diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..ef4a8cc5
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+ - package-ecosystem: gomod
+ directory: /
+ schedule:
+ interval: weekly
+ target-branch: develop
diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml
index 8df39db4..6522d256 100644
--- a/.github/workflows/test-e2e.yml
+++ b/.github/workflows/test-e2e.yml
@@ -55,16 +55,6 @@ jobs:
- name: Install Kurtosis CDK tools
uses: ./kurtosis-cdk/.github/actions/setup-kurtosis-cdk
- - name: Install polycli
- run: |
- POLYCLI_VERSION="${{ vars.POLYCLI_VERSION }}"
- tmp_dir=$(mktemp -d)
- curl -L "https://github.com/0xPolygon/polygon-cli/releases/download/${POLYCLI_VERSION}/polycli_${POLYCLI_VERSION}_linux_amd64.tar.gz" | tar -xz -C "$tmp_dir"
- mv "$tmp_dir"/* /usr/local/bin/polycli
- rm -rf "$tmp_dir"
- sudo chmod +x /usr/local/bin/polycli
- /usr/local/bin/polycli version
-
- name: Setup Bats and bats libs
uses: bats-core/bats-action@2.0.0
@@ -138,18 +128,10 @@ jobs:
with:
repository: 0xPolygon/kurtosis-cdk
path: kurtosis-cdk
- ref: jhilliard/multi-pp-testing
+ ref: main
- name: Install Kurtosis CDK tools
uses: ./kurtosis-cdk/.github/actions/setup-kurtosis-cdk
-
- - name: Install polycli
- run: |
- git clone https://github.com/0xPolygon/polygon-cli -b jhilliard/alonso
- cd polygon-cli
- make install
- cp ~/go/bin/polycli /usr/local/bin/polycli
- /usr/local/bin/polycli version
- name: Setup Bats and bats libs
uses: bats-core/bats-action@2.0.0
diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml
index 7db18445..6df8d1ba 100644
--- a/.github/workflows/test-unit.yml
+++ b/.github/workflows/test-unit.yml
@@ -32,11 +32,9 @@ jobs:
- name: Test
run: make test-unit
-
- # TODO: Uncomment the following lines to enable SonarCloud analysis, once the project is set up in SonarCloud
- #
- # - name: Analyze with SonarCloud
- # uses: sonarsource/sonarcloud-github-action@master
- # env:
- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- # SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
\ No newline at end of file
+
+ - name: Analyze with SonarCloud
+ uses: sonarsource/sonarcloud-github-action@master
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/.mockery.yaml b/.mockery.yaml
new file mode 100644
index 00000000..13b7e49b
--- /dev/null
+++ b/.mockery.yaml
@@ -0,0 +1,92 @@
+issue-845-fix: true
+with-expecter: true
+resolve-type-alias: false
+dir: "{{ .InterfaceDir }}/../mocks"
+outpkg: "mocks"
+filename: "mock_{{ .InterfaceName | snakecase | lower }}.go"
+mockname: "{{ .InterfaceName }}"
+packages:
+ github.com/agglayer/aggkit/agglayer:
+ config:
+ inpackage: true
+ dir: "{{ .InterfaceDir }}"
+ outpkg: "{{ .PackageName }}"
+ interfaces:
+ AgglayerClientInterface:
+ config:
+ mockname: AgglayerClientMock
+ filename: mock_agglayer_client.go
+ github.com/agglayer/aggkit/aggoracle/chaingersender:
+ config:
+ interfaces:
+ EthTxManager:
+ configs:
+ - mockname: EthTxManagerMock
+ filename: mock_ethtxmanager.go
+ - mockname: EthTxManagerMock
+ filename: mock_ethtxmanager.go
+ dir: "{{ .InterfaceDir }}/../../test/helpers"
+ outpkg: "helpers"
+ L2GERManagerContract:
+ config:
+ mockname: L2GERManagerMock
+ filename: mock_l2germanager.go
+ github.com/agglayer/aggkit/aggsender/db:
+ config:
+ all: true
+ github.com/agglayer/aggkit/aggsender/rpc:
+ config:
+ all: true
+ github.com/agglayer/aggkit/aggsender/types:
+ config:
+ all: true
+ github.com/agglayer/aggkit/bridgesync:
+ config:
+ dir: "{{ .InterfaceDir }}/mocks"
+ interfaces:
+ ReorgDetector:
+ EthClienter:
+ github.com/agglayer/aggkit/l1infotreesync:
+ config:
+ dir: "{{ .InterfaceDir }}/mocks"
+ interfaces:
+ EthClienter:
+ github.com/agglayer/aggkit/reorgdetector:
+ config:
+ dir: "{{ .InterfaceDir }}"
+ outpkg: "{{ .PackageName }}"
+ mockname: "{{ .InterfaceName }}Mock"
+ interfaces:
+ EthClient:
+ github.com/agglayer/aggkit/rpc/client:
+ config:
+ all: true
+ github.com/agglayer/aggkit/rpc:
+ config:
+ dir: "{{ .InterfaceDir }}/mocks"
+ all: true
+ github.com/agglayer/aggkit/sync:
+ config:
+ dir: "{{ .InterfaceDir }}"
+ outpkg: "{{ .PackageName }}"
+ mockname: "{{ .InterfaceName }}Mock"
+ inpackage: true
+ interfaces:
+ ReorgDetector:
+ configs:
+ - dir: "{{ .InterfaceDir }}/../l1infotreesync/mocks"
+ outpkg: "mocks"
+ mockname: "{{ .InterfaceName }}Mock"
+ inpackage: false
+ - dir: "{{ .InterfaceDir }}"
+ outpkg: "{{ .PackageName }}"
+ mockname: "{{ .InterfaceName }}Mock"
+ processorInterface:
+ config:
+ mockname: "ProcessorMock"
+ evmDownloaderFull:
+ config:
+ mockname: "EVMDownloaderMock"
+ EthClienter:
+ config:
+ mockname: "L2Mock"
diff --git a/Cargo.lock b/Cargo.lock
index 81547bae..65b948cf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "Inflector"
@@ -38,31 +38,6 @@ dependencies = [
"cpufeatures",
]
-[[package]]
-name = "aggkit"
-version = "0.1.0"
-dependencies = [
- "aggkit-config",
- "alloy-json-rpc",
- "alloy-rpc-client",
- "alloy-transport-http",
- "anyhow",
- "clap",
- "colored",
- "dotenvy",
- "execute",
- "regex",
- "reqwest 0.12.8",
- "serde",
- "serde_json",
- "tempfile",
- "tokio",
- "toml",
- "tracing",
- "tracing-subscriber",
- "url",
-]
-
[[package]]
name = "aggkit-config"
version = "0.1.0"
@@ -722,6 +697,31 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "cdk"
+version = "0.1.0"
+dependencies = [
+ "aggkit-config",
+ "alloy-json-rpc",
+ "alloy-rpc-client",
+ "alloy-transport-http",
+ "anyhow",
+ "clap",
+ "colored",
+ "dotenvy",
+ "execute",
+ "regex",
+ "reqwest 0.12.8",
+ "serde",
+ "serde_json",
+ "tempfile",
+ "tokio",
+ "toml",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+]
+
[[package]]
name = "cesu8"
version = "1.1.0"
diff --git a/README.md b/README.md
index 76e396dc..a93bd6f1 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,9 @@
-## Polygon AggKit
+## AggKit
-**Polygon AggKit** is a modular framework that developers can use to build and deploy Pessimistic Proofs enabled chains (TBD).
+**AggKit** is a modular framework that developers can use to connect networks to the AggLayer
@@ -59,18 +59,13 @@ Feel free to [open an issue](https://github.com/agglayer/aggkit/issues/new) if y
## License
-Polygon AggKit
Copyright (c) 2024 PT Services DMCC
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published
-by the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+Licensed under either of
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
+* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
+at your option.
+
+The SPDX license identifier for this project is `MIT OR Apache-2.0`.
diff --git a/aggoracle/mocks/mock_l2germanager.go b/aggoracle/mocks/mock_l2germanager.go
index a7ec0296..8c1dd89c 100644
--- a/aggoracle/mocks/mock_l2germanager.go
+++ b/aggoracle/mocks/mock_l2germanager.go
@@ -10,7 +10,7 @@ import (
mock "github.com/stretchr/testify/mock"
)
-// L2GERManagerMock is an autogenerated mock type for the L2GERManager type
+// L2GERManagerMock is an autogenerated mock type for the L2GERManagerContract type
type L2GERManagerMock struct {
mock.Mock
}
diff --git a/aggsender/mocks/agg_sender_storage.go b/aggsender/mocks/mock_agg_sender_storage.go
similarity index 100%
rename from aggsender/mocks/agg_sender_storage.go
rename to aggsender/mocks/mock_agg_sender_storage.go
diff --git a/aggsender/mocks/aggsender_interface.go b/aggsender/mocks/mock_aggsender_interface.go
similarity index 94%
rename from aggsender/mocks/aggsender_interface.go
rename to aggsender/mocks/mock_aggsender_interface.go
index bf7b6876..df1d129d 100644
--- a/aggsender/mocks/aggsender_interface.go
+++ b/aggsender/mocks/mock_aggsender_interface.go
@@ -7,7 +7,7 @@ import (
mock "github.com/stretchr/testify/mock"
)
-// AggsenderInterface is an autogenerated mock type for the aggsenderInterface type
+// AggsenderInterface is an autogenerated mock type for the AggsenderInterface type
type AggsenderInterface struct {
mock.Mock
}
@@ -20,7 +20,7 @@ func (_m *AggsenderInterface) EXPECT() *AggsenderInterface_Expecter {
return &AggsenderInterface_Expecter{mock: &_m.Mock}
}
-// Info provides a mock function with given fields:
+// Info provides a mock function with no fields
func (_m *AggsenderInterface) Info() types.AggsenderInfo {
ret := _m.Called()
diff --git a/aggsender/mocks/aggsender_storer.go b/aggsender/mocks/mock_aggsender_storer.go
similarity index 97%
rename from aggsender/mocks/aggsender_storer.go
rename to aggsender/mocks/mock_aggsender_storer.go
index cc2aa309..3f832a69 100644
--- a/aggsender/mocks/aggsender_storer.go
+++ b/aggsender/mocks/mock_aggsender_storer.go
@@ -7,7 +7,7 @@ import (
mock "github.com/stretchr/testify/mock"
)
-// AggsenderStorer is an autogenerated mock type for the aggsenderStorer type
+// AggsenderStorer is an autogenerated mock type for the AggsenderStorer type
type AggsenderStorer struct {
mock.Mock
}
@@ -78,7 +78,7 @@ func (_c *AggsenderStorer_GetCertificateByHeight_Call) RunAndReturn(run func(uin
return _c
}
-// GetLastSentCertificate provides a mock function with given fields:
+// GetLastSentCertificate provides a mock function with no fields
func (_m *AggsenderStorer) GetLastSentCertificate() (*types.CertificateInfo, error) {
ret := _m.Called()
diff --git a/aggsender/mocks/block_notifier.go b/aggsender/mocks/mock_block_notifier.go
similarity index 100%
rename from aggsender/mocks/block_notifier.go
rename to aggsender/mocks/mock_block_notifier.go
diff --git a/aggsender/mocks/epoch_notifier.go b/aggsender/mocks/mock_epoch_notifier.go
similarity index 100%
rename from aggsender/mocks/epoch_notifier.go
rename to aggsender/mocks/mock_epoch_notifier.go
diff --git a/aggsender/mocks/eth_client.go b/aggsender/mocks/mock_eth_client.go
similarity index 100%
rename from aggsender/mocks/eth_client.go
rename to aggsender/mocks/mock_eth_client.go
diff --git a/aggsender/mocks/generic_subscriber.go b/aggsender/mocks/mock_generic_subscriber.go
similarity index 91%
rename from aggsender/mocks/generic_subscriber.go
rename to aggsender/mocks/mock_generic_subscriber.go
index b4bee4b4..a713d033 100644
--- a/aggsender/mocks/generic_subscriber.go
+++ b/aggsender/mocks/mock_generic_subscriber.go
@@ -5,11 +5,11 @@ package mocks
import mock "github.com/stretchr/testify/mock"
// GenericSubscriber is an autogenerated mock type for the GenericSubscriber type
-type GenericSubscriber[T interface{}] struct {
+type GenericSubscriber[T any] struct {
mock.Mock
}
-type GenericSubscriber_Expecter[T interface{}] struct {
+type GenericSubscriber_Expecter[T any] struct {
mock *mock.Mock
}
@@ -23,7 +23,7 @@ func (_m *GenericSubscriber[T]) Publish(data T) {
}
// GenericSubscriber_Publish_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Publish'
-type GenericSubscriber_Publish_Call[T interface{}] struct {
+type GenericSubscriber_Publish_Call[T any] struct {
*mock.Call
}
@@ -71,7 +71,7 @@ func (_m *GenericSubscriber[T]) Subscribe(subscriberName string) <-chan T {
}
// GenericSubscriber_Subscribe_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Subscribe'
-type GenericSubscriber_Subscribe_Call[T interface{}] struct {
+type GenericSubscriber_Subscribe_Call[T any] struct {
*mock.Call
}
@@ -100,7 +100,7 @@ func (_c *GenericSubscriber_Subscribe_Call[T]) RunAndReturn(run func(string) <-c
// NewGenericSubscriber creates a new instance of GenericSubscriber. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
-func NewGenericSubscriber[T interface{}](t interface {
+func NewGenericSubscriber[T any](t interface {
mock.TestingT
Cleanup(func())
}) *GenericSubscriber[T] {
diff --git a/aggsender/mocks/l1_info_tree_syncer.go b/aggsender/mocks/mock_l1_info_tree_syncer.go
similarity index 100%
rename from aggsender/mocks/l1_info_tree_syncer.go
rename to aggsender/mocks/mock_l1_info_tree_syncer.go
diff --git a/aggsender/mocks/l2_bridge_syncer.go b/aggsender/mocks/mock_l2_bridge_syncer.go
similarity index 100%
rename from aggsender/mocks/l2_bridge_syncer.go
rename to aggsender/mocks/mock_l2_bridge_syncer.go
diff --git a/aggsender/mocks/logger.go b/aggsender/mocks/mock_logger.go
similarity index 100%
rename from aggsender/mocks/logger.go
rename to aggsender/mocks/mock_logger.go
diff --git a/aggsender/rpc/aggsender_rpc.go b/aggsender/rpc/aggsender_rpc.go
index 8b08a509..a9d1950a 100644
--- a/aggsender/rpc/aggsender_rpc.go
+++ b/aggsender/rpc/aggsender_rpc.go
@@ -12,26 +12,26 @@ const (
base10 = 10
)
-type aggsenderStorer interface {
+type AggsenderStorer interface {
GetCertificateByHeight(height uint64) (*types.CertificateInfo, error)
GetLastSentCertificate() (*types.CertificateInfo, error)
}
-type aggsenderInterface interface {
+type AggsenderInterface interface {
Info() types.AggsenderInfo
}
// AggsenderRPC is the RPC interface for the aggsender
type AggsenderRPC struct {
logger *log.Logger
- storage aggsenderStorer
- aggsender aggsenderInterface
+ storage AggsenderStorer
+ aggsender AggsenderInterface
}
func NewAggsenderRPC(
logger *log.Logger,
- storage aggsenderStorer,
- aggsender aggsenderInterface,
+ storage AggsenderStorer,
+ aggsender AggsenderInterface,
) *AggsenderRPC {
return &AggsenderRPC{
logger: logger,
diff --git a/bridgesync/mocks/eth_clienter.go b/bridgesync/mocks/mock_eth_clienter.go
similarity index 99%
rename from bridgesync/mocks/eth_clienter.go
rename to bridgesync/mocks/mock_eth_clienter.go
index 3d208e45..673c1e4d 100644
--- a/bridgesync/mocks/eth_clienter.go
+++ b/bridgesync/mocks/mock_eth_clienter.go
@@ -1,6 +1,6 @@
// Code generated by mockery. DO NOT EDIT.
-package mocks_bridgesync
+package mocks
import (
big "math/big"
diff --git a/bridgesync/mocks/reorg_detector.go b/bridgesync/mocks/mock_reorg_detector.go
similarity index 99%
rename from bridgesync/mocks/reorg_detector.go
rename to bridgesync/mocks/mock_reorg_detector.go
index d9838db4..8804f75a 100644
--- a/bridgesync/mocks/reorg_detector.go
+++ b/bridgesync/mocks/mock_reorg_detector.go
@@ -1,6 +1,6 @@
// Code generated by mockery. DO NOT EDIT.
-package mocks_bridgesync
+package mocks
import (
context "context"
diff --git a/dataavailability/mocks_da/da_backender.go b/dataavailability/mocks_da/da_backender.go
deleted file mode 100644
index 73c732c4..00000000
--- a/dataavailability/mocks_da/da_backender.go
+++ /dev/null
@@ -1,263 +0,0 @@
-// Code generated by mockery. DO NOT EDIT.
-
-package mocks_da
-
-import (
- context "context"
-
- common "github.com/ethereum/go-ethereum/common"
-
- etherman "github.com/agglayer/aggkit/etherman"
-
- mock "github.com/stretchr/testify/mock"
-)
-
-// DABackender is an autogenerated mock type for the DABackender type
-type DABackender struct {
- mock.Mock
-}
-
-type DABackender_Expecter struct {
- mock *mock.Mock
-}
-
-func (_m *DABackender) EXPECT() *DABackender_Expecter {
- return &DABackender_Expecter{mock: &_m.Mock}
-}
-
-// GetSequence provides a mock function with given fields: ctx, batchHashes, dataAvailabilityMessage
-func (_m *DABackender) GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) {
- ret := _m.Called(ctx, batchHashes, dataAvailabilityMessage)
-
- if len(ret) == 0 {
- panic("no return value specified for GetSequence")
- }
-
- var r0 [][]byte
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, []common.Hash, []byte) ([][]byte, error)); ok {
- return rf(ctx, batchHashes, dataAvailabilityMessage)
- }
- if rf, ok := ret.Get(0).(func(context.Context, []common.Hash, []byte) [][]byte); ok {
- r0 = rf(ctx, batchHashes, dataAvailabilityMessage)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([][]byte)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, []common.Hash, []byte) error); ok {
- r1 = rf(ctx, batchHashes, dataAvailabilityMessage)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// DABackender_GetSequence_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSequence'
-type DABackender_GetSequence_Call struct {
- *mock.Call
-}
-
-// GetSequence is a helper method to define mock.On call
-// - ctx context.Context
-// - batchHashes []common.Hash
-// - dataAvailabilityMessage []byte
-func (_e *DABackender_Expecter) GetSequence(ctx interface{}, batchHashes interface{}, dataAvailabilityMessage interface{}) *DABackender_GetSequence_Call {
- return &DABackender_GetSequence_Call{Call: _e.mock.On("GetSequence", ctx, batchHashes, dataAvailabilityMessage)}
-}
-
-func (_c *DABackender_GetSequence_Call) Run(run func(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte)) *DABackender_GetSequence_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(context.Context), args[1].([]common.Hash), args[2].([]byte))
- })
- return _c
-}
-
-func (_c *DABackender_GetSequence_Call) Return(_a0 [][]byte, _a1 error) *DABackender_GetSequence_Call {
- _c.Call.Return(_a0, _a1)
- return _c
-}
-
-func (_c *DABackender_GetSequence_Call) RunAndReturn(run func(context.Context, []common.Hash, []byte) ([][]byte, error)) *DABackender_GetSequence_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// Init provides a mock function with given fields:
-func (_m *DABackender) Init() error {
- ret := _m.Called()
-
- if len(ret) == 0 {
- panic("no return value specified for Init")
- }
-
- var r0 error
- if rf, ok := ret.Get(0).(func() error); ok {
- r0 = rf()
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// DABackender_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init'
-type DABackender_Init_Call struct {
- *mock.Call
-}
-
-// Init is a helper method to define mock.On call
-func (_e *DABackender_Expecter) Init() *DABackender_Init_Call {
- return &DABackender_Init_Call{Call: _e.mock.On("Init")}
-}
-
-func (_c *DABackender_Init_Call) Run(run func()) *DABackender_Init_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run()
- })
- return _c
-}
-
-func (_c *DABackender_Init_Call) Return(_a0 error) *DABackender_Init_Call {
- _c.Call.Return(_a0)
- return _c
-}
-
-func (_c *DABackender_Init_Call) RunAndReturn(run func() error) *DABackender_Init_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// PostSequenceBanana provides a mock function with given fields: ctx, sequence
-func (_m *DABackender) PostSequenceBanana(ctx context.Context, sequence etherman.SequenceBanana) ([]byte, error) {
- ret := _m.Called(ctx, sequence)
-
- if len(ret) == 0 {
- panic("no return value specified for PostSequenceBanana")
- }
-
- var r0 []byte
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, etherman.SequenceBanana) ([]byte, error)); ok {
- return rf(ctx, sequence)
- }
- if rf, ok := ret.Get(0).(func(context.Context, etherman.SequenceBanana) []byte); ok {
- r0 = rf(ctx, sequence)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]byte)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, etherman.SequenceBanana) error); ok {
- r1 = rf(ctx, sequence)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// DABackender_PostSequenceBanana_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PostSequenceBanana'
-type DABackender_PostSequenceBanana_Call struct {
- *mock.Call
-}
-
-// PostSequenceBanana is a helper method to define mock.On call
-// - ctx context.Context
-// - sequence etherman.SequenceBanana
-func (_e *DABackender_Expecter) PostSequenceBanana(ctx interface{}, sequence interface{}) *DABackender_PostSequenceBanana_Call {
- return &DABackender_PostSequenceBanana_Call{Call: _e.mock.On("PostSequenceBanana", ctx, sequence)}
-}
-
-func (_c *DABackender_PostSequenceBanana_Call) Run(run func(ctx context.Context, sequence etherman.SequenceBanana)) *DABackender_PostSequenceBanana_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(context.Context), args[1].(etherman.SequenceBanana))
- })
- return _c
-}
-
-func (_c *DABackender_PostSequenceBanana_Call) Return(_a0 []byte, _a1 error) *DABackender_PostSequenceBanana_Call {
- _c.Call.Return(_a0, _a1)
- return _c
-}
-
-func (_c *DABackender_PostSequenceBanana_Call) RunAndReturn(run func(context.Context, etherman.SequenceBanana) ([]byte, error)) *DABackender_PostSequenceBanana_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// PostSequenceElderberry provides a mock function with given fields: ctx, batchesData
-func (_m *DABackender) PostSequenceElderberry(ctx context.Context, batchesData [][]byte) ([]byte, error) {
- ret := _m.Called(ctx, batchesData)
-
- if len(ret) == 0 {
- panic("no return value specified for PostSequenceElderberry")
- }
-
- var r0 []byte
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, [][]byte) ([]byte, error)); ok {
- return rf(ctx, batchesData)
- }
- if rf, ok := ret.Get(0).(func(context.Context, [][]byte) []byte); ok {
- r0 = rf(ctx, batchesData)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]byte)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, [][]byte) error); ok {
- r1 = rf(ctx, batchesData)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// DABackender_PostSequenceElderberry_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PostSequenceElderberry'
-type DABackender_PostSequenceElderberry_Call struct {
- *mock.Call
-}
-
-// PostSequenceElderberry is a helper method to define mock.On call
-// - ctx context.Context
-// - batchesData [][]byte
-func (_e *DABackender_Expecter) PostSequenceElderberry(ctx interface{}, batchesData interface{}) *DABackender_PostSequenceElderberry_Call {
- return &DABackender_PostSequenceElderberry_Call{Call: _e.mock.On("PostSequenceElderberry", ctx, batchesData)}
-}
-
-func (_c *DABackender_PostSequenceElderberry_Call) Run(run func(ctx context.Context, batchesData [][]byte)) *DABackender_PostSequenceElderberry_Call {
- _c.Call.Run(func(args mock.Arguments) {
- run(args[0].(context.Context), args[1].([][]byte))
- })
- return _c
-}
-
-func (_c *DABackender_PostSequenceElderberry_Call) Return(_a0 []byte, _a1 error) *DABackender_PostSequenceElderberry_Call {
- _c.Call.Return(_a0, _a1)
- return _c
-}
-
-func (_c *DABackender_PostSequenceElderberry_Call) RunAndReturn(run func(context.Context, [][]byte) ([]byte, error)) *DABackender_PostSequenceElderberry_Call {
- _c.Call.Return(run)
- return _c
-}
-
-// NewDABackender creates a new instance of DABackender. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func NewDABackender(t interface {
- mock.TestingT
- Cleanup(func())
-}) *DABackender {
- mock := &DABackender{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/docs/assets/gitflow.png b/docs/assets/gitflow.png
new file mode 100644
index 00000000..52bcf712
Binary files /dev/null and b/docs/assets/gitflow.png differ
diff --git a/docs/release_lifecycle.md b/docs/release_lifecycle.md
new file mode 100644
index 00000000..3a8533ba
--- /dev/null
+++ b/docs/release_lifecycle.md
@@ -0,0 +1,63 @@
+This document presents the Aggkit [Software release lifecycle](https://simple.wikipedia.org/wiki/Software_release_life_cycle). The Aggkit team has adopted a process grounded in industry-standard best practices to avoid reinventing the wheel and, more importantly, to prevent confusion among new developers and users. By adhering to these widely recognized practices, we ensure that anyone in the industry can intuitively understand and follow our internal procedures with minimal explanation.
+
+## Versioning
+
+The versioning process follows the standard [Semantic Versioning](https://semver.org/) to tag new versions
+
+Summary
+
+1. MAJOR version when you make incompatible API changes
+2. MINOR version when you add functionality in a backward compatible manner
+3. PATCH version when you make backward compatible bug fixes
+
+At this time the project is in development phase so refer to the [FAQ](https://semver.org/#faq) for the current versioning criteria:
+
+### How should I deal with revisions in the 0.y.z initial development phase?
+
+The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.
+
+### How do I know when to release 1.0.0?
+
+If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backward compatibility, you should probably already be 1.0.0.
+
+## Pre-Releases
+
+Refer to the [Software release lifecycle](https://simple.wikipedia.org/wiki/Software_release_life_cycle) Wikipedia article for a definition and criteria this project is following regarding pre-releases.
+
+## Release process
+
+The release process is based on the [Gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) for managing the source code repository.
+
+For a quick reference you can check https://cheatography.com/mikesac/cheat-sheets/gitflow/
+
+As a quick reference this is the diagram of the branching cycle:
+
+![image.png](assets/gitflow.png)
+
+## FAQ
+
+### Should I cherry pick commits made to a release branch while it’s still unmerged?
+
+As stated by the Gitflow workflow, release branches should be short-lived and merged back to `main` and `develop` branches, but it can happen from time to time that `develop` branch needs a commit from a release branch before it’s released.
+
+In that case, a cherry-pick commit can be merged into `develop` containing the desired changes, as they would have end-up in `develop` at some point in the future anyway.
+
+### How do we manage several developments in parallel?
+
+Sometimes there's a necessity to release a new stable version of the previous branch with certain features while simultaneously working on the next version. In that case, we'll maintain two release branches like `release/4.0.0` and `release/5.0.0`. These branches will evolve in parallel, but most of the changes from the lower release will need to be cherry-picked onto the newest release. Additionally, if any critical fix is made to the newest release, it should be back-ported to the older release.
+
+### How to create a hotfix for an older release?
+
+When a release branch is merged into `main` and `develop`, it is removed, and only the tag is left. To create a hotfix release, a new release branch will be created from the tag so the necessary fixes can be applied. Then follow the normal release cycle: create a new beta for the release, test it in all environments, then create the final tag and release it.
+
+The fixes may need to be cherry-picked into any open release branches.
+
+### Why we should not squash merge when merging a release branch to `main` or `develop` ?
+
+This is opinionated but in general there’s quite a lot of downsides when squash merging release branches, see this response for some of them https://stackoverflow.com/questions/41139783/gitflow-should-i-squash-commits-when-merging-from-a-release-branch-into-master/41298098#41298098
+
+Another big downside is that `main` and `develop` branch will distance more and more in terms of commits as time passes, making them totally different after some time.
+
+## Reference
+
+Comparison of popular branching strategies https://docs.aws.amazon.com/prescriptive-guidance/latest/choosing-git-branch-approach/git-branching-strategies.html
diff --git a/go.mod b/go.mod
index 8ffa0c0e..cb6d0833 100644
--- a/go.mod
+++ b/go.mod
@@ -27,9 +27,9 @@ require (
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/metric v1.24.0
go.uber.org/zap v1.27.0
- golang.org/x/crypto v0.27.0
+ golang.org/x/crypto v0.31.0
golang.org/x/net v0.29.0
- golang.org/x/sync v0.9.0
+ golang.org/x/sync v0.10.0
google.golang.org/protobuf v1.34.2
modernc.org/sqlite v1.32.0
)
@@ -75,7 +75,7 @@ require (
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
github.com/gofrs/flock v0.12.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
+ github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
@@ -139,8 +139,8 @@ require (
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
- golang.org/x/sys v0.25.0 // indirect
- golang.org/x/text v0.18.0 // indirect
+ golang.org/x/sys v0.28.0 // indirect
+ golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.5.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
diff --git a/go.sum b/go.sum
index aec6d2d7..7ccb9294 100644
--- a/go.sum
+++ b/go.sum
@@ -119,8 +119,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
-github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
-github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
+github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -365,8 +365,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
-golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -389,8 +389,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
-golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -414,16 +414,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
-golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
-golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
diff --git a/l1infotreesync/mocks/eth_clienter.go b/l1infotreesync/mocks/mock_eth_clienter.go
similarity index 99%
rename from l1infotreesync/mocks/eth_clienter.go
rename to l1infotreesync/mocks/mock_eth_clienter.go
index 270c40d9..72d67a97 100644
--- a/l1infotreesync/mocks/eth_clienter.go
+++ b/l1infotreesync/mocks/mock_eth_clienter.go
@@ -1,6 +1,6 @@
// Code generated by mockery. DO NOT EDIT.
-package mocks_l1infotreesync
+package mocks
import (
context "context"
diff --git a/l1infotreesync/mocks/mock_reorgdetector.go b/l1infotreesync/mocks/mock_reorg_detector.go
similarity index 99%
rename from l1infotreesync/mocks/mock_reorgdetector.go
rename to l1infotreesync/mocks/mock_reorg_detector.go
index f92260c3..b8c62ba4 100644
--- a/l1infotreesync/mocks/mock_reorgdetector.go
+++ b/l1infotreesync/mocks/mock_reorg_detector.go
@@ -1,6 +1,6 @@
// Code generated by mockery. DO NOT EDIT.
-package mocks_l1infotreesync
+package mocks
import (
context "context"
diff --git a/reorgdetector/reorgdetector.go b/reorgdetector/reorgdetector.go
index d11f90d5..752dbeb1 100644
--- a/reorgdetector/reorgdetector.go
+++ b/reorgdetector/reorgdetector.go
@@ -159,10 +159,11 @@ func (rd *ReorgDetector) detectReorgInTrackedList(ctx context.Context) error {
// and hashes matches. If higher than finalized block, we assume a reorg still might happen.
if hdr.Num <= lastFinalisedBlock.Number.Uint64() {
hdrs.removeRange(hdr.Num, hdr.Num)
- }
- if err := rd.removeTrackedBlockRange(id, hdr.Num, hdr.Num); err != nil {
- return fmt.Errorf("error removing blocks from DB for subscriber %s between blocks %d and %d: %w",
- id, hdr.Num, hdr.Num, err)
+
+ if err := rd.removeTrackedBlockRange(id, hdr.Num, hdr.Num); err != nil {
+ return fmt.Errorf("error removing blocks from DB for subscriber %s between blocks %d and %d: %w",
+ id, hdr.Num, hdr.Num, err)
+ }
}
continue
diff --git a/reorgdetector/reorgdetector_db.go b/reorgdetector/reorgdetector_db.go
index f5bed3a7..5900bfc5 100644
--- a/reorgdetector/reorgdetector_db.go
+++ b/reorgdetector/reorgdetector_db.go
@@ -70,7 +70,7 @@ func (rd *ReorgDetector) saveTrackedBlock(id string, b header) error {
// updateTrackedBlocksDB updates the tracked blocks for a subscriber in db
func (rd *ReorgDetector) removeTrackedBlockRange(id string, fromBlock, toBlock uint64) error {
_, err := rd.db.Exec(
- "DELETE FROM tracked_block WHERE num >= $1 AND NUM <= 2 AND subscriber_id = $3;",
+ "DELETE FROM tracked_block WHERE num >= $1 AND num <= $2 AND subscriber_id = $3;",
fromBlock, toBlock, id,
)
return err
diff --git a/reorgdetector/reorgdetector_test.go b/reorgdetector/reorgdetector_test.go
index f5cf50b4..7bb78bda 100644
--- a/reorgdetector/reorgdetector_test.go
+++ b/reorgdetector/reorgdetector_test.go
@@ -2,14 +2,18 @@ package reorgdetector
import (
"context"
+ big "math/big"
"path"
"strings"
+ "sync"
"testing"
"time"
aggkittypes "github.com/agglayer/aggkit/config/types"
common "github.com/ethereum/go-ethereum/common"
+ types "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient/simulated"
+ "github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
)
@@ -158,3 +162,98 @@ func TestNotSubscribed(t *testing.T) {
err = reorgDetector.AddBlockToTrack(context.Background(), "foo", 1, common.Hash{})
require.True(t, strings.Contains(err.Error(), "is not subscribed"))
}
+
+func TestDetectReorgs(t *testing.T) {
+ t.Parallel()
+
+ ctx := context.Background()
+ syncerID := "test-syncer"
+ trackedBlock := &types.Header{Number: big.NewInt(9)}
+
+ t.Run("Block not finalized", func(t *testing.T) {
+ t.Parallel()
+
+ lastFinalizedBlock := &types.Header{Number: big.NewInt(8)}
+ client := NewEthClientMock(t)
+ client.On("HeaderByNumber", ctx, big.NewInt(int64(rpc.FinalizedBlockNumber))).Return(lastFinalizedBlock, nil)
+ client.On("HeaderByNumber", ctx, trackedBlock.Number).Return(trackedBlock, nil)
+
+ testDir := path.Join(t.TempDir(), "reorgdetectorTestDetectReorgs.sqlite")
+ reorgDetector, err := New(client, Config{DBPath: testDir, CheckReorgsInterval: aggkittypes.NewDuration(time.Millisecond * 100)})
+ require.NoError(t, err)
+
+ _, err = reorgDetector.Subscribe(syncerID)
+ require.NoError(t, err)
+ require.NoError(t, reorgDetector.AddBlockToTrack(ctx, syncerID, trackedBlock.Number.Uint64(), trackedBlock.Hash()))
+
+ require.NoError(t, reorgDetector.detectReorgInTrackedList(ctx))
+
+ trackedBlocks, err := reorgDetector.getTrackedBlocks()
+ require.NoError(t, err)
+ require.Equal(t, 1, len(trackedBlocks))
+
+ syncerTrackedBlocks, ok := trackedBlocks[syncerID]
+ require.True(t, ok)
+ require.Equal(t, 1, syncerTrackedBlocks.len())
+ })
+
+ t.Run("Block finalized", func(t *testing.T) {
+ t.Parallel()
+
+ lastFinalizedBlock := trackedBlock
+ client := NewEthClientMock(t)
+ client.On("HeaderByNumber", ctx, big.NewInt(int64(rpc.FinalizedBlockNumber))).Return(lastFinalizedBlock, nil)
+
+ testDir := path.Join(t.TempDir(), "reorgdetectorTestDetectReorgs.sqlite")
+ reorgDetector, err := New(client, Config{DBPath: testDir, CheckReorgsInterval: aggkittypes.NewDuration(time.Millisecond * 100)})
+ require.NoError(t, err)
+
+ _, err = reorgDetector.Subscribe(syncerID)
+ require.NoError(t, err)
+ require.NoError(t, reorgDetector.AddBlockToTrack(ctx, syncerID, trackedBlock.Number.Uint64(), trackedBlock.Hash()))
+
+ require.NoError(t, reorgDetector.detectReorgInTrackedList(ctx))
+
+ trackedBlocks, err := reorgDetector.getTrackedBlocks()
+ require.NoError(t, err)
+ require.Equal(t, 0, len(trackedBlocks))
+ })
+
+ t.Run("Reorg happened", func(t *testing.T) {
+ t.Parallel()
+
+ lastFinalizedBlock := &types.Header{Number: big.NewInt(5)}
+ reorgedTrackedBlock := &types.Header{Number: trackedBlock.Number, Extra: []byte("reorged")} // Different hash
+
+ client := NewEthClientMock(t)
+ client.On("HeaderByNumber", ctx, big.NewInt(int64(rpc.FinalizedBlockNumber))).Return(lastFinalizedBlock, nil)
+ client.On("HeaderByNumber", ctx, trackedBlock.Number).Return(reorgedTrackedBlock, nil)
+
+ testDir := path.Join(t.TempDir(), "reorgdetectorTestDetectReorgs.sqlite")
+ reorgDetector, err := New(client, Config{DBPath: testDir, CheckReorgsInterval: aggkittypes.NewDuration(time.Millisecond * 100)})
+ require.NoError(t, err)
+
+ subscription, err := reorgDetector.Subscribe(syncerID)
+ require.NoError(t, err)
+
+ var wg sync.WaitGroup
+
+ wg.Add(1)
+ go func() {
+ <-subscription.ReorgedBlock
+ subscription.ReorgProcessed <- true
+
+ wg.Done()
+ }()
+
+ require.NoError(t, reorgDetector.AddBlockToTrack(ctx, syncerID, trackedBlock.Number.Uint64(), trackedBlock.Hash()))
+
+ require.NoError(t, reorgDetector.detectReorgInTrackedList(ctx))
+
+ wg.Wait() // we wait here to make sure the reorg is processed
+
+ trackedBlocks, err := reorgDetector.getTrackedBlocks()
+ require.NoError(t, err)
+ require.Equal(t, 0, len(trackedBlocks)) // shouldn't be any since a reorg happened on that block
+ })
+}
diff --git a/rpc/mocks/bridge_client_interface.go b/rpc/mocks/mock_bridge_client_interface.go
similarity index 100%
rename from rpc/mocks/bridge_client_interface.go
rename to rpc/mocks/mock_bridge_client_interface.go
diff --git a/rpc/mocks/bridger.go b/rpc/mocks/mock_bridger.go
similarity index 100%
rename from rpc/mocks/bridger.go
rename to rpc/mocks/mock_bridger.go
diff --git a/rpc/mocks/claim_sponsorer.go b/rpc/mocks/mock_claim_sponsorer.go
similarity index 100%
rename from rpc/mocks/claim_sponsorer.go
rename to rpc/mocks/mock_claim_sponsorer.go
diff --git a/rpc/mocks/client_factory_interface.go b/rpc/mocks/mock_client_factory_interface.go
similarity index 100%
rename from rpc/mocks/client_factory_interface.go
rename to rpc/mocks/mock_client_factory_interface.go
diff --git a/rpc/mocks/client_interface.go b/rpc/mocks/mock_client_interface.go
similarity index 100%
rename from rpc/mocks/client_interface.go
rename to rpc/mocks/mock_client_interface.go
diff --git a/rpc/mocks/l1_info_treer.go b/rpc/mocks/mock_l1_info_treer.go
similarity index 99%
rename from rpc/mocks/l1_info_treer.go
rename to rpc/mocks/mock_l1_info_treer.go
index e7441155..b9c04a2a 100644
--- a/rpc/mocks/l1_info_treer.go
+++ b/rpc/mocks/mock_l1_info_treer.go
@@ -27,7 +27,7 @@ func (_m *L1InfoTreer) EXPECT() *L1InfoTreer_Expecter {
return &L1InfoTreer_Expecter{mock: &_m.Mock}
}
-// GetFirstInfo provides a mock function with given fields:
+// GetFirstInfo provides a mock function with no fields
func (_m *L1InfoTreer) GetFirstInfo() (*l1infotreesync.L1InfoTreeLeaf, error) {
ret := _m.Called()
@@ -376,7 +376,7 @@ func (_c *L1InfoTreer_GetInfoByIndex_Call) RunAndReturn(run func(context.Context
return _c
}
-// GetLastInfo provides a mock function with given fields:
+// GetLastInfo provides a mock function with no fields
func (_m *L1InfoTreer) GetLastInfo() (*l1infotreesync.L1InfoTreeLeaf, error) {
ret := _m.Called()
diff --git a/rpc/mocks/last_ge_rer.go b/rpc/mocks/mock_last_ge_rer.go
similarity index 100%
rename from rpc/mocks/last_ge_rer.go
rename to rpc/mocks/mock_last_ge_rer.go
diff --git a/scripts/local_config b/scripts/local_config
index aab17d20..87fe60df 100755
--- a/scripts/local_config
+++ b/scripts/local_config
@@ -413,12 +413,10 @@ cat << EOF
"args":[
"run",
"-cfg", "$DEST_TEMPLATE_FILE",
- "-components", "sequence-sender,aggregator",
+ "-components", "aggsender",
]
},
- To run AggSender change components to:
- "-components", "aggsender",
EOF
echo " -----------------------------------------------------------"
diff --git a/sync/driver.go b/sync/driver.go
deleted file mode 100644
index f85c04fb..00000000
--- a/sync/driver.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package sync
-
-import (
- "context"
- "errors"
-)
-
-var ErrInconsistentState = errors.New("state is inconsistent, try again later once the state is consolidated")
-
-type Block struct {
- Num uint64
- Events []interface{}
-}
-
-type ProcessorInterface interface {
- GetLastProcessedBlock(ctx context.Context) (uint64, error)
- ProcessBlock(block Block) error
- Reorg(firstReorgedBlock uint64) error
-}
diff --git a/sync/evmdriver.go b/sync/evmdriver.go
index 72476cef..cfa96f41 100644
--- a/sync/evmdriver.go
+++ b/sync/evmdriver.go
@@ -9,6 +9,13 @@ import (
"github.com/ethereum/go-ethereum/common"
)
+var ErrInconsistentState = errors.New("state is inconsistent, try again later once the state is consolidated")
+
+type Block struct {
+ Num uint64
+ Events []interface{}
+}
+
type evmDownloaderFull interface {
EVMDownloaderInterface
downloader
diff --git a/sync/mock_l2_test.go b/sync/mock_eth_clienter.go
similarity index 100%
rename from sync/mock_l2_test.go
rename to sync/mock_eth_clienter.go
diff --git a/sync/mock_downloader_test.go b/sync/mock_evm_downloader_full.go
similarity index 100%
rename from sync/mock_downloader_test.go
rename to sync/mock_evm_downloader_full.go
diff --git a/sync/mock_processor_test.go b/sync/mock_processor_interface.go
similarity index 100%
rename from sync/mock_processor_test.go
rename to sync/mock_processor_interface.go
diff --git a/sync/mock_reorgdetector_test.go b/sync/mock_reorg_detector.go
similarity index 100%
rename from sync/mock_reorgdetector_test.go
rename to sync/mock_reorg_detector.go
diff --git a/test/Makefile b/test/Makefile
index b99b372e..cced2c9d 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,52 +1,8 @@
-.PHONY: generate-mocks
-generate-mocks: generate-mocks-bridgesync generate-mocks-reorgdetector \
- generate-mocks-da \
- generate-mocks-l1infotreesync generate-mocks-helpers \
- generate-mocks-sync \
- generate-mocks-aggsender generate-mocks-agglayer
-
COMMON_MOCKERY_PARAMS=--disable-version-string --with-expecter --exported
-.PHONY: generate-mocks-bridgesync
-generate-mocks-bridgesync: ## Generates mocks for bridgesync, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../bridgesync --output ../bridgesync/mocks --outpkg mocks_bridgesync ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-reorgdetector
-generate-mocks-reorgdetector: ## Generates mocks for reorgdetector, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthClient --dir=../reorgdetector --output=../reorgdetector --outpkg=reorgdetector --inpackage --structname=EthClientMock --filename=mock_eth_client.go ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-rpc
-generate-mocks-rpc: ## Generates mocks for rpc, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../rpc --output ../rpc/mocks --outpkg mocks ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-l1infotreesync
-generate-mocks-l1infotreesync: ## Generates mocks for l1infotreesync, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../l1infotreesync --output ../l1infotreesync/mocks --outpkg mocks_l1infotreesync ${COMMON_MOCKERY_PARAMS}
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ReorgDetector --dir=../sync --output=../l1infotreesync/mocks --outpkg=mocks_l1infotreesync --structname=ReorgDetectorMock --filename=mock_reorgdetector.go ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-helpers
-generate-mocks-helpers: ## Generates mocks for helpers, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthTxManager --dir=../aggoracle/chaingersender --output=./helpers --outpkg=helpers --structname=EthTxManagerMock --filename=mock_ethtxmanager.go ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-aggoracle
-generate-mocks-aggoracle: ## Generates mocks for aggoracle, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthTxManager --dir ../aggoracle/chaingersender --output ../aggoracle/mocks --outpkg mocks --structname=EthTxManagerMock --filename=mock_ethtxmanager.go ${COMMON_MOCKERY_PARAMS}
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=L2GERManager --dir ../aggoracle/chaingersender --output ../aggoracle/mocks --outpkg mocks --structname=L2GERManagerMock --filename=mock_l2germanager.go ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-sync
-generate-mocks-sync: ## Generates mocks for sync, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthClienter --dir=../sync --output=../sync --outpkg=sync --inpackage --structname=L2Mock --filename=mock_l2_test.go ${COMMON_MOCKERY_PARAMS}
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=evmDownloaderFull --dir=../sync --output=../sync --outpkg=sync --inpackage --structname=EVMDownloaderMock --filename=mock_downloader_test.go ${COMMON_MOCKERY_PARAMS}
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=processorInterface --dir=../sync --output=../sync --outpkg=sync --inpackage --structname=ProcessorMock --filename=mock_processor_test.go ${COMMON_MOCKERY_PARAMS}
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ReorgDetector --dir=../sync --output=../sync --outpkg=sync --inpackage --structname=ReorgDetectorMock --filename=mock_reorgdetector_test.go ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-aggsender
-generate-mocks-aggsender: ## Generates mocks for aggsender, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../aggsender --output ../aggsender/mocks --outpkg mocks ${COMMON_MOCKERY_PARAMS}
-
-.PHONY: generate-mocks-agglayer
-generate-mocks-agglayer: ## Generates mocks for agglayer, using mockery tool
- export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=AgglayerClientInterface --dir=../agglayer --output=../agglayer --outpkg=agglayer --inpackage --structname=AgglayerClientMock --filename=mock_agglayer_client.go ${COMMON_MOCKERY_PARAMS}
+.PHONY: generate-mocks
+generate-mocks:
+ mockery ${COMMON_MOCKERY_PARAMS}
.PHONY: test-e2e-fork12-pessimistic
test-e2e-fork12-pessimistic: stop
diff --git a/test/combinations/fork12-pessimistic-multi-attach-second-cdk.yml b/test/combinations/fork12-pessimistic-multi-attach-second-cdk.yml
index 47aa6d78..18e555d2 100644
--- a/test/combinations/fork12-pessimistic-multi-attach-second-cdk.yml
+++ b/test/combinations/fork12-pessimistic-multi-attach-second-cdk.yml
@@ -27,7 +27,7 @@ args:
cdk_node_image: cdk:latest
- cdk_erigon_node_image: hermeznetwork/cdk-erigon:v2.60.0
+ cdk_erigon_node_image: hermeznetwork/cdk-erigon:v2.61.2
zkevm_contracts_image: leovct/zkevm-contracts:v9.0.0-rc.3-pp-fork.12-patch.1
additional_services: []
consensus_contract_type: pessimistic
@@ -37,4 +37,3 @@ args:
zkevm_use_real_verifier: true
enable_normalcy: true
verifier_program_vkey: 0x00766aa16a6efe4ac05c0fe21d4b50f9631dbd1a2663a982da861427085ea2ea
-
diff --git a/test/combinations/fork12-pessimistic-multi.yml b/test/combinations/fork12-pessimistic-multi.yml
index 46845991..36bb57ea 100644
--- a/test/combinations/fork12-pessimistic-multi.yml
+++ b/test/combinations/fork12-pessimistic-multi.yml
@@ -1,7 +1,7 @@
args:
cdk_node_image: cdk:latest
agglayer_image: ghcr.io/agglayer/agglayer:0.2.0-rc.20
- cdk_erigon_node_image: hermeznetwork/cdk-erigon:v2.60.0
+ cdk_erigon_node_image: hermeznetwork/cdk-erigon:v2.61.2
zkevm_contracts_image: leovct/zkevm-contracts:v9.0.0-rc.3-pp-fork.12-patch.1
additional_services: []
consensus_contract_type: pessimistic
@@ -12,4 +12,3 @@ args:
enable_normalcy: true
verifier_program_vkey: 0x00766aa16a6efe4ac05c0fe21d4b50f9631dbd1a2663a982da861427085ea2ea
agglayer_prover_sp1_key: {{.AGGLAYER_PROVER_SP1_KEY}}
-
diff --git a/test/combinations/fork12-pessimistic.yml b/test/combinations/fork12-pessimistic.yml
index f4f229d3..96b3ec18 100644
--- a/test/combinations/fork12-pessimistic.yml
+++ b/test/combinations/fork12-pessimistic.yml
@@ -1,6 +1,6 @@
args:
agglayer_image: ghcr.io/agglayer/agglayer:0.2.0-rc.20
- cdk_erigon_node_image: hermeznetwork/cdk-erigon:v2.60.0-beta8
+ cdk_erigon_node_image: hermeznetwork/cdk-erigon:v2.61.2
cdk_node_image: cdk
zkevm_bridge_proxy_image: haproxy:3.0-bookworm
zkevm_bridge_service_image: hermeznetwork/zkevm-bridge-service:v0.6.0-RC1
diff --git a/test/scripts/env.sh b/test/scripts/env.sh
index 298d4f73..5dbde9de 100644
--- a/test/scripts/env.sh
+++ b/test/scripts/env.sh
@@ -1,7 +1,7 @@
#!/bin/bash
### Common variables
KURTOSIS_ENCLAVE=cdk
-TMP_CDK_FOLDER=tmp/cdk
-DEST_KURTOSIS_PARAMS_YML=../$TMP_CDK_FOLDER/e2e-params.yml
+TMP_AGGKIT_FOLDER=tmp/aggkit
+DEST_KURTOSIS_PARAMS_YML=../$TMP_AGGKIT_FOLDER/e2e-params.yml
KURTOSIS_FOLDER=${KURTOSIS_FOLDER:=../kurtosis-cdk}
USE_L1_GAS_TOKEN_CONTRACT=true