From 2e08b19d8a72f041fcf0aec745a3c279e0f1f796 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 5 Mar 2025 19:44:06 +0900 Subject: [PATCH 01/37] support milli timestamp Signed-off-by: Naohiro Yoshida --- module/header.go | 9 +++++++++ module/prover.go | 2 +- tests/prover_network_test.go | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/module/header.go b/module/header.go index e90b499c..119f9f01 100644 --- a/module/header.go +++ b/module/header.go @@ -2,6 +2,7 @@ package module import ( "fmt" + "github.com/holiman/uint256" "log" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -82,3 +83,11 @@ func (h *Header) Account(path common.Address) (*types.StateAccount, error) { } return verifyAccount(target, h.AccountProof, path) } + +func MilliTimestamp(h *types.Header) uint64 { + milliseconds := uint64(0) + if h.MixDigest != (common.Hash{}) { + milliseconds = uint256.NewInt(0).SetBytes32(h.MixDigest[:]).Uint64() + } + return h.Time*1000 + milliseconds +} diff --git a/module/prover.go b/module/prover.go index efc71781..bda0f093 100644 --- a/module/prover.go +++ b/module/prover.go @@ -257,7 +257,7 @@ func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState ForkSpecs: GetForkParameters(Network(pr.config.Network)), } consensusState := ConsensusState{ - Timestamp: header.Time, + Timestamp: MilliTimestamp(header), PreviousValidatorsHash: makeEpochHash(previousValidators, previousTurnLength), CurrentValidatorsHash: makeEpochHash(currentValidators, currentTurnLength), StateRoot: stateRoot.Bytes(), diff --git a/tests/prover_network_test.go b/tests/prover_network_test.go index 56b912bf..381d9e6a 100644 --- a/tests/prover_network_test.go +++ b/tests/prover_network_test.go @@ -99,7 +99,7 @@ func (ts *ProverNetworkTestSuite) TestSuccessCreateInitialLightClientState() { consState := s2.(*module.ConsensusState) ts.Require().Equal(consState.CurrentValidatorsHash, module.MakeEpochHash(cVal, cTurn)) ts.Require().Equal(consState.PreviousValidatorsHash, module.MakeEpochHash(pVal, pTurn)) - ts.Require().Equal(consState.Timestamp, header.Time) + ts.Require().Equal(consState.Timestamp, module.MilliTimestamp(header)) storageRoot, err := ts.prover.GetStorageRoot(header) ts.Require().NoError(err) ts.Require().Equal(common.BytesToHash(consState.StateRoot), storageRoot) From 1ddc5959917ccc6b539f328c24c3a1b0e285f0b3 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 5 Mar 2025 19:56:57 +0900 Subject: [PATCH 02/37] tweak tool Signed-off-by: Naohiro Yoshida --- tool/testdata/internal/create_client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tool/testdata/internal/create_client.go b/tool/testdata/internal/create_client.go index 9c65f305..c8257836 100644 --- a/tool/testdata/internal/create_client.go +++ b/tool/testdata/internal/create_client.go @@ -54,9 +54,9 @@ func (m *createClientModule) createClientSuccessCmd() *cobra.Command { log.Println("consensusState", common.Bytes2Hex(anyConsState)) log.Println("height", cs.GetLatestHeight().GetRevisionHeight()) log.Println("time", consState.GetTimestamp()) - log.Println("currentEpochHash", module.MakeEpochHash(currentValidatorSet, currentTurnLength)) - log.Println("previousEpochHash", module.MakeEpochHash(previousValidatorSet, previousTurnLength)) - log.Println("storageRoot", consState.(*module.ConsensusState).StateRoot) + log.Println("currentEpochHash", common.BytesToHash(module.MakeEpochHash(currentValidatorSet, currentTurnLength))) + log.Println("previousEpochHash", common.BytesToHash(module.MakeEpochHash(previousValidatorSet, previousTurnLength))) + log.Println("storageRoot", common.BytesToHash(consState.(*module.ConsensusState).StateRoot)) return nil }, From 01a284fa31363822f35bbdea3033f56c7fd1ffa5 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Mon, 17 Mar 2025 15:16:23 +0900 Subject: [PATCH 03/37] change epoch length Signed-off-by: Naohiro Yoshida --- .github/workflows/ci.yml | 5 +++- e2e/Makefile | 3 +-- e2e/chains/bsc/docker-compose.bsc.yml | 2 +- e2e/chains/bsc/docker-compose.simple.yml | 2 -- .../bsc/genesis/genesis-template.template | 8 +++++-- e2e/chains/bsc/scripts/bootstrap.sh | 5 ---- go.mod | 2 +- module/constant/development.go | 24 ------------------- module/constant/production.go | 4 +--- 9 files changed, 14 insertions(+), 41 deletions(-) delete mode 100644 module/constant/development.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd9b8529..cca1e084 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,10 @@ jobs: run: | make chain make contracts - sleep 20 + # epoch length is fixed in lorentz HF. + # epoch is 200, 400, 500, 1000 + # must wait for 1000 block (1.5sec * 1000) + sleep 1500 make relayer make test - name: integration-test diff --git a/e2e/Makefile b/e2e/Makefile index 440bf9c8..82b711f9 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -13,8 +13,7 @@ contracts: .PHONY:relayer relayer: rm -rf .testrly - go build -tags dev -ldflags="-X github.com/datachainlab/ibc-parlia-relay/module/constant.blocksPerEpoch=20" -o testrly . - # go build -o testrly . + go build -o testrly . ./testrly config init --home .testrly ./testrly chains add-dir config/demo/ --home .testrly ./testrly paths add ibc0 ibc1 ibc01 --file=config/path.json --home .testrly diff --git a/e2e/chains/bsc/docker-compose.bsc.yml b/e2e/chains/bsc/docker-compose.bsc.yml index c183b876..67af2269 100644 --- a/e2e/chains/bsc/docker-compose.bsc.yml +++ b/e2e/chains/bsc/docker-compose.bsc.yml @@ -5,5 +5,5 @@ services: dockerfile: Dockerfile.bsc args: GIT_SOURCE: https://github.com/bnb-chain/bsc - GIT_CHECKOUT_BRANCH: v1.5.5 + GIT_CHECKOUT_BRANCH: develop image: bsc-geth:docker-local diff --git a/e2e/chains/bsc/docker-compose.simple.yml b/e2e/chains/bsc/docker-compose.simple.yml index 3efc0a57..649dd689 100644 --- a/e2e/chains/bsc/docker-compose.simple.yml +++ b/e2e/chains/bsc/docker-compose.simple.yml @@ -19,7 +19,6 @@ services: dockerfile: Dockerfile.bootstrap env_file: .env environment: - BLOCKS_PER_EPOCH: 20 INIT_HOLDER_BALANCE: "500000000000000000000" NUMS_OF_VALIDATOR: 5 INIT_NUM_OF_CABINETS: 4 @@ -42,7 +41,6 @@ services: dockerfile: Dockerfile.bootstrap env_file: .env2 environment: - BLOCKS_PER_EPOCH: 20 INIT_HOLDER_BALANCE: "500000000000000000000" NUMS_OF_VALIDATOR: 3 INIT_NUM_OF_CABINETS: 2 diff --git a/e2e/chains/bsc/genesis/genesis-template.template b/e2e/chains/bsc/genesis/genesis-template.template index ad1c6b4d..e7074ecf 100644 --- a/e2e/chains/bsc/genesis/genesis-template.template +++ b/e2e/chains/bsc/genesis/genesis-template.template @@ -35,6 +35,7 @@ "bohrTime": 0, "pascalTime": 0, "pragueTime": 0, + "lorentzTime": 0, "blobSchedule": { "cancun": { "target": 3, @@ -45,11 +46,14 @@ "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 + }, + "lorentz": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 } }, "parlia": { - "period": 3, - "epoch": {{BLOCKS_PER_EPOCH}} } }, "nonce": "0x0", diff --git a/e2e/chains/bsc/scripts/bootstrap.sh b/e2e/chains/bsc/scripts/bootstrap.sh index 094d7ab5..db05736f 100755 --- a/e2e/chains/bsc/scripts/bootstrap.sh +++ b/e2e/chains/bsc/scripts/bootstrap.sh @@ -35,10 +35,6 @@ function init_validator() { function generate_genesis() { INIT_HOLDER_ADDRESSES=$(ls ${workspace}/init-holders | tr '\n' ',') INIT_HOLDER_ADDRESSES=${INIT_HOLDER_ADDRESSES/%,/} - echo "blocks per epoch = ${BLOCKS_PER_EPOCH}" - - echo "replace genesis-template.template" - sed "s/{{BLOCKS_PER_EPOCH}}/${BLOCKS_PER_EPOCH}/g" genesis-template.template >genesis-template.json echo "replace init_holders.template" sed "s/{{INIT_HOLDER_ADDRESSES}}/${INIT_HOLDER_ADDRESSES}/g" scripts/init_holders.template | sed "s/{{INIT_HOLDER_BALANCE}}/${INIT_HOLDER_BALANCE}/g" >scripts/init_holders.js @@ -49,7 +45,6 @@ function generate_genesis() { echo "replace generate.py" sed "s/dev_chain_id: int = 714/dev_chain_id: int = ${BSC_CHAIN_ID}/g" scripts/generate.py > scripts/generate.py.out - sed "s/epoch: str = \"200\"/epoch: str = \"${BLOCKS_PER_EPOCH}\"/g" scripts/generate.py.out > scripts/generate.py echo "start generate validators" node scripts/generate-validator.js diff --git a/go.mod b/go.mod index f2fb2b1b..7f281ec2 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/datachainlab/ethereum-ibc-relay-chain v0.3.16 github.com/datachainlab/ibc-hd-signer v0.1.2 github.com/ethereum/go-ethereum v1.15.0 + github.com/holiman/uint256 v1.3.2 github.com/hyperledger-labs/yui-relayer v0.5.11 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.10.0 @@ -132,7 +133,6 @@ require ( github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.3.2 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect diff --git a/module/constant/development.go b/module/constant/development.go deleted file mode 100644 index 042841f4..00000000 --- a/module/constant/development.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build dev - -package constant - -import ( - "log" - "strconv" -) - -// can change by ldflags -var blocksPerEpoch string = "200" - -var BlocksPerEpoch uint64 = 200 - -func init() { - iBlocksPerEpoch, err := strconv.Atoi(blocksPerEpoch) - if err != nil { - panic(err) - } - BlocksPerEpoch = uint64(iBlocksPerEpoch) - if BlocksPerEpoch != 200 { - log.Printf("blocks per epoch = %d", BlocksPerEpoch) - } -} diff --git a/module/constant/production.go b/module/constant/production.go index a10e2f74..3e952cf3 100644 --- a/module/constant/production.go +++ b/module/constant/production.go @@ -1,5 +1,3 @@ -//go:build !dev - package constant -const BlocksPerEpoch uint64 = 200 +const BlocksPerEpoch uint64 = 500 From 87a6c5d4f3b7b29523446db799caf35fd5e436f7 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Mon, 17 Mar 2025 18:50:21 +0900 Subject: [PATCH 04/37] change bootstrap --- e2e/chains/bsc/scripts/bootstrap.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/e2e/chains/bsc/scripts/bootstrap.sh b/e2e/chains/bsc/scripts/bootstrap.sh index db05736f..33c86f80 100755 --- a/e2e/chains/bsc/scripts/bootstrap.sh +++ b/e2e/chains/bsc/scripts/bootstrap.sh @@ -36,6 +36,9 @@ function generate_genesis() { INIT_HOLDER_ADDRESSES=$(ls ${workspace}/init-holders | tr '\n' ',') INIT_HOLDER_ADDRESSES=${INIT_HOLDER_ADDRESSES/%,/} + echo "replace genesis-template.template" + cp genesis-template.template genesis-template.json + echo "replace init_holders.template" sed "s/{{INIT_HOLDER_ADDRESSES}}/${INIT_HOLDER_ADDRESSES}/g" scripts/init_holders.template | sed "s/{{INIT_HOLDER_BALANCE}}/${INIT_HOLDER_BALANCE}/g" >scripts/init_holders.js @@ -45,6 +48,7 @@ function generate_genesis() { echo "replace generate.py" sed "s/dev_chain_id: int = 714/dev_chain_id: int = ${BSC_CHAIN_ID}/g" scripts/generate.py > scripts/generate.py.out + cp scripts/generate.py.out scripts/generate.py echo "start generate validators" node scripts/generate-validator.js From fe2c43eff24788fe2248295fd470503387ae6cf6 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Tue, 18 Mar 2025 19:55:49 +0900 Subject: [PATCH 05/37] fix test Signed-off-by: Naohiro Yoshida --- module/header_query_test.go | 10 +++++----- module/lib_test.go | 20 ++++++++++---------- tests/prover_network_test.go | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/module/header_query_test.go b/module/header_query_test.go index 264cff69..a05948d7 100644 --- a/module/header_query_test.go +++ b/module/header_query_test.go @@ -45,7 +45,7 @@ func (ts *HeaderQueryTestSuite) TestErrorQueryFinalizedHeader() { return &types.Header{Number: big.NewInt(int64(height))}, nil } - headers, err = queryFinalizedHeader(fn, 360, 400) + headers, err = queryFinalizedHeader(fn, 760, 1000) ts.Require().NoError(err) ts.Require().Nil(headers) } @@ -60,9 +60,9 @@ func (ts *HeaderQueryTestSuite) TestSuccessQueryFinalizedHeader() { return &types.Header{Number: big.NewInt(int64(height))}, nil } - headers, err := queryFinalizedHeader(fn, 360, 402) + headers, err := queryFinalizedHeader(fn, 760, 1002) ts.Require().NoError(err) - ts.Require().Len(headers, 402-360) + ts.Require().Len(headers, 1002-760) } func (ts *HeaderQueryTestSuite) TestSuccessQueryLatestFinalizedHeader() { @@ -78,9 +78,9 @@ func (ts *HeaderQueryTestSuite) TestSuccessQueryLatestFinalizedHeader() { height, h, err := queryLatestFinalizedHeader(getHeader, latestBlockNumber) ts.Require().NoError(err) ts.Require().Len(h, 3) - ts.Require().Equal(int(height), 401) + ts.Require().Equal(int(height), 1001) } - for i := 403; i < 403+100; i++ { + for i := 1003; i < 1003+100; i++ { verify(uint64(i)) } } diff --git a/module/lib_test.go b/module/lib_test.go index 572d8e31..e2131704 100644 --- a/module/lib_test.go +++ b/module/lib_test.go @@ -17,36 +17,36 @@ func fromRlp(hex string) *types.Header { } func previousEpochHeader() *types.Header { - return fromRlp("f90391a0844dee9abff97d261ae0049fe38246ac10aba49f2b8618f28f7c2d19e62eccf9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0ecf1aa30fa754576ac4abc3cf2a61d1babd41c7e5515855efd857b2d3f37866ba00f0ea7d212c4aaca329b03f5e9ed9c69d3641eb5e03a4edb69b61e6f9d8d51efa0c3372a1f332fc4245e1a9fdcb62580fc6dae741087a8029560f19216dd3d58b9b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000281c88402625a00826c7484669a6a91b90173d98301040b846765746889676f312e32312e3132856c696e7578000020155b72048fdaaa7e6631e438625ca25c857a3727ea28e565b94a73be71b4a5703b4d0b36e4f65d52615b668b385efc047f7f385ace378981fa3750a0bc16ca6f8217be599bcfa274b2e42bc54d19116d2348ac83461e2e0915d508ad921ebe99c27c8fdbd30aecdbe86f95aee2e06995f83ebeb327924669629f193ffd3257315c79ed5a4867ec53b502b5e6d9a13701eafb76870cb220843b8c6476824bfa158c66a3f3d2fba1d440da8edc79b59ed9a3a43db62bd7659f7d4e25073f9241dba560600b23e26c30d48ea0395eeeb4ede04db2de85453e0936b441c339a26d10cfa71b50a50dd5edefbafd33740101d074b6d58b56a787a7644ddfff77d0c00f9e62cc58c931e671afc564f3f6e255cc6fc8a567015cbc63c3d778cef5e8dbfdaf1fd8f758a764f2667aad2d3775954e4ac23e726226b66f0a94631bd0b6d937b22955d73eed65a31a6f535662f51cc7547143f6f201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080") + return fromRlp("f90482a05e0415a04370b022b7a003e86fdd29e13e8781435867230cc6e5ff45e1924cbea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a0bae6330554017c1046039ecbd12d5e62956bf2af0bc371415b4778d5b33a085fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201f48402625a00808467d7b8bbb90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926901f8ae0fb860a7c69dd2e73ffb364f69c37bded01a0b6a4ed65dbc6d8f86bf4e96f1372273d6b91e7e4e74976067acf10aab91ce53c508376fbd5d29c3a9387b6ffca3d190a8e375d1c3bf55cb104738c99bc8882afb20b8dc6b3c02a7d9c40fa0ed02937ad6f8488201f2a0074b91607b4a91e13eef4df4ad575ec25da52100a0d56a481803dd41143c90838201f3a05e0415a04370b022b7a003e86fdd29e13e8781435867230cc6e5ff45e1924cbe8031443f1f703eae6925ce1036aa58458d8d7673ef4d0f40a7ea18a0ef91f1a07c62ffe6be3e7db067ec696db0d9e6be5c50ffe4482f05b79f9c55a7b4ca5d58ca01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") } func epochHeader() *types.Header { - return fromRlp("f90442a04ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa0015ebe4a5d6cd56f0bf97db1d21746f59ab5cbecf216e34753920d815403ada2a03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201908402625a008229a884669a6ce9b90223d98301040b846765746889676f312e32312e3132856c696e7578000020155b72048fdaaa7e6631e438625ca25c857a3727ea28e565b94a73be71b4a5703b4d0b36e4f65d52615b668b385efc047f7f385ace378981fa3750a0bc16ca6f8217be599bcfa274a7876ea32e7a748c697d01345145485561305b248cd0ede772633b8baea9958f9b602db36d78934d948244a13c2d66e998f987783276e9aee6facbff50b0d63574406b51b2e42bc54d19116d2348ac83461e2e0915d508ad921ebe99c27c8fdbd30aecdbe86f95aee2e06995f83ebeb327924669629f193ffd3257315c79ed5a4867ec53b502b5e6e04db2de85453e0936b441c339a26d10cfa71b50a50dd5edefbafd33740101d074b6d58b56a787a7644ddfff77d0c00f9e62cc58c931e671afc564f3f6e255cc6fc8a56701f8ae0fb8608b6dc552b410a6fa44fa31643850bcb314f1d4edb32c0c79ee3efef5397691f3685d80057d77510a00e77a39e8b2497419053c3b81a8901e85590a20a0a2dad529c82f6c175ec3ebca8a9112415aa94718af673c16c0e90e327e27709666e499f84882018ea0709f88597f05218c198818991cf5598c9280db30d5bfe899da9b7a8c963bff6c82018fa04ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5d8012518315e9c22a4a648f4d26efcf57f877a26498de6d53fe7a267e8d5ef01482009817fc9de90ca8008ef1f420aa606ddc0c56a975bace3906601fd5cde657d600a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080") + return fromRlp("f90484a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948fdaaa7e6631e438625ca25c857a3727ea28e565a04c35879f76cd366249e5810ce3ff0a4be2f4e1a995e004fa207bcbece6b43bf2a0e0781acd204a300b1a607656df80d8a3ab2684fb6fa9e83d4087aa9e9157330ca03cd1ebc99cd975182c58de47be968c97658cff4c465e20654185f408a851403cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e88402625a008229a88467d7bba9b90223d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0048fdaaa7e6631e438625ca25c857a3727ea28e565b00d73deea8ca44ff831d529526b46ac87dc187399497f5b2b671371fe86232004649c5ee362ef07c388f2c7f2cb7198a7876ea32e7a748c697d01345145485561305b24b1e91d15cdacddb71c64a5227970bd4f99376c40387efb60274a093429de86c81a85f448706d5e4214a406f47db1fa08d9a13701eafb76870cb220843b8c6476824bfa158668fccdfba6b5d5bc1a39e431d716ea715244473169f178d9af70c33b89a7481f54098cf885c8db140fdcd55ad5e4e9e04db2de85453e0936b441c339a26d10cfa71b50a258fb77ce7f0d3ac60e0d97fdade3efe76d8e6950ce30b40aa9914f7b2d42c247cbd36821d8741739dea2451720926906f8ae0fb86099f5bd42d7a4e11f283b9daa22fe1f7ae89e5260b61722ec3f57dc2b18a669e0040e42a6f81d114732c00609d4648b0d0fec3a07fb300cf49a7cf6116abb217b13a63ee6330663349e8a316c42dc04f16131445a331365d2b32bcb4d5b546c25f8488203e6a0302d35ff53c930401473e5650e8169f18f1156d0127cd1bd1a3e65fe365c5efc8203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a80a240096b876248068d454519a30d241182b95497f8a66d6d179495e9fd6d9427096f4c35eb87299f195d8fd4731d162a2c8ab445dd0ea56989288b2825c640c100a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") } func epochHeaderPlus1() *types.Header { - return fromRlp("f9032ea0e256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad31a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794b2e42bc54d19116d2348ac83461e2e0915d508ada08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201918402625a008084669a6cecb90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb8609338bf42b6ef715e9c887e1b285e706355c2a993cd227497b447f8aad4b7fa44d18cd895862e1a2b961b78656d620f9c015e777cf9bcb6c50e1db2783818bd91f647f6879f8bd199f266f1166f9241f00f955fb5210e7e89e7678680900d1cc1f84882018fa04ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5d820190a0e256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad3180d6c559fceda3795918a2fdd34cb4f77608c8095b67091aadcef5d5c4efe09fc0477a1977c0037f19244240648637c3c5ec9fe22f1db4899a022575bec96cfccf01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080") + return fromRlp("f90370a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a7876ea32e7a748c697d01345145485561305b24a04ff32807d3701bcff50e1213fdce58ce988fb64c9e1cc269874a3d970ef7d1e8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203e98402625a00808467d7bbaab90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860a51854c31fb60a02ba70c07eeb467be677b9548c828607f99dfd0edc80a9b25be05670b86485dd71d8fb8e19d7458a9103d942ea6b84070ed47adcd3a3f284385fc538a5f692289c3abc25372e461a54ef23100718aedf80224a1e4fe26671d3f8488203e7a0322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a8203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c80313317225cc094c83c097e6a830295a3e3a6df48baadc709927d7d2bc643d9ef4d474ff4442565ef2c0bf90644095ee4d3a9934650d1b989f9d82ba9d664e57100a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") } func epochHeaderPlus2() *types.Header { - return fromRlp("f9032ea0669cf9fc3b3d480d7a8de1cc051e1d95fa24be8870aa93bb5bfc03f1d592db46a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201928402625a008084669a6cefb90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb8608d465cf004274c6caaddd041116c93f12cba458536d23efc6148134af357a685c7b84b1d3de59eb61b2756e7b99a99de00a6158245e16d23dd10602ef719836ce41862c567745727a145df4bde737415e8ffbec5056d4653b02fe1ddc8f21069f848820190a0e256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad31820191a0669cf9fc3b3d480d7a8de1cc051e1d95fa24be8870aa93bb5bfc03f1d592db468083bec325b33996ad2fc35e146d7e8fd215177b1423378d3b07cb73293d5384733488a981b64ae03cbcf44af281cfbd57431addbd8432042c49fb4c78d5573f0d01a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080") + return fromRlp("f90370a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794d9a13701eafb76870cb220843b8c6476824bfa15a08c694a1f89eafbe7d2a2e08e4e64f855159fe234cb26637edf6a166429d4f338a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203ea8402625a00808467d7bbacb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb86094e9755690770485712c5b0f060b43d2bd542c3712146d8542053d4f42d05bf253ed5ee05efb85862f2faf4b6c25279e1735110b78af88000b4c90462ff318fc195be0b1a7a0d4e41943ec288aafab6eb3c5ebc31dd2a0ce428cceebf20553aef8488203e8a03a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c8203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8020c2f74f57683c3ca4405ad21e3fdf74c30624571bbcf7b88cf27d4b12631ac9069c6fa8ff35fac1662e9bc89dc040cec541fd36aee8c8058c299bafc0ed5d1700a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") } func epochHeaderPlus3() *types.Header { - return fromRlp("f9032ea0705444384ac2acf605c4ca8353e5070f37cc0976597dfdfc74413e278725eee7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a08d30abd786d85a8a10ba441afafdf853b7fd2769351f6600402b88a1ac2d4d7aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028201938402625a008084669a6cf2b90111d98301040b846765746889676f312e32312e3132856c696e7578000020155b72f8ae0fb860a6e88879bc7f8ff4ee90ba0776b414b97ffcb0a2bc4f9484075ea121e00b7ce27e21c0fbf76f34746b232e76a37cfc220011efbd7863237e75eb2830748736e9092847a283401bf6793e94d00619764884d012609cf5bace403e93b66f60c3bcf848820191a0669cf9fc3b3d480d7a8de1cc051e1d95fa24be8870aa93bb5bfc03f1d592db46820192a0705444384ac2acf605c4ca8353e5070f37cc0976597dfdfc74413e278725eee780f5171f7fc98ba3118543b55677128c397b07085a29dcd71c989c7f0eb602308342cf64470f85ebe31ebdda4244e7992b82ff2026ac461d0f2997332ccb99255201a0000000000000000000000000000000000000000000000000000000000000000088000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080") + return fromRlp("f90370a04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e04db2de85453e0936b441c339a26d10cfa71b50a0167484b0a23d96c53238b8e02465ce28353b86bde23a4c76079c206ef68c9646a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028203eb8402625a00808467d7bbadb90111d883010507846765746888676f312e32332e37856c696e75780000001c8a30c0f8ae0fb860acaa8373b727de717178de93621351e285bc9803b59af041bcf6125421adb461838a18c251c2fe3e747b4081010e429411a750ddc02871238102ac2df09bcb6085b48d9061f23dda19b5084c1b6b8cbdf816f29643413a0b616ba24a3b00145bf8488203e9a04e490385e3e7a962e9f76d0a07d84d23920c6c35f18e1f789370256e6c987acd8203eaa04efd97fb852943cd7e995432bfb2d3ec64847f7e84b37d5a3022d7b3c04abd24805444abf4fc554f34fd1f7e8e768ffa50740d4cbe373175fa115bc3b674d4d2322496a207e5d5bf5224071a161d9194db4b9c4e628e3214c3f4c35bf194998b0c00a000000000000000000000000000000000000000000000000000000000000001f488000000000000000080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000a0e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") } func headerByHeight(height int64) *types.Header { switch height { - case 200: + case 500: return previousEpochHeader() - case 400: + case 1000: return epochHeader() - case 401: + case 1001: return epochHeaderPlus1() - case 402: + case 1002: return epochHeaderPlus2() - case 403: + case 1003: return epochHeaderPlus3() } return nil diff --git a/tests/prover_network_test.go b/tests/prover_network_test.go index 630bca49..c4a33aa0 100644 --- a/tests/prover_network_test.go +++ b/tests/prover_network_test.go @@ -98,7 +98,7 @@ func (ts *ProverNetworkTestSuite) TestSuccessCreateInitialLightClientState() { consState := s2.(*module.ConsensusState) ts.Require().Equal(consState.CurrentValidatorsHash, module.MakeEpochHash(cVal, cTurn)) ts.Require().Equal(consState.PreviousValidatorsHash, module.MakeEpochHash(pVal, pTurn)) - ts.Require().Equal(consState.Timestamp, header.Time) + ts.Require().Equal(consState.Timestamp, module.MilliTimestamp(header)) ts.Require().Equal(common.BytesToHash(consState.StateRoot), header.Root) } From 5f84fd19c406f5dcabdfabada0a215961dd9cacf Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Tue, 18 Mar 2025 22:03:28 +0900 Subject: [PATCH 06/37] fix test Signed-off-by: Naohiro Yoshida --- module/setup_test.go | 7 ++++--- module/validator_set_test.go | 4 ++-- module/vote_test.go | 26 +++++++++++++------------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/module/setup_test.go b/module/setup_test.go index 161b5e61..44a84292 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -141,8 +141,8 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_allEmpty() { func (ts *SetupTestSuite) TestSuccess_setupNeighboringEpochHeader() { - epochHeight := uint64(400) - trustedEpochHeight := uint64(200) + epochHeight := constant.BlocksPerEpoch * 2 + trustedEpochHeight := constant.BlocksPerEpoch neighboringEpochFn := func(height uint64, limit uint64) (core.Header, error) { target, err := newETHHeader(&types2.Header{ @@ -162,5 +162,6 @@ func (ts *SetupTestSuite) TestSuccess_setupNeighboringEpochHeader() { ts.Require().NoError(err) // next checkpoint - 1 - ts.Require().Equal(int64(602), target.Number.Int64()) + // turnLength = 6, then checkpoint = 18 + ts.Require().Equal(int64(1517), target.Number.Int64()) } diff --git a/module/validator_set_test.go b/module/validator_set_test.go index 0a0c0dd7..4226b3b7 100644 --- a/module/validator_set_test.go +++ b/module/validator_set_test.go @@ -32,7 +32,7 @@ func (ts *ValidatorSetTestSuite) TestSuccessExtractValidatorSet() { validators, turnLength, err = extractValidatorSetAndTurnLength(block) ts.Require().NoError(err) ts.Require().Len(validators, 4) - ts.Require().Equal(turnLength, uint8(1)) + ts.Require().Equal(turnLength, uint8(6)) } @@ -57,7 +57,7 @@ func (ts *ValidatorSetTestSuite) TestSuccessQueryValidatorSet() { validators, turnLength, err := QueryValidatorSetAndTurnLength(fn, 400) ts.Require().NoError(err) ts.Require().Len(validators, 4) - ts.Require().Equal(turnLength, uint8(1)) + ts.Require().Equal(turnLength, uint8(6)) } func (ts *ValidatorSetTestSuite) TestErrorQueryValidatorSet() { diff --git a/module/vote_test.go b/module/vote_test.go index 1015428e..c31cd97c 100644 --- a/module/vote_test.go +++ b/module/vote_test.go @@ -1,6 +1,7 @@ package module import ( + "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/suite" @@ -20,22 +21,22 @@ func (ts *VoteTestSuite) SetupTest() { } func (ts *VoteTestSuite) TestSuccessGetVoteAttestationFromHeaderEpoch() { - // 400 + // 100 header := epochHeader() vote, err := getVoteAttestationFromHeader(header) ts.Require().NoError(err) ts.Require().Equal(vote.VoteAddressSet, uint64(15)) - ts.Require().Equal(vote.Data.SourceHash, common.HexToHash("0x709f88597f05218c198818991cf5598c9280db30d5bfe899da9b7a8c963bff6c")) - ts.Require().Equal(vote.Data.SourceNumber, uint64(398)) - ts.Require().Equal(vote.Data.TargetHash, common.HexToHash("0x4ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5d")) - ts.Require().Equal(vote.Data.TargetNumber, uint64(399)) - ts.Require().Equal(common.Bytes2Hex(vote.AggSignature[:]), "8b6dc552b410a6fa44fa31643850bcb314f1d4edb32c0c79ee3efef5397691f3685d80057d77510a00e77a39e8b2497419053c3b81a8901e85590a20a0a2dad529c82f6c175ec3ebca8a9112415aa94718af673c16c0e90e327e27709666e499") + ts.Require().Equal(vote.Data.SourceHash, common.HexToHash("0x302d35ff53c930401473e5650e8169f18f1156d0127cd1bd1a3e65fe365c5efc")) + ts.Require().Equal(vote.Data.SourceNumber, header.Number.Uint64()-2) + ts.Require().Equal(vote.Data.TargetHash, common.HexToHash("0x322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a")) + ts.Require().Equal(vote.Data.TargetNumber, header.Number.Uint64()-1) + ts.Require().Equal(common.Bytes2Hex(vote.AggSignature[:]), "99f5bd42d7a4e11f283b9daa22fe1f7ae89e5260b61722ec3f57dc2b18a669e0040e42a6f81d114732c00609d4648b0d0fec3a07fb300cf49a7cf6116abb217b13a63ee6330663349e8a316c42dc04f16131445a331365d2b32bcb4d5b546c25") } func (ts *VoteTestSuite) TestErrorGetVoteAttestationFromHeaderEpochNoVote() { header := &types.Header{ Extra: common.Hex2Bytes("d98301040d846765746889676f312e32312e3132856c696e757800000299d9bc0808265da01e1a65d62b903c7b34c08cb389bf3d9996f763f030b1adcfb369c5a5df4a18e1529baffe7feaec66db3dbd1bc06810f7f6f88b7be6645418a7e2a2a3f40514c215a13e315cbfb9398a26d77a299963bf034c28f8b0183ea044211f468630233d2533b73307979c78a9486b33bb4ee04ca31a65f3e86fba804db7fe293fa643e6b72bb3821a3d9d7a717d64e6088ac937d5aacdd3e20ca963979974cd8ff90cbf097023dc8c448245ceff671e965d57d82eaf9be91478cfa0f24d2993e0c5f43a6c5a4cd99850023040d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d53387f3321fd69d1e030bb921230dfb188826affaa39ebf1c38b190851e4db0588a3e90142c5299041fb8a0db3bb9a1fa4bdf0dae84ca37ee12a6b8c26caab775f0e007b76d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf7f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bfd447b49cd040d20bc21e49ffea6487f5638e4346ad9fc6d1ec30e28016d3892b51a7898bd354cfe78643453fd3868410da412de7f2883180d0a2840111ad2e043fa403eb04cc3c0ed356ea54a6e7015490240681b002cb63e12f65c456cafca335c730b123553e70df5322013812429e0bc31508e1f1fbf0ab312e4aaade9e022150071a1f00"), - Number: big.NewInt(43198800), + Number: big.NewInt(0).SetUint64(constant.BlocksPerEpoch), } vote, err := getVoteAttestationFromHeader(header) ts.Require().NoError(err) @@ -43,16 +44,15 @@ func (ts *VoteTestSuite) TestErrorGetVoteAttestationFromHeaderEpochNoVote() { } func (ts *VoteTestSuite) TestSuccessGetVoteAttestationFromHeaderNotEpoch() { - // 401 header := epochHeaderPlus1() vote, err := getVoteAttestationFromHeader(header) ts.Require().NoError(err) ts.Require().Equal(vote.VoteAddressSet, uint64(15)) - ts.Require().Equal(vote.Data.SourceHash, common.HexToHash("0x4ec3c90370deeeab62de72108470bccac75d1abe118a778f01afa7a99c976a5d")) - ts.Require().Equal(vote.Data.SourceNumber, uint64(399)) - ts.Require().Equal(vote.Data.TargetHash, common.HexToHash("0xe256fac4dd62cc71eaefd8d6c24ae5209c0e48f5c0b62bcced06dfa838c2ad31")) - ts.Require().Equal(vote.Data.TargetNumber, uint64(400)) - ts.Require().Equal(common.Bytes2Hex(vote.AggSignature[:]), "9338bf42b6ef715e9c887e1b285e706355c2a993cd227497b447f8aad4b7fa44d18cd895862e1a2b961b78656d620f9c015e777cf9bcb6c50e1db2783818bd91f647f6879f8bd199f266f1166f9241f00f955fb5210e7e89e7678680900d1cc1") + ts.Require().Equal(vote.Data.SourceHash, common.HexToHash("0x322d19e268300c0c825ffdc22a4376232406b925a7c4be8727f9a4425818ec8a")) + ts.Require().Equal(vote.Data.SourceNumber, header.Number.Uint64()-2) + ts.Require().Equal(vote.Data.TargetHash, common.HexToHash("0x3a302bedfa30dd88b82a95136a99d93ea8863a741c2201ad77a63d0f9c0c329c")) + ts.Require().Equal(vote.Data.TargetNumber, header.Number.Uint64()-1) + ts.Require().Equal(common.Bytes2Hex(vote.AggSignature[:]), "a51854c31fb60a02ba70c07eeb467be677b9548c828607f99dfd0edc80a9b25be05670b86485dd71d8fb8e19d7458a9103d942ea6b84070ed47adcd3a3f284385fc538a5f692289c3abc25372e461a54ef23100718aedf80224a1e4fe26671d3") } func (ts *VoteTestSuite) TestErrorGetVoteAttestationFromHeader() { From 5ecb5178ab172d0efe662b20344532cb17fd4019 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Thu, 20 Mar 2025 15:01:44 +0900 Subject: [PATCH 07/37] add epoch length Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 36 +++++ module/parlia.pb.go | 139 +++++++++++------- proto/ibc/lightclients/parlia/v1/parlia.proto | 1 + 3 files changed, 121 insertions(+), 55 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index eb093c1c..df716f81 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -1,5 +1,10 @@ package module +import ( + "os" + "strconv" +) + type Network string const ( @@ -9,12 +14,31 @@ const ( ) func GetForkParameters(network Network) []*ForkSpec { + switch network { case Localnet: + + localLorentzHFTimestamp := os.Getenv("LOCAL_LORENTZ_HF_TIMESTAMP") + localLorentzHFTimestampInt := uint64(1) + if localLorentzHFTimestamp != "" { + result, err := strconv.Atoi(localLorentzHFTimestamp) + if err != nil { + panic(err) + } + localLorentzHFTimestampInt = uint64(result) + } return []*ForkSpec{ + // Pascal HF { HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, AdditionalHeaderItemCount: 1, + EpochLength: 200, + }, + // Lorentz HF + { + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: localLorentzHFTimestampInt}, + AdditionalHeaderItemCount: 1, + EpochLength: 500, }, } case Testnet: @@ -22,6 +46,12 @@ func GetForkParameters(network Network) []*ForkSpec { { HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, AdditionalHeaderItemCount: 1, + EpochLength: 200, + }, + { + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1}, + AdditionalHeaderItemCount: 1, + EpochLength: 500, }, } case Mainnet: @@ -29,6 +59,12 @@ func GetForkParameters(network Network) []*ForkSpec { { HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, AdditionalHeaderItemCount: 1, + EpochLength: 200, + }, + { + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1}, + AdditionalHeaderItemCount: 1, + EpochLength: 500, }, } } diff --git a/module/parlia.pb.go b/module/parlia.pb.go index 7641d20c..4fcee62f 100644 --- a/module/parlia.pb.go +++ b/module/parlia.pb.go @@ -34,6 +34,7 @@ type ForkSpec struct { // *ForkSpec_Timestamp HeightOrTimestamp isForkSpec_HeightOrTimestamp `protobuf_oneof:"height_or_timestamp"` AdditionalHeaderItemCount uint64 `protobuf:"varint,3,opt,name=additional_header_item_count,json=additionalHeaderItemCount,proto3" json:"additional_header_item_count,omitempty"` + EpochLength uint64 `protobuf:"varint,4,opt,name=epoch_length,json=epochLength,proto3" json:"epoch_length,omitempty"` } func (m *ForkSpec) Reset() { *m = ForkSpec{} } @@ -369,61 +370,62 @@ func init() { } var fileDescriptor_dc631224085c6c85 = []byte{ - // 855 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0xf6, 0x24, 0xc1, 0xb1, 0x2b, 0xf6, 0x86, 0xed, 0xec, 0x2e, 0x93, 0xb0, 0x4c, 0x2c, 0x2f, - 0x08, 0x83, 0x94, 0x19, 0x1c, 0x24, 0xc4, 0x05, 0x45, 0x1b, 0x2f, 0xc8, 0x11, 0xbb, 0x52, 0x34, - 0x59, 0x71, 0x40, 0x48, 0xad, 0x9e, 0x99, 0xb6, 0xa7, 0x95, 0x99, 0x69, 0xab, 0xbb, 0xc7, 0x5a, - 0x78, 0x0a, 0x8e, 0x1c, 0x78, 0x01, 0x9e, 0x62, 0xaf, 0x39, 0xa1, 0x3d, 0x72, 0xe2, 0x27, 0x79, - 0x11, 0xd4, 0x3f, 0xfe, 0x41, 0x81, 0x05, 0x6e, 0x5d, 0x55, 0xdf, 0x57, 0xd5, 0x5d, 0x5f, 0x75, - 0xc1, 0xfb, 0x2c, 0x49, 0xa3, 0x82, 0x4d, 0x73, 0x95, 0x16, 0x8c, 0x56, 0x4a, 0x46, 0x33, 0x22, - 0x0a, 0x46, 0xa2, 0xf9, 0xd0, 0x9d, 0xc2, 0x99, 0xe0, 0x8a, 0xa3, 0x03, 0x96, 0xa4, 0xe1, 0x3a, - 0x30, 0x74, 0xe1, 0xf9, 0xf0, 0xe0, 0xde, 0x94, 0x4f, 0xb9, 0x81, 0x45, 0xfa, 0x64, 0x19, 0x07, - 0x87, 0x3a, 0x75, 0xca, 0x05, 0x8d, 0x2c, 0x43, 0xa7, 0xb4, 0x27, 0x07, 0x08, 0xa6, 0x9c, 0x4f, - 0x0b, 0x1a, 0x19, 0x2b, 0xa9, 0x27, 0x51, 0x56, 0x0b, 0xa2, 0x18, 0xaf, 0x6c, 0xbc, 0xff, 0xa3, - 0x07, 0xad, 0x2f, 0xb8, 0xb8, 0xbc, 0x98, 0xd1, 0x14, 0xf9, 0xd0, 0xcc, 0xa9, 0x2e, 0xef, 0x7b, - 0x3d, 0x6f, 0xb0, 0x35, 0x6e, 0xc4, 0xce, 0x46, 0x01, 0xb4, 0x15, 0x2b, 0xa9, 0x54, 0xa4, 0x9c, - 0xf9, 0x1b, 0x2e, 0xb8, 0x72, 0xa1, 0x13, 0x78, 0x48, 0xb2, 0x8c, 0xe9, 0xc4, 0xa4, 0xc0, 0x39, - 0x25, 0x19, 0x15, 0x98, 0x29, 0x5a, 0xe2, 0x94, 0xd7, 0x95, 0xf2, 0x37, 0x35, 0x25, 0xde, 0x5f, - 0x61, 0xc6, 0x06, 0x72, 0xa6, 0x68, 0x39, 0xd2, 0x80, 0xd3, 0xfb, 0xb0, 0x67, 0x4b, 0x61, 0x2e, - 0xf0, 0x32, 0x6f, 0xff, 0xe5, 0x26, 0xec, 0x8c, 0xcc, 0x7b, 0x2e, 0x14, 0x51, 0x14, 0xed, 0x43, - 0x2b, 0xcd, 0x09, 0xab, 0x30, 0xcb, 0xec, 0x1d, 0xe3, 0x6d, 0x63, 0x9f, 0x65, 0xe8, 0x43, 0xb8, - 0xcb, 0x92, 0x14, 0x4b, 0xc5, 0x05, 0xc5, 0x24, 0xcb, 0x04, 0x95, 0xd2, 0x5c, 0xb5, 0x13, 0xef, - 0xb2, 0x24, 0xbd, 0xd0, 0xfe, 0xc7, 0xd6, 0x8d, 0x3e, 0x82, 0x7b, 0x1a, 0x9b, 0xf2, 0xb2, 0x64, - 0xaa, 0xd4, 0x9d, 0xc6, 0xb2, 0xe0, 0xf6, 0x9a, 0x9d, 0x18, 0xb1, 0x24, 0x1d, 0xad, 0x42, 0x17, - 0x05, 0x57, 0xe8, 0x04, 0xba, 0x05, 0x51, 0x54, 0x2a, 0xec, 0x3a, 0xb4, 0xd5, 0xf3, 0x06, 0x3b, - 0xc7, 0x07, 0xa1, 0x96, 0x4c, 0x0b, 0x10, 0xba, 0xb6, 0xcf, 0x87, 0xe1, 0xd8, 0x20, 0xe2, 0x8e, - 0x25, 0x58, 0x0b, 0x3d, 0x85, 0x5d, 0x25, 0x6a, 0xa9, 0x58, 0x35, 0xc5, 0x33, 0x2a, 0x18, 0xcf, - 0xfc, 0x37, 0x4c, 0x8a, 0xfd, 0xd0, 0x4a, 0x14, 0x2e, 0x24, 0x0a, 0x9f, 0x38, 0x89, 0x4e, 0x5b, - 0x57, 0xbf, 0x1e, 0x36, 0x7e, 0xf8, 0xed, 0xd0, 0x8b, 0xef, 0x2c, 0xb8, 0xe7, 0x86, 0x8a, 0xbe, - 0x84, 0xdd, 0x92, 0xbc, 0xc0, 0x69, 0xc1, 0xd3, 0x4b, 0x9c, 0x09, 0x36, 0x51, 0x7e, 0xf3, 0xbf, - 0x67, 0xeb, 0x96, 0xe4, 0xc5, 0x48, 0x53, 0x9f, 0x68, 0x26, 0x7a, 0x00, 0xcd, 0x89, 0xe0, 0xdf, - 0xd1, 0xca, 0xdf, 0xee, 0x79, 0x83, 0x56, 0xec, 0x2c, 0x34, 0x02, 0x98, 0x70, 0x71, 0x89, 0xe5, - 0x8c, 0xa6, 0xd2, 0x6f, 0xf5, 0x36, 0x07, 0x3b, 0xc7, 0xef, 0x86, 0xff, 0x3c, 0xa3, 0xe1, 0x62, - 0x90, 0xe2, 0xf6, 0xc4, 0x9d, 0x64, 0xff, 0x11, 0xb4, 0x3f, 0x7f, 0x3e, 0xb6, 0x72, 0xeb, 0x4a, - 0x76, 0x36, 0x8c, 0x78, 0x9d, 0xd8, 0x59, 0xfd, 0x9f, 0x37, 0xa0, 0xe9, 0x20, 0x27, 0xb0, 0x6d, - 0x9d, 0xd2, 0xf7, 0x4c, 0xc5, 0xf7, 0x5e, 0x57, 0x71, 0x99, 0x3a, 0x5e, 0xb0, 0xd0, 0x63, 0xb0, - 0xcd, 0xa2, 0xd9, 0x42, 0xaa, 0x8d, 0x7f, 0x95, 0xaa, 0xeb, 0x18, 0x4e, 0xab, 0x23, 0x40, 0x69, - 0x2d, 0x04, 0xad, 0x14, 0x9e, 0x93, 0x82, 0x65, 0x44, 0x71, 0x21, 0xfd, 0xcd, 0xde, 0xe6, 0xa0, - 0x13, 0xdf, 0x75, 0x91, 0xaf, 0x96, 0x01, 0x14, 0xc1, 0xde, 0x4c, 0xd0, 0x39, 0xe3, 0xb5, 0x5c, - 0xc7, 0x6f, 0x19, 0x3c, 0x5a, 0x84, 0xd6, 0x08, 0x21, 0xec, 0x2d, 0xf2, 0xab, 0x5a, 0x54, 0xb8, - 0xa0, 0xd5, 0x54, 0xe5, 0x66, 0x1e, 0xba, 0xcb, 0x02, 0xcf, 0x6b, 0x51, 0x3d, 0x35, 0x01, 0x3d, - 0xae, 0xcb, 0x02, 0xeb, 0x84, 0xa6, 0x21, 0x2c, 0x2b, 0xac, 0x18, 0xfd, 0x97, 0x1e, 0xdc, 0x19, - 0xf1, 0x4a, 0xd2, 0x4a, 0xd6, 0xd2, 0x7e, 0x9d, 0x77, 0x00, 0xa4, 0x3e, 0x60, 0xc1, 0xb9, 0x72, - 0xfd, 0x6f, 0x1b, 0x4f, 0xcc, 0xb9, 0x42, 0x0f, 0x6f, 0xfd, 0xf0, 0xf5, 0xff, 0xfd, 0x09, 0xbc, - 0x75, 0xbb, 0x23, 0x38, 0x27, 0x32, 0x77, 0x7f, 0xe6, 0xfe, 0xad, 0xb6, 0x8c, 0x89, 0xcc, 0xd1, - 0xa7, 0xe0, 0xff, 0x4d, 0x6b, 0x2c, 0x71, 0xcb, 0x10, 0x1f, 0xdc, 0xee, 0x8f, 0x66, 0xf6, 0x7f, - 0xf2, 0xa0, 0xf3, 0x8c, 0xc9, 0x84, 0xe6, 0x44, 0x87, 0x05, 0x7a, 0x1b, 0xda, 0x56, 0xb7, 0xc5, - 0xdf, 0x6f, 0xc7, 0x2d, 0xeb, 0x38, 0xcb, 0xd0, 0x67, 0xd0, 0x72, 0x4b, 0x67, 0xe8, 0xe4, 0xee, - 0xbf, 0x6e, 0x6c, 0xfe, 0x3a, 0x33, 0xc3, 0x35, 0xfa, 0xb1, 0x79, 0xcf, 0xff, 0xa2, 0x1f, 0xf7, - 0xbf, 0x01, 0x38, 0x17, 0x7c, 0x4e, 0x6d, 0xa3, 0x1f, 0x41, 0x97, 0xa4, 0x66, 0xed, 0xe1, 0x99, - 0xe0, 0x7c, 0xe2, 0x7a, 0xdd, 0x71, 0xce, 0x73, 0xed, 0x43, 0x1f, 0xc0, 0x9b, 0xab, 0xed, 0xe3, - 0x70, 0x6e, 0x59, 0xad, 0xfc, 0x06, 0x7a, 0xfa, 0xec, 0xea, 0x8f, 0xa0, 0x71, 0x75, 0x1d, 0x78, - 0xaf, 0xae, 0x03, 0xef, 0xf7, 0xeb, 0xc0, 0xfb, 0xfe, 0x26, 0x68, 0xbc, 0xba, 0x09, 0x1a, 0xbf, - 0xdc, 0x04, 0x8d, 0xaf, 0xa3, 0x29, 0x53, 0x79, 0x9d, 0x84, 0x29, 0x2f, 0xa3, 0x8c, 0x28, 0x62, - 0xd6, 0x61, 0x41, 0x92, 0x88, 0x25, 0xe9, 0x91, 0xbd, 0xf2, 0x91, 0xa0, 0x05, 0xf9, 0x36, 0x2a, - 0x79, 0x56, 0x17, 0x34, 0x69, 0x9a, 0xcd, 0xf0, 0xf1, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x04, - 0x47, 0xe3, 0x32, 0x96, 0x06, 0x00, 0x00, + // 869 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xf6, 0xc6, 0xc1, 0xb1, 0x27, 0x76, 0x43, 0x27, 0x6d, 0xd9, 0x84, 0xb2, 0x09, 0x2e, 0x88, + 0x80, 0x94, 0x5d, 0x1c, 0x24, 0xc4, 0x0d, 0x8a, 0x1a, 0x17, 0xe4, 0x88, 0x56, 0x8a, 0x36, 0x15, + 0x17, 0x08, 0x69, 0x34, 0x3b, 0x3b, 0xf6, 0x8e, 0xb2, 0xbb, 0xb3, 0x9a, 0x99, 0xb5, 0x0a, 0x4f, + 0xc1, 0x25, 0xaf, 0xc0, 0x53, 0xf4, 0x36, 0x57, 0xa8, 0x97, 0x5c, 0xf1, 0x93, 0xbc, 0x08, 0x9a, + 0x9f, 0xb5, 0x8d, 0x0c, 0x05, 0xee, 0x66, 0xce, 0xf9, 0xbe, 0x73, 0x66, 0xce, 0x77, 0xce, 0x01, + 0x1f, 0xb0, 0x84, 0x44, 0x39, 0x9b, 0x65, 0x8a, 0xe4, 0x8c, 0x96, 0x4a, 0x46, 0x15, 0x16, 0x39, + 0xc3, 0xd1, 0x7c, 0xe4, 0x4e, 0x61, 0x25, 0xb8, 0xe2, 0x70, 0x9f, 0x25, 0x24, 0x5c, 0x05, 0x86, + 0xce, 0x3d, 0x1f, 0xed, 0xdf, 0x9b, 0xf1, 0x19, 0x37, 0xb0, 0x48, 0x9f, 0x2c, 0x63, 0xff, 0x40, + 0x87, 0x26, 0x5c, 0xd0, 0xc8, 0x32, 0x74, 0x48, 0x7b, 0x72, 0x80, 0x60, 0xc6, 0xf9, 0x2c, 0xa7, + 0x91, 0xb9, 0x25, 0xf5, 0x34, 0x4a, 0x6b, 0x81, 0x15, 0xe3, 0xa5, 0xf5, 0x0f, 0x5f, 0x7a, 0xa0, + 0xfb, 0x25, 0x17, 0x57, 0x97, 0x15, 0x25, 0xd0, 0x07, 0x9d, 0x8c, 0xea, 0xf4, 0xbe, 0x77, 0xe8, + 0x1d, 0x6d, 0x4e, 0x5a, 0xb1, 0xbb, 0xc3, 0x00, 0xf4, 0x14, 0x2b, 0xa8, 0x54, 0xb8, 0xa8, 0xfc, + 0x0d, 0xe7, 0x5c, 0x9a, 0xe0, 0x29, 0x78, 0x88, 0xd3, 0x94, 0xe9, 0xc0, 0x38, 0x47, 0x19, 0xc5, + 0x29, 0x15, 0x88, 0x29, 0x5a, 0x20, 0xc2, 0xeb, 0x52, 0xf9, 0x6d, 0x4d, 0x89, 0xf7, 0x96, 0x98, + 0x89, 0x81, 0x9c, 0x2b, 0x5a, 0x8c, 0x35, 0x00, 0xbe, 0x0b, 0xfa, 0xb4, 0xe2, 0x24, 0x43, 0x39, + 0x2d, 0x67, 0x2a, 0xf3, 0x37, 0x0d, 0x61, 0xdb, 0xd8, 0x9e, 0x1a, 0xd3, 0xd9, 0x7d, 0xb0, 0x6b, + 0x5f, 0x83, 0xb8, 0x40, 0x8b, 0xd4, 0xc3, 0x97, 0x6d, 0xb0, 0x3d, 0x36, 0x5f, 0xbe, 0x54, 0x58, + 0x51, 0xb8, 0x07, 0xba, 0x24, 0xc3, 0xac, 0x44, 0x2c, 0xb5, 0xdf, 0x88, 0xb7, 0xcc, 0xfd, 0x3c, + 0x85, 0x1f, 0x81, 0xbb, 0x2c, 0x21, 0x48, 0x2a, 0x2e, 0x28, 0xc2, 0x69, 0x2a, 0xa8, 0x94, 0xe6, + 0x37, 0xfd, 0x78, 0x87, 0x25, 0xe4, 0x52, 0xdb, 0x1f, 0x5b, 0x33, 0xfc, 0x18, 0xdc, 0xd3, 0x58, + 0xc2, 0x8b, 0x82, 0xa9, 0x42, 0x8b, 0x81, 0x64, 0xce, 0xed, 0x4f, 0xfa, 0x31, 0x64, 0x09, 0x19, + 0x2f, 0x5d, 0x97, 0x39, 0x57, 0xf0, 0x14, 0x0c, 0x72, 0xac, 0xa8, 0x54, 0xc8, 0x15, 0x51, 0xff, + 0x61, 0xfb, 0x64, 0x3f, 0xd4, 0xaa, 0x6a, 0x8d, 0x42, 0xa7, 0xcc, 0x7c, 0x14, 0x4e, 0x0c, 0x22, + 0xee, 0x5b, 0x82, 0xbd, 0xc1, 0xa7, 0x60, 0x47, 0x89, 0x5a, 0x2a, 0x56, 0xce, 0x50, 0x45, 0x05, + 0xe3, 0xa9, 0xff, 0x86, 0x09, 0xb1, 0x17, 0x5a, 0x15, 0xc3, 0x46, 0xc5, 0xf0, 0x89, 0x53, 0xf1, + 0xac, 0x7b, 0xfd, 0xeb, 0x41, 0xeb, 0xc7, 0xdf, 0x0e, 0xbc, 0xf8, 0x4e, 0xc3, 0xbd, 0x30, 0x54, + 0xf8, 0x15, 0xd8, 0x29, 0xf0, 0x0b, 0x44, 0x72, 0x4e, 0xae, 0x50, 0x2a, 0xd8, 0x54, 0xf9, 0x9d, + 0xff, 0x1e, 0x6d, 0x50, 0xe0, 0x17, 0x63, 0x4d, 0x7d, 0xa2, 0x99, 0xf0, 0x01, 0xe8, 0x4c, 0x05, + 0xff, 0x9e, 0x96, 0xfe, 0xd6, 0xa1, 0x77, 0xd4, 0x8d, 0xdd, 0x0d, 0x8e, 0x01, 0x98, 0x72, 0x71, + 0x85, 0x64, 0x45, 0x89, 0xf4, 0xbb, 0x87, 0xed, 0xa3, 0xed, 0x93, 0xf7, 0xc2, 0x7f, 0x6e, 0xe3, + 0xb0, 0xe9, 0xb5, 0xb8, 0x37, 0x75, 0x27, 0x39, 0x7c, 0x04, 0x7a, 0x5f, 0x3c, 0x9f, 0xd8, 0x8e, + 0xd0, 0x99, 0x6c, 0xfb, 0x18, 0xf1, 0xfa, 0xb1, 0xbb, 0x0d, 0x7f, 0xde, 0x00, 0x1d, 0x07, 0x39, + 0x05, 0x5b, 0xd6, 0x28, 0x7d, 0xcf, 0x64, 0x7c, 0xff, 0x75, 0x19, 0x17, 0xa1, 0xe3, 0x86, 0x05, + 0x1f, 0x03, 0x5b, 0x2c, 0x9a, 0x36, 0x52, 0x6d, 0xfc, 0xab, 0x54, 0x03, 0xc7, 0x70, 0x5a, 0x1d, + 0x03, 0x48, 0x6a, 0x21, 0x68, 0xa9, 0xd0, 0x1c, 0xe7, 0x2c, 0xc5, 0x8a, 0x0b, 0xe9, 0xb7, 0x0f, + 0xdb, 0x47, 0xfd, 0xf8, 0xae, 0xf3, 0x7c, 0xbd, 0x70, 0xc0, 0x08, 0xec, 0x56, 0x82, 0xce, 0x19, + 0xaf, 0xe5, 0x2a, 0x7e, 0xd3, 0xe0, 0x61, 0xe3, 0x5a, 0x21, 0x84, 0x60, 0xb7, 0x89, 0xaf, 0x6a, + 0x51, 0x36, 0x63, 0xa1, 0xfb, 0x61, 0xb0, 0x48, 0xf0, 0xbc, 0x16, 0xa5, 0x1d, 0x0e, 0xdd, 0xae, + 0x8b, 0x04, 0xab, 0x84, 0x8e, 0x21, 0x2c, 0x32, 0x2c, 0x19, 0x7a, 0xf2, 0xef, 0x8c, 0x79, 0x29, + 0x69, 0x29, 0x6b, 0x69, 0x47, 0xe7, 0x1d, 0x00, 0xa4, 0x3e, 0x20, 0xc1, 0xb9, 0x72, 0xf5, 0xef, + 0x19, 0x4b, 0xcc, 0xb9, 0x82, 0x0f, 0xd7, 0x96, 0xc0, 0xea, 0x0a, 0xf8, 0x14, 0xbc, 0xb5, 0x5e, + 0x11, 0x94, 0x61, 0x99, 0xb9, 0x99, 0xb9, 0xbf, 0x56, 0x96, 0x09, 0x96, 0x19, 0xfc, 0x0c, 0xf8, + 0x7f, 0x53, 0x1a, 0x4b, 0xdc, 0x34, 0xc4, 0x07, 0xeb, 0xf5, 0xd1, 0xcc, 0xe1, 0x4f, 0x1e, 0xe8, + 0x3f, 0x63, 0x32, 0xa1, 0x19, 0xd6, 0x6e, 0x01, 0xdf, 0x06, 0x3d, 0xab, 0x5b, 0x33, 0xfb, 0xbd, + 0xb8, 0x6b, 0x0d, 0xe7, 0x29, 0xfc, 0x1c, 0x74, 0xdd, 0x5e, 0x1a, 0x39, 0xb9, 0x87, 0xaf, 0x6b, + 0x9b, 0xbf, 0xf6, 0xcc, 0x68, 0x85, 0x7e, 0x62, 0xfe, 0xf3, 0xbf, 0xe8, 0x27, 0xc3, 0x6f, 0x01, + 0xb8, 0x10, 0x7c, 0x4e, 0x6d, 0xa1, 0x1f, 0x81, 0x01, 0x26, 0x66, 0x33, 0xa2, 0x4a, 0x70, 0x3e, + 0x75, 0xb5, 0xee, 0x3b, 0xe3, 0x85, 0xb6, 0xc1, 0x0f, 0xc1, 0x9b, 0xcb, 0xed, 0xe3, 0x70, 0x6e, + 0x59, 0x2d, 0xed, 0x06, 0x7a, 0xf6, 0xec, 0xfa, 0x8f, 0xa0, 0x75, 0x7d, 0x13, 0x78, 0xaf, 0x6e, + 0x02, 0xef, 0xf7, 0x9b, 0xc0, 0xfb, 0xe1, 0x36, 0x68, 0xbd, 0xba, 0x0d, 0x5a, 0xbf, 0xdc, 0x06, + 0xad, 0x6f, 0xa2, 0x19, 0x53, 0x59, 0x9d, 0x84, 0x84, 0x17, 0x51, 0x8a, 0x15, 0x36, 0xeb, 0x30, + 0xc7, 0x49, 0xc4, 0x12, 0x72, 0x6c, 0x9f, 0x7c, 0x2c, 0x68, 0x8e, 0xbf, 0x8b, 0x0a, 0x9e, 0xd6, + 0x39, 0x4d, 0x3a, 0x66, 0x33, 0x7c, 0xf2, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x3a, 0x4e, + 0x76, 0xb9, 0x06, 0x00, 0x00, } func (m *ForkSpec) Marshal() (dAtA []byte, err error) { @@ -446,6 +448,11 @@ func (m *ForkSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.EpochLength != 0 { + i = encodeVarintParlia(dAtA, i, uint64(m.EpochLength)) + i-- + dAtA[i] = 0x20 + } if m.AdditionalHeaderItemCount != 0 { i = encodeVarintParlia(dAtA, i, uint64(m.AdditionalHeaderItemCount)) i-- @@ -851,6 +858,9 @@ func (m *ForkSpec) Size() (n int) { if m.AdditionalHeaderItemCount != 0 { n += 1 + sovParlia(uint64(m.AdditionalHeaderItemCount)) } + if m.EpochLength != 0 { + n += 1 + sovParlia(uint64(m.EpochLength)) + } return n } @@ -1115,6 +1125,25 @@ func (m *ForkSpec) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochLength", wireType) + } + m.EpochLength = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParlia + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochLength |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParlia(dAtA[iNdEx:]) diff --git a/proto/ibc/lightclients/parlia/v1/parlia.proto b/proto/ibc/lightclients/parlia/v1/parlia.proto index 380eb0ce..b9c1b857 100644 --- a/proto/ibc/lightclients/parlia/v1/parlia.proto +++ b/proto/ibc/lightclients/parlia/v1/parlia.proto @@ -13,6 +13,7 @@ message ForkSpec { uint64 timestamp = 2; } uint64 additional_header_item_count = 3; + uint64 epoch_length = 4; } message ClientState { From ed20939b11db648736ae462e1cc1a0b43797ba0a Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Thu, 20 Mar 2025 18:28:35 +0900 Subject: [PATCH 08/37] add Lorentz Fork Spec Signed-off-by: Naohiro Yoshida --- module/constant/production.go | 3 - module/fork_spec.go | 142 +++++++++++++++++++++++++++++++++- module/proof.go | 27 ++++++- module/prover.go | 10 ++- module/setup.go | 115 ++++++++++++++++++++------- 5 files changed, 258 insertions(+), 39 deletions(-) delete mode 100644 module/constant/production.go diff --git a/module/constant/production.go b/module/constant/production.go deleted file mode 100644 index 3e952cf3..00000000 --- a/module/constant/production.go +++ /dev/null @@ -1,3 +0,0 @@ -package constant - -const BlocksPerEpoch uint64 = 500 diff --git a/module/fork_spec.go b/module/fork_spec.go index df716f81..266003bc 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -1,6 +1,10 @@ package module import ( + "context" + "fmt" + "github.com/hyperledger-labs/yui-relayer/log" + "math" "os" "strconv" ) @@ -30,12 +34,14 @@ func GetForkParameters(network Network) []*ForkSpec { return []*ForkSpec{ // Pascal HF { + // Must Set Milli timestamp HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, AdditionalHeaderItemCount: 1, EpochLength: 200, }, // Lorentz HF { + // Must Set Milli timestamp HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: localLorentzHFTimestampInt}, AdditionalHeaderItemCount: 1, EpochLength: 500, @@ -44,12 +50,13 @@ func GetForkParameters(network Network) []*ForkSpec { case Testnet: return []*ForkSpec{ { - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, + // https://forum.bnbchain.org/t/bnb-chain-upgrades-testnet/934 + HeightOrTimestamp: &ForkSpec_Height{Height: 48576786}, AdditionalHeaderItemCount: 1, EpochLength: 200, }, { - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1}, + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, AdditionalHeaderItemCount: 1, EpochLength: 500, }, @@ -57,12 +64,14 @@ func GetForkParameters(network Network) []*ForkSpec { case Mainnet: return []*ForkSpec{ { - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, + // https://bscscan.com/block/47618307 + // https://github.com/bnb-chain/bsc/releases/tag/v1.5.7 + HeightOrTimestamp: &ForkSpec_Height{Height: 47618307}, AdditionalHeaderItemCount: 1, EpochLength: 200, }, { - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1}, + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, AdditionalHeaderItemCount: 1, EpochLength: 500, }, @@ -70,3 +79,128 @@ func GetForkParameters(network Network) []*ForkSpec { } return nil } + +type BoundaryEpochs struct { + PreviousForkSpec ForkSpec + CurrentForkSpec ForkSpec + BoundaryHeight uint64 + PrevLast uint64 + CurrentFirst uint64 + Intermediates []uint64 +} + +type BoundaryHeight uint64 + +func (b BoundaryHeight) getBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec ForkSpec) (*BoundaryEpochs, error) { + boundaryHeight := uint64(b) + prevLast := boundaryHeight - (boundaryHeight % prevForkSpec.EpochLength) + index := uint64(0) + currentFirst := uint64(0) + for { + candidate := boundaryHeight + index + if candidate%currentForkSpec.EpochLength == 0 { + currentFirst = candidate + break + } + } + var intermediates []uint64 + for mid := prevLast + prevForkSpec.EpochLength; mid < currentFirst; mid += prevForkSpec.EpochLength { + intermediates = append(intermediates, mid) + } + + return &BoundaryEpochs{ + PreviousForkSpec: prevForkSpec, + CurrentForkSpec: currentForkSpec, + BoundaryHeight: boundaryHeight, + PrevLast: prevLast, + CurrentFirst: currentFirst, + Intermediates: intermediates, + }, nil +} + +func (be BoundaryEpochs) CurrentEpochBlockNumber(number uint64) uint64 { + if number >= be.CurrentFirst { + return number - (number % be.CurrentForkSpec.EpochLength) + } + return number - (number % be.PreviousForkSpec.EpochLength) +} + +func (be BoundaryEpochs) PreviousEpochBlockNumber(currentEpochBlockNumber uint64) uint64 { + if currentEpochBlockNumber <= be.PrevLast { + return currentEpochBlockNumber - be.PreviousForkSpec.EpochLength + } + + for i, mid := range be.Intermediates { + if currentEpochBlockNumber == mid { + if i == 0 { + return be.PrevLast + } + return be.Intermediates[i-1] + } + } + + if currentEpochBlockNumber == be.CurrentFirst { + if len(be.Intermediates) == 0 { + return be.PrevLast + } + return be.Intermediates[len(be.Intermediates)-1] + } + + return currentEpochBlockNumber - be.CurrentForkSpec.EpochLength +} + +func findTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) (*ForkSpec, *ForkSpec, error) { + reversed := make([]*ForkSpec, len(forkSpecs)) + for i, spec := range forkSpecs { + reversed[len(forkSpecs)-i-1] = spec + } + + getPrev := func(current *ForkSpec, i int) *ForkSpec { + if i == len(reversed)-1 { + return current + } + return reversed[i+1] + } + + for i, spec := range reversed { + if x, ok := spec.GetHeightOrTimestamp().(*ForkSpec_Height); ok { + if x.Height <= height { + return spec, getPrev(spec, i), nil + } + } else { + if spec.GetTimestamp() <= timestamp { + return spec, getPrev(spec, i), nil + } + } + } + return nil, nil, fmt.Errorf("no fork spec found height=%d, timestmp=%d", height, timestamp) +} + +var cache map[uint64]BoundaryHeight + +func getBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (BoundaryHeight, error) { + logger := log.GetLogger() + boundaryHeight := uint64(0) + if condition, ok := currentForkSpec.GetHeightOrTimestamp().(*ForkSpec_Height); ok { + boundaryHeight = condition.Height + } else { + ts := currentForkSpec.GetTimestamp() + if v, ok := cache[ts]; ok { + return v, nil + } + logger.Debug("seek fork height", "currentHeight", currentHeight, "ts", ts) + for i := currentHeight; i >= 0; i-- { + h, err := headerFn(context.Background(), i) + if err != nil { + return 0, err + } + if MilliTimestamp(h) == ts { + boundaryHeight = h.Number.Uint64() + logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) + cache[currentForkSpec.GetTimestamp()] = BoundaryHeight(boundaryHeight) + break + } + } + } + return BoundaryHeight(boundaryHeight), nil +} diff --git a/module/proof.go b/module/proof.go index 0f54071d..f48db3e8 100644 --- a/module/proof.go +++ b/module/proof.go @@ -2,6 +2,7 @@ package module import ( "bytes" + "context" "fmt" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/hyperledger-labs/yui-relayer/core" @@ -170,22 +171,40 @@ func verifyAccount(target *types.Header, accountProof []byte, path common.Addres return &account, nil } -func withValidators(headerFn getHeaderFn, height uint64, ethHeaders []*ETHHeader) (core.Header, error) { +func withValidators(headerFn getHeaderFn, height uint64, ethHeaders []*ETHHeader, forkSpecs []*ForkSpec) (core.Header, error) { header := &Header{ Headers: ethHeaders, } + blockHeader, err := headerFn(context.Background(), height) + if err != nil { + return nil, fmt.Errorf("failed to get block header : number = %d : %+v", height, err) + } + currentForkSpec, prevForkSpec, err := findTargetForkSpec(forkSpecs, height, blockHeader.Time) + if err != nil { + return nil, err + } + + boundaryHeight, err := getBoundaryHeight(headerFn, height, *currentForkSpec) + if err != nil { + return nil, err + } + + boundaryEpochs, err := boundaryHeight.getBoundaryEpochs(*currentForkSpec, *prevForkSpec) + if err != nil { + return nil, err + } + // Get validator set for verify headers - previousEpoch := getPreviousEpoch(height) + previousEpoch := boundaryEpochs.PreviousEpochBlockNumber(height) var previousTurnLength uint8 - var err error header.PreviousValidators, previousTurnLength, err = queryValidatorSetAndTurnLength(headerFn, previousEpoch) header.PreviousTurnLength = uint32(previousTurnLength) if err != nil { return nil, fmt.Errorf("ValidatorSet was not found in previous epoch : number = %d : %+v", previousEpoch, err) } - currentEpoch := getCurrentEpoch(height) + currentEpoch := boundaryEpochs.CurrentEpochBlockNumber(height) var currentTurnLength uint8 header.CurrentValidators, currentTurnLength, err = queryValidatorSetAndTurnLength(headerFn, currentEpoch) header.CurrentTurnLength = uint32(currentTurnLength) diff --git a/module/prover.go b/module/prover.go index 10bc4387..7d45ea30 100644 --- a/module/prover.go +++ b/module/prover.go @@ -138,7 +138,9 @@ func (pr *Prover) SetupHeadersForUpdateByLatestHeight(ctx context.Context, clien pr.chain.Header, clientStateLatestHeight, latestFinalizedHeader, - latestHeight) + latestHeight, + GetForkParameters(Network(pr.config.Network)), + ) } func (pr *Prover) ProveState(ctx core.QueryContext, path string, value []byte) ([]byte, clienttypes.Height, error) { @@ -227,7 +229,11 @@ func (pr *Prover) CheckRefreshRequired(ctx context.Context, counterparty core.Ch } func (pr *Prover) withValidators(height uint64, ethHeaders []*ETHHeader) (core.Header, error) { - return withValidators(pr.chain.Header, height, ethHeaders) + return withValidators(pr.chain.Header, height, ethHeaders, pr.getForkParameters()) +} + +func (pr *Prover) getForkParameters() []*ForkSpec { + return GetForkParameters(Network(pr.config.Network)) } func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState, exported.ConsensusState, error) { diff --git a/module/setup.go b/module/setup.go index dc86ec3d..aabbd90b 100644 --- a/module/setup.go +++ b/module/setup.go @@ -1,22 +1,51 @@ package module import ( + "context" "fmt" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/cosmos/ibc-go/v8/modules/core/exported" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/hyperledger-labs/yui-relayer/core" "github.com/hyperledger-labs/yui-relayer/log" ) +const skip = 100 + type queryVerifiableNeighboringEpochHeaderFn = func(uint64, uint64) (core.Header, error) +func shouldSubmitBoundaryTimestampHeader( + getHeader getHeaderFn, + trustedBlockNumber uint64, + latestFinalizedBlockNumber uint64, + forkSpecs []*ForkSpec) (*uint64, uint64, error) { + + trustedBlock, err := getHeader(context.Background(), trustedBlockNumber) + if err != nil { + return nil, 0, err + } + latestFinalizedBlock, err := getHeader(context.Background(), latestFinalizedBlockNumber) + if err != nil { + return nil, 0, err + } + + latestForkSpec := forkSpecs[len(forkSpecs)-1] + latestCondition := latestForkSpec.GetHeightOrTimestamp() + if x, ok := latestCondition.(*ForkSpec_Timestamp); ok { + if MilliTimestamp(trustedBlock) < x.Timestamp && x.Timestamp < MilliTimestamp(latestFinalizedBlock) { + // TODO 対象のheightを出す + return &x.Timestamp, 0, nil + } + } + return nil, 0, nil +} + func setupHeadersForUpdate( queryVerifiableNeighboringEpochHeader queryVerifiableNeighboringEpochHeaderFn, getHeader getHeaderFn, clientStateLatestHeight exported.Height, latestFinalizedHeader *Header, latestHeight exported.Height, + forkSpecs []*ForkSpec, ) ([]core.Header, error) { logger := log.GetLogger() logger.Debug("setupHeadersForUpdate start", "target", latestFinalizedHeader.GetHeight().GetRevisionHeight()) @@ -27,47 +56,81 @@ func setupHeadersForUpdate( return targetHeaders, nil } savedLatestHeight := clientStateLatestHeight.GetRevisionHeight() - firstUnsavedEpoch := toEpoch(savedLatestHeight) + constant.BlocksPerEpoch + + trustedBlock, err := getHeader(context.Background(), savedLatestHeight) + if err != nil { + return nil, err + } + + trustedCurrentForkSpec, trustedPreviousForkSpec, err := findTargetForkSpec(forkSpecs, savedLatestHeight, MilliTimestamp(trustedBlock)) + if err != nil { + return nil, err + } + trustedBoundaryHeight, err := getBoundaryHeight(getHeader, savedLatestHeight, *trustedCurrentForkSpec) + if err != nil { + return nil, err + } + trustedBoundaryEpochs, err := trustedBoundaryHeight.getBoundaryEpochs(*trustedCurrentForkSpec, *trustedPreviousForkSpec) + if err != nil { + return nil, err + } + + trustedEpochHeight := trustedBoundaryEpochs.CurrentEpochBlockNumber(savedLatestHeight) latestFinalizedHeight := latestFinalizedHeader.GetHeight().GetRevisionHeight() - if latestFinalizedHeight < firstUnsavedEpoch { - return withTrustedHeight(append(targetHeaders, latestFinalizedHeader), clientStateLatestHeight), nil + + // If the condition is timestamp. we must submit the header with the timestamp + nextForkBoundaryTs, nextForkBoundaryHeightMinus1, err := shouldSubmitBoundaryTimestampHeader(getHeader, savedLatestHeight, latestFinalizedHeader.GetHeight().GetRevisionHeight(), forkSpecs) + if err != nil { + return nil, err } + logger.Info("Must set boundary timestamp", "ts", nextForkBoundaryTs, "nextForkBoundaryHeightMinus1", nextForkBoundaryHeightMinus1) - trustedEpochHeight := toEpoch(savedLatestHeight) + firstUnsaved := trustedEpochHeight + skip - // Append insufficient epoch blocks - for epochHeight := firstUnsavedEpoch; epochHeight < latestFinalizedHeight; epochHeight += constant.BlocksPerEpoch { - verifiableEpoch, err := setupNeighboringEpochHeader(getHeader, queryVerifiableNeighboringEpochHeader, epochHeight, trustedEpochHeight, latestHeight) + var submittingHeights []uint64 + if latestFinalizedHeight < firstUnsaved { + if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } + } else { + for epochCandidate := firstUnsaved; epochCandidate < latestFinalizedHeight; epochCandidate += skip { + if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < epochCandidate { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1, epochCandidate) + } else { + submittingHeights = append(submittingHeights, epochCandidate) + } + } + if nextForkBoundaryTs != nil && + submittingHeights[len(submittingHeights)-1] < nextForkBoundaryHeightMinus1 && + nextForkBoundaryHeightMinus1 < latestFinalizedHeight { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } + } + logger.Debug("submitting heights", "heights", submittingHeights) + + trustedHeight := clientStateLatestHeight.GetRevisionHeight() + for _, submittingHeight := range submittingHeights { + verifiableHeader, err := setupIntermediateHeader(queryVerifiableNeighboringEpochHeader, submittingHeight, latestHeight) if err != nil { return nil, err } - if verifiableEpoch == nil { - logger.Error("[FastFinalityError]", fmt.Errorf("insufficient vote attestation: epochHeight=%d, trustedEpochHeight=%d", epochHeight, trustedEpochHeight)) + if verifiableHeader == nil { + logger.Error("[FastFinalityError]", fmt.Errorf("insufficient vote attestation: submittingHeight=%d, trusted=%d", submittingHeight, trustedHeight)) return withTrustedHeight(targetHeaders, clientStateLatestHeight), nil } - targetHeaders = append(targetHeaders, verifiableEpoch) - trustedEpochHeight = epochHeight - logger.Debug("setup epoch header", "height", epochHeight) + targetHeaders = append(targetHeaders, verifiableHeader) + trustedHeight = submittingHeight + logger.Debug("setup epoch header", "trusted", trustedHeight, "height", submittingHeight) } return withTrustedHeight(append(targetHeaders, latestFinalizedHeader), clientStateLatestHeight), nil } -func setupNeighboringEpochHeader( - getHeader getHeaderFn, +func setupIntermediateHeader( queryVerifiableHeader queryVerifiableNeighboringEpochHeaderFn, - epochHeight uint64, - trustedEpochHeight uint64, + submittingHeight uint64, latestHeight exported.Height, ) (core.Header, error) { - // neighboring epoch needs block before checkpoint - currentValidatorSet, currentTurnLength, err := queryValidatorSetAndTurnLength(getHeader, epochHeight) - if err != nil { - return nil, fmt.Errorf("setupNeighboringEpochHeader: failed to get current validator set: epochHeight=%d : %+v", epochHeight, err) - } - // ex) trusted(prevSaved = 200), epochHeight = 400 must be finalized by min(610,latest) - nextCheckpoint := currentValidatorSet.Checkpoint(currentTurnLength) + (epochHeight + constant.BlocksPerEpoch) - limit := minUint64(nextCheckpoint-1, latestHeight.GetRevisionHeight()) - return queryVerifiableHeader(epochHeight, limit) + return queryVerifiableHeader(submittingHeight, minUint64(submittingHeight+skip, latestHeight.GetRevisionHeight())) } func withTrustedHeight(targetHeaders []core.Header, clientStateLatestHeight exported.Height) []core.Header { From c83c2c8870bd31d19b8578d5a7c59d6d0de355e1 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 21 Mar 2025 14:27:46 +0900 Subject: [PATCH 09/37] update Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/fork_spec.go b/module/fork_spec.go index 266003bc..a3c39415 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -122,6 +122,12 @@ func (be BoundaryEpochs) CurrentEpochBlockNumber(number uint64) uint64 { if number >= be.CurrentFirst { return number - (number % be.CurrentForkSpec.EpochLength) } + + for i := len(be.Intermediates); i >= 0; i-- { + if number >= be.Intermediates[i] { + return be.Intermediates[i] + } + } return number - (number % be.PreviousForkSpec.EpochLength) } From 575183f04383cda7176f4e979a84c0844d873a34 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 21 Mar 2025 14:37:32 +0900 Subject: [PATCH 10/37] modify Signed-off-by: Naohiro Yoshida --- module/prover.go | 15 +++++---------- module/util.go | 18 ------------------ module/util_test.go | 27 --------------------------- 3 files changed, 5 insertions(+), 55 deletions(-) delete mode 100644 module/util_test.go diff --git a/module/prover.go b/module/prover.go index 7d45ea30..4898999c 100644 --- a/module/prover.go +++ b/module/prover.go @@ -237,18 +237,13 @@ func (pr *Prover) getForkParameters() []*ForkSpec { } func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState, exported.ConsensusState, error) { - currentEpoch := getCurrentEpoch(dstHeader.GetHeight().GetRevisionHeight()) - currentValidators, currentTurnLength, err := queryValidatorSetAndTurnLength(pr.chain.Header, currentEpoch) + dstHeader, err := pr.withValidators(dstHeader.GetHeight().GetRevisionHeight(), dstHeader.(*Header).Headers) if err != nil { return nil, nil, err } - previousEpoch := getPreviousEpoch(dstHeader.GetHeight().GetRevisionHeight()) - previousValidators, previousTurnLength, err := queryValidatorSetAndTurnLength(pr.chain.Header, previousEpoch) - if err != nil { - return nil, nil, err - } - header, err := dstHeader.(*Header).Target() + downcast := dstHeader.(*Header) + header, err := downcast.Target() if err != nil { return nil, nil, err } @@ -271,8 +266,8 @@ func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState } consensusState := ConsensusState{ Timestamp: MilliTimestamp(header), - PreviousValidatorsHash: makeEpochHash(previousValidators, previousTurnLength), - CurrentValidatorsHash: makeEpochHash(currentValidators, currentTurnLength), + PreviousValidatorsHash: makeEpochHash(downcast.PreviousValidators, uint8(downcast.PreviousTurnLength)), + CurrentValidatorsHash: makeEpochHash(downcast.CurrentValidators, uint8(downcast.CurrentTurnLength)), StateRoot: header.Root.Bytes(), } return &clientState, &consensusState, nil diff --git a/module/util.go b/module/util.go index f56351cc..d87b9642 100644 --- a/module/util.go +++ b/module/util.go @@ -3,30 +3,12 @@ package module import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/cosmos/ibc-go/v8/modules/core/exported" - "github.com/datachainlab/ibc-parlia-relay/module/constant" ) -func getPreviousEpoch(v uint64) uint64 { - epochCount := v / constant.BlocksPerEpoch - if epochCount == 0 { - return 0 - } - return (epochCount - 1) * constant.BlocksPerEpoch -} - -func getCurrentEpoch(v uint64) uint64 { - return toEpoch(v) -} - func toHeight(height exported.Height) clienttypes.Height { return clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()) } -func toEpoch(v uint64) uint64 { - epochCount := v / constant.BlocksPerEpoch - return epochCount * constant.BlocksPerEpoch -} - func minUint64(x uint64, y uint64) uint64 { if x > y { return y diff --git a/module/util_test.go b/module/util_test.go deleted file mode 100644 index 86028021..00000000 --- a/module/util_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package module - -import ( - "github.com/datachainlab/ibc-parlia-relay/module/constant" - "github.com/stretchr/testify/suite" - "testing" -) - -type UtilTestSuite struct { - suite.Suite -} - -func TestUtilTestSuite(t *testing.T) { - suite.Run(t, new(UtilTestSuite)) -} - -func (ts *UtilTestSuite) SetupTest() { -} - -func (ts *UtilTestSuite) TestGetPreviousEpoch() { - ts.Require().Equal(constant.BlocksPerEpoch, getPreviousEpoch(2*constant.BlocksPerEpoch)) - ts.Require().Equal(uint64(0), getPreviousEpoch(2*constant.BlocksPerEpoch-1)) - ts.Require().Equal(uint64(0), getPreviousEpoch(constant.BlocksPerEpoch+1)) - ts.Require().Equal(uint64(0), getPreviousEpoch(constant.BlocksPerEpoch)) - ts.Require().Equal(uint64(0), getPreviousEpoch(constant.BlocksPerEpoch-1)) - ts.Require().Equal(uint64(0), getPreviousEpoch(0)) -} From 65c004bdea368244b43f39736bf738c66a9206ce Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 21 Mar 2025 15:46:39 +0900 Subject: [PATCH 11/37] fix test Signed-off-by: Naohiro Yoshida --- module/facade.go | 9 --- module/fork_spec.go | 13 +++-- module/setup.go | 3 + module/setup_test.go | 130 ++++++++++++++++++------------------------- module/vote.go | 8 ++- module/vote_test.go | 6 +- 6 files changed, 73 insertions(+), 96 deletions(-) diff --git a/module/facade.go b/module/facade.go index 9b806186..a30d464e 100644 --- a/module/facade.go +++ b/module/facade.go @@ -3,15 +3,6 @@ package module import "github.com/ethereum/go-ethereum/core/types" // Facade for tool modules - -func GetPreviousEpoch(v uint64) uint64 { - return getPreviousEpoch(v) -} - -func GetCurrentEpoch(v uint64) uint64 { - return getCurrentEpoch(v) -} - func QueryFinalizedHeader(fn getHeaderFn, height uint64, limitHeight uint64) ([]*ETHHeader, error) { return queryFinalizedHeader(fn, height, limitHeight) } diff --git a/module/fork_spec.go b/module/fork_spec.go index a3c39415..a8d14313 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -102,6 +102,7 @@ func (b BoundaryHeight) getBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec currentFirst = candidate break } + index++ } var intermediates []uint64 for mid := prevLast + prevForkSpec.EpochLength; mid < currentFirst; mid += prevForkSpec.EpochLength { @@ -123,9 +124,11 @@ func (be BoundaryEpochs) CurrentEpochBlockNumber(number uint64) uint64 { return number - (number % be.CurrentForkSpec.EpochLength) } - for i := len(be.Intermediates); i >= 0; i-- { - if number >= be.Intermediates[i] { - return be.Intermediates[i] + if len(be.Intermediates) > 0 { + for i := len(be.Intermediates); i >= 0; i-- { + if number >= be.Intermediates[i] { + return be.Intermediates[i] + } } } return number - (number % be.PreviousForkSpec.EpochLength) @@ -182,7 +185,7 @@ func findTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) return nil, nil, fmt.Errorf("no fork spec found height=%d, timestmp=%d", height, timestamp) } -var cache map[uint64]BoundaryHeight +var cache = make(map[uint64]BoundaryHeight) func getBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (BoundaryHeight, error) { logger := log.GetLogger() @@ -203,7 +206,7 @@ func getBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSp if MilliTimestamp(h) == ts { boundaryHeight = h.Number.Uint64() logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) - cache[currentForkSpec.GetTimestamp()] = BoundaryHeight(boundaryHeight) + cache[ts] = BoundaryHeight(boundaryHeight) break } } diff --git a/module/setup.go b/module/setup.go index aabbd90b..917d774e 100644 --- a/module/setup.go +++ b/module/setup.go @@ -86,6 +86,9 @@ func setupHeadersForUpdate( logger.Info("Must set boundary timestamp", "ts", nextForkBoundaryTs, "nextForkBoundaryHeightMinus1", nextForkBoundaryHeightMinus1) firstUnsaved := trustedEpochHeight + skip + if firstUnsaved == savedLatestHeight { + firstUnsaved += skip + } var submittingHeights []uint64 if latestFinalizedHeight < firstUnsaved { diff --git a/module/setup_test.go b/module/setup_test.go index 44a84292..aba03287 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -3,7 +3,6 @@ package module import ( "context" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" - "github.com/datachainlab/ibc-parlia-relay/module/constant" types2 "github.com/ethereum/go-ethereum/core/types" "github.com/hyperledger-labs/yui-relayer/core" "github.com/hyperledger-labs/yui-relayer/log" @@ -27,8 +26,8 @@ func (ts *SetupTestSuite) SetupTest() { func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_neighboringEpoch() { - verify := func(latestHeight, nextHeight uint64, expected int) { - clientStateLatestHeight := clienttypes.NewHeight(0, latestHeight) + verify := func(trustedHeight, nextHeight uint64, expected int) { + clientStateLatestHeight := clienttypes.NewHeight(0, trustedHeight) target, err := newETHHeader(&types2.Header{ Number: big.NewInt(int64(nextHeight)), }) @@ -53,47 +52,47 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_neighboringEpoch() { }, nil } - targets, err := setupHeadersForUpdate(neighborFn, headerFn, clientStateLatestHeight, latestFinalizedHeader, clienttypes.NewHeight(0, 100000)) + targets, err := setupHeadersForUpdate(neighborFn, headerFn, clientStateLatestHeight, latestFinalizedHeader, clienttypes.NewHeight(0, 100000), GetForkParameters(Localnet)) ts.Require().NoError(err) ts.Require().Len(targets, expected) for i, h := range targets { trusted := h.(*Header).TrustedHeight if i == 0 { - ts.Require().Equal(trusted.RevisionHeight, latestHeight) + ts.Require().Equal(trusted.RevisionHeight, trustedHeight) } else { ts.Require().Equal(*trusted, targets[i-1].GetHeight()) } } } - verify(0, constant.BlocksPerEpoch-1, 1) - verify(0, constant.BlocksPerEpoch, 1) - verify(0, constant.BlocksPerEpoch+1, 2) - verify(0, 10*constant.BlocksPerEpoch-1, 10) - verify(0, 10*constant.BlocksPerEpoch, 10) - verify(0, 10*constant.BlocksPerEpoch+1, 11) - verify(constant.BlocksPerEpoch-1, constant.BlocksPerEpoch-1, 0) - verify(constant.BlocksPerEpoch-1, constant.BlocksPerEpoch, 1) - verify(constant.BlocksPerEpoch-1, constant.BlocksPerEpoch+1, 2) - verify(constant.BlocksPerEpoch-1, 10*constant.BlocksPerEpoch-1, 10) - verify(constant.BlocksPerEpoch-1, 10*constant.BlocksPerEpoch, 10) - verify(constant.BlocksPerEpoch-1, 10*constant.BlocksPerEpoch+1, 11) - verify(constant.BlocksPerEpoch, constant.BlocksPerEpoch, 0) - verify(constant.BlocksPerEpoch, constant.BlocksPerEpoch+1, 1) - verify(constant.BlocksPerEpoch, 10*constant.BlocksPerEpoch-1, 9) - verify(constant.BlocksPerEpoch, 10*constant.BlocksPerEpoch, 9) - verify(constant.BlocksPerEpoch, 10*constant.BlocksPerEpoch+1, 10) - verify(constant.BlocksPerEpoch+1, constant.BlocksPerEpoch+1, 0) - verify(constant.BlocksPerEpoch+1, 10*constant.BlocksPerEpoch-1, 9) - verify(constant.BlocksPerEpoch+1, 10*constant.BlocksPerEpoch, 9) - verify(constant.BlocksPerEpoch+1, 10*constant.BlocksPerEpoch+1, 10) + verify(0, skip-1, 1) + verify(0, skip, 1) + verify(0, skip+1, 2) + verify(0, 10*skip-1, 10) + verify(0, 10*skip, 10) + verify(0, 10*skip+1, 11) + verify(skip-1, skip-1, 0) + verify(skip-1, skip, 1) + verify(skip-1, skip+1, 2) + verify(skip-1, 10*skip-1, 10) + verify(skip-1, 10*skip, 10) + verify(skip-1, 10*skip+1, 11) + verify(skip, skip, 0) + verify(skip, skip+1, 1) + verify(skip, 10*skip-1, 9) + verify(skip, 10*skip, 9) + verify(skip, 10*skip+1, 10) + verify(skip+1, skip+1, 0) + verify(skip+1, 10*skip-1, 10) + verify(skip+1, 10*skip, 10) + verify(skip+1, 10*skip+1, 11) } func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_allEmpty() { - verify := func(latestHeight, nextHeight uint64, expected int) { - clientStateLatestHeight := clienttypes.NewHeight(0, latestHeight) + verify := func(trustedHeight, nextHeight uint64, expected int) { + clientStateLatestHeight := clienttypes.NewHeight(0, trustedHeight) target, err := newETHHeader(&types2.Header{ Number: big.NewInt(int64(nextHeight)), }) @@ -111,57 +110,34 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_allEmpty() { Extra: epochHeader().Extra, }, nil } - targets, err := setupHeadersForUpdate(neighboringEpochFn, headerFn, clientStateLatestHeight, latestFinalizedHeader, clienttypes.NewHeight(0, 1000000)) + targets, err := setupHeadersForUpdate(neighboringEpochFn, headerFn, clientStateLatestHeight, latestFinalizedHeader, + clienttypes.NewHeight(0, + 1000000), GetForkParameters(Localnet)) ts.Require().NoError(err) ts.Require().Len(targets, expected) } - verify(0, constant.BlocksPerEpoch-1, 1) - verify(0, constant.BlocksPerEpoch, 1) - verify(0, constant.BlocksPerEpoch+1, 0) // non neighboring - verify(0, 10*constant.BlocksPerEpoch-1, 0) - verify(0, 10*constant.BlocksPerEpoch, 0) // non neighboring - verify(0, 10*constant.BlocksPerEpoch+1, 0) // non neighboring - verify(constant.BlocksPerEpoch-1, constant.BlocksPerEpoch-1, 0) // same - verify(constant.BlocksPerEpoch-1, constant.BlocksPerEpoch, 1) - verify(constant.BlocksPerEpoch-1, constant.BlocksPerEpoch+1, 0) // non neighboring - verify(constant.BlocksPerEpoch-1, 10*constant.BlocksPerEpoch-1, 0) - verify(constant.BlocksPerEpoch-1, 10*constant.BlocksPerEpoch, 0) // non neighboring - verify(constant.BlocksPerEpoch-1, 10*constant.BlocksPerEpoch+1, 0) // non neighboring - verify(constant.BlocksPerEpoch, constant.BlocksPerEpoch, 0) // same - verify(constant.BlocksPerEpoch, constant.BlocksPerEpoch+1, 1) - verify(constant.BlocksPerEpoch, 10*constant.BlocksPerEpoch-1, 0) // non neighboring - verify(constant.BlocksPerEpoch, 10*constant.BlocksPerEpoch, 0) // non neighboring - verify(constant.BlocksPerEpoch, 10*constant.BlocksPerEpoch+1, 0) // non neighboring - verify(constant.BlocksPerEpoch+1, constant.BlocksPerEpoch+1, 0) // same - verify(constant.BlocksPerEpoch+1, 10*constant.BlocksPerEpoch-1, 0) // non neighboring - verify(constant.BlocksPerEpoch+1, 10*constant.BlocksPerEpoch, 0) // non neighboring - verify(constant.BlocksPerEpoch+1, 10*constant.BlocksPerEpoch+1, 0) // non neighboring -} - -func (ts *SetupTestSuite) TestSuccess_setupNeighboringEpochHeader() { - - epochHeight := constant.BlocksPerEpoch * 2 - trustedEpochHeight := constant.BlocksPerEpoch - - neighboringEpochFn := func(height uint64, limit uint64) (core.Header, error) { - target, err := newETHHeader(&types2.Header{ - Number: big.NewInt(int64(limit)), - }) - ts.Require().NoError(err) - return &Header{ - Headers: []*ETHHeader{target}, - }, nil - } - headerFn := func(_ context.Context, height uint64) (*types2.Header, error) { - return headerByHeight(int64(height)), nil - } - hs, err := setupNeighboringEpochHeader(headerFn, neighboringEpochFn, epochHeight, trustedEpochHeight, clienttypes.NewHeight(0, 10000)) - ts.Require().NoError(err) - target, err := hs.(*Header).Target() - ts.Require().NoError(err) - - // next checkpoint - 1 - // turnLength = 6, then checkpoint = 18 - ts.Require().Equal(int64(1517), target.Number.Int64()) + const skip = 100 + + verify(0, skip-1, 1) + verify(0, skip, 1) + verify(0, skip+1, 0) // non neighboring + verify(0, 10*skip-1, 0) + verify(0, 10*skip, 0) // non neighboring + verify(0, 10*skip+1, 0) // non neighboring + verify(skip-1, skip-1, 0) // same + verify(skip-1, skip, 1) + verify(skip-1, skip+1, 0) // non neighboring + verify(skip-1, 10*skip-1, 0) + verify(skip-1, 10*skip, 0) // non neighboring + verify(skip-1, 10*skip+1, 0) // non neighboring + verify(skip, skip, 0) // same + verify(skip, skip+1, 1) + verify(skip, 10*skip-1, 0) // non neighboring + verify(skip, 10*skip, 0) // non neighboring + verify(skip, 10*skip+1, 0) // non neighboring + verify(skip+1, skip+1, 0) // same + verify(skip+1, 10*skip-1, 0) // non neighboring + verify(skip+1, 10*skip, 0) // non neighboring + verify(skip+1, 10*skip+1, 0) // non neighboring } diff --git a/module/vote.go b/module/vote.go index a68c0141..55f1ca4a 100644 --- a/module/vote.go +++ b/module/vote.go @@ -3,7 +3,6 @@ package module import ( "bytes" "fmt" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" @@ -39,8 +38,13 @@ func getVoteAttestationFromHeader(header *types.Header) (*VoteAttestation, error return nil, nil } + isEpoch := true + if _, _, err := extractValidatorSetAndTurnLength(header); err != nil { + isEpoch = false + } + var attestationBytes []byte - if header.Number.Uint64()%constant.BlocksPerEpoch != 0 { + if !isEpoch { attestationBytes = header.Extra[extraVanity : len(header.Extra)-extraSeal] } else { num := int(header.Extra[extraVanity]) diff --git a/module/vote_test.go b/module/vote_test.go index c31cd97c..caf6490b 100644 --- a/module/vote_test.go +++ b/module/vote_test.go @@ -1,7 +1,6 @@ package module import ( - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/suite" @@ -36,7 +35,7 @@ func (ts *VoteTestSuite) TestSuccessGetVoteAttestationFromHeaderEpoch() { func (ts *VoteTestSuite) TestErrorGetVoteAttestationFromHeaderEpochNoVote() { header := &types.Header{ Extra: common.Hex2Bytes("d98301040d846765746889676f312e32312e3132856c696e757800000299d9bc0808265da01e1a65d62b903c7b34c08cb389bf3d9996f763f030b1adcfb369c5a5df4a18e1529baffe7feaec66db3dbd1bc06810f7f6f88b7be6645418a7e2a2a3f40514c215a13e315cbfb9398a26d77a299963bf034c28f8b0183ea044211f468630233d2533b73307979c78a9486b33bb4ee04ca31a65f3e86fba804db7fe293fa643e6b72bb3821a3d9d7a717d64e6088ac937d5aacdd3e20ca963979974cd8ff90cbf097023dc8c448245ceff671e965d57d82eaf9be91478cfa0f24d2993e0c5f43a6c5a4cd99850023040d3256eb0babe89f0ea54edaa398513136612f5a334b49d766ebe3eb9f6bdc163bd2c19aa7e8cee1667851ae0c1651f01c4cf7cf2cfcf8475bff3e99cab25b05631472d53387f3321fd69d1e030bb921230dfb188826affaa39ebf1c38b190851e4db0588a3e90142c5299041fb8a0db3bb9a1fa4bdf0dae84ca37ee12a6b8c26caab775f0e007b76d76ee8823de52a1a431884c2ca930c5e72bff3803af79641cf964cc001671017f0b680f93b7dde085b24bbc67b2a562a216f903ac878c5477641328172a353f1e493cf7f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea99e3849ef31887c0f880a0feb92f356f58fbd023a82f5311fc87a5883a662e9ebbbefc90bf13aa533c2438a4113804bfd447b49cd040d20bc21e49ffea6487f5638e4346ad9fc6d1ec30e28016d3892b51a7898bd354cfe78643453fd3868410da412de7f2883180d0a2840111ad2e043fa403eb04cc3c0ed356ea54a6e7015490240681b002cb63e12f65c456cafca335c730b123553e70df5322013812429e0bc31508e1f1fbf0ab312e4aaade9e022150071a1f00"), - Number: big.NewInt(0).SetUint64(constant.BlocksPerEpoch), + Number: big.NewInt(0), } vote, err := getVoteAttestationFromHeader(header) ts.Require().NoError(err) @@ -57,7 +56,8 @@ func (ts *VoteTestSuite) TestSuccessGetVoteAttestationFromHeaderNotEpoch() { func (ts *VoteTestSuite) TestErrorGetVoteAttestationFromHeader() { testnetHeader := &types.Header{ - Extra: make([]byte, extraSeal+extraVanity), + Extra: make([]byte, extraSeal+extraVanity), + Number: big.NewInt(0), } vote, err := getVoteAttestationFromHeader(testnetHeader) ts.Require().Nil(vote) From 22061b2b5e59f77ab64ecd487b0b87db8daec2fe Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 21 Mar 2025 16:42:24 +0900 Subject: [PATCH 12/37] add test Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 8 ++--- module/setup.go | 34 ++++++++++++------ module/setup_test.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 14 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index a8d14313..e3f233e8 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -35,7 +35,7 @@ func GetForkParameters(network Network) []*ForkSpec { // Pascal HF { // Must Set Milli timestamp - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, + HeightOrTimestamp: &ForkSpec_Height{Height: 0}, AdditionalHeaderItemCount: 1, EpochLength: 200, }, @@ -125,7 +125,7 @@ func (be BoundaryEpochs) CurrentEpochBlockNumber(number uint64) uint64 { } if len(be.Intermediates) > 0 { - for i := len(be.Intermediates); i >= 0; i-- { + for i := len(be.Intermediates) - 1; i >= 0; i-- { if number >= be.Intermediates[i] { return be.Intermediates[i] } @@ -198,8 +198,8 @@ func getBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSp return v, nil } logger.Debug("seek fork height", "currentHeight", currentHeight, "ts", ts) - for i := currentHeight; i >= 0; i-- { - h, err := headerFn(context.Background(), i) + for i := int64(currentHeight); i >= 0; i-- { + h, err := headerFn(context.Background(), uint64(i)) if err != nil { return 0, err } diff --git a/module/setup.go b/module/setup.go index 917d774e..6874a0e8 100644 --- a/module/setup.go +++ b/module/setup.go @@ -32,8 +32,15 @@ func shouldSubmitBoundaryTimestampHeader( latestCondition := latestForkSpec.GetHeightOrTimestamp() if x, ok := latestCondition.(*ForkSpec_Timestamp); ok { if MilliTimestamp(trustedBlock) < x.Timestamp && x.Timestamp < MilliTimestamp(latestFinalizedBlock) { - // TODO 対象のheightを出す - return &x.Timestamp, 0, nil + boundaryHeight, err := getBoundaryHeight(getHeader, latestFinalizedBlock.Number.Uint64(), *latestForkSpec) + if err != nil { + return nil, 0, err + } + // Must be right before boundary height + if boundaryHeight == 0 { + return nil, 0, fmt.Errorf("boundary height not found") + } + return &x.Timestamp, uint64(boundaryHeight) - 1, nil } } return nil, 0, nil @@ -96,17 +103,24 @@ func setupHeadersForUpdate( submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) } } else { + var temp []uint64 for epochCandidate := firstUnsaved; epochCandidate < latestFinalizedHeight; epochCandidate += skip { - if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < epochCandidate { - submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1, epochCandidate) - } else { + temp = append(temp, epochCandidate) + } + if nextForkBoundaryTs != nil { + for i, epochCandidate := range temp { + if i > 0 { + if temp[i-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < epochCandidate { + submittingHeights = append(submittingHeights, temp[i-1]) + } + } submittingHeights = append(submittingHeights, epochCandidate) } - } - if nextForkBoundaryTs != nil && - submittingHeights[len(submittingHeights)-1] < nextForkBoundaryHeightMinus1 && - nextForkBoundaryHeightMinus1 < latestFinalizedHeight { - submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + if submittingHeights[len(submittingHeights)-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } + } else { + submittingHeights = temp } } logger.Debug("submitting heights", "heights", submittingHeights) diff --git a/module/setup_test.go b/module/setup_test.go index aba03287..f2175583 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/suite" "math/big" "testing" + "time" ) type SetupTestSuite struct { @@ -141,3 +142,87 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_allEmpty() { verify(skip+1, 10*skip, 0) // non neighboring verify(skip+1, 10*skip+1, 0) // non neighboring } + +func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_withHFBoundary() { + + verify := func(trustedHeight, nextHeight uint64, expected int) { + now := time.Now() + getTime := func(height uint64) time.Time { + return now.Add(time.Duration(height) * time.Second) + } + + hftime := now.Add(time.Duration(trustedHeight+(nextHeight-trustedHeight)/2) * time.Second).Unix() + forkSpecs := []*ForkSpec{ + { + // Must Set Milli timestamp + HeightOrTimestamp: &ForkSpec_Height{Height: 0}, + AdditionalHeaderItemCount: 1, + EpochLength: 200, + }, + { + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: uint64(hftime * 1000)}, + AdditionalHeaderItemCount: 1, + EpochLength: 500, + }, + } + clientStateLatestHeight := clienttypes.NewHeight(0, trustedHeight) + target, err := newETHHeader(&types2.Header{ + Number: big.NewInt(int64(nextHeight)), + Time: uint64(now.Unix()), + }) + ts.Require().NoError(err) + latestFinalizedHeader := &Header{ + Headers: []*ETHHeader{target}, + CurrentValidators: [][]byte{{1}}, + PreviousValidators: [][]byte{{1}}, + } + neighborFn := func(height uint64, _ uint64) (core.Header, error) { + h, e := newETHHeader(&types2.Header{ + Number: big.NewInt(int64(height)), + Time: uint64(getTime(height).Unix()), + }) + return &Header{ + Headers: []*ETHHeader{h}, + }, e + } + headerFn := func(_ context.Context, height uint64) (*types2.Header, error) { + return &types2.Header{ + Number: big.NewInt(int64(height)), + Extra: epochHeader().Extra, + Time: uint64(getTime(height).Unix()), + }, nil + } + + targets, err := setupHeadersForUpdate(neighborFn, headerFn, clientStateLatestHeight, latestFinalizedHeader, clienttypes.NewHeight(0, 100000), forkSpecs) + ts.Require().NoError(err) + ts.Require().Len(targets, expected) + for i, h := range targets { + trusted := h.(*Header).TrustedHeight + if i == 0 { + ts.Require().Equal(trusted.RevisionHeight, trustedHeight) + } else { + ts.Require().Equal(*trusted, targets[i-1].GetHeight()) + } + } + } + + verify(0, 10*skip-1, 10+1) + verify(0, 10*skip, 10+1) + verify(0, 10*skip+1, 11+1) + verify(skip-1, skip-1, 0) + verify(skip-1, skip, 1) + verify(skip-1, skip+1, 2) + verify(skip-1, 10*skip-1, 10+1) + verify(skip-1, 10*skip, 10+1) + verify(skip-1, 10*skip+1, 11+1) + verify(skip, skip, 0) + verify(skip, skip+1, 1) + verify(skip, 10*skip-1, 9+1) + verify(skip, 10*skip, 9+1) + verify(skip, 10*skip+1, 10+1) + verify(skip+1, skip+1, 0) + verify(skip+1, 10*skip-1, 10+1) + verify(skip+1, 10*skip, 10+1) + verify(skip+1, 10*skip+1, 11+1) + +} From 5a522632c71575a2bf54dfde5be1f8e311eb5c09 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 21 Mar 2025 18:10:59 +0900 Subject: [PATCH 13/37] change test Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 6 +++--- module/setup.go | 8 ++++---- tests/prover_network_test.go | 13 +++++++++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index e3f233e8..e9280f1e 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -91,7 +91,7 @@ type BoundaryEpochs struct { type BoundaryHeight uint64 -func (b BoundaryHeight) getBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec ForkSpec) (*BoundaryEpochs, error) { +func (b BoundaryHeight) GetBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec ForkSpec) (*BoundaryEpochs, error) { boundaryHeight := uint64(b) prevLast := boundaryHeight - (boundaryHeight % prevForkSpec.EpochLength) index := uint64(0) @@ -158,7 +158,7 @@ func (be BoundaryEpochs) PreviousEpochBlockNumber(currentEpochBlockNumber uint64 return currentEpochBlockNumber - be.CurrentForkSpec.EpochLength } -func findTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) (*ForkSpec, *ForkSpec, error) { +func FindTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) (*ForkSpec, *ForkSpec, error) { reversed := make([]*ForkSpec, len(forkSpecs)) for i, spec := range forkSpecs { reversed[len(forkSpecs)-i-1] = spec @@ -187,7 +187,7 @@ func findTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) var cache = make(map[uint64]BoundaryHeight) -func getBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (BoundaryHeight, error) { +func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (BoundaryHeight, error) { logger := log.GetLogger() boundaryHeight := uint64(0) if condition, ok := currentForkSpec.GetHeightOrTimestamp().(*ForkSpec_Height); ok { diff --git a/module/setup.go b/module/setup.go index 6874a0e8..52d1d5b7 100644 --- a/module/setup.go +++ b/module/setup.go @@ -32,7 +32,7 @@ func shouldSubmitBoundaryTimestampHeader( latestCondition := latestForkSpec.GetHeightOrTimestamp() if x, ok := latestCondition.(*ForkSpec_Timestamp); ok { if MilliTimestamp(trustedBlock) < x.Timestamp && x.Timestamp < MilliTimestamp(latestFinalizedBlock) { - boundaryHeight, err := getBoundaryHeight(getHeader, latestFinalizedBlock.Number.Uint64(), *latestForkSpec) + boundaryHeight, err := GetBoundaryHeight(getHeader, latestFinalizedBlock.Number.Uint64(), *latestForkSpec) if err != nil { return nil, 0, err } @@ -69,15 +69,15 @@ func setupHeadersForUpdate( return nil, err } - trustedCurrentForkSpec, trustedPreviousForkSpec, err := findTargetForkSpec(forkSpecs, savedLatestHeight, MilliTimestamp(trustedBlock)) + trustedCurrentForkSpec, trustedPreviousForkSpec, err := FindTargetForkSpec(forkSpecs, savedLatestHeight, MilliTimestamp(trustedBlock)) if err != nil { return nil, err } - trustedBoundaryHeight, err := getBoundaryHeight(getHeader, savedLatestHeight, *trustedCurrentForkSpec) + trustedBoundaryHeight, err := GetBoundaryHeight(getHeader, savedLatestHeight, *trustedCurrentForkSpec) if err != nil { return nil, err } - trustedBoundaryEpochs, err := trustedBoundaryHeight.getBoundaryEpochs(*trustedCurrentForkSpec, *trustedPreviousForkSpec) + trustedBoundaryEpochs, err := trustedBoundaryHeight.GetBoundaryEpochs(*trustedCurrentForkSpec, *trustedPreviousForkSpec) if err != nil { return nil, err } diff --git a/tests/prover_network_test.go b/tests/prover_network_test.go index c4a33aa0..071dda62 100644 --- a/tests/prover_network_test.go +++ b/tests/prover_network_test.go @@ -91,9 +91,18 @@ func (ts *ProverNetworkTestSuite) TestSuccessCreateInitialLightClientState() { ts.Require().NoError(err) ts.Require().Equal(cs.GetLatestHeight().GetRevisionHeight(), header.Number.Uint64()) - cVal, cTurn, err := module.QueryValidatorSetAndTurnLength(ts.chain.Header, module.GetCurrentEpoch(header.Number.Uint64())) + forkParams := module.GetForkParameters(module.Localnet) + currentForkSpec, prevForkSpec, err := module.FindTargetForkSpec(forkParams, header.Number.Uint64(), module.MilliTimestamp(header)) ts.Require().NoError(err) - pVal, pTurn, err := module.QueryValidatorSetAndTurnLength(ts.chain.Header, module.GetPreviousEpoch(header.Number.Uint64())) + bs, err := module.GetBoundaryHeight(ts.chain.Header, header.Number.Uint64(), *currentForkSpec) + ts.Require().NoError(err) + be, err := bs.GetBoundaryEpochs(*currentForkSpec, *prevForkSpec) + ts.Require().NoError(err) + + currentEpoch := be.CurrentEpochBlockNumber(header.Number.Uint64()) + cVal, cTurn, err := module.QueryValidatorSetAndTurnLength(ts.chain.Header, currentEpoch) + ts.Require().NoError(err) + pVal, pTurn, err := module.QueryValidatorSetAndTurnLength(ts.chain.Header, be.PreviousEpochBlockNumber(currentEpoch)) ts.Require().NoError(err) consState := s2.(*module.ConsensusState) ts.Require().Equal(consState.CurrentValidatorsHash, module.MakeEpochHash(cVal, cTurn)) From b75adf57aff180e0601d0a79af98c33f66571edb Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Fri, 21 Mar 2025 18:52:01 +0900 Subject: [PATCH 14/37] change --- module/proof.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/module/proof.go b/module/proof.go index f48db3e8..893c31a1 100644 --- a/module/proof.go +++ b/module/proof.go @@ -181,29 +181,22 @@ func withValidators(headerFn getHeaderFn, height uint64, ethHeaders []*ETHHeader if err != nil { return nil, fmt.Errorf("failed to get block header : number = %d : %+v", height, err) } - currentForkSpec, prevForkSpec, err := findTargetForkSpec(forkSpecs, height, blockHeader.Time) + currentForkSpec, prevForkSpec, err := FindTargetForkSpec(forkSpecs, height, blockHeader.Time) if err != nil { return nil, err } - boundaryHeight, err := getBoundaryHeight(headerFn, height, *currentForkSpec) + boundaryHeight, err := GetBoundaryHeight(headerFn, height, *currentForkSpec) if err != nil { return nil, err } - boundaryEpochs, err := boundaryHeight.getBoundaryEpochs(*currentForkSpec, *prevForkSpec) + boundaryEpochs, err := boundaryHeight.GetBoundaryEpochs(*currentForkSpec, *prevForkSpec) if err != nil { return nil, err } // Get validator set for verify headers - previousEpoch := boundaryEpochs.PreviousEpochBlockNumber(height) - var previousTurnLength uint8 - header.PreviousValidators, previousTurnLength, err = queryValidatorSetAndTurnLength(headerFn, previousEpoch) - header.PreviousTurnLength = uint32(previousTurnLength) - if err != nil { - return nil, fmt.Errorf("ValidatorSet was not found in previous epoch : number = %d : %+v", previousEpoch, err) - } currentEpoch := boundaryEpochs.CurrentEpochBlockNumber(height) var currentTurnLength uint8 header.CurrentValidators, currentTurnLength, err = queryValidatorSetAndTurnLength(headerFn, currentEpoch) @@ -212,5 +205,13 @@ func withValidators(headerFn getHeaderFn, height uint64, ethHeaders []*ETHHeader return nil, fmt.Errorf("ValidatorSet was not found in current epoch : number= %d : %+v", currentEpoch, err) } + previousEpoch := boundaryEpochs.PreviousEpochBlockNumber(currentEpoch) + var previousTurnLength uint8 + header.PreviousValidators, previousTurnLength, err = queryValidatorSetAndTurnLength(headerFn, previousEpoch) + header.PreviousTurnLength = uint32(previousTurnLength) + if err != nil { + return nil, fmt.Errorf("ValidatorSet was not found in previous epoch : number = %d : %+v", previousEpoch, err) + } + return header, nil } From 2b2a875be4f863068fd75dcf18b4d0ac695e130d Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sat, 22 Mar 2025 16:41:54 +0900 Subject: [PATCH 15/37] remove how to change epoch length Signed-off-by: Naohiro Yoshida --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 131c6f7e..3f67e8fe 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ ![CI](https://github.com/datachainlab/ibc-parlia-relay/workflows/CI/badge.svg?branch=main) ## Supported Versions -- [yui-relayer v0.5.3](https://github.com/hyperledger-labs/yui-relayer/releases/tag/v0.5.3) -- [ethereum-ibc-relay-chain v0.3.4](https://github.com/datachainlab/ethereum-ibc-relay-chain/releases/tag/v0.3.4) +- [yui-relayer v0.5.11](https://github.com/hyperledger-labs/yui-relayer/releases/tag/v0.5.11) +- [ethereum-ibc-relay-chain v0.3.16](https://github.com/datachainlab/ethereum-ibc-relay-chain/releases/tag/v0.3.6) ## Setup Relayer @@ -29,14 +29,6 @@ func main() { } ``` -## Change blocks per epoch - -* You can change blocks per epoch by build arguments. -* This is only for local net. -``` -go build -tags dev -ldflags="-X github.com/datachainlab/ibc-parlia-relay/module/constant.blocksPerEpoch=20" -o testrly . -``` - ## Development Generate proto buf with protobuf definition of [parlia-elc](https://github.com/datachainlab/parlia-elc). @@ -48,3 +40,8 @@ cd ibc-parlia-relay make proto-import make proto-gen ``` + +## About ForkSpec + +As soon as the HF height is determined, please modify the timestamp in the ForkSpec to the height as soon as possible. +HF height is calculated from timestamp, but the further away from the HF, the longer it takes to calculate. From b9e0fac866da92e65c9765de539d28e7e3a99e75 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sat, 22 Mar 2025 17:03:11 +0900 Subject: [PATCH 16/37] change ts Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/module/fork_spec.go b/module/fork_spec.go index e9280f1e..286667a8 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -208,6 +208,11 @@ func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSp logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) cache[ts] = BoundaryHeight(boundaryHeight) break + } else if MilliTimestamp(h) < ts { + boundaryHeight = h.Number.Uint64() + 1 + logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) + cache[ts] = BoundaryHeight(boundaryHeight) + break } } } From b4dc6bed43d276079bcf501688cbe0d1e3e0831d Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sat, 22 Mar 2025 18:41:19 +0900 Subject: [PATCH 17/37] move env var into init Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index 286667a8..26186900 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -17,20 +17,24 @@ const ( Mainnet Network = "mainnet" ) +var localLorentzHF isForkSpec_HeightOrTimestamp = &ForkSpec_Height{Height: 1} + +func init() { + localLorentzHFTimestamp := os.Getenv("LOCAL_LORENTZ_HF_TIMESTAMP") + if localLorentzHFTimestamp != "" { + fmt.Println("LOCAL_LORENTZ_HF_TIMESTAMP is found", localLorentzHFTimestamp) + result, err := strconv.Atoi(localLorentzHFTimestamp) + if err != nil { + panic(err) + } + localLorentzHF = &ForkSpec_Timestamp{Timestamp: uint64(result)} + } +} + func GetForkParameters(network Network) []*ForkSpec { switch network { case Localnet: - - localLorentzHFTimestamp := os.Getenv("LOCAL_LORENTZ_HF_TIMESTAMP") - localLorentzHFTimestampInt := uint64(1) - if localLorentzHFTimestamp != "" { - result, err := strconv.Atoi(localLorentzHFTimestamp) - if err != nil { - panic(err) - } - localLorentzHFTimestampInt = uint64(result) - } return []*ForkSpec{ // Pascal HF { @@ -42,7 +46,7 @@ func GetForkParameters(network Network) []*ForkSpec { // Lorentz HF { // Must Set Milli timestamp - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: localLorentzHFTimestampInt}, + HeightOrTimestamp: localLorentzHF, AdditionalHeaderItemCount: 1, EpochLength: 500, }, From 8f859c36b01f8d80620924968d555506e8b88703 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sat, 22 Mar 2025 19:14:38 +0900 Subject: [PATCH 18/37] change submitting headers Signed-off-by: Naohiro Yoshida --- module/setup.go | 57 ++++++++++++++++++++++++-------------------- module/setup_test.go | 55 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 28 deletions(-) diff --git a/module/setup.go b/module/setup.go index 52d1d5b7..d78ce3f1 100644 --- a/module/setup.go +++ b/module/setup.go @@ -97,32 +97,7 @@ func setupHeadersForUpdate( firstUnsaved += skip } - var submittingHeights []uint64 - if latestFinalizedHeight < firstUnsaved { - if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { - submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) - } - } else { - var temp []uint64 - for epochCandidate := firstUnsaved; epochCandidate < latestFinalizedHeight; epochCandidate += skip { - temp = append(temp, epochCandidate) - } - if nextForkBoundaryTs != nil { - for i, epochCandidate := range temp { - if i > 0 { - if temp[i-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < epochCandidate { - submittingHeights = append(submittingHeights, temp[i-1]) - } - } - submittingHeights = append(submittingHeights, epochCandidate) - } - if submittingHeights[len(submittingHeights)-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { - submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) - } - } else { - submittingHeights = temp - } - } + submittingHeights := makeSubmittingHeights(latestFinalizedHeight, firstUnsaved, nextForkBoundaryTs, nextForkBoundaryHeightMinus1) logger.Debug("submitting heights", "heights", submittingHeights) trustedHeight := clientStateLatestHeight.GetRevisionHeight() @@ -165,3 +140,33 @@ func withTrustedHeight(targetHeaders []core.Header, clientStateLatestHeight expo } return targetHeaders } + +func makeSubmittingHeights(latestFinalizedHeight uint64, firstUnsaved uint64, nextForkBoundaryTs *uint64, nextForkBoundaryHeightMinus1 uint64) []uint64 { + var submittingHeights []uint64 + if latestFinalizedHeight < firstUnsaved { + if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } + } else { + var temp []uint64 + for epochCandidate := firstUnsaved; epochCandidate < latestFinalizedHeight; epochCandidate += skip { + temp = append(temp, epochCandidate) + } + if nextForkBoundaryTs != nil { + for i, epochCandidate := range temp { + if i > 0 { + if temp[i-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < epochCandidate { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } + } + submittingHeights = append(submittingHeights, epochCandidate) + } + if submittingHeights[len(submittingHeights)-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } + } else { + submittingHeights = temp + } + } + return submittingHeights +} diff --git a/module/setup_test.go b/module/setup_test.go index f2175583..eebae60b 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -118,8 +118,6 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_allEmpty() { ts.Require().Len(targets, expected) } - const skip = 100 - verify(0, skip-1, 1) verify(0, skip, 1) verify(0, skip+1, 0) // non neighboring @@ -226,3 +224,56 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_withHFBoundary() { verify(skip+1, 10*skip+1, 11+1) } + +func (ts *SetupTestSuite) Test_makeSubmittingHeights() { + rq := ts.Require() + msec := uint64(0) + rq.Len(makeSubmittingHeights(10, 11, nil, 0), 0) + rq.Len(makeSubmittingHeights(10, 11, &msec, 11), 0) + rq.Len(makeSubmittingHeights(10, 11, &msec, 9), 1) + rq.Equal( + []uint64{100, 200, 300, 400, 500}, + makeSubmittingHeights(501, 100, &msec, 99), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 500}, + makeSubmittingHeights(501, 100, &msec, 100), + ) + rq.Equal( + []uint64{100, 101, 200, 300, 400, 500}, + makeSubmittingHeights(501, 100, &msec, 101), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 500}, + makeSubmittingHeights(501, 100, nil, 101), + ) + rq.Equal( + []uint64{100, 200, 201, 300, 400, 500}, + makeSubmittingHeights(501, 100, &msec, 201), + ) + rq.Equal( + []uint64{100, 200, 300, 301, 400, 500}, + makeSubmittingHeights(501, 100, &msec, 301), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 401, 500}, + makeSubmittingHeights(501, 100, &msec, 401), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 500}, + makeSubmittingHeights(501, 100, nil, 401), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 500}, + makeSubmittingHeights(501, 100, &msec, 501), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 500, 501}, + makeSubmittingHeights(502, 100, &msec, 501), + ) + rq.Equal( + []uint64{100, 200, 300, 400, 500}, + makeSubmittingHeights(502, 100, nil, 501), + ) + +} From 219ad16e2929136079bb8e038df2abd481b27e62 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sat, 22 Mar 2025 20:07:20 +0900 Subject: [PATCH 19/37] add test Signed-off-by: Naohiro Yoshida --- module/fork_spec_test.go | 203 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 module/fork_spec_test.go diff --git a/module/fork_spec_test.go b/module/fork_spec_test.go new file mode 100644 index 00000000..80031f2f --- /dev/null +++ b/module/fork_spec_test.go @@ -0,0 +1,203 @@ +package module + +import ( + "context" + "fmt" + "github.com/ethereum/go-ethereum/core/types" + "github.com/hyperledger-labs/yui-relayer/log" + "github.com/stretchr/testify/suite" + "math/big" + "testing" +) + +type ForkSpecTestSuite struct { + suite.Suite +} + +func TestForkSpecTestSuite(t *testing.T) { + suite.Run(t, new(ForkSpecTestSuite)) +} + +func (ts *ForkSpecTestSuite) SetupTest() { + _ = log.InitLogger("DEBUG", "text", "stdout") +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_ValidHeight() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 100}}, + {HeightOrTimestamp: &ForkSpec_Height{Height: 200}}, + } + height := uint64(150) + timestamp := uint64(0) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.NoError(err) + ts.Equal(forkSpecs[0], current) + ts.Equal(forkSpecs[0], previous) +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_ValidHeight2() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 100}}, + {HeightOrTimestamp: &ForkSpec_Height{Height: 200}}, + } + height := uint64(200) + timestamp := uint64(0) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.NoError(err) + ts.Equal(forkSpecs[1], current) + ts.Equal(forkSpecs[0], previous) +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_ValidTimestamp() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000}}, + {HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 2000}}, + } + height := uint64(0) + timestamp := uint64(1500) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.NoError(err) + ts.Equal(forkSpecs[0], current) + ts.Equal(forkSpecs[0], previous) +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_ValidTimestamp2() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000}}, + {HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 2000}}, + } + height := uint64(0) + timestamp := uint64(2000) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.NoError(err) + ts.Equal(forkSpecs[1], current) + ts.Equal(forkSpecs[0], previous) +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_NoMatch() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 100}}, + {HeightOrTimestamp: &ForkSpec_Height{Height: 200}}, + } + height := uint64(50) + timestamp := uint64(0) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.Error(err) + ts.Nil(current) + ts.Nil(previous) +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_Both() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 100}}, + {HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 200}}, + } + height := uint64(50) + timestamp := uint64(200) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.NoError(err) + ts.Equal(forkSpecs[1], current) + ts.Equal(forkSpecs[0], previous) +} + +func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_EmptyForkSpecs() { + forkSpecs := []*ForkSpec{} + height := uint64(100) + timestamp := uint64(1000) + + current, previous, err := FindTargetForkSpec(forkSpecs, height, timestamp) + + ts.Error(err) + ts.Nil(current) + ts.Nil(previous) +} + +func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidHeight() { + headerFn := func(ctx context.Context, height uint64) (*types.Header, error) { + return &types.Header{Number: big.NewInt(int64(height))}, nil + } + currentHeight := uint64(100) + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Height{Height: 50}} + + boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + + ts.NoError(err) + ts.Equal(BoundaryHeight(50), boundaryHeight) +} + +func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestamp() { + headerFn := func(ctx context.Context, height uint64) (*types.Header, error) { + return &types.Header{Number: big.NewInt(int64(height)), Time: uint64(1000)}, nil + } + currentHeight := uint64(100) + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000 * 1000}} // msec + + boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + + ts.NoError(err) + ts.Equal(BoundaryHeight(100), boundaryHeight) +} + +func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeader() { + headerFn := func(ctx context.Context, height uint64) (*types.Header, error) { + return &types.Header{Number: big.NewInt(int64(height)), Time: height}, nil + } + currentHeight := uint64(1100) + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000 * 1000}} // msec + + boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + + ts.NoError(err) + ts.Equal(BoundaryHeight(1000), boundaryHeight) +} + +func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeaderNotJust() { + headerFn := func(ctx context.Context, height uint64) (*types.Header, error) { + return &types.Header{Number: big.NewInt(int64(height)), Time: height}, nil + } + currentHeight := uint64(1100) + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 999_999}} // msec + + boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + + ts.NoError(err) + ts.Equal(BoundaryHeight(1000), boundaryHeight) +} + +func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_TimestampNotFound() { + headerFn := func(ctx context.Context, height uint64) (*types.Header, error) { + return &types.Header{Number: big.NewInt(int64(height)), Time: uint64(500)}, nil + } + currentHeight := uint64(100) + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000}} + + boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + + ts.NoError(err) + ts.Equal(BoundaryHeight(0), boundaryHeight) +} + +func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_HeaderFnError() { + headerFn := func(ctx context.Context, height uint64) (*types.Header, error) { + return nil, fmt.Errorf("header not found") + } + currentHeight := uint64(100) + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000}} + + boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + + ts.Error(err) + ts.Equal(BoundaryHeight(0), boundaryHeight) +} From f3b05b27c477bf6635d052184fe4e55c84bcfbb5 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sat, 22 Mar 2025 20:22:00 +0900 Subject: [PATCH 20/37] add test --- module/fork_spec.go | 2 +- module/fork_spec_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index 26186900..6909db98 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -108,7 +108,7 @@ func (b BoundaryHeight) GetBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec } index++ } - var intermediates []uint64 + intermediates := make([]uint64, 0) for mid := prevLast + prevForkSpec.EpochLength; mid < currentFirst; mid += prevForkSpec.EpochLength { intermediates = append(intermediates, mid) } diff --git a/module/fork_spec_test.go b/module/fork_spec_test.go index 80031f2f..bbf77605 100644 --- a/module/fork_spec_test.go +++ b/module/fork_spec_test.go @@ -201,3 +201,39 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_HeaderFnError() { ts.Error(err) ts.Equal(BoundaryHeight(0), boundaryHeight) } + +func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 0}, EpochLength: 200}, + {EpochLength: 500}, + } + epochs, err := BoundaryHeight(1501).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(1400)) + ts.Require().Equal(epochs.Intermediates, []uint64{1600, 1800}) + ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) + + epochs, err = BoundaryHeight(1600).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(1600)) + ts.Require().Equal(epochs.Intermediates, []uint64{1800}) + ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) + + epochs, err = BoundaryHeight(1601).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(1600)) + ts.Require().Equal(epochs.Intermediates, []uint64{1800}) + ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) + + epochs, err = BoundaryHeight(1800).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(1800)) + ts.Require().Equal(epochs.Intermediates, []uint64{}) + ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) + + epochs, err = BoundaryHeight(2000).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(2000)) + ts.Require().Equal(epochs.Intermediates, []uint64{}) + ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) +} From 5824ec7daea682e4cdb537f709762cdfaa1e263f Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 11:14:26 +0900 Subject: [PATCH 21/37] add test Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 18 +++++++--- module/fork_spec_test.go | 73 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index 6909db98..fd5ecb27 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -109,6 +109,13 @@ func (b BoundaryHeight) GetBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec index++ } intermediates := make([]uint64, 0) + // starts 0, 200, 400...epoch_length + if prevLast == 0 { + const defaultEpochLength = 200 + for mid := prevLast + defaultEpochLength; mid < prevForkSpec.EpochLength; mid += defaultEpochLength { + intermediates = append(intermediates, mid) + } + } for mid := prevLast + prevForkSpec.EpochLength; mid < currentFirst; mid += prevForkSpec.EpochLength { intermediates = append(intermediates, mid) } @@ -139,6 +146,9 @@ func (be BoundaryEpochs) CurrentEpochBlockNumber(number uint64) uint64 { } func (be BoundaryEpochs) PreviousEpochBlockNumber(currentEpochBlockNumber uint64) uint64 { + if currentEpochBlockNumber == 0 { + return 0 + } if currentEpochBlockNumber <= be.PrevLast { return currentEpochBlockNumber - be.PreviousForkSpec.EpochLength } @@ -189,7 +199,7 @@ func FindTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) return nil, nil, fmt.Errorf("no fork spec found height=%d, timestmp=%d", height, timestamp) } -var cache = make(map[uint64]BoundaryHeight) +var boundaryHeightCache = make(map[uint64]BoundaryHeight) func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (BoundaryHeight, error) { logger := log.GetLogger() @@ -198,7 +208,7 @@ func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSp boundaryHeight = condition.Height } else { ts := currentForkSpec.GetTimestamp() - if v, ok := cache[ts]; ok { + if v, ok := boundaryHeightCache[ts]; ok { return v, nil } logger.Debug("seek fork height", "currentHeight", currentHeight, "ts", ts) @@ -210,12 +220,12 @@ func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSp if MilliTimestamp(h) == ts { boundaryHeight = h.Number.Uint64() logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) - cache[ts] = BoundaryHeight(boundaryHeight) + boundaryHeightCache[ts] = BoundaryHeight(boundaryHeight) break } else if MilliTimestamp(h) < ts { boundaryHeight = h.Number.Uint64() + 1 logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) - cache[ts] = BoundaryHeight(boundaryHeight) + boundaryHeightCache[ts] = BoundaryHeight(boundaryHeight) break } } diff --git a/module/fork_spec_test.go b/module/fork_spec_test.go index bbf77605..63556d8e 100644 --- a/module/fork_spec_test.go +++ b/module/fork_spec_test.go @@ -20,6 +20,7 @@ func TestForkSpecTestSuite(t *testing.T) { func (ts *ForkSpecTestSuite) SetupTest() { _ = log.InitLogger("DEBUG", "text", "stdout") + boundaryHeightCache = make(map[uint64]BoundaryHeight) } func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_ValidHeight() { @@ -155,7 +156,7 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeader() return &types.Header{Number: big.NewInt(int64(height)), Time: height}, nil } currentHeight := uint64(1100) - currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000 * 1000}} // msec + currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000_000}} // msec boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) @@ -237,3 +238,73 @@ func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs() { ts.Require().Equal(epochs.Intermediates, []uint64{}) ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) } + +func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs_After_Lorentz() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 0}, EpochLength: 200}, + {EpochLength: 500}, + } + epochs, err := BoundaryHeight(1).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(0)) + ts.Require().Equal(epochs.Intermediates, []uint64{200, 400}) + ts.Require().Equal(epochs.CurrentFirst, uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(199), uint64(0)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(200), uint64(200)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(399), uint64(200)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(400), uint64(400)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(499), uint64(400)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(500), uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(501), uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(999), uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1000), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1001), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1499), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1500), uint64(1500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1501), uint64(1500)) + + ts.Require().Equal(epochs.PreviousEpochBlockNumber(0), uint64(0)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(200), uint64(0)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(400), uint64(200)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(500), uint64(400)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(1000), uint64(500)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(1500), uint64(1000)) +} + +func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs_After_Maxwell() { + forkSpecs := []*ForkSpec{ + {HeightOrTimestamp: &ForkSpec_Height{Height: 0}, EpochLength: 500}, + {EpochLength: 1000}, + } + epochs, err := BoundaryHeight(1).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + ts.Require().NoError(err) + ts.Require().Equal(epochs.PrevLast, uint64(0)) + ts.Require().Equal(epochs.Intermediates, []uint64{200, 400, 500}) + ts.Require().Equal(epochs.CurrentFirst, uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(199), uint64(0)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(200), uint64(200)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(399), uint64(200)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(400), uint64(400)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(499), uint64(400)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(500), uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(501), uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(999), uint64(500)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1000), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1001), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1499), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1500), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1501), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(1999), uint64(1000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(2000), uint64(2000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(2001), uint64(2000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(2999), uint64(2000)) + ts.Require().Equal(epochs.CurrentEpochBlockNumber(3000), uint64(3000)) + + ts.Require().Equal(epochs.PreviousEpochBlockNumber(0), uint64(0)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(200), uint64(0)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(400), uint64(200)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(500), uint64(400)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(1000), uint64(500)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(2000), uint64(1000)) + ts.Require().Equal(epochs.PreviousEpochBlockNumber(3000), uint64(2000)) +} From c9a4f43edf4a3c0417095eab86612f9b9e765a4c Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 11:31:02 +0900 Subject: [PATCH 22/37] change --- module/proof.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/module/proof.go b/module/proof.go index 893c31a1..7284b646 100644 --- a/module/proof.go +++ b/module/proof.go @@ -6,6 +6,7 @@ import ( "fmt" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/hyperledger-labs/yui-relayer/core" + "github.com/hyperledger-labs/yui-relayer/log" "math/big" "github.com/cosmos/gogoproto/proto" @@ -181,20 +182,23 @@ func withValidators(headerFn getHeaderFn, height uint64, ethHeaders []*ETHHeader if err != nil { return nil, fmt.Errorf("failed to get block header : number = %d : %+v", height, err) } - currentForkSpec, prevForkSpec, err := FindTargetForkSpec(forkSpecs, height, blockHeader.Time) + currentForkSpec, prevForkSpec, err := FindTargetForkSpec(forkSpecs, height, MilliTimestamp(blockHeader)) if err != nil { return nil, err } + log.GetLogger().Debug("target fork spec", "currentForkSpec", currentForkSpec, "prevForkSpec", prevForkSpec) boundaryHeight, err := GetBoundaryHeight(headerFn, height, *currentForkSpec) if err != nil { return nil, err } + log.GetLogger().Debug("get boundary height by ", "height", height, "boundaryHeight", boundaryHeight) boundaryEpochs, err := boundaryHeight.GetBoundaryEpochs(*currentForkSpec, *prevForkSpec) if err != nil { return nil, err } + log.GetLogger().Debug("boundary epoch", "prevLast", boundaryEpochs.PrevLast, "currentFirst", boundaryEpochs.CurrentFirst, "intermediates", boundaryEpochs.Intermediates) // Get validator set for verify headers currentEpoch := boundaryEpochs.CurrentEpochBlockNumber(height) From bd5b4cfb3b2331d539ddc21b6d7fe8a4ad89b021 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 11:48:59 +0900 Subject: [PATCH 23/37] refactor --- module/fork_spec.go | 59 ++++++++++++++++++++---------------- module/fork_spec_test.go | 29 +++++++++--------- module/proof.go | 2 +- module/setup.go | 6 ++-- tests/prover_network_test.go | 2 +- 5 files changed, 52 insertions(+), 46 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index fd5ecb27..ecddaf3e 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -93,16 +93,19 @@ type BoundaryEpochs struct { Intermediates []uint64 } -type BoundaryHeight uint64 +type BoundaryHeight struct { + Height uint64 + CurrentForkSpec ForkSpec +} -func (b BoundaryHeight) GetBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec ForkSpec) (*BoundaryEpochs, error) { - boundaryHeight := uint64(b) +func (b BoundaryHeight) GetBoundaryEpochs(prevForkSpec ForkSpec) (*BoundaryEpochs, error) { + boundaryHeight := b.Height prevLast := boundaryHeight - (boundaryHeight % prevForkSpec.EpochLength) index := uint64(0) currentFirst := uint64(0) for { candidate := boundaryHeight + index - if candidate%currentForkSpec.EpochLength == 0 { + if candidate%b.CurrentForkSpec.EpochLength == 0 { currentFirst = candidate break } @@ -122,7 +125,7 @@ func (b BoundaryHeight) GetBoundaryEpochs(currentForkSpec ForkSpec, prevForkSpec return &BoundaryEpochs{ PreviousForkSpec: prevForkSpec, - CurrentForkSpec: currentForkSpec, + CurrentForkSpec: b.CurrentForkSpec, BoundaryHeight: boundaryHeight, PrevLast: prevLast, CurrentFirst: currentFirst, @@ -199,9 +202,9 @@ func FindTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) return nil, nil, fmt.Errorf("no fork spec found height=%d, timestmp=%d", height, timestamp) } -var boundaryHeightCache = make(map[uint64]BoundaryHeight) +var boundaryHeightCache = make(map[uint64]uint64) -func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (BoundaryHeight, error) { +func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (*BoundaryHeight, error) { logger := log.GetLogger() boundaryHeight := uint64(0) if condition, ok := currentForkSpec.GetHeightOrTimestamp().(*ForkSpec_Height); ok { @@ -209,26 +212,30 @@ func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSp } else { ts := currentForkSpec.GetTimestamp() if v, ok := boundaryHeightCache[ts]; ok { - return v, nil - } - logger.Debug("seek fork height", "currentHeight", currentHeight, "ts", ts) - for i := int64(currentHeight); i >= 0; i-- { - h, err := headerFn(context.Background(), uint64(i)) - if err != nil { - return 0, err - } - if MilliTimestamp(h) == ts { - boundaryHeight = h.Number.Uint64() - logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) - boundaryHeightCache[ts] = BoundaryHeight(boundaryHeight) - break - } else if MilliTimestamp(h) < ts { - boundaryHeight = h.Number.Uint64() + 1 - logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) - boundaryHeightCache[ts] = BoundaryHeight(boundaryHeight) - break + boundaryHeight = v + } else { + logger.Debug("seek fork height", "currentHeight", currentHeight, "ts", ts) + for i := int64(currentHeight); i >= 0; i-- { + h, err := headerFn(context.Background(), uint64(i)) + if err != nil { + return nil, err + } + if MilliTimestamp(h) == ts { + boundaryHeight = h.Number.Uint64() + logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) + boundaryHeightCache[ts] = boundaryHeight + break + } else if MilliTimestamp(h) < ts { + boundaryHeight = h.Number.Uint64() + 1 + logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) + boundaryHeightCache[ts] = boundaryHeight + break + } } } } - return BoundaryHeight(boundaryHeight), nil + return &BoundaryHeight{ + Height: boundaryHeight, + CurrentForkSpec: currentForkSpec, + }, nil } diff --git a/module/fork_spec_test.go b/module/fork_spec_test.go index 63556d8e..6fee38ed 100644 --- a/module/fork_spec_test.go +++ b/module/fork_spec_test.go @@ -20,7 +20,7 @@ func TestForkSpecTestSuite(t *testing.T) { func (ts *ForkSpecTestSuite) SetupTest() { _ = log.InitLogger("DEBUG", "text", "stdout") - boundaryHeightCache = make(map[uint64]BoundaryHeight) + boundaryHeightCache = make(map[uint64]uint64) } func (ts *ForkSpecTestSuite) Test_FindTargetForkSpec_ValidHeight() { @@ -135,7 +135,7 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidHeight() { boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) ts.NoError(err) - ts.Equal(BoundaryHeight(50), boundaryHeight) + ts.Equal(uint64(50), boundaryHeight.Height) } func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestamp() { @@ -148,7 +148,7 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestamp() { boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) ts.NoError(err) - ts.Equal(BoundaryHeight(100), boundaryHeight) + ts.Equal(uint64(100), boundaryHeight.Height) } func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeader() { @@ -161,7 +161,7 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeader() boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) ts.NoError(err) - ts.Equal(BoundaryHeight(1000), boundaryHeight) + ts.Equal(uint64(1000), boundaryHeight.Height) } func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeaderNotJust() { @@ -174,7 +174,7 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_ValidTimestampMultiHeaderNot boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) ts.NoError(err) - ts.Equal(BoundaryHeight(1000), boundaryHeight) + ts.Equal(uint64(1000), boundaryHeight.Height) } func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_TimestampNotFound() { @@ -187,7 +187,7 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_TimestampNotFound() { boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) ts.NoError(err) - ts.Equal(BoundaryHeight(0), boundaryHeight) + ts.Equal(uint64(0), boundaryHeight.Height) } func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_HeaderFnError() { @@ -197,10 +197,9 @@ func (ts *ForkSpecTestSuite) Test_GetBoundaryHeight_HeaderFnError() { currentHeight := uint64(100) currentForkSpec := ForkSpec{HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1000}} - boundaryHeight, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) + _, err := GetBoundaryHeight(headerFn, currentHeight, currentForkSpec) ts.Error(err) - ts.Equal(BoundaryHeight(0), boundaryHeight) } func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs() { @@ -208,31 +207,31 @@ func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs() { {HeightOrTimestamp: &ForkSpec_Height{Height: 0}, EpochLength: 200}, {EpochLength: 500}, } - epochs, err := BoundaryHeight(1501).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err := BoundaryHeight{Height: 1501, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(1400)) ts.Require().Equal(epochs.Intermediates, []uint64{1600, 1800}) ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) - epochs, err = BoundaryHeight(1600).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err = BoundaryHeight{Height: 1600, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(1600)) ts.Require().Equal(epochs.Intermediates, []uint64{1800}) ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) - epochs, err = BoundaryHeight(1601).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err = BoundaryHeight{Height: 1601, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(1600)) ts.Require().Equal(epochs.Intermediates, []uint64{1800}) ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) - epochs, err = BoundaryHeight(1800).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err = BoundaryHeight{Height: 1800, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(1800)) ts.Require().Equal(epochs.Intermediates, []uint64{}) ts.Require().Equal(epochs.CurrentFirst, uint64(2000)) - epochs, err = BoundaryHeight(2000).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err = BoundaryHeight{Height: 2000, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(2000)) ts.Require().Equal(epochs.Intermediates, []uint64{}) @@ -244,7 +243,7 @@ func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs_After_Lorentz() { {HeightOrTimestamp: &ForkSpec_Height{Height: 0}, EpochLength: 200}, {EpochLength: 500}, } - epochs, err := BoundaryHeight(1).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err := BoundaryHeight{Height: 1, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(0)) ts.Require().Equal(epochs.Intermediates, []uint64{200, 400}) @@ -276,7 +275,7 @@ func (ts *ForkSpecTestSuite) Test_Success_GetBoundaryEpochs_After_Maxwell() { {HeightOrTimestamp: &ForkSpec_Height{Height: 0}, EpochLength: 500}, {EpochLength: 1000}, } - epochs, err := BoundaryHeight(1).GetBoundaryEpochs(*forkSpecs[1], *forkSpecs[0]) + epochs, err := BoundaryHeight{Height: 1, CurrentForkSpec: *forkSpecs[1]}.GetBoundaryEpochs(*forkSpecs[0]) ts.Require().NoError(err) ts.Require().Equal(epochs.PrevLast, uint64(0)) ts.Require().Equal(epochs.Intermediates, []uint64{200, 400, 500}) diff --git a/module/proof.go b/module/proof.go index 7284b646..38965e17 100644 --- a/module/proof.go +++ b/module/proof.go @@ -194,7 +194,7 @@ func withValidators(headerFn getHeaderFn, height uint64, ethHeaders []*ETHHeader } log.GetLogger().Debug("get boundary height by ", "height", height, "boundaryHeight", boundaryHeight) - boundaryEpochs, err := boundaryHeight.GetBoundaryEpochs(*currentForkSpec, *prevForkSpec) + boundaryEpochs, err := boundaryHeight.GetBoundaryEpochs(*prevForkSpec) if err != nil { return nil, err } diff --git a/module/setup.go b/module/setup.go index d78ce3f1..962eac20 100644 --- a/module/setup.go +++ b/module/setup.go @@ -37,10 +37,10 @@ func shouldSubmitBoundaryTimestampHeader( return nil, 0, err } // Must be right before boundary height - if boundaryHeight == 0 { + if boundaryHeight.Height == 0 { return nil, 0, fmt.Errorf("boundary height not found") } - return &x.Timestamp, uint64(boundaryHeight) - 1, nil + return &x.Timestamp, uint64(boundaryHeight.Height) - 1, nil } } return nil, 0, nil @@ -77,7 +77,7 @@ func setupHeadersForUpdate( if err != nil { return nil, err } - trustedBoundaryEpochs, err := trustedBoundaryHeight.GetBoundaryEpochs(*trustedCurrentForkSpec, *trustedPreviousForkSpec) + trustedBoundaryEpochs, err := trustedBoundaryHeight.GetBoundaryEpochs(*trustedPreviousForkSpec) if err != nil { return nil, err } diff --git a/tests/prover_network_test.go b/tests/prover_network_test.go index 071dda62..86c36173 100644 --- a/tests/prover_network_test.go +++ b/tests/prover_network_test.go @@ -96,7 +96,7 @@ func (ts *ProverNetworkTestSuite) TestSuccessCreateInitialLightClientState() { ts.Require().NoError(err) bs, err := module.GetBoundaryHeight(ts.chain.Header, header.Number.Uint64(), *currentForkSpec) ts.Require().NoError(err) - be, err := bs.GetBoundaryEpochs(*currentForkSpec, *prevForkSpec) + be, err := bs.GetBoundaryEpochs(*prevForkSpec) ts.Require().NoError(err) currentEpoch := be.CurrentEpochBlockNumber(header.Number.Uint64()) From f8e2d547b045d2836294893852792168892ce74a Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 14:24:25 +0900 Subject: [PATCH 24/37] check strict Signed-off-by: Naohiro Yoshida --- module/prover.go | 15 +++++++++++++++ module/setup.go | 10 +++++++--- module/setup_test.go | 32 ++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/module/prover.go b/module/prover.go index 4898999c..afa32dfa 100644 --- a/module/prover.go +++ b/module/prover.go @@ -237,6 +237,21 @@ func (pr *Prover) getForkParameters() []*ForkSpec { } func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState, exported.ConsensusState, error) { + + // Last ForkSpec must have height or CreateClient is less than fork spec timestamp + forkSpecs := pr.getForkParameters() + lastForkSpec := forkSpecs[len(forkSpecs)-1] + lastForkSpecTime := lastForkSpec.GetHeightOrTimestamp().(*ForkSpec_Timestamp) + if lastForkSpecTime != nil { + target, err := dstHeader.(*Header).Target() + if err != nil { + return nil, nil, err + } + if MilliTimestamp(target) >= lastForkSpecTime.Timestamp { + return nil, nil, fmt.Errorf("target timestamp is less than the last fork spec timestamp %d, %d", lastForkSpecTime.Timestamp, MilliTimestamp(target)) + } + } + dstHeader, err := pr.withValidators(dstHeader.GetHeight().GetRevisionHeight(), dstHeader.(*Header).Headers) if err != nil { return nil, nil, err diff --git a/module/setup.go b/module/setup.go index 962eac20..6bde643b 100644 --- a/module/setup.go +++ b/module/setup.go @@ -93,11 +93,11 @@ func setupHeadersForUpdate( logger.Info("Must set boundary timestamp", "ts", nextForkBoundaryTs, "nextForkBoundaryHeightMinus1", nextForkBoundaryHeightMinus1) firstUnsaved := trustedEpochHeight + skip - if firstUnsaved == savedLatestHeight { + if firstUnsaved <= savedLatestHeight { firstUnsaved += skip } - submittingHeights := makeSubmittingHeights(latestFinalizedHeight, firstUnsaved, nextForkBoundaryTs, nextForkBoundaryHeightMinus1) + submittingHeights := makeSubmittingHeights(latestFinalizedHeight, savedLatestHeight, firstUnsaved, nextForkBoundaryTs, nextForkBoundaryHeightMinus1) logger.Debug("submitting heights", "heights", submittingHeights) trustedHeight := clientStateLatestHeight.GetRevisionHeight() @@ -141,7 +141,7 @@ func withTrustedHeight(targetHeaders []core.Header, clientStateLatestHeight expo return targetHeaders } -func makeSubmittingHeights(latestFinalizedHeight uint64, firstUnsaved uint64, nextForkBoundaryTs *uint64, nextForkBoundaryHeightMinus1 uint64) []uint64 { +func makeSubmittingHeights(latestFinalizedHeight uint64, savedLatestHeight uint64, firstUnsaved uint64, nextForkBoundaryTs *uint64, nextForkBoundaryHeightMinus1 uint64) []uint64 { var submittingHeights []uint64 if latestFinalizedHeight < firstUnsaved { if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { @@ -158,6 +158,10 @@ func makeSubmittingHeights(latestFinalizedHeight uint64, firstUnsaved uint64, ne if temp[i-1] < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < epochCandidate { submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) } + } else if i == 0 { + if savedLatestHeight < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < epochCandidate { + submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) + } } submittingHeights = append(submittingHeights, epochCandidate) } diff --git a/module/setup_test.go b/module/setup_test.go index eebae60b..12efed9e 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -228,52 +228,56 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_withHFBoundary() { func (ts *SetupTestSuite) Test_makeSubmittingHeights() { rq := ts.Require() msec := uint64(0) - rq.Len(makeSubmittingHeights(10, 11, nil, 0), 0) - rq.Len(makeSubmittingHeights(10, 11, &msec, 11), 0) - rq.Len(makeSubmittingHeights(10, 11, &msec, 9), 1) + rq.Len(makeSubmittingHeights(10, 1, 11, nil, 0), 0) + rq.Len(makeSubmittingHeights(10, 1, 11, &msec, 11), 0) + rq.Len(makeSubmittingHeights(10, 1, 11, &msec, 9), 1) + rq.Equal( + []uint64{99, 100, 200, 300, 400, 500}, + makeSubmittingHeights(501, 0, 100, &msec, 99), + ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(501, 100, &msec, 99), + makeSubmittingHeights(501, 101, 100, &msec, 99), ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(501, 100, &msec, 100), + makeSubmittingHeights(501, 0, 100, &msec, 100), ) rq.Equal( []uint64{100, 101, 200, 300, 400, 500}, - makeSubmittingHeights(501, 100, &msec, 101), + makeSubmittingHeights(501, 0, 100, &msec, 101), ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(501, 100, nil, 101), + makeSubmittingHeights(501, 0, 100, nil, 101), ) rq.Equal( []uint64{100, 200, 201, 300, 400, 500}, - makeSubmittingHeights(501, 100, &msec, 201), + makeSubmittingHeights(501, 0, 100, &msec, 201), ) rq.Equal( []uint64{100, 200, 300, 301, 400, 500}, - makeSubmittingHeights(501, 100, &msec, 301), + makeSubmittingHeights(501, 0, 100, &msec, 301), ) rq.Equal( []uint64{100, 200, 300, 400, 401, 500}, - makeSubmittingHeights(501, 100, &msec, 401), + makeSubmittingHeights(501, 0, 100, &msec, 401), ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(501, 100, nil, 401), + makeSubmittingHeights(501, 0, 100, nil, 401), ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(501, 100, &msec, 501), + makeSubmittingHeights(501, 0, 100, &msec, 501), ) rq.Equal( []uint64{100, 200, 300, 400, 500, 501}, - makeSubmittingHeights(502, 100, &msec, 501), + makeSubmittingHeights(502, 0, 100, &msec, 501), ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(502, 100, nil, 501), + makeSubmittingHeights(502, 0, 100, nil, 501), ) } From 1b8d38ed4a6efb521c2809ac7266a36299c70b9b Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 14:25:24 +0900 Subject: [PATCH 25/37] check strict Signed-off-by: Naohiro Yoshida --- module/setup_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/setup_test.go b/module/setup_test.go index 12efed9e..7f776d39 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -237,7 +237,7 @@ func (ts *SetupTestSuite) Test_makeSubmittingHeights() { ) rq.Equal( []uint64{100, 200, 300, 400, 500}, - makeSubmittingHeights(501, 101, 100, &msec, 99), + makeSubmittingHeights(501, 99, 100, &msec, 99), ) rq.Equal( []uint64{100, 200, 300, 400, 500}, From 0da2a4b447ce7f2ab1bf433d3c86fbf9a7655f59 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 15:52:10 +0900 Subject: [PATCH 26/37] remove log --- module/fork_spec.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index ecddaf3e..56b6e945 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -22,7 +22,6 @@ var localLorentzHF isForkSpec_HeightOrTimestamp = &ForkSpec_Height{Height: 1} func init() { localLorentzHFTimestamp := os.Getenv("LOCAL_LORENTZ_HF_TIMESTAMP") if localLorentzHFTimestamp != "" { - fmt.Println("LOCAL_LORENTZ_HF_TIMESTAMP is found", localLorentzHFTimestamp) result, err := strconv.Atoi(localLorentzHFTimestamp) if err != nil { panic(err) @@ -32,7 +31,6 @@ func init() { } func GetForkParameters(network Network) []*ForkSpec { - switch network { case Localnet: return []*ForkSpec{ From d1ab860619940af3de5f05740ac81a696327cf87 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 16:47:07 +0900 Subject: [PATCH 27/37] update Signed-off-by: Naohiro Yoshida --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3f67e8fe..1343dd61 100644 --- a/README.md +++ b/README.md @@ -43,5 +43,9 @@ make proto-gen ## About ForkSpec +1. Set HF height as soon as possibile As soon as the HF height is determined, please modify the timestamp in the ForkSpec to the height as soon as possible. HF height is calculated from timestamp, but the further away from the HF, the longer it takes to calculate. + +2. Limitation of the CreateClient +When the latest HF height is not set it is impossible to create client if the latest finalize header is after latest HF timestamp \ No newline at end of file From a9bbd78676a45b3f822b054ca863b923e66cd05d Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Sun, 23 Mar 2025 17:14:25 +0900 Subject: [PATCH 28/37] change log Signed-off-by: Naohiro Yoshida --- module/prover.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/prover.go b/module/prover.go index afa32dfa..282338b9 100644 --- a/module/prover.go +++ b/module/prover.go @@ -248,7 +248,7 @@ func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState return nil, nil, err } if MilliTimestamp(target) >= lastForkSpecTime.Timestamp { - return nil, nil, fmt.Errorf("target timestamp is less than the last fork spec timestamp %d, %d", lastForkSpecTime.Timestamp, MilliTimestamp(target)) + return nil, nil, fmt.Errorf("target timestamp must be less than the last fork spec timestamp to submit height to ELC. %d, %d ", lastForkSpecTime.Timestamp, MilliTimestamp(target)) } } From b7c1a283fd0eb2f8f8b73bc3e5197955d27e9135 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Mon, 24 Mar 2025 13:38:17 +0900 Subject: [PATCH 29/37] change stack --- module/setup.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/setup.go b/module/setup.go index 6bde643b..adb8012a 100644 --- a/module/setup.go +++ b/module/setup.go @@ -93,12 +93,12 @@ func setupHeadersForUpdate( logger.Info("Must set boundary timestamp", "ts", nextForkBoundaryTs, "nextForkBoundaryHeightMinus1", nextForkBoundaryHeightMinus1) firstUnsaved := trustedEpochHeight + skip - if firstUnsaved <= savedLatestHeight { + for firstUnsaved <= savedLatestHeight { firstUnsaved += skip } submittingHeights := makeSubmittingHeights(latestFinalizedHeight, savedLatestHeight, firstUnsaved, nextForkBoundaryTs, nextForkBoundaryHeightMinus1) - logger.Debug("submitting heights", "heights", submittingHeights) + logger.Debug("submitting heights", "heights", submittingHeights, "trusted height", savedLatestHeight, "trusted epoch", trustedEpochHeight, "first unsaved", firstUnsaved) trustedHeight := clientStateLatestHeight.GetRevisionHeight() for _, submittingHeight := range submittingHeights { From 38284e6d2c3abbe8dc851fb4047e52a10c68084c Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Mon, 24 Mar 2025 17:16:34 +0900 Subject: [PATCH 30/37] check Signed-off-by: Naohiro Yoshida --- module/setup.go | 2 +- module/setup_test.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/module/setup.go b/module/setup.go index adb8012a..cb36eb83 100644 --- a/module/setup.go +++ b/module/setup.go @@ -144,7 +144,7 @@ func withTrustedHeight(targetHeaders []core.Header, clientStateLatestHeight expo func makeSubmittingHeights(latestFinalizedHeight uint64, savedLatestHeight uint64, firstUnsaved uint64, nextForkBoundaryTs *uint64, nextForkBoundaryHeightMinus1 uint64) []uint64 { var submittingHeights []uint64 if latestFinalizedHeight < firstUnsaved { - if nextForkBoundaryTs != nil && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { + if nextForkBoundaryTs != nil && savedLatestHeight < nextForkBoundaryHeightMinus1 && nextForkBoundaryHeightMinus1 < latestFinalizedHeight { submittingHeights = append(submittingHeights, nextForkBoundaryHeightMinus1) } } else { diff --git a/module/setup_test.go b/module/setup_test.go index 7f776d39..ad29de7b 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -231,6 +231,7 @@ func (ts *SetupTestSuite) Test_makeSubmittingHeights() { rq.Len(makeSubmittingHeights(10, 1, 11, nil, 0), 0) rq.Len(makeSubmittingHeights(10, 1, 11, &msec, 11), 0) rq.Len(makeSubmittingHeights(10, 1, 11, &msec, 9), 1) + rq.Len(makeSubmittingHeights(10, 9, 11, &msec, 9), 0) rq.Equal( []uint64{99, 100, 200, 300, 400, 500}, makeSubmittingHeights(501, 0, 100, &msec, 99), From 77bce5187dee48a54f4bde7388325cd4f7586b54 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Mon, 24 Mar 2025 22:05:47 +0900 Subject: [PATCH 31/37] check type --- module/prover.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/prover.go b/module/prover.go index 282338b9..c219f673 100644 --- a/module/prover.go +++ b/module/prover.go @@ -241,8 +241,8 @@ func (pr *Prover) buildInitialState(dstHeader core.Header) (exported.ClientState // Last ForkSpec must have height or CreateClient is less than fork spec timestamp forkSpecs := pr.getForkParameters() lastForkSpec := forkSpecs[len(forkSpecs)-1] - lastForkSpecTime := lastForkSpec.GetHeightOrTimestamp().(*ForkSpec_Timestamp) - if lastForkSpecTime != nil { + lastForkSpecTime, ok := lastForkSpec.GetHeightOrTimestamp().(*ForkSpec_Timestamp) + if ok && lastForkSpecTime != nil { target, err := dstHeader.(*Header).Target() if err != nil { return nil, nil, err From e341b9021e3227cf3105196f60e0de05954b5374 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 26 Mar 2025 19:52:55 +0900 Subject: [PATCH 32/37] change sleep time Signed-off-by: Naohiro Yoshida --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cca1e084..df78a434 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,8 +56,8 @@ jobs: make contracts # epoch length is fixed in lorentz HF. # epoch is 200, 400, 500, 1000 - # must wait for 1000 block (1.5sec * 1000) - sleep 1500 + # must wait for 1000 block (1.5sec * 400) + sleep 600 make relayer make test - name: integration-test From f37a183ca199bcff77d29ccd110a00e7ae741eb6 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 26 Mar 2025 21:00:04 +0900 Subject: [PATCH 33/37] fix ut Signed-off-by: Naohiro Yoshida --- module/setup_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/module/setup_test.go b/module/setup_test.go index 81b83751..5860a0db 100644 --- a/module/setup_test.go +++ b/module/setup_test.go @@ -85,9 +85,9 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_neighboringEpoch() { verify(skip, 10*skip, 9) verify(skip, 10*skip+1, 10) verify(skip+1, skip+1, 0) - verify(skip+1, 10*skip-1, 10) - verify(skip+1, 10*skip, 10) - verify(skip+1, 10*skip+1, 11) + verify(skip+1, 10*skip-1, 9) + verify(skip+1, 10*skip, 9) + verify(skip+1, 10*skip+1, 10) } @@ -220,9 +220,9 @@ func (ts *SetupTestSuite) TestSuccess_setupHeadersForUpdate_withHFBoundary() { verify(skip, 10*skip, 9+1) verify(skip, 10*skip+1, 10+1) verify(skip+1, skip+1, 0) - verify(skip+1, 10*skip-1, 10+1) - verify(skip+1, 10*skip, 10+1) - verify(skip+1, 10*skip+1, 11+1) + verify(skip+1, 10*skip-1, 9+1) + verify(skip+1, 10*skip, 9+1) + verify(skip+1, 10*skip+1, 10+1) } From 7a54feb1c0c2a0a8433c71ab3b2efc924e89120d Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 26 Mar 2025 21:27:44 +0900 Subject: [PATCH 34/37] add max_turn_length Signed-off-by: Naohiro Yoshida --- module/fork_spec.go | 6 + module/parlia.pb.go | 141 +++++++++++------- proto/ibc/lightclients/parlia/v1/parlia.proto | 1 + tests/prover_network_test.go | 2 + 4 files changed, 94 insertions(+), 56 deletions(-) diff --git a/module/fork_spec.go b/module/fork_spec.go index 56b6e945..38608715 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -40,6 +40,7 @@ func GetForkParameters(network Network) []*ForkSpec { HeightOrTimestamp: &ForkSpec_Height{Height: 0}, AdditionalHeaderItemCount: 1, EpochLength: 200, + MaxTurnLength: 9, }, // Lorentz HF { @@ -47,6 +48,7 @@ func GetForkParameters(network Network) []*ForkSpec { HeightOrTimestamp: localLorentzHF, AdditionalHeaderItemCount: 1, EpochLength: 500, + MaxTurnLength: 64, }, } case Testnet: @@ -56,11 +58,13 @@ func GetForkParameters(network Network) []*ForkSpec { HeightOrTimestamp: &ForkSpec_Height{Height: 48576786}, AdditionalHeaderItemCount: 1, EpochLength: 200, + MaxTurnLength: 9, }, { HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, AdditionalHeaderItemCount: 1, EpochLength: 500, + MaxTurnLength: 64, }, } case Mainnet: @@ -71,11 +75,13 @@ func GetForkParameters(network Network) []*ForkSpec { HeightOrTimestamp: &ForkSpec_Height{Height: 47618307}, AdditionalHeaderItemCount: 1, EpochLength: 200, + MaxTurnLength: 9, }, { HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, AdditionalHeaderItemCount: 1, EpochLength: 500, + MaxTurnLength: 64, }, } } diff --git a/module/parlia.pb.go b/module/parlia.pb.go index 4fcee62f..6915774d 100644 --- a/module/parlia.pb.go +++ b/module/parlia.pb.go @@ -35,6 +35,7 @@ type ForkSpec struct { HeightOrTimestamp isForkSpec_HeightOrTimestamp `protobuf_oneof:"height_or_timestamp"` AdditionalHeaderItemCount uint64 `protobuf:"varint,3,opt,name=additional_header_item_count,json=additionalHeaderItemCount,proto3" json:"additional_header_item_count,omitempty"` EpochLength uint64 `protobuf:"varint,4,opt,name=epoch_length,json=epochLength,proto3" json:"epoch_length,omitempty"` + MaxTurnLength uint64 `protobuf:"varint,5,opt,name=max_turn_length,json=maxTurnLength,proto3" json:"max_turn_length,omitempty"` } func (m *ForkSpec) Reset() { *m = ForkSpec{} } @@ -370,62 +371,63 @@ func init() { } var fileDescriptor_dc631224085c6c85 = []byte{ - // 869 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0x1b, 0x45, - 0x14, 0xf6, 0xc6, 0xc1, 0xb1, 0x27, 0x76, 0x43, 0x27, 0x6d, 0xd9, 0x84, 0xb2, 0x09, 0x2e, 0x88, - 0x80, 0x94, 0x5d, 0x1c, 0x24, 0xc4, 0x0d, 0x8a, 0x1a, 0x17, 0xe4, 0x88, 0x56, 0x8a, 0x36, 0x15, - 0x17, 0x08, 0x69, 0x34, 0x3b, 0x3b, 0xf6, 0x8e, 0xb2, 0xbb, 0xb3, 0x9a, 0x99, 0xb5, 0x0a, 0x4f, - 0xc1, 0x25, 0xaf, 0xc0, 0x53, 0xf4, 0x36, 0x57, 0xa8, 0x97, 0x5c, 0xf1, 0x93, 0xbc, 0x08, 0x9a, - 0x9f, 0xb5, 0x8d, 0x0c, 0x05, 0xee, 0x66, 0xce, 0xf9, 0xbe, 0x73, 0x66, 0xce, 0x77, 0xce, 0x01, - 0x1f, 0xb0, 0x84, 0x44, 0x39, 0x9b, 0x65, 0x8a, 0xe4, 0x8c, 0x96, 0x4a, 0x46, 0x15, 0x16, 0x39, - 0xc3, 0xd1, 0x7c, 0xe4, 0x4e, 0x61, 0x25, 0xb8, 0xe2, 0x70, 0x9f, 0x25, 0x24, 0x5c, 0x05, 0x86, - 0xce, 0x3d, 0x1f, 0xed, 0xdf, 0x9b, 0xf1, 0x19, 0x37, 0xb0, 0x48, 0x9f, 0x2c, 0x63, 0xff, 0x40, - 0x87, 0x26, 0x5c, 0xd0, 0xc8, 0x32, 0x74, 0x48, 0x7b, 0x72, 0x80, 0x60, 0xc6, 0xf9, 0x2c, 0xa7, - 0x91, 0xb9, 0x25, 0xf5, 0x34, 0x4a, 0x6b, 0x81, 0x15, 0xe3, 0xa5, 0xf5, 0x0f, 0x5f, 0x7a, 0xa0, - 0xfb, 0x25, 0x17, 0x57, 0x97, 0x15, 0x25, 0xd0, 0x07, 0x9d, 0x8c, 0xea, 0xf4, 0xbe, 0x77, 0xe8, - 0x1d, 0x6d, 0x4e, 0x5a, 0xb1, 0xbb, 0xc3, 0x00, 0xf4, 0x14, 0x2b, 0xa8, 0x54, 0xb8, 0xa8, 0xfc, - 0x0d, 0xe7, 0x5c, 0x9a, 0xe0, 0x29, 0x78, 0x88, 0xd3, 0x94, 0xe9, 0xc0, 0x38, 0x47, 0x19, 0xc5, - 0x29, 0x15, 0x88, 0x29, 0x5a, 0x20, 0xc2, 0xeb, 0x52, 0xf9, 0x6d, 0x4d, 0x89, 0xf7, 0x96, 0x98, - 0x89, 0x81, 0x9c, 0x2b, 0x5a, 0x8c, 0x35, 0x00, 0xbe, 0x0b, 0xfa, 0xb4, 0xe2, 0x24, 0x43, 0x39, - 0x2d, 0x67, 0x2a, 0xf3, 0x37, 0x0d, 0x61, 0xdb, 0xd8, 0x9e, 0x1a, 0xd3, 0xd9, 0x7d, 0xb0, 0x6b, - 0x5f, 0x83, 0xb8, 0x40, 0x8b, 0xd4, 0xc3, 0x97, 0x6d, 0xb0, 0x3d, 0x36, 0x5f, 0xbe, 0x54, 0x58, - 0x51, 0xb8, 0x07, 0xba, 0x24, 0xc3, 0xac, 0x44, 0x2c, 0xb5, 0xdf, 0x88, 0xb7, 0xcc, 0xfd, 0x3c, - 0x85, 0x1f, 0x81, 0xbb, 0x2c, 0x21, 0x48, 0x2a, 0x2e, 0x28, 0xc2, 0x69, 0x2a, 0xa8, 0x94, 0xe6, - 0x37, 0xfd, 0x78, 0x87, 0x25, 0xe4, 0x52, 0xdb, 0x1f, 0x5b, 0x33, 0xfc, 0x18, 0xdc, 0xd3, 0x58, - 0xc2, 0x8b, 0x82, 0xa9, 0x42, 0x8b, 0x81, 0x64, 0xce, 0xed, 0x4f, 0xfa, 0x31, 0x64, 0x09, 0x19, - 0x2f, 0x5d, 0x97, 0x39, 0x57, 0xf0, 0x14, 0x0c, 0x72, 0xac, 0xa8, 0x54, 0xc8, 0x15, 0x51, 0xff, - 0x61, 0xfb, 0x64, 0x3f, 0xd4, 0xaa, 0x6a, 0x8d, 0x42, 0xa7, 0xcc, 0x7c, 0x14, 0x4e, 0x0c, 0x22, - 0xee, 0x5b, 0x82, 0xbd, 0xc1, 0xa7, 0x60, 0x47, 0x89, 0x5a, 0x2a, 0x56, 0xce, 0x50, 0x45, 0x05, - 0xe3, 0xa9, 0xff, 0x86, 0x09, 0xb1, 0x17, 0x5a, 0x15, 0xc3, 0x46, 0xc5, 0xf0, 0x89, 0x53, 0xf1, - 0xac, 0x7b, 0xfd, 0xeb, 0x41, 0xeb, 0xc7, 0xdf, 0x0e, 0xbc, 0xf8, 0x4e, 0xc3, 0xbd, 0x30, 0x54, - 0xf8, 0x15, 0xd8, 0x29, 0xf0, 0x0b, 0x44, 0x72, 0x4e, 0xae, 0x50, 0x2a, 0xd8, 0x54, 0xf9, 0x9d, - 0xff, 0x1e, 0x6d, 0x50, 0xe0, 0x17, 0x63, 0x4d, 0x7d, 0xa2, 0x99, 0xf0, 0x01, 0xe8, 0x4c, 0x05, - 0xff, 0x9e, 0x96, 0xfe, 0xd6, 0xa1, 0x77, 0xd4, 0x8d, 0xdd, 0x0d, 0x8e, 0x01, 0x98, 0x72, 0x71, - 0x85, 0x64, 0x45, 0x89, 0xf4, 0xbb, 0x87, 0xed, 0xa3, 0xed, 0x93, 0xf7, 0xc2, 0x7f, 0x6e, 0xe3, - 0xb0, 0xe9, 0xb5, 0xb8, 0x37, 0x75, 0x27, 0x39, 0x7c, 0x04, 0x7a, 0x5f, 0x3c, 0x9f, 0xd8, 0x8e, - 0xd0, 0x99, 0x6c, 0xfb, 0x18, 0xf1, 0xfa, 0xb1, 0xbb, 0x0d, 0x7f, 0xde, 0x00, 0x1d, 0x07, 0x39, - 0x05, 0x5b, 0xd6, 0x28, 0x7d, 0xcf, 0x64, 0x7c, 0xff, 0x75, 0x19, 0x17, 0xa1, 0xe3, 0x86, 0x05, - 0x1f, 0x03, 0x5b, 0x2c, 0x9a, 0x36, 0x52, 0x6d, 0xfc, 0xab, 0x54, 0x03, 0xc7, 0x70, 0x5a, 0x1d, - 0x03, 0x48, 0x6a, 0x21, 0x68, 0xa9, 0xd0, 0x1c, 0xe7, 0x2c, 0xc5, 0x8a, 0x0b, 0xe9, 0xb7, 0x0f, - 0xdb, 0x47, 0xfd, 0xf8, 0xae, 0xf3, 0x7c, 0xbd, 0x70, 0xc0, 0x08, 0xec, 0x56, 0x82, 0xce, 0x19, - 0xaf, 0xe5, 0x2a, 0x7e, 0xd3, 0xe0, 0x61, 0xe3, 0x5a, 0x21, 0x84, 0x60, 0xb7, 0x89, 0xaf, 0x6a, - 0x51, 0x36, 0x63, 0xa1, 0xfb, 0x61, 0xb0, 0x48, 0xf0, 0xbc, 0x16, 0xa5, 0x1d, 0x0e, 0xdd, 0xae, - 0x8b, 0x04, 0xab, 0x84, 0x8e, 0x21, 0x2c, 0x32, 0x2c, 0x19, 0x7a, 0xf2, 0xef, 0x8c, 0x79, 0x29, - 0x69, 0x29, 0x6b, 0x69, 0x47, 0xe7, 0x1d, 0x00, 0xa4, 0x3e, 0x20, 0xc1, 0xb9, 0x72, 0xf5, 0xef, - 0x19, 0x4b, 0xcc, 0xb9, 0x82, 0x0f, 0xd7, 0x96, 0xc0, 0xea, 0x0a, 0xf8, 0x14, 0xbc, 0xb5, 0x5e, - 0x11, 0x94, 0x61, 0x99, 0xb9, 0x99, 0xb9, 0xbf, 0x56, 0x96, 0x09, 0x96, 0x19, 0xfc, 0x0c, 0xf8, - 0x7f, 0x53, 0x1a, 0x4b, 0xdc, 0x34, 0xc4, 0x07, 0xeb, 0xf5, 0xd1, 0xcc, 0xe1, 0x4f, 0x1e, 0xe8, - 0x3f, 0x63, 0x32, 0xa1, 0x19, 0xd6, 0x6e, 0x01, 0xdf, 0x06, 0x3d, 0xab, 0x5b, 0x33, 0xfb, 0xbd, - 0xb8, 0x6b, 0x0d, 0xe7, 0x29, 0xfc, 0x1c, 0x74, 0xdd, 0x5e, 0x1a, 0x39, 0xb9, 0x87, 0xaf, 0x6b, - 0x9b, 0xbf, 0xf6, 0xcc, 0x68, 0x85, 0x7e, 0x62, 0xfe, 0xf3, 0xbf, 0xe8, 0x27, 0xc3, 0x6f, 0x01, - 0xb8, 0x10, 0x7c, 0x4e, 0x6d, 0xa1, 0x1f, 0x81, 0x01, 0x26, 0x66, 0x33, 0xa2, 0x4a, 0x70, 0x3e, - 0x75, 0xb5, 0xee, 0x3b, 0xe3, 0x85, 0xb6, 0xc1, 0x0f, 0xc1, 0x9b, 0xcb, 0xed, 0xe3, 0x70, 0x6e, - 0x59, 0x2d, 0xed, 0x06, 0x7a, 0xf6, 0xec, 0xfa, 0x8f, 0xa0, 0x75, 0x7d, 0x13, 0x78, 0xaf, 0x6e, - 0x02, 0xef, 0xf7, 0x9b, 0xc0, 0xfb, 0xe1, 0x36, 0x68, 0xbd, 0xba, 0x0d, 0x5a, 0xbf, 0xdc, 0x06, - 0xad, 0x6f, 0xa2, 0x19, 0x53, 0x59, 0x9d, 0x84, 0x84, 0x17, 0x51, 0x8a, 0x15, 0x36, 0xeb, 0x30, - 0xc7, 0x49, 0xc4, 0x12, 0x72, 0x6c, 0x9f, 0x7c, 0x2c, 0x68, 0x8e, 0xbf, 0x8b, 0x0a, 0x9e, 0xd6, - 0x39, 0x4d, 0x3a, 0x66, 0x33, 0x7c, 0xf2, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x3a, 0x4e, - 0x76, 0xb9, 0x06, 0x00, 0x00, + // 882 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x6f, 0x23, 0x35, + 0x18, 0xce, 0x34, 0x25, 0x4d, 0x9c, 0x64, 0xcb, 0xba, 0xbb, 0xcb, 0xb4, 0x2c, 0x69, 0xc9, 0xf2, + 0x51, 0x90, 0x3a, 0x43, 0x82, 0x84, 0xb8, 0xa0, 0x6a, 0x9b, 0x05, 0xa5, 0x62, 0x57, 0xaa, 0xa6, + 0x2b, 0x0e, 0x08, 0xc9, 0xf2, 0x78, 0x9c, 0x8c, 0xd5, 0x99, 0xf1, 0xc8, 0xf6, 0x44, 0x0b, 0xbf, + 0x82, 0x23, 0x7f, 0x81, 0x5f, 0xb1, 0xd7, 0x9e, 0xd0, 0x1e, 0x39, 0xf1, 0xd1, 0x1e, 0xf8, 0x1b, + 0xc8, 0x1f, 0x93, 0x04, 0x0a, 0x0b, 0x7b, 0xb3, 0xdf, 0xf7, 0x79, 0xfc, 0xda, 0xcf, 0xf3, 0xfa, + 0x05, 0xef, 0xb3, 0x98, 0x84, 0x19, 0x9b, 0xa7, 0x8a, 0x64, 0x8c, 0x16, 0x4a, 0x86, 0x25, 0x16, + 0x19, 0xc3, 0xe1, 0x62, 0xe4, 0x56, 0x41, 0x29, 0xb8, 0xe2, 0x70, 0x8f, 0xc5, 0x24, 0x58, 0x07, + 0x06, 0x2e, 0xbd, 0x18, 0xed, 0xdd, 0x99, 0xf3, 0x39, 0x37, 0xb0, 0x50, 0xaf, 0x2c, 0x63, 0x6f, + 0x5f, 0x1f, 0x4d, 0xb8, 0xa0, 0xa1, 0x65, 0xe8, 0x23, 0xed, 0xca, 0x01, 0x06, 0x73, 0xce, 0xe7, + 0x19, 0x0d, 0xcd, 0x2e, 0xae, 0x66, 0x61, 0x52, 0x09, 0xac, 0x18, 0x2f, 0x6c, 0x7e, 0xf8, 0x87, + 0x07, 0xda, 0x5f, 0x70, 0x71, 0x71, 0x5e, 0x52, 0x02, 0x7d, 0xd0, 0x4a, 0xa9, 0x2e, 0xef, 0x7b, + 0x07, 0xde, 0xe1, 0xe6, 0xb4, 0x11, 0xb9, 0x3d, 0x1c, 0x80, 0x8e, 0x62, 0x39, 0x95, 0x0a, 0xe7, + 0xa5, 0xbf, 0xe1, 0x92, 0xab, 0x10, 0x3c, 0x06, 0xf7, 0x71, 0x92, 0x30, 0x7d, 0x30, 0xce, 0x50, + 0x4a, 0x71, 0x42, 0x05, 0x62, 0x8a, 0xe6, 0x88, 0xf0, 0xaa, 0x50, 0x7e, 0x53, 0x53, 0xa2, 0xdd, + 0x15, 0x66, 0x6a, 0x20, 0xa7, 0x8a, 0xe6, 0x13, 0x0d, 0x80, 0x6f, 0x83, 0x1e, 0x2d, 0x39, 0x49, + 0x51, 0x46, 0x8b, 0xb9, 0x4a, 0xfd, 0x4d, 0x43, 0xe8, 0x9a, 0xd8, 0x63, 0x13, 0x82, 0xef, 0x81, + 0xed, 0x1c, 0x3f, 0x43, 0xaa, 0x12, 0x45, 0x8d, 0x7a, 0xcd, 0xa0, 0xfa, 0x39, 0x7e, 0xf6, 0xb4, + 0x12, 0x85, 0xc5, 0x9d, 0xdc, 0x05, 0x3b, 0xf6, 0xd6, 0x88, 0x0b, 0xb4, 0xbc, 0xe2, 0xf0, 0x79, + 0x13, 0x74, 0x27, 0x46, 0x9a, 0x73, 0x85, 0x15, 0x85, 0xbb, 0xa0, 0x4d, 0x52, 0xcc, 0x0a, 0xc4, + 0x12, 0xfb, 0xdc, 0x68, 0xcb, 0xec, 0x4f, 0x13, 0xf8, 0x21, 0xb8, 0xcd, 0x62, 0x82, 0xa4, 0xe2, + 0x82, 0x22, 0x9c, 0x24, 0x82, 0x4a, 0x69, 0x5e, 0xdd, 0x8b, 0xb6, 0x59, 0x4c, 0xce, 0x75, 0xfc, + 0xa1, 0x0d, 0xc3, 0x8f, 0xc0, 0x1d, 0x8d, 0x25, 0x3c, 0xcf, 0x99, 0xca, 0xb5, 0x69, 0x48, 0x66, + 0xdc, 0xbe, 0xb8, 0x17, 0x41, 0x16, 0x93, 0xc9, 0x2a, 0x75, 0x9e, 0x71, 0x05, 0x8f, 0x41, 0x3f, + 0xc3, 0x8a, 0x4a, 0x85, 0x9c, 0xd8, 0xfa, 0xad, 0xdd, 0xf1, 0x5e, 0xa0, 0xdd, 0xd7, 0x5e, 0x06, + 0xce, 0xc1, 0xc5, 0x28, 0x98, 0x1a, 0x44, 0xd4, 0xb3, 0x04, 0xbb, 0x83, 0x8f, 0xc1, 0xb6, 0x12, + 0x95, 0x54, 0xac, 0x98, 0xa3, 0x92, 0x0a, 0xc6, 0x13, 0x23, 0x44, 0x77, 0xbc, 0x1b, 0x58, 0xb7, + 0x83, 0xda, 0xed, 0xe0, 0x91, 0x73, 0xfb, 0xa4, 0x7d, 0xf9, 0xcb, 0x7e, 0xe3, 0x87, 0x5f, 0xf7, + 0xbd, 0xe8, 0x56, 0xcd, 0x3d, 0x33, 0x54, 0xf8, 0xa5, 0x95, 0x95, 0x64, 0x9c, 0x5c, 0xa0, 0x44, + 0xb0, 0x99, 0xf2, 0x5b, 0xff, 0xff, 0x34, 0xad, 0xfd, 0x44, 0x53, 0x1f, 0x69, 0x26, 0xbc, 0x07, + 0x5a, 0x33, 0xc1, 0xbf, 0xa3, 0x85, 0xbf, 0x75, 0xe0, 0x1d, 0xb6, 0x23, 0xb7, 0x83, 0x13, 0x00, + 0x66, 0x5c, 0x5c, 0x20, 0x59, 0x52, 0x22, 0xfd, 0xf6, 0x41, 0xf3, 0xb0, 0x3b, 0x7e, 0x27, 0xf8, + 0xf7, 0x76, 0x0f, 0xea, 0x9e, 0x8c, 0x3a, 0x33, 0xb7, 0x92, 0xc3, 0x07, 0xa0, 0xf3, 0xf9, 0xd3, + 0xa9, 0xed, 0x1c, 0x5d, 0xc9, 0xb6, 0x99, 0x31, 0xaf, 0x17, 0xb9, 0xdd, 0xf0, 0xa7, 0x0d, 0xd0, + 0x72, 0x90, 0x63, 0xb0, 0x65, 0x83, 0xd2, 0xf7, 0x4c, 0xc5, 0x77, 0x5f, 0x56, 0x71, 0x79, 0x74, + 0x54, 0xb3, 0xe0, 0x43, 0x60, 0xc5, 0xa2, 0x49, 0x6d, 0xd5, 0xc6, 0x7f, 0x5a, 0xd5, 0x77, 0x0c, + 0xe7, 0xd5, 0x11, 0x80, 0xa4, 0x12, 0x82, 0x16, 0x0a, 0x2d, 0x70, 0xc6, 0x12, 0xac, 0xb8, 0x90, + 0x7e, 0xf3, 0xa0, 0x79, 0xd8, 0x8b, 0x6e, 0xbb, 0xcc, 0x57, 0xcb, 0x04, 0x0c, 0xc1, 0x4e, 0x29, + 0xe8, 0x82, 0xf1, 0x4a, 0xae, 0xe3, 0x37, 0x0d, 0x1e, 0xd6, 0xa9, 0x35, 0x42, 0x00, 0x76, 0xea, + 0xf3, 0xff, 0xfe, 0x31, 0xfa, 0xcb, 0x02, 0xab, 0xcf, 0xa1, 0xdb, 0x75, 0x59, 0x60, 0x9d, 0xd0, + 0x32, 0x84, 0x65, 0x85, 0x15, 0x63, 0xf8, 0xdc, 0x03, 0xb7, 0x26, 0xbc, 0x90, 0xb4, 0x90, 0x95, + 0xb4, 0x5f, 0xe7, 0x2d, 0x00, 0xa4, 0x5e, 0x20, 0xc1, 0xb9, 0x72, 0xfa, 0x77, 0x4c, 0x24, 0xe2, + 0x5c, 0xc1, 0xfb, 0x37, 0x86, 0xc5, 0xfa, 0xa8, 0xf8, 0x04, 0xbc, 0x71, 0x53, 0x11, 0x94, 0x62, + 0x99, 0xba, 0x3f, 0x73, 0xf7, 0x86, 0x2c, 0x53, 0x2c, 0x53, 0xf8, 0x29, 0xf0, 0xff, 0x41, 0x1a, + 0x4b, 0xdc, 0x34, 0xc4, 0x7b, 0x37, 0xf5, 0xd1, 0xcc, 0xe1, 0x8f, 0x1e, 0xe8, 0x3d, 0x61, 0x32, + 0xa6, 0x29, 0xd6, 0x69, 0x01, 0xdf, 0x04, 0x1d, 0xeb, 0x5b, 0xfd, 0xf7, 0x3b, 0x51, 0xdb, 0x06, + 0x4e, 0x13, 0xf8, 0x19, 0x68, 0xbb, 0xf9, 0x35, 0x72, 0x76, 0x0f, 0x5f, 0xd6, 0x36, 0x7f, 0xed, + 0x99, 0xd1, 0x1a, 0x7d, 0x6c, 0xde, 0xf3, 0x4a, 0xf4, 0xf1, 0xf0, 0x1b, 0x00, 0xce, 0x04, 0x5f, + 0x50, 0x2b, 0xf4, 0x03, 0xd0, 0xc7, 0xc4, 0x4c, 0x50, 0x54, 0x0a, 0xce, 0x67, 0x4e, 0xeb, 0x9e, + 0x0b, 0x9e, 0xe9, 0x18, 0xfc, 0x00, 0xbc, 0xbe, 0x9a, 0x3e, 0x0e, 0xe7, 0x86, 0xd5, 0x2a, 0x6e, + 0xa0, 0x27, 0x4f, 0x2e, 0x7f, 0x1f, 0x34, 0x2e, 0xaf, 0x06, 0xde, 0x8b, 0xab, 0x81, 0xf7, 0xdb, + 0xd5, 0xc0, 0xfb, 0xfe, 0x7a, 0xd0, 0x78, 0x71, 0x3d, 0x68, 0xfc, 0x7c, 0x3d, 0x68, 0x7c, 0x1d, + 0xce, 0x99, 0x4a, 0xab, 0x38, 0x20, 0x3c, 0x0f, 0x13, 0xac, 0xb0, 0x19, 0x87, 0x19, 0x8e, 0x43, + 0x16, 0x93, 0x23, 0x7b, 0xe5, 0x23, 0x41, 0x33, 0xfc, 0x6d, 0x98, 0xf3, 0xa4, 0xca, 0x68, 0xdc, + 0x32, 0x93, 0xe1, 0xe3, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x11, 0x5a, 0xe7, 0x6a, 0xe1, 0x06, + 0x00, 0x00, } func (m *ForkSpec) Marshal() (dAtA []byte, err error) { @@ -448,6 +450,11 @@ func (m *ForkSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxTurnLength != 0 { + i = encodeVarintParlia(dAtA, i, uint64(m.MaxTurnLength)) + i-- + dAtA[i] = 0x28 + } if m.EpochLength != 0 { i = encodeVarintParlia(dAtA, i, uint64(m.EpochLength)) i-- @@ -861,6 +868,9 @@ func (m *ForkSpec) Size() (n int) { if m.EpochLength != 0 { n += 1 + sovParlia(uint64(m.EpochLength)) } + if m.MaxTurnLength != 0 { + n += 1 + sovParlia(uint64(m.MaxTurnLength)) + } return n } @@ -1144,6 +1154,25 @@ func (m *ForkSpec) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxTurnLength", wireType) + } + m.MaxTurnLength = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParlia + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxTurnLength |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParlia(dAtA[iNdEx:]) diff --git a/proto/ibc/lightclients/parlia/v1/parlia.proto b/proto/ibc/lightclients/parlia/v1/parlia.proto index b9c1b857..e67d5e37 100644 --- a/proto/ibc/lightclients/parlia/v1/parlia.proto +++ b/proto/ibc/lightclients/parlia/v1/parlia.proto @@ -14,6 +14,7 @@ message ForkSpec { } uint64 additional_header_item_count = 3; uint64 epoch_length = 4; + uint64 max_turn_length = 5; } message ClientState { diff --git a/tests/prover_network_test.go b/tests/prover_network_test.go index e2a5185a..a7a1e6eb 100644 --- a/tests/prover_network_test.go +++ b/tests/prover_network_test.go @@ -153,6 +153,8 @@ func (ts *ProverNetworkTestSuite) makeProver(chain module.Chain) *module.Prover Numerator: 3, Denominator: 2, }, + Network: string(module.Localnet), } + ts.Require().NoError(config.Validate()) return module.NewProver(chain, &config).(*module.Prover) } From e232ac10ba8f8b7778a340d7132dfcebd68b9ce8 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Thu, 27 Mar 2025 11:37:51 +0900 Subject: [PATCH 35/37] fix testtool Signed-off-by: Naohiro Yoshida --- module/setup.go | 6 ++- tool/testdata/internal/create_client.go | 14 ++---- tool/testdata/internal/header.go | 9 ++-- tool/testdata/internal/misbehavior.go | 18 +++++-- tool/testdata/internal/update_client.go | 66 ++++++++++++++++++------- 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/module/setup.go b/module/setup.go index 6e58730a..a67214f9 100644 --- a/module/setup.go +++ b/module/setup.go @@ -41,7 +41,10 @@ func shouldSubmitBoundaryTimestampHeader( if boundaryHeight.Height == 0 { return nil, 0, fmt.Errorf("boundary height not found") } - return &x.Timestamp, uint64(boundaryHeight.Height) - 1, nil + + nextForkBoundaryHeightMinus1 := uint64(boundaryHeight.Height) - 1 + log.GetLogger().Info("ForkSpec height required", "ts", x.Timestamp, "height", boundaryHeight, "nextForkBoundaryHeightMinus1", nextForkBoundaryHeightMinus1) + return &x.Timestamp, nextForkBoundaryHeightMinus1, nil } } return nil, 0, nil @@ -92,7 +95,6 @@ func setupHeadersForUpdate( if err != nil { return nil, err } - logger.Info("Must set boundary timestamp", "ts", nextForkBoundaryTs, "nextForkBoundaryHeightMinus1", nextForkBoundaryHeightMinus1) firstUnsaved := trustedEpochHeight + skip for firstUnsaved <= savedLatestHeight { diff --git a/tool/testdata/internal/create_client.go b/tool/testdata/internal/create_client.go index 9689258b..aef0188b 100644 --- a/tool/testdata/internal/create_client.go +++ b/tool/testdata/internal/create_client.go @@ -17,7 +17,7 @@ func (m *createClientModule) createClientSuccessCmd() *cobra.Command { cmd := &cobra.Command{ Use: "success", RunE: func(cmd *cobra.Command, args []string) error { - prover, chain, err := createProver(cmd.Context()) + prover, _, err := createProver(cmd.Context()) if err != nil { return err } @@ -42,20 +42,12 @@ func (m *createClientModule) createClientSuccessCmd() *cobra.Command { if err != nil { return err } - currentValidatorSet, currentTurnLength, err := module.QueryValidatorSetAndTurnLength(cmd.Context(), chain.Header, module.GetCurrentEpoch(cs.GetLatestHeight().GetRevisionHeight())) - if err != nil { - return err - } - previousValidatorSet, previousTurnLength, err := module.QueryValidatorSetAndTurnLength(cmd.Context(), chain.Header, module.GetPreviousEpoch(cs.GetLatestHeight().GetRevisionHeight())) - if err != nil { - return err - } log.Println("clientState", common.Bytes2Hex(anyClientState)) log.Println("consensusState", common.Bytes2Hex(anyConsState)) log.Println("height", cs.GetLatestHeight().GetRevisionHeight()) log.Println("time", consState.GetTimestamp()) - log.Println("currentEpochHash", common.BytesToHash(module.MakeEpochHash(currentValidatorSet, currentTurnLength))) - log.Println("previousEpochHash", common.BytesToHash(module.MakeEpochHash(previousValidatorSet, previousTurnLength))) + log.Println("currentEpochHash", common.BytesToHash(consState.(*module.ConsensusState).CurrentValidatorsHash)) + log.Println("previousEpochHash", common.BytesToHash(consState.(*module.ConsensusState).PreviousValidatorsHash)) log.Println("storageRoot", common.BytesToHash(consState.(*module.ConsensusState).StateRoot)) return nil diff --git a/tool/testdata/internal/header.go b/tool/testdata/internal/header.go index 6b091aac..b2de0609 100644 --- a/tool/testdata/internal/header.go +++ b/tool/testdata/internal/header.go @@ -5,7 +5,6 @@ import ( "log" "github.com/datachainlab/ibc-parlia-relay/module" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" "github.com/pkg/errors" @@ -56,11 +55,9 @@ func (m *headerModule) printHeader(chain module.Chain, height uint64) error { if err != nil { return errors.WithStack(err) } - if height%constant.BlocksPerEpoch == 0 { - vals, turnLength, err := module.ExtractValidatorSetAndTurnLength(header) - if err != nil { - return errors.WithStack(err) - } + + vals, turnLength, err := module.ExtractValidatorSetAndTurnLength(header) + if err == nil { log.Println("validators = ") for _, val := range vals { log.Println(common.Bytes2Hex(val)) diff --git a/tool/testdata/internal/misbehavior.go b/tool/testdata/internal/misbehavior.go index d66d8bd2..6c537d88 100644 --- a/tool/testdata/internal/misbehavior.go +++ b/tool/testdata/internal/misbehavior.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/datachainlab/ethereum-ibc-relay-chain/pkg/relay/ethereum" "github.com/datachainlab/ibc-parlia-relay/module" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" "github.com/spf13/cobra" @@ -105,8 +104,21 @@ func (m *misbehaviorModule) error() *cobra.Command { log.Println("Invalid block: current_validator_hash", common.Bytes2Hex(module.MakeEpochHash(header.(*module.Header).CurrentValidators, uint8(header.(*module.Header).CurrentTurnLength)))) log.Println("Invalid block: previous_validator_hash", common.Bytes2Hex(module.MakeEpochHash(header.(*module.Header).PreviousValidators, uint8(header.(*module.Header).PreviousTurnLength)))) log.Println("Invalid block: trusted_height", updating[0].(*module.Header).TrustedHeight) - epochCount := header.GetHeight().GetRevisionHeight() / constant.BlocksPerEpoch - log.Println("Invalid block: currentEpoch", epochCount*constant.BlocksPerEpoch) + + forkSpec, prev, err := module.FindTargetForkSpec(module.GetForkParameters(module.Localnet), header.GetHeight().GetRevisionHeight(), module.MilliTimestamp(target2)) + if err != nil { + return err + } + bh, err := module.GetBoundaryHeight(chain.Header, header.GetHeight().GetRevisionHeight(), *forkSpec) + if err != nil { + return err + } + be, err := bh.GetBoundaryEpochs(*prev) + if err != nil { + return err + } + currentEpochBlockNumber := be.CurrentEpochBlockNumber(header.GetHeight().GetRevisionHeight()) + log.Println("Invalid block: currentEpoch", currentEpochBlockNumber) return nil }, } diff --git a/tool/testdata/internal/update_client.go b/tool/testdata/internal/update_client.go index b47ed67c..86cd1b92 100644 --- a/tool/testdata/internal/update_client.go +++ b/tool/testdata/internal/update_client.go @@ -6,7 +6,6 @@ import ( "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/datachainlab/ibc-parlia-relay/module" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -47,8 +46,12 @@ func (m *updateClientModule) success() *cobra.Command { if err != nil { return err } - epochCount := latest.GetRevisionHeight() / constant.BlocksPerEpoch - return m.printHeader(cmd.Context(), prover, chain, epochCount*constant.BlocksPerEpoch+2) + be, err := m.GetBoundaryEpoch(chain, latest.GetRevisionHeight()) + if err != nil { + return err + } + epoch := be.CurrentEpochBlockNumber(latest.GetRevisionHeight()) + return m.printHeader(cmd.Context(), prover, chain, epoch+2) }, }) var num uint64 @@ -60,8 +63,12 @@ func (m *updateClientModule) success() *cobra.Command { if err != nil { return errors.WithStack(err) } - currentEpoch := module.GetCurrentEpoch(num) - previousEpoch := module.GetPreviousEpoch(num) + be, err := m.GetBoundaryEpoch(chain, num) + if err != nil { + return err + } + currentEpoch := be.CurrentEpochBlockNumber(num) + previousEpoch := be.PreviousEpochBlockNumber(currentEpoch) validator, turnLength, err := module.QueryValidatorSetAndTurnLength(cmd.Context(), chain.Header, previousEpoch) if err != nil { return errors.WithStack(err) @@ -109,18 +116,24 @@ func (m *updateClientModule) error() *cobra.Command { if err != nil { return errors.WithStack(err) } - epoch := module.GetCurrentEpoch(latest.GetRevisionHeight()) + be, err := m.GetBoundaryEpoch(chain, latest.GetRevisionHeight()) + if err != nil { + return errors.WithStack(err) + } + epoch := be.CurrentEpochBlockNumber(latest.GetRevisionHeight()) + prevEpoch := be.PreviousEpochBlockNumber(epoch) header, err := prover.GetLatestFinalizedHeaderByLatestHeight(cmd.Context(), epoch+2) if err != nil { return errors.WithStack(err) } - updating, err := prover.SetupHeadersForUpdateByLatestHeight(cmd.Context(), types.NewHeight(0, header.GetHeight().GetRevisionNumber()-constant.BlocksPerEpoch), header.(*module.Header)) + updating, err := prover.SetupHeadersForUpdateByLatestHeight(cmd.Context(), types.NewHeight(0, prevEpoch), header.(*module.Header)) if err != nil { return errors.WithStack(err) } // non neighboring epoch - newTrustedHeight := types.NewHeight(0, header.GetHeight().GetRevisionHeight()-2*constant.BlocksPerEpoch) + prevPrevEpoch := be.PreviousEpochBlockNumber(prevEpoch) + newTrustedHeight := types.NewHeight(0, prevPrevEpoch) updating[0].(*module.Header).TrustedHeight = &newTrustedHeight pack, err := types.PackClientMessage(updating[0]) if err != nil { @@ -168,11 +181,17 @@ func (m *updateClientModule) printHeader(ctx context.Context, prover *module.Pro } trustedHeight := updating[0].(*module.Header).TrustedHeight.GetRevisionHeight() - currentValidatorSetOfTrustedHeight, currentTurnLengthOfTrustedHeight, err := module.QueryValidatorSetAndTurnLength(ctx, chain.Header, module.GetCurrentEpoch(trustedHeight)) + trustedBe, err := m.GetBoundaryEpoch(chain, trustedHeight) + if err != nil { + return err + } + currentEpoch := trustedBe.CurrentEpochBlockNumber(trustedHeight) + currentValidatorSetOfTrustedHeight, currentTurnLengthOfTrustedHeight, err := module.QueryValidatorSetAndTurnLength(ctx, chain.Header, currentEpoch) if err != nil { return err } - previousValidatorSetOfTrustedHeight, previousTurnLengthOfTrustedHeight, err := module.QueryValidatorSetAndTurnLength(ctx, chain.Header, module.GetPreviousEpoch(trustedHeight)) + previousEpoch := trustedBe.PreviousEpochBlockNumber(currentEpoch) + previousValidatorSetOfTrustedHeight, previousTurnLengthOfTrustedHeight, err := module.QueryValidatorSetAndTurnLength(ctx, chain.Header, previousEpoch) if err != nil { return err } @@ -181,19 +200,32 @@ func (m *updateClientModule) printHeader(ctx context.Context, prover *module.Pro log.Println("trustedHeight", trustedHeight) log.Println("currentEpochHashOfTrustedHeight", common.Bytes2Hex(module.MakeEpochHash(currentValidatorSetOfTrustedHeight, currentTurnLengthOfTrustedHeight))) log.Println("previousEpochHashOfTrustedHeight", common.Bytes2Hex(module.MakeEpochHash(previousValidatorSetOfTrustedHeight, previousTurnLengthOfTrustedHeight))) - if target.Number.Uint64()%constant.BlocksPerEpoch == 0 { - newValidators, newTurnLength, err := module.ExtractValidatorSetAndTurnLength(target) - if err != nil { - return err - } - log.Println("newCurrentEpochHash", common.Bytes2Hex(module.MakeEpochHash(newValidators, newTurnLength))) - } else { + newValidators, newTurnLength, err := module.ExtractValidatorSetAndTurnLength(target) + if err != nil { log.Println("newCurrentEpochHash", common.Bytes2Hex(module.MakeEpochHash(header.CurrentValidators, uint8(header.CurrentTurnLength)))) + } else { + log.Println("newCurrentEpochHash", common.Bytes2Hex(module.MakeEpochHash(newValidators, newTurnLength))) } log.Println("newPreviousEpochHash", common.Bytes2Hex(module.MakeEpochHash(header.PreviousValidators, uint8(header.PreviousTurnLength)))) return nil } +func (m *updateClientModule) GetBoundaryEpoch(chain module.Chain, height uint64) (*module.BoundaryEpochs, error) { + header, err := chain.Header(context.Background(), height) + if err != nil { + return nil, err + } + forkSpec, prev, err := module.FindTargetForkSpec(module.GetForkParameters(module.Localnet), header.Number.Uint64(), module.MilliTimestamp(header)) + if err != nil { + return nil, err + } + bh, err := module.GetBoundaryHeight(chain.Header, header.Number.Uint64(), *forkSpec) + if err != nil { + return nil, err + } + return bh.GetBoundaryEpochs(*prev) +} + func CreateUpdateClient() *cobra.Command { cmd := &cobra.Command{ Use: "update", From 7a254456f68ec9568c4c7f4461e0df10d5cf122a Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 2 Apr 2025 17:16:31 +0900 Subject: [PATCH 36/37] add lorentz ts Signed-off-by: Naohiro Yoshida --- .github/workflows/ci.yml | 3 +- e2e/chains/bsc/Dockerfile.bootstrap | 4 +- e2e/chains/bsc/docker-compose.bsc.yml | 2 +- .../bsc/genesis/contracts/BSCValidatorSet.sol | 436 +++--------------- .../bsc/genesis/genesis-template.template | 5 - .../bsc/genesis/scripts/init_holders.template | 2 +- module/fork_spec.go | 2 +- 7 files changed, 58 insertions(+), 396 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df78a434..33a54f14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,9 +54,8 @@ jobs: run: | make chain make contracts - # epoch length is fixed in lorentz HF. # epoch is 200, 400, 500, 1000 - # must wait for 1000 block (1.5sec * 400) + # must wait for 400 block (1.5sec * 400) sleep 600 make relayer make test diff --git a/e2e/chains/bsc/Dockerfile.bootstrap b/e2e/chains/bsc/Dockerfile.bootstrap index b7da3b7f..0eca9543 100644 --- a/e2e/chains/bsc/Dockerfile.bootstrap +++ b/e2e/chains/bsc/Dockerfile.bootstrap @@ -3,8 +3,8 @@ FROM ghcr.io/foundry-rs/foundry:nightly-462b2ac6c038dc24b8f38b0c59b664d0740604c2 RUN apk add --d --no-cache ca-certificates npm nodejs bash alpine-sdk expect jq curl bash python3 RUN curl -sSL https://install.python-poetry.org | python3 - -RUN git clone https://github.com/bnb-chain/bsc-genesis-contract -b v1.2.4 /root/genesis \ - && cd /root/genesis && npm ci +RUN git clone https://github.com/bnb-chain/bsc-genesis-contract -b develop /root/genesis \ + && cd /root/genesis && git checkout 44ebc6c17a00bd24db3240141a78091528dcebbb && npm ci RUN cd /root/genesis && /root/.local/bin/poetry install RUN cd /root/genesis && forge install --no-git --no-commit foundry-rs/forge-std@v1.7.3 diff --git a/e2e/chains/bsc/docker-compose.bsc.yml b/e2e/chains/bsc/docker-compose.bsc.yml index 67af2269..76a0fe84 100644 --- a/e2e/chains/bsc/docker-compose.bsc.yml +++ b/e2e/chains/bsc/docker-compose.bsc.yml @@ -5,5 +5,5 @@ services: dockerfile: Dockerfile.bsc args: GIT_SOURCE: https://github.com/bnb-chain/bsc - GIT_CHECKOUT_BRANCH: develop + GIT_CHECKOUT_BRANCH: v1.5.9 image: bsc-geth:docker-local diff --git a/e2e/chains/bsc/genesis/contracts/BSCValidatorSet.sol b/e2e/chains/bsc/genesis/contracts/BSCValidatorSet.sol index 2db490ed..314bde66 100644 --- a/e2e/chains/bsc/genesis/contracts/BSCValidatorSet.sol +++ b/e2e/chains/bsc/genesis/contracts/BSCValidatorSet.sol @@ -2,67 +2,42 @@ pragma solidity 0.6.4; pragma experimental ABIEncoderV2; import "./System.sol"; -import "./lib/BytesLib.sol"; -import "./lib/BytesToTypes.sol"; -import "./lib/Memory.sol"; -import "./interface/ILightClient.sol"; -import "./interface/ISlashIndicator.sol"; -import "./interface/ITokenHub.sol"; -import "./interface/IRelayerHub.sol"; -import "./interface/IParamSubscriber.sol"; -import "./interface/IBSCValidatorSet.sol"; -import "./interface/IApplication.sol"; -import "./interface/IStakeHub.sol"; -import "./lib/SafeMath.sol"; -import "./lib/RLPDecode.sol"; -import "./lib/CmnPkg.sol"; - -interface ICrossChain { - function registeredContractChannelMap(address, uint8) external view returns (bool); -} +import "./lib/0.6.x/BytesLib.sol"; +import "./lib/0.6.x/BytesToTypes.sol"; +import "./lib/0.6.x/Memory.sol"; +import "./interface/0.6.x/ISlashIndicator.sol"; +import "./interface/0.6.x/IParamSubscriber.sol"; +import "./interface/0.6.x/IBSCValidatorSet.sol"; +import "./interface/0.6.x/IApplication.sol"; +import "./interface/0.6.x/IStakeHub.sol"; +import "./lib/0.6.x/SafeMath.sol"; +import "./lib/0.6.x/RLPDecode.sol"; contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplication { using SafeMath for uint256; using RLPDecode for *; - // will not transfer value less than 0.1 BNB for validators - uint256 public constant DUSTY_INCOMING = 1e17; - - uint8 public constant JAIL_MESSAGE_TYPE = 1; - uint8 public constant VALIDATORS_UPDATE_MESSAGE_TYPE = 0; - - // the precision of cross chain value transfer. - uint256 public constant PRECISION = 1e10; - uint256 public constant EXPIRE_TIME_SECOND_GAP = 1000; - uint256 public constant MAX_NUM_OF_VALIDATORS = 100; - bytes public constant INIT_VALIDATORSET_BYTES = hex"f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000"; - uint32 public constant ERROR_UNKNOWN_PACKAGE_TYPE = 101; - uint32 public constant ERROR_FAIL_CHECK_VALIDATORS = 102; - uint32 public constant ERROR_LEN_OF_VAL_MISMATCH = 103; - uint32 public constant ERROR_RELAYFEE_TOO_LARGE = 104; - uint256 public constant INIT_NUM_OF_CABINETS = 21; - uint256 public constant EPOCH = 200; /*----------------- state of the contract -----------------*/ Validator[] public currentValidatorSet; - uint256 public expireTimeSecondGap; + uint256 public expireTimeSecondGap; // @dev deprecated uint256 public totalInComing; // key is the `consensusAddress` of `Validator`, // value is the index of the element in `currentValidatorSet`. mapping(address => uint256) public currentValidatorSetMap; - uint256 public numOfJailed; + uint256 public numOfJailed; // @dev deprecated uint256 public constant BLOCK_FEES_RATIO_SCALE = 10000; address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; uint256 public constant INIT_BURN_RATIO = 1000; uint256 public burnRatio; - bool public burnRatioInitialized; // deprecated + bool public burnRatioInitialized; // @dev deprecated // BEP-127 Temporary Maintenance uint256 public constant INIT_MAX_NUM_OF_MAINTAINING = 3; @@ -86,14 +61,14 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica uint256 public systemRewardBaseRatio; uint256 public previousHeight; - uint256 public previousBalanceOfSystemReward; // deprecated + uint256 public previousBalanceOfSystemReward; // @dev deprecated bytes[] public previousVoteAddrFullSet; bytes[] public currentVoteAddrFullSet; bool public isSystemRewardIncluded; // BEP-294 BC-fusion - Validator[] private _tmpMigratedValidatorSet; - bytes[] private _tmpMigratedVoteAddrs; + Validator[] private _tmpMigratedValidatorSet; // @dev deprecated + bytes[] private _tmpMigratedVoteAddrs; // @dev deprecated // BEP-341 Validators can produce consecutive blocks uint256 public turnLength; // Consecutive number of blocks a validator receives priority for block production @@ -119,8 +94,7 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica uint256[19] slots; } - /*----------------- cross chain package -----------------*/ - struct IbcValidatorSetPackage { + struct ValidatorSetPackage { uint8 packageType; Validator[] validatorSet; bytes[] voteAddrs; @@ -153,38 +127,38 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica /*----------------- events -----------------*/ event validatorSetUpdated(); - event validatorJailed(address indexed validator); - event validatorEmptyJailed(address indexed validator); - event batchTransfer(uint256 amount); - event batchTransferFailed(uint256 indexed amount, string reason); - event batchTransferLowerFailed(uint256 indexed amount, bytes reason); event systemTransfer(uint256 amount); - event directTransfer(address payable indexed validator, uint256 amount); - event directTransferFail(address payable indexed validator, uint256 amount); event deprecatedDeposit(address indexed validator, uint256 amount); event validatorDeposit(address indexed validator, uint256 amount); event validatorMisdemeanor(address indexed validator, uint256 amount); event validatorFelony(address indexed validator, uint256 amount); - event failReasonWithStr(string message); - event unexpectedPackage(uint8 channelId, bytes msgBytes); event paramChange(string key, bytes value); event feeBurned(uint256 amount); event validatorEnterMaintenance(address indexed validator); event validatorExitMaintenance(address indexed validator); event finalityRewardDeposit(address indexed validator, uint256 amount); event deprecatedFinalityRewardDeposit(address indexed validator, uint256 amount); - event tmpValidatorSetUpdated(uint256 validatorsNum); + + event validatorJailed(address indexed validator); // @dev deprecated + event validatorEmptyJailed(address indexed validator); // @dev deprecated + event batchTransfer(uint256 amount); // @dev deprecated + event batchTransferFailed(uint256 indexed amount, string reason); // @dev deprecated + event batchTransferLowerFailed(uint256 indexed amount, bytes reason); // @dev deprecated + event directTransfer(address payable indexed validator, uint256 amount); // @dev deprecated + event directTransferFail(address payable indexed validator, uint256 amount); // @dev deprecated + event failReasonWithStr(string message); // @dev deprecated + event unexpectedPackage(uint8 channelId, bytes msgBytes); // @dev deprecated + event tmpValidatorSetUpdated(uint256 validatorsNum); // @dev deprecated /*----------------- init -----------------*/ function init() external onlyNotInit { - (IbcValidatorSetPackage memory validatorSetPkg, bool valid) = - decodeValidatorSetSynPackage(INIT_VALIDATORSET_BYTES); + (ValidatorSetPackage memory validatorSetPkg, bool valid) = + decodeValidatorSet(INIT_VALIDATORSET_BYTES); require(valid, "failed to parse init validatorSet"); for (uint256 i; i < validatorSetPkg.validatorSet.length; ++i) { currentValidatorSet.push(validatorSetPkg.validatorSet[i]); currentValidatorSetMap[validatorSetPkg.validatorSet[i].consensusAddress] = i + 1; } - expireTimeSecondGap = EXPIRE_TIME_SECOND_GAP; alreadyInit = true; } @@ -195,49 +169,15 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica uint8, bytes calldata msgBytes ) external override onlyInit onlyCrossChainContract initValidatorExtraSet returns (bytes memory responsePayload) { - (IbcValidatorSetPackage memory validatorSetPackage, bool ok) = decodeValidatorSetSynPackage(msgBytes); - if (!ok) { - return CmnPkg.encodeCommonAckPackage(ERROR_FAIL_DECODE); - } - uint32 resCode; - if (validatorSetPackage.packageType == VALIDATORS_UPDATE_MESSAGE_TYPE) { - resCode = updateValidatorSet(validatorSetPackage.validatorSet, validatorSetPackage.voteAddrs); - } else if (validatorSetPackage.packageType == JAIL_MESSAGE_TYPE) { - if (validatorSetPackage.validatorSet.length != 1) { - emit failReasonWithStr("length of jail validators must be one"); - resCode = ERROR_LEN_OF_VAL_MISMATCH; - } else { - address validator = validatorSetPackage.validatorSet[0].consensusAddress; - uint256 index = currentValidatorSetMap[validator]; - if (index == 0 || currentValidatorSet[index - 1].jailed) { - emit validatorEmptyJailed(validator); - } else { - // felony will failed if the validator is the only one in the validator set - bool success = _felony(validator, index - 1); - if (!success) { - emit validatorEmptyJailed(validator); - } - } - resCode = CODE_OK; - } - } else { - resCode = ERROR_UNKNOWN_PACKAGE_TYPE; - } - if (resCode == CODE_OK) { - return new bytes(0); - } else { - return CmnPkg.encodeCommonAckPackage(resCode); - } + revert("deprecated"); } function handleAckPackage(uint8 channelId, bytes calldata msgBytes) external override onlyCrossChainContract { - // should not happen - emit unexpectedPackage(channelId, msgBytes); + revert("deprecated"); } function handleFailAckPackage(uint8 channelId, bytes calldata msgBytes) external override onlyCrossChainContract { - // should not happen - emit unexpectedPackage(channelId, msgBytes); + revert("deprecated"); } /*----------------- External Functions -----------------*/ @@ -262,35 +202,6 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica }); } - // if staking channel is not closed, store the migrated validator set and return - if ( - ICrossChain(CROSS_CHAIN_CONTRACT_ADDR).registeredContractChannelMap( - VALIDATOR_CONTRACT_ADDR, STAKING_CHANNELID - ) - ) { - uint256 newLength = _validatorSet.length; - uint256 oldLength = _tmpMigratedValidatorSet.length; - if (oldLength > newLength) { - for (uint256 i = newLength; i < oldLength; ++i) { - _tmpMigratedValidatorSet.pop(); - _tmpMigratedVoteAddrs.pop(); - } - } - - for (uint256 i; i < newLength; ++i) { - if (i >= oldLength) { - _tmpMigratedValidatorSet.push(_validatorSet[i]); - _tmpMigratedVoteAddrs.push(_voteAddrs[i]); - } else { - _tmpMigratedValidatorSet[i] = _validatorSet[i]; - _tmpMigratedVoteAddrs[i] = _voteAddrs[i]; - } - } - - emit tmpValidatorSetUpdated(newLength); - return; - } - // step 0: force all maintaining validators to exit `Temporary Maintenance` // - 1. validators exit maintenance // - 2. clear all maintainInfo @@ -315,7 +226,6 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica // step 3: do update validator set state totalInComing = 0; - numOfJailed = 0; if (validatorSetTemp.length != 0) { doUpdateState(validatorSetTemp, voteAddrsTemp); } @@ -387,7 +297,7 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica uint256 totalValue; uint256 balanceOfSystemReward = address(SYSTEM_REWARD_ADDR).balance; if (balanceOfSystemReward > MAX_SYSTEM_REWARD_BALANCE) { - // when a slash happens, theres will no rewards in some epochs, + // when a slash happens, theres will no rewards in some finalityReward intervals, // it's tolerated because slash happens rarely totalValue = balanceOfSystemReward.sub(MAX_SYSTEM_REWARD_BALANCE); } else { @@ -474,17 +384,19 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica function getMiningValidators() external view override returns (address[] memory, bytes[] memory) { uint256 _maxNumOfWorkingCandidates = maxNumOfWorkingCandidates; uint256 _numOfCabinets = numOfCabinets > 0 ? numOfCabinets : INIT_NUM_OF_CABINETS; + uint256 _shuffleInterval = 200; address[] memory validators = getValidators(); bytes[] memory voteAddrs = getVoteAddresses(validators); if (validators.length <= _numOfCabinets) { return (validators, voteAddrs); } + // remove unused shuffle address[] memory miningValidators = new address[](_numOfCabinets); bytes[] memory miningVoteAddrs = new bytes[](_numOfCabinets); // modify to rotate validators start - uint256 epochNumber = block.number / EPOCH; + uint256 epochNumber = block.number / _shuffleInterval; uint256 start = epochNumber % validators.length; uint256 target = start; for (uint i; i<_numOfCabinets; i++) { @@ -616,12 +528,7 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica } function removeTmpMigratedValidator(address validator) external onlyStakeHub { - for (uint256 i; i < _tmpMigratedValidatorSet.length; ++i) { - if (_tmpMigratedValidatorSet[i].consensusAddress == validator) { - _tmpMigratedValidatorSet[i].jailed = true; - break; - } - } + revert("deprecated"); } /*----------------- For Temporary Maintenance -----------------*/ @@ -679,15 +586,7 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica /*----------------- Param update -----------------*/ function updateParam(string calldata key, bytes calldata value) external override onlyInit onlyGov { - if (Memory.compareStrings(key, "expireTimeSecondGap")) { - require(value.length == 32, "length of expireTimeSecondGap mismatch"); - uint256 newExpireTimeSecondGap = BytesToTypes.bytesToUint256(32, value); - require( - newExpireTimeSecondGap >= 100 && newExpireTimeSecondGap <= 1e5, - "the expireTimeSecondGap is out of range" - ); - expireTimeSecondGap = newExpireTimeSecondGap; - } else if (Memory.compareStrings(key, "burnRatio")) { + if (Memory.compareStrings(key, "burnRatio")) { require(value.length == 32, "length of burnRatio mismatch"); uint256 newBurnRatio = BytesToTypes.bytesToUint256(32, value); require( @@ -731,9 +630,12 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica require(value.length == 32, "length of numOfCabinets mismatch"); uint256 newNumOfCabinets = BytesToTypes.bytesToUint256(32, value); require(newNumOfCabinets > 0, "the numOfCabinets must be greater than 0"); + + uint256 maxElectedValidators = IStakeHub(STAKE_HUB_ADDR).maxElectedValidators(); require( - newNumOfCabinets <= MAX_NUM_OF_VALIDATORS, "the numOfCabinets must be less than MAX_NUM_OF_VALIDATORS" + newNumOfCabinets <= maxElectedValidators, "the numOfCabinets must be less than maxElectedValidators" ); + numOfCabinets = newNumOfCabinets; } else if (Memory.compareStrings(key, "systemRewardBaseRatio")) { require(value.length == 32, "length of systemRewardBaseRatio mismatch"); @@ -755,8 +657,8 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica require(value.length == 32, "length of turnLength mismatch"); uint256 newTurnLength = BytesToTypes.bytesToUint256(32, value); require( - newTurnLength >= 3 && newTurnLength <= 9 || newTurnLength == 1, - "the turnLength should be in [3,9] or equal to 1" + newTurnLength >= 3 && newTurnLength <= 64 || newTurnLength == 1, + "the turnLength should be in [3,64] or equal to 1" ); turnLength = newTurnLength; } else { @@ -766,177 +668,6 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica } /*----------------- Internal Functions -----------------*/ - function updateValidatorSet(Validator[] memory validatorSet, bytes[] memory voteAddrs) internal returns (uint32) { - { - // do verify. - if (validatorSet.length > MAX_NUM_OF_VALIDATORS) { - emit failReasonWithStr("the number of validators exceed the limit"); - return ERROR_FAIL_CHECK_VALIDATORS; - } - for (uint256 i; i < validatorSet.length; ++i) { - for (uint256 j; j < i; ++j) { - if (validatorSet[i].consensusAddress == validatorSet[j].consensusAddress) { - emit failReasonWithStr("duplicate consensus address of validatorSet"); - return ERROR_FAIL_CHECK_VALIDATORS; - } - } - } - } - - // step 0: force all maintaining validators to exit `Temporary Maintenance` - // - 1. validators exit maintenance - // - 2. clear all maintainInfo - // - 3. get unjailed validators from validatorSet - Validator[] memory validatorSetTemp; - bytes[] memory voteAddrsTemp; - { - // get migrated validators - Validator[] memory bscValidatorSet = _tmpMigratedValidatorSet; - bytes[] memory bscVoteAddrs = _tmpMigratedVoteAddrs; - for (uint256 i; i < bscValidatorSet.length; ++i) { - bscValidatorSet[i].votingPower = bscValidatorSet[i].votingPower * 3; // amplify the voting power for BSC validators - } - (Validator[] memory mergedValidators, bytes[] memory mergedVoteAddrs) = - _mergeValidatorSet(validatorSet, voteAddrs, bscValidatorSet, bscVoteAddrs); - - (validatorSetTemp, voteAddrsTemp) = _forceMaintainingValidatorsExit(mergedValidators, mergedVoteAddrs); - } - - { - //step 1: do calculate distribution, do not make it as an internal function for saving gas. - uint256 crossSize; - uint256 directSize; - uint256 validatorsNum = currentValidatorSet.length; - uint8[] memory isMigrated = new uint8[](validatorsNum); - for (uint256 i; i < validatorsNum; ++i) { - if ( - IStakeHub(STAKE_HUB_ADDR).consensusToOperator(currentValidatorSet[i].consensusAddress) != address(0) - ) { - isMigrated[i] = 1; - if (currentValidatorSet[i].incoming != 0) { - ++directSize; - } - } else if (currentValidatorSet[i].incoming >= DUSTY_INCOMING) { - ++crossSize; - } else if (currentValidatorSet[i].incoming != 0) { - ++directSize; - } - } - - //cross transfer - address[] memory crossAddrs = new address[](crossSize); - uint256[] memory crossAmounts = new uint256[](crossSize); - uint256[] memory crossIndexes = new uint256[](crossSize); - address[] memory crossRefundAddrs = new address[](crossSize); - uint256 crossTotal; - // direct transfer - address payable[] memory directAddrs = new address payable[](directSize); - uint256[] memory directAmounts = new uint256[](directSize); - crossSize = 0; - directSize = 0; - uint256 relayFee = ITokenHub(TOKEN_HUB_ADDR).getMiniRelayFee(); - if (relayFee > DUSTY_INCOMING) { - emit failReasonWithStr("fee is larger than DUSTY_INCOMING"); - return ERROR_RELAYFEE_TOO_LARGE; - } - for (uint256 i; i < validatorsNum; ++i) { - if (isMigrated[i] == 1) { - if (currentValidatorSet[i].incoming != 0) { - directAddrs[directSize] = payable(currentValidatorSet[i].consensusAddress); - directAmounts[directSize] = currentValidatorSet[i].incoming; - isMigrated[directSize] = 1; // directSize must be less than i. so we can use directSize as index - ++directSize; - } - } else if (currentValidatorSet[i].incoming >= DUSTY_INCOMING) { - crossAddrs[crossSize] = currentValidatorSet[i].BBCFeeAddress; - uint256 value = currentValidatorSet[i].incoming - currentValidatorSet[i].incoming % PRECISION; - crossAmounts[crossSize] = value.sub(relayFee); - crossRefundAddrs[crossSize] = currentValidatorSet[i].feeAddress; - crossIndexes[crossSize] = i; - crossTotal = crossTotal.add(value); - ++crossSize; - } else if (currentValidatorSet[i].incoming != 0) { - directAddrs[directSize] = currentValidatorSet[i].feeAddress; - directAmounts[directSize] = currentValidatorSet[i].incoming; - isMigrated[directSize] = 0; - ++directSize; - } - } - - //step 2: do cross chain transfer - bool failCross = false; - if (crossTotal > 0) { - try ITokenHub(TOKEN_HUB_ADDR).batchTransferOutBNB{ value: crossTotal }( - crossAddrs, crossAmounts, crossRefundAddrs, uint64(block.timestamp + expireTimeSecondGap) - ) returns (bool success) { - if (success) { - emit batchTransfer(crossTotal); - } else { - emit batchTransferFailed(crossTotal, "batch transfer return false"); - } - } catch Error(string memory reason) { - failCross = true; - emit batchTransferFailed(crossTotal, reason); - } catch (bytes memory lowLevelData) { - failCross = true; - emit batchTransferLowerFailed(crossTotal, lowLevelData); - } - } - - if (failCross) { - for (uint256 i; i < crossIndexes.length; ++i) { - uint256 idx = crossIndexes[i]; - bool success = currentValidatorSet[idx].feeAddress.send(currentValidatorSet[idx].incoming); - if (success) { - emit directTransfer(currentValidatorSet[idx].feeAddress, currentValidatorSet[idx].incoming); - } else { - emit directTransferFail(currentValidatorSet[idx].feeAddress, currentValidatorSet[idx].incoming); - } - } - } - - // step 3: direct transfer - if (directAddrs.length > 0) { - for (uint256 i; i < directAddrs.length; ++i) { - if (isMigrated[i] == 1) { - IStakeHub(STAKE_HUB_ADDR).distributeReward{ value: directAmounts[i] }(directAddrs[i]); - } else { - bool success = directAddrs[i].send(directAmounts[i]); - if (success) { - emit directTransfer(directAddrs[i], directAmounts[i]); - } else { - emit directTransferFail(directAddrs[i], directAmounts[i]); - } - } - } - } - } - - for (uint256 i; i < currentValidatorSet.length; ++i) { - if (currentValidatorSet[i].incoming != 0) { - currentValidatorSet[i].incoming = 0; - } - } - - // step 4: do dusk transfer - if (address(this).balance > 0) { - emit systemTransfer(address(this).balance); - address(uint160(SYSTEM_REWARD_ADDR)).transfer(address(this).balance); - } - - // step 5: do update validator set state - totalInComing = 0; - numOfJailed = 0; - if (validatorSetTemp.length > 0) { - doUpdateState(validatorSetTemp, voteAddrsTemp); - } - - // step 6: clean slash contract - ISlashIndicator(SLASH_CONTRACT_ADDR).clean(); - emit validatorSetUpdated(); - return CODE_OK; - } - function doUpdateState(Validator[] memory newValidatorSet, bytes[] memory newVoteAddrs) private { uint256 n = currentValidatorSet.length; uint256 m = newValidatorSet.length; @@ -1007,19 +738,19 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica } /** - * @dev With each epoch, there will be a partial rotation between cabinets and candidates. Rotation is determined by this function + * @dev With each shuffle interval blocks, there will be a partial rotation between cabinets and candidates. Rotation is determined by this function */ function shuffle( address[] memory validators, bytes[] memory voteAddrs, - uint256 epochNumber, + uint256 shuffleNumber, uint256 startIdx, uint256 offset, uint256 limit, uint256 modNumber ) internal pure { for (uint256 i; i < limit; ++i) { - uint256 random = uint256(keccak256(abi.encodePacked(epochNumber, startIdx + i))) % modNumber; + uint256 random = uint256(keccak256(abi.encodePacked(shuffleNumber, startIdx + i))) % modNumber; if ((startIdx + i) != (offset + random)) { address tmpAddr = validators[startIdx + i]; bytes memory tmpBLS = voteAddrs[startIdx + i]; @@ -1308,11 +1039,7 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica isFelony = false; if (slashCount >= felonyThreshold) { _felony(validator, index); - if (IStakeHub(STAKE_HUB_ADDR).consensusToOperator(validator) != address(0)) { - ISlashIndicator(SLASH_CONTRACT_ADDR).downtimeSlash(validator, slashCount, shouldRevert); - } else { - ISlashIndicator(SLASH_CONTRACT_ADDR).sendFelonyPackage(validator); - } + ISlashIndicator(SLASH_CONTRACT_ADDR).downtimeSlash(validator, slashCount, shouldRevert); isFelony = true; } else if (slashCount >= misdemeanorThreshold) { _misdemeanor(validator); @@ -1321,71 +1048,12 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica emit validatorExitMaintenance(validator); } - function _mergeValidatorSet( - Validator[] memory validatorSet1, - bytes[] memory voteAddrSet1, - Validator[] memory validatorSet2, - bytes[] memory voteAddrSet2 - ) internal view returns (Validator[] memory, bytes[] memory) { - uint256 _length = IStakeHub(STAKE_HUB_ADDR).maxElectedValidators(); - if (validatorSet1.length + validatorSet2.length < _length) { - _length = validatorSet1.length + validatorSet2.length; - } - Validator[] memory mergedValidatorSet = new Validator[](_length); - bytes[] memory mergedVoteAddrSet = new bytes[](_length); - - uint256 i; - uint256 j; - uint256 k; - while ((i < validatorSet1.length || j < validatorSet2.length) && k < _length) { - if (i == validatorSet1.length) { - mergedValidatorSet[k] = validatorSet2[j]; - mergedVoteAddrSet[k] = voteAddrSet2[j]; - ++j; - ++k; - continue; - } - - if (j == validatorSet2.length) { - mergedValidatorSet[k] = validatorSet1[i]; - mergedVoteAddrSet[k] = voteAddrSet1[i]; - ++i; - ++k; - continue; - } - - if (validatorSet1[i].votingPower > validatorSet2[j].votingPower) { - mergedValidatorSet[k] = validatorSet1[i]; - mergedVoteAddrSet[k] = voteAddrSet1[i]; - ++i; - } else if (validatorSet1[i].votingPower < validatorSet2[j].votingPower) { - mergedValidatorSet[k] = validatorSet2[j]; - mergedVoteAddrSet[k] = voteAddrSet2[j]; - ++j; - } else { - if (validatorSet1[i].consensusAddress < validatorSet2[j].consensusAddress) { - mergedValidatorSet[k] = validatorSet1[i]; - mergedVoteAddrSet[k] = voteAddrSet1[i]; - ++i; - } else { - mergedValidatorSet[k] = validatorSet2[j]; - mergedVoteAddrSet[k] = voteAddrSet2[j]; - ++j; - } - } - ++k; - } - - return (mergedValidatorSet, mergedVoteAddrSet); - } - - //rlp encode & decode function - function decodeValidatorSetSynPackage(bytes memory msgBytes) + function decodeValidatorSet(bytes memory msgBytes) internal pure - returns (IbcValidatorSetPackage memory, bool) + returns (ValidatorSetPackage memory, bool) { - IbcValidatorSetPackage memory validatorSetPkg; + ValidatorSetPackage memory validatorSetPkg; RLPDecode.Iterator memory iter = msgBytes.toRLPItem().iterator(); bool success = false; diff --git a/e2e/chains/bsc/genesis/genesis-template.template b/e2e/chains/bsc/genesis/genesis-template.template index e7074ecf..5a62f795 100644 --- a/e2e/chains/bsc/genesis/genesis-template.template +++ b/e2e/chains/bsc/genesis/genesis-template.template @@ -46,11 +46,6 @@ "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 - }, - "lorentz": { - "target": 6, - "max": 9, - "baseFeeUpdateFraction": 5007716 } }, "parlia": { diff --git a/e2e/chains/bsc/genesis/scripts/init_holders.template b/e2e/chains/bsc/genesis/scripts/init_holders.template index 40129091..7e97d8d6 100644 --- a/e2e/chains/bsc/genesis/scripts/init_holders.template +++ b/e2e/chains/bsc/genesis/scripts/init_holders.template @@ -1,7 +1,7 @@ const web3 = require("web3") const addresses = "{{INIT_HOLDER_ADDRESSES}}" -const balance = web3.utils.toBN("{{INIT_HOLDER_BALANCE}}").toString("hex") +const balance = BigInt("{{INIT_HOLDER_BALANCE}}").toString(16) const init_holders = addresses.split(",").map(address => ({ address, balance })); exports = module.exports = init_holders diff --git a/module/fork_spec.go b/module/fork_spec.go index 38608715..1beafd6f 100644 --- a/module/fork_spec.go +++ b/module/fork_spec.go @@ -61,7 +61,7 @@ func GetForkParameters(network Network) []*ForkSpec { MaxTurnLength: 9, }, { - HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, + HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 1744097580 * 1000}, AdditionalHeaderItemCount: 1, EpochLength: 500, MaxTurnLength: 64, From 49dcb36c109c350e995a497afb50127e684202c6 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Mon, 7 Apr 2025 13:08:37 +0900 Subject: [PATCH 37/37] fix comment Signed-off-by: Naohiro Yoshida --- README.md | 2 +- module/setup.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1343dd61..72a07128 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ make proto-gen ## About ForkSpec -1. Set HF height as soon as possibile +1. Set HF height as soon as possible As soon as the HF height is determined, please modify the timestamp in the ForkSpec to the height as soon as possible. HF height is calculated from timestamp, but the further away from the HF, the longer it takes to calculate. diff --git a/module/setup.go b/module/setup.go index a67214f9..b7279900 100644 --- a/module/setup.go +++ b/module/setup.go @@ -10,6 +10,7 @@ import ( "github.com/hyperledger-labs/yui-relayer/log" ) +// Maximum header interval to be submitted to LCP const skip = 100 type queryVerifiableNeighboringEpochHeaderFn = func(context.Context, uint64, uint64) (core.Header, error) @@ -121,6 +122,7 @@ func setupHeadersForUpdate( return withTrustedHeight(append(targetHeaders, latestFinalizedHeader), clientStateLatestHeight), nil } +// Get verifiable headers. This method must be executed at block intervals that do not miss any epochs. func setupIntermediateHeader( ctx context.Context, queryVerifiableHeader queryVerifiableNeighboringEpochHeaderFn,