From 4f7f8a99d3e107ab1cf996dd472e37615085965f Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Wed, 6 Sep 2023 18:32:39 +0900 Subject: [PATCH] add testdata maker Signed-off-by: Naohiro Yoshida --- module/header.go | 2 +- module/header_test.go | 4 +- module/prover.go | 9 +- module/prover_mainnet_test.go | 122 -------------- module/prover_test.go | 2 +- tool/testdata/README.md | 6 +- tool/testdata/internal/create_misbehavior.go | 95 +++++------ .../testdata/internal/create_update_client.go | 150 ++++++++++++++++++ tool/testdata/main.go | 1 + 9 files changed, 207 insertions(+), 184 deletions(-) delete mode 100644 module/prover_mainnet_test.go create mode 100644 tool/testdata/internal/create_update_client.go diff --git a/module/header.go b/module/header.go index bb834f6..82403c3 100644 --- a/module/header.go +++ b/module/header.go @@ -68,7 +68,7 @@ func (h *Header) Account(path common.Address) (*types.StateAccount, error) { return verifyAccount(target, h.AccountProof, path) } -func extractValidatorSet(h *types.Header) ([][]byte, error) { +func ExtractValidatorSet(h *types.Header) ([][]byte, error) { extra := h.Extra if len(extra) < extraVanity+extraSeal { return nil, fmt.Errorf("invalid extra length : %d", h.Number.Uint64()) diff --git a/module/header_test.go b/module/header_test.go index 1cbc115..ead6b37 100644 --- a/module/header_test.go +++ b/module/header_test.go @@ -46,7 +46,7 @@ func (ts *HeaderTestSuite) TestNewHeaderSuccess() { target, err := header.DecodedTarget() ts.Require().NoError(err) ts.Require().Equal(target.Number, rawHeader.Number) - validator, err := extractValidatorSet(target) + validator, err := ExtractValidatorSet(target) ts.Require().NoError(err) ts.Require().Equal(len(validator), 21) ts.Require().NoError(header.ValidateBasic()) @@ -65,7 +65,7 @@ func (ts *HeaderTestSuite) TestExtractValidatorSet() { Number: big.NewInt(29835600), Extra: common.Hex2Bytes("d883010202846765746888676f312e31392e39856c696e7578000000110bea95071284214b9b9c85549ab3d2b972df0deef66ac2c9ab1757500d6f4fdee439b17cf8e43267f94bc759162fb68de676d2fe10cc4cde26dd06be7e345e9cbf4b1dbf86b262bc35552c16704d214347f29fa77f77da6d75d7c752b742ad4855bae330426b823e742da31f816cc83bc16d69a9134be0cfb4a1d17ec34f1b5b32d5c20440b8536b1e88f0f296c5d20b2a975c050e4220be276ace4892f4b41a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000980a75ecd1309ea12fa2ed87a8744fbfc9b863d589037a9ace3b590165ea1c0c5ac72bf600b7c88c1e435f41932c1132aae1bfa0bb68e46b96ccb12c3415e4d82af717d8a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0b973c2d38487e58fd6e145491b110080fb14ac915a0411fc78f19e09a399ddee0d20c63a75d8f930f1694544ad2dc01bb71b214cb885500844365e95cd9942c7276e7fd8a2750ec6dded3dcdc2f351782310b0eadc077db59abca0f0cd26776e2e7acb9f3bce40b1fa5221fd1561226c6263cc5ff474cf03cceff28abc65c9cbae594f725c80e12d96c9b86c3400e529bfe184056e257c07940bb664636f689e8d2027c834681f8f878b73445261034e946bb2d901b4b878f8b27bb860a140cc9c8cc07d4ddf366440d9784efc88743d26af40f8956dd1c3501e560f745910bb14a5ec392f53cf78ddc2d2d69a146af287f7e079c3cbbfd3d446836d9b9397aa9a803b6c6b4f1cfc50baddbe2378cf194da35b9f4a1a32850114f1c5d9f84c8401c7414ea049d2e0876f51ce4693892331f8344a102aad88eb9e9bcfaa247cc9f898d1f8008401c7414fa0cf8d34727ff1d895bb49ca4be60c3b24d98d8afa9ce78644924e4b9aa39df8548022dc981e8703d3ca8b23fc032089667cb631cb28c32731762813bbf9fdb7e7a56b3945d65f2d72402a2abb9fbaf4bf094a3e5a542e175ecc54b426ee366b2ba200"), } - validators, err := extractValidatorSet(testnetHeader) + validators, err := ExtractValidatorSet(testnetHeader) ts.Require().NoError(err) ts.Require().Len(validators, 7) ts.Require().Equal(common.Bytes2Hex(validators[0]), "1284214b9b9c85549ab3d2b972df0deef66ac2c9ab1757500d6f4fdee439b17cf8e43267f94bc759162fb68de676d2fe10cc4cde26dd06be7e345e9cbf4b1dbf86b262bc") diff --git a/module/prover.go b/module/prover.go index f5096b7..e360a05 100644 --- a/module/prover.go +++ b/module/prover.go @@ -101,7 +101,7 @@ func (pr *Prover) CreateMsgCreateClient(_ string, dstHeader core.Header, _ sdk.A if err != nil { return nil, err } - previousValidators, err := extractValidatorSet(previousEpochHeader) + previousValidators, err := ExtractValidatorSet(previousEpochHeader) if err != nil { return nil, err } @@ -134,9 +134,6 @@ func (pr *Prover) CreateMsgCreateClient(_ string, dstHeader core.Header, _ sdk.A // Since ibc handler may not be deployed at the target epoch when create_client is used, state_root is not obtained. StateRoot: pr.getStateRootOrEmpty(previousEpochHeader).Bytes(), } - if pr.config.Debug { - log.Printf("initialConsensusState timestamp=%d, validatorHash=%s, validatorSize=%d", previousEpochHeader.Time, common.Bytes2Hex(consensusState.ValidatorsHash), len(previousValidators)) - } anyConsensusState, err := codectypes.NewAnyWithValue(&consensusState) if err != nil { return nil, err @@ -204,7 +201,7 @@ func (pr *Prover) SetupHeadersForUpdateByLatestHeight(clientStateLatestHeight ex parentValidatorsHash := common.Bytes2Hex(crypto.Keccak256(h.(*Header).ParentValidators...)) target, _ := h.(*Header).DecodedTarget() if target.Number.Uint64()%constant.BlocksPerEpoch == 0 { - newValidators, _ := extractValidatorSet(target) + newValidators, _ := ExtractValidatorSet(target) newValidatorsHash := common.Bytes2Hex(crypto.Keccak256(newValidators...)) log.Printf("SetupHeadersForUpdate: targetHeight=%v, trustedHeight=%v targetValidatorsHash=%s, parentValidatorsHash=%s, newValidatorsHash=%s\n", h.GetHeight(), trustedHeight, targetValidatorsHash, parentValidatorsHash, newValidatorsHash) } else { @@ -304,7 +301,7 @@ func (pr *Prover) queryValidatorSet(epochBlockNumber uint64) ([][]byte, error) { if err != nil { return nil, err } - return extractValidatorSet(header) + return ExtractValidatorSet(header) } // newETHHeader returns the new ETHHeader diff --git a/module/prover_mainnet_test.go b/module/prover_mainnet_test.go deleted file mode 100644 index 56bf75e..0000000 --- a/module/prover_mainnet_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package module - -import ( - "github.com/datachainlab/ibc-parlia-relay/module/constant" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "log" - "testing" - - "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - "github.com/datachainlab/ethereum-ibc-relay-chain/pkg/relay/ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/suite" -) - -type ProverMainnetTestSuite struct { - suite.Suite - prover *Prover -} - -func TestProverMainnetTestSuite(t *testing.T) { - suite.Run(t, new(ProverMainnetTestSuite)) -} - -func (ts *ProverMainnetTestSuite) SetupTest() { - chain, err := ethereum.NewChain(ethereum.ChainConfig{ - EthChainId: 56, - // We can get accountProof by eth_geProof only from AllThatNode - RpcAddr: "https://bsc-mainnet-rpc.allthatnode.com", - HdwMnemonic: hdwMnemonic, - HdwPath: hdwPath, - // TODO change address after starting mainnet test - IbcAddress: "0x151f3951FA218cac426edFe078fA9e5C6dceA500", - }) - ts.Require().NoError(err) - - config := ProverConfig{ - Debug: true, - } - ts.prover = NewProver(NewChain(chain), &config).(*Prover) -} - -func (ts *ProverMainnetTestSuite) TestQueryLatestFinalizedHeader() { - latestHeight, err := ts.prover.chain.LatestHeight() - ts.Require().NoError(err) - latest := latestHeight.GetRevisionHeight() - println(latest) - iHeader, err := ts.prover.GetLatestFinalizedHeaderByLatestHeight(31494202) - ts.Require().NoError(err) - ts.Require().NoError(iHeader.ValidateBasic()) - - header := iHeader.(*Header) - - // target header - target, err := header.DecodedTarget() - ts.Require().NoError(err) - parent, err := header.DecodedParent() - ts.Require().NoError(err) - ts.Require().Equal(target.Number.Int64()-1, parent.Number.Int64()) - - // headers to verify - if target.Number.Uint64()%200 == 0 { - validators, err := extractValidatorSet(target) - ts.Require().NoError(err) - ts.Require().Len(validators, 21) - } - - // account proof - account, err := header.Account(ts.prover.chain.IBCAddress()) - ts.Require().NoError(err) - ts.Require().NotEqual(account.Root, common.Hash{}) - log.Println(account.Root) - - // setup - updating, err := ts.prover.SetupHeadersForUpdateByLatestHeight(types.NewHeight(header.GetHeight().GetRevisionNumber(), target.Number.Uint64()-1), header) - ts.Require().NoError(err) - ts.Require().Len(updating, 1) - ts.Require().Equal(updating[0].(*Header).GetHeight(), header.GetHeight()) - - // updating msg - pack, err := types.PackClientMessage(updating[0]) - ts.Require().NoError(err) - marshal, err := pack.Marshal() - ts.Require().NoError(err) - log.Println("header", common.Bytes2Hex(marshal)) - - // misbehavior - misbehavior := Misbehaviour{ - ClientId: "xx-parlia-1", - Header_1: updating[0].(*Header), - Header_2: updating[0].(*Header), - } - pack, _ = types.PackClientMessage(&misbehavior) - marshal, _ = pack.Marshal() - log.Println("misbehavior", common.Bytes2Hex(marshal)) - - // misbehavior(collapsed) - header2, _ := ts.prover.GetLatestFinalizedHeaderByLatestHeight(latest) - updating2, _ := ts.prover.SetupHeadersForUpdateByLatestHeight(types.NewHeight(header2.GetHeight().GetRevisionNumber(), target.Number.Uint64()-1), header2.(*Header)) - target2, _ := updating2[0].(*Header).DecodedTarget() - target2.Root = common.Hash{} - rlpTarget, err := rlp.EncodeToBytes(target2) - ts.Require().NoError(err) - updating2[0].(*Header).Target = ÐHeader{Header: rlpTarget} - misbehavior2 := Misbehaviour{ - ClientId: "xx-parlia-1", - Header_1: updating[0].(*Header), - Header_2: updating2[0].(*Header), - } - pack, _ = types.PackClientMessage(&misbehavior2) - marshal, _ = pack.Marshal() - log.Println("misbehavior2", common.Bytes2Hex(marshal)) - - // validators hash - log.Println("target_validator_hash", common.Bytes2Hex(crypto.Keccak256(header.TargetValidators...))) - log.Println("parent_validator_hash", common.Bytes2Hex(crypto.Keccak256(header.ParentValidators...))) - if target.Number.Uint64()%constant.BlocksPerEpoch == 0 { - newValidators, err := extractValidatorSet(target) - ts.Require().NoError(err) - log.Println("new_validator_hash", common.Bytes2Hex(crypto.Keccak256(newValidators...))) - } -} diff --git a/module/prover_test.go b/module/prover_test.go index 7619002..8424de4 100644 --- a/module/prover_test.go +++ b/module/prover_test.go @@ -198,7 +198,7 @@ func (ts *ProverTestSuite) TestCreateMsgCreateClient() { ts.Require().NoError(proto.Unmarshal(msg.ConsensusState.Value, &cs2)) target, err := previousEpochHeader.DecodedTarget() ts.Require().NoError(err) - validatorSet, err := extractValidatorSet(target) + validatorSet, err := ExtractValidatorSet(target) ts.Require().NoError(err) ts.Require().Equal(cs2.ValidatorsHash, crypto.Keccak256(validatorSet...)) ts.Require().Equal(cs2.Timestamp, target.Time) diff --git a/tool/testdata/README.md b/tool/testdata/README.md index f87eec9..1310e26 100644 --- a/tool/testdata/README.md +++ b/tool/testdata/README.md @@ -6,21 +6,17 @@ go run main.go misbehavior success # src/client.rs test_error_submit_misbehavior -# src/misbehavior.rs test_error_try_from_any go run main.go misbehavior error ``` ### Header ```sh # src/client.rs test_success_update_client_epoch -# src/header/mod.rs test_success_verify_epoch go run main.go header success epoch # src/client.rs test_success_update_client_non_epoch -# src/header/mod.rs test_success_verify_non_epoch -go run main.go header success non_epoch +go run main.go header success latest # src/client.rs test_error_update_client -# src/header/mod.rs test_error_verify go run main.go header error ``` \ No newline at end of file diff --git a/tool/testdata/internal/create_misbehavior.go b/tool/testdata/internal/create_misbehavior.go index b628d7f..e818bc7 100644 --- a/tool/testdata/internal/create_misbehavior.go +++ b/tool/testdata/internal/create_misbehavior.go @@ -19,6 +19,7 @@ const ( IbcAddress = "0x702E40245797c5a2108A566b3CE2Bf14Bc6aF841" LocalNetValidatorSize = 3 MainNetValidatorSize = 21 + MainNetIbcAddress = "0x151f3951FA218cac426edFe078fA9e5C6dceA500" ) func CreateMisbehavior() *cobra.Command { @@ -26,22 +27,22 @@ func CreateMisbehavior() *cobra.Command { Use: "misbehavior", Short: "Create testdata for misbehavior. ", } - cmd.AddCommand(successCmd()) - cmd.AddCommand(errorCmd()) + cmd.AddCommand(misbehaviorSuccessCmd()) + cmd.AddCommand(misbehaviorErrorCmd()) return cmd } -func successCmd() *cobra.Command { +func misbehaviorSuccessCmd() *cobra.Command { return &cobra.Command{ Use: "success", Short: "create misbehavior testdata for success", RunE: func(cmd *cobra.Command, args []string) error { chainID := int64(9999) - targetHeight, header1, err := getHeader(chainID, 8645, 0) + targetHeight, header1, err := getLocalHeader(chainID, 8645, 0) if err != nil { log.Panic(err) } - _, header2, err := getHeader(chainID, 8545, targetHeight) + _, header2, err := getLocalHeader(chainID, 8545, targetHeight) if err != nil { log.Panic(err) } @@ -70,47 +71,7 @@ func successCmd() *cobra.Command { } } -func getHeader(chainID int64, port int64, targetHeight uint64) (uint64, *module.Header, error) { - chain, err := ethereum.NewChain(ethereum.ChainConfig{ - EthChainId: chainID, - RpcAddr: fmt.Sprintf("http://localhost:%d", port), - HdwMnemonic: hdwMnemonic, - HdwPath: hdwPath, - IbcAddress: IbcAddress, - }) - if err != nil { - return targetHeight, nil, err - } - if targetHeight == 0 { - latest, err := chain.LatestHeight() - if err != nil { - return targetHeight, nil, err - } - targetHeight = latest.GetRevisionHeight() - } - config := module.ProverConfig{ - Debug: true, - } - prover := module.NewProver(module.NewChain(chain), &config).(*module.Prover) - - // Get Finalized header - latestHeight := types.NewHeight(0, targetHeight) - latest := latestHeight.GetRevisionHeight() - iHeader, err := prover.GetLatestFinalizedHeaderByLatestHeight(latest) - if err != nil { - return latest, nil, err - } - header := iHeader.(*module.Header) - target, err := header.DecodedTarget() - if err != nil { - return latest, nil, err - } - trustedHeight := types.NewHeight(0, target.Number.Uint64()-5) - header.TrustedHeight = &trustedHeight - return latest, header, nil -} - -func errorCmd() *cobra.Command { +func misbehaviorErrorCmd() *cobra.Command { return &cobra.Command{ Use: "error", Short: "create misbehavior testdata for error", @@ -120,7 +81,7 @@ func errorCmd() *cobra.Command { RpcAddr: "https://bsc-mainnet-rpc.allthatnode.com", HdwMnemonic: hdwMnemonic, HdwPath: hdwPath, - IbcAddress: "0x151f3951FA218cac426edFe078fA9e5C6dceA500", + IbcAddress: MainNetIbcAddress, }) if err != nil { return err @@ -184,3 +145,43 @@ func errorCmd() *cobra.Command { }, } } + +func getLocalHeader(chainID int64, port int64, targetHeight uint64) (uint64, *module.Header, error) { + chain, err := ethereum.NewChain(ethereum.ChainConfig{ + EthChainId: chainID, + RpcAddr: fmt.Sprintf("http://localhost:%d", port), + HdwMnemonic: hdwMnemonic, + HdwPath: hdwPath, + IbcAddress: IbcAddress, + }) + if err != nil { + return targetHeight, nil, err + } + if targetHeight == 0 { + latest, err := chain.LatestHeight() + if err != nil { + return targetHeight, nil, err + } + targetHeight = latest.GetRevisionHeight() + } + config := module.ProverConfig{ + Debug: true, + } + prover := module.NewProver(module.NewChain(chain), &config).(*module.Prover) + + // Get Finalized header + latestHeight := types.NewHeight(0, targetHeight) + latest := latestHeight.GetRevisionHeight() + iHeader, err := prover.GetLatestFinalizedHeaderByLatestHeight(latest) + if err != nil { + return latest, nil, err + } + header := iHeader.(*module.Header) + target, err := header.DecodedTarget() + if err != nil { + return latest, nil, err + } + trustedHeight := types.NewHeight(0, target.Number.Uint64()-5) + header.TrustedHeight = &trustedHeight + return latest, header, nil +} diff --git a/tool/testdata/internal/create_update_client.go b/tool/testdata/internal/create_update_client.go new file mode 100644 index 0000000..82352eb --- /dev/null +++ b/tool/testdata/internal/create_update_client.go @@ -0,0 +1,150 @@ +package internal + +import ( + "fmt" + "github.com/cosmos/ibc-go/v7/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/crypto" + "github.com/hyperledger-labs/yui-relayer/core" + "github.com/spf13/cobra" + "log" +) + +func CreateUpdateClient() *cobra.Command { + cmd := &cobra.Command{ + Use: "update", + Short: "Create testdata for update client. ", + } + cmd.AddCommand(updateClientSuccessCmd()) + cmd.AddCommand(updateClientErrorCmd()) + return cmd +} + +func updateClientSuccessCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "success", + Short: "create updateClient testdata for success", + } + cmd.AddCommand(&cobra.Command{ + Use: "latest", + Short: "for latest block", + RunE: func(cmd *cobra.Command, args []string) error { + prover, chain, err := createMainnetProver() + if err != nil { + return err + } + latest, err := chain.LatestHeight() + if err != nil { + return err + } + return printMainnetHeader(prover, latest.GetRevisionHeight()) + }, + }) + cmd.AddCommand(&cobra.Command{ + Use: "epoch", + Short: "for epoch block", + RunE: func(cmd *cobra.Command, args []string) error { + prover, chain, err := createMainnetProver() + if err != nil { + return err + } + latest, err := chain.LatestHeight() + if err != nil { + return err + } + epochCount := latest.GetRevisionHeight() / constant.BlocksPerEpoch + return printMainnetHeader(prover, epochCount*constant.BlocksPerEpoch+2) + }, + }) + return cmd +} + +func updateClientErrorCmd() *cobra.Command { + return &cobra.Command{ + Use: "error", + Short: "create updateClient testdata for error", + RunE: func(cmd *cobra.Command, args []string) error { + return nil + }, + } +} +func printMainnetHeader(prover *module.Prover, height uint64) error { + log.Println("printMainnetHeader latest=", height) + iHeader, err := prover.GetLatestFinalizedHeaderByLatestHeight(height) + if err != nil { + return err + } + if err = iHeader.ValidateBasic(); err != nil { + return err + } + header := iHeader.(*module.Header) + target, err := header.DecodedTarget() + if err != nil { + return err + } + + account, err := header.Account(common.HexToAddress(MainNetIbcAddress)) + if err != nil { + return err + } + + // setup + updating, err := prover.SetupHeadersForUpdateByLatestHeight(types.NewHeight(header.GetHeight().GetRevisionNumber(), target.Number.Uint64()-1), header) + if err != nil { + return err + } + + // updating msg + pack, err := types.PackClientMessage(updating[0]) + if err != nil { + return err + } + marshal, err := pack.Marshal() + if err != nil { + return err + } + log.Println("header", common.Bytes2Hex(marshal)) + log.Println("stateRoot", account.Root) + log.Println("height", header.GetHeight().GetRevisionHeight()) + log.Println("trustedHeight", header.TrustedHeight.GetRevisionHeight()) + epochCount := header.GetHeight().GetRevisionHeight() / constant.BlocksPerEpoch + log.Println("currentEpochHeight", epochCount*constant.BlocksPerEpoch) + + // validators hash + log.Println("target_validator_size", len(header.TargetValidators)) + log.Println("target_validator_hash", common.Bytes2Hex(crypto.Keccak256(header.TargetValidators...))) + if target.Number.Uint64()%constant.BlocksPerEpoch == 0 { + newValidators, err := module.ExtractValidatorSet(target) + if err != nil { + return err + } + if len(newValidators) != MainNetValidatorSize { + return fmt.Errorf("invalid validator size for test") + } + log.Println("new_validator_hash", common.Bytes2Hex(crypto.Keccak256(newValidators...))) + log.Println("new_validator_size", len(newValidators)) + } + return nil +} + +func createMainnetProver() (*module.Prover, core.Chain, error) { + chain, err := ethereum.NewChain(ethereum.ChainConfig{ + EthChainId: 56, + RpcAddr: "https://bsc-mainnet-rpc.allthatnode.com", + HdwMnemonic: hdwMnemonic, + HdwPath: hdwPath, + IbcAddress: MainNetIbcAddress, + }) + if err != nil { + return nil, chain, err + } + + config := module.ProverConfig{ + Debug: true, + } + ec := module.NewChain(chain) + return module.NewProver(ec, &config).(*module.Prover), chain, nil +} diff --git a/tool/testdata/main.go b/tool/testdata/main.go index 10cb96e..a062ee8 100644 --- a/tool/testdata/main.go +++ b/tool/testdata/main.go @@ -12,6 +12,7 @@ func main() { var rootCmd = &cobra.Command{} rootCmd.AddCommand(internal.CreateMisbehavior()) + rootCmd.AddCommand(internal.CreateUpdateClient()) if err := rootCmd.ExecuteContext(context.Background()); err != nil { log.Panicf("Failed to run command : %+v", err)