From 0ca3a5334fc08eec67259bbd612d9e1d2ed02735 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Mon, 7 Oct 2024 17:22:44 -0500 Subject: [PATCH 01/34] wip --- scripts/local/e2e_test.sh | 3 +- .../validator-manager/erc20_token_staking.go | 12 ++--- tests/utils/chain.go | 11 ++++- tests/utils/validator_manager.go | 47 ++++++++++++++----- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index f45c931d2..16ddc818b 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -20,7 +20,8 @@ rm -rf $BASEDIR/avalanchego BASEDIR=$BASEDIR AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego "${TELEPORTER_PATH}/scripts/install_avalanchego_release.sh" BASEDIR=$BASEDIR "${TELEPORTER_PATH}/scripts/install_subnetevm_release.sh" -cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +# cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +cp /Users/cameron.schultz/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy echo "Copied ${BASEDIR}/subnet-evm/subnet-evm binary to ${BASEDIR}/avalanchego/plugins/" export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 71292725f..3abb97f18 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -2,6 +2,7 @@ package staking import ( "context" + "log" "sort" "time" @@ -12,7 +13,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/warp/message" "github.com/ava-labs/subnet-evm/accounts/abi/bind" - subnetEvmUtils "github.com/ava-labs/subnet-evm/tests/utils" "github.com/ava-labs/teleporter/tests/interfaces" "github.com/ava-labs/teleporter/tests/utils" . "github.com/onsi/gomega" @@ -130,6 +130,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { }, } + log.Println("Issuing ConvertSubnetTx") _, err = network.GetPChainWallet().IssueConvertSubnetTx( subnetAInfo.SubnetID, subnetAInfo.BlockchainID, @@ -140,15 +141,10 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { utils.PChainProposerVMWorkaround(network) - // Issue txs on the subnet to advance the proposer vm - for i := 0; i < 5; i++ { - err = subnetEvmUtils.IssueTxsToActivateProposerVMFork( - ctx, subnetAInfo.EVMChainID, fundedKey, subnetAInfo.WSClient, - ) - Expect(err).Should(BeNil()) - } + utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) // Initialize the validator set on the subnet + log.Println("Initializing validator set") _ = utils.InitializeERC20TokenValidatorSet( ctx, fundedKey, diff --git a/tests/utils/chain.go b/tests/utils/chain.go index 5469d8f10..61b3d33eb 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -539,7 +539,14 @@ func InstantiateGenesisTemplate( // func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.SignatureAggregator { - logger := logging.NoLog{} + logger := logging.NewLogger( + "test-debug", + logging.NewWrappedCore( + logging.Debug, + os.Stdout, + logging.JSON.ConsoleEncoder(), + ), + ) cfg := sigAggConfig.Config{ PChainAPI: &relayerConfig.APIConfig{ BaseURL: apiUri, @@ -560,7 +567,7 @@ func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.Signatu Expect(err).Should(BeNil()) messageCreator, err := message.NewCreator( - logger, + logging.NoLog{}, registry, constants.DefaultNetworkCompressionType, constants.DefaultNetworkMaximumInboundTimeout, diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 0dcac85b1..92fd128c6 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/precompile/contracts/warp" predicateutils "github.com/ava-labs/subnet-evm/predicate" + subnetEvmUtils "github.com/ava-labs/subnet-evm/tests/utils" exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" erc20tokenstakingmanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/ERC20TokenStakingManager" examplerewardcalculator "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/ExampleRewardCalculator" @@ -827,6 +828,7 @@ func InitializeAndCompleteERC20ValidatorRegistration( // Initiate validator registration var receipt *types.Receipt + log.Println("Initializing validator registration") receipt, validationID := InitializeERC20ValidatorRegistration( ctx, fundedKey, @@ -858,14 +860,15 @@ func InitializeAndCompleteERC20ValidatorRegistration( // blsPublicKey, // ) _, err := network.GetPChainWallet().IssueRegisterSubnetValidatorTx( - units.Avax, + 100*units.Avax, node.NodePoP.ProofOfPossession, signedWarpMessage.Bytes(), ) Expect(err).Should(BeNil()) PChainProposerVMWorkaround(network) - + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator registration") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, expiry, @@ -1399,6 +1402,7 @@ func InitializeAndCompleteEndERC20Validation( weight uint64, nonce uint64, ) { + log.Println("Initializing validator removal") WaitMinStakeDuration(ctx, subnetInfo, fundedKey) receipt := ForceInitializeEndERC20Validation( ctx, @@ -1422,7 +1426,7 @@ func InitializeAndCompleteEndERC20Validation( unsignedMessage, nil, subnetInfo.SubnetID, - 67, + 100, ) Expect(err).Should(BeNil()) log.Println("SetSubnetValidatorWeightMessage") @@ -1433,7 +1437,11 @@ func InitializeAndCompleteEndERC20Validation( // Deliver the Warp message to the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) PChainProposerVMWorkaround(network) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator removal") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, expiry, @@ -1456,12 +1464,12 @@ func InitializeAndCompleteEndERC20Validation( ) // Check that the validator is has been delisted from the staking contract - registrationEvent, err := GetEventFromLogs( + validationEndedEvent, err := GetEventFromLogs( receipt.Logs, stakingManager.ParseValidationPeriodEnded, ) Expect(err).Should(BeNil()) - Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) } func InitializeAndCompleteEndPoAValidation( @@ -1573,13 +1581,16 @@ func ConstructSubnetValidatorRegistrationMessage( registrationUnsignedMessage, justification.Bytes(), subnet.SubnetID, - 67, + 100, ) - log.Println("registrationSignedMessage") - log.Println(registrationSignedMessage.Signature.NumSigners()) - log.Println(registrationSignedMessage.Signature.String()) - log.Println(registrationSignedMessage.SourceChainID.String()) Expect(err).Should(BeNil()) + log.Println("SubnetValidatorRegistrationMessage") + log.Printf("valid=%t", valid) + numSigners, err := registrationSignedMessage.Signature.NumSigners() + Expect(err).Should(BeNil()) + log.Println("numSigners", numSigners) + log.Println("signature", registrationSignedMessage.Signature.String()) + log.Println("sourceChain", registrationSignedMessage.SourceChainID.String()) return registrationSignedMessage } @@ -1638,7 +1649,7 @@ func ConstructSubnetConversionMessage( subnetConversionUnsignedMessage, subnet.SubnetID[:], subnet.SubnetID, - 67, + 100, ) Expect(err).Should(BeNil()) return subnetConversionSignedMessage @@ -1893,3 +1904,17 @@ func PChainProposerVMWorkaround( Expect(err).Should(BeNil()) // End workaround } + +func AdvanceProposerVM( + ctx context.Context, + subnet interfaces.SubnetTestInfo, + fundedKey *ecdsa.PrivateKey, + blocks int, +) { + for i := 0; i < blocks; i++ { + err := subnetEvmUtils.IssueTxsToActivateProposerVMFork( + ctx, subnet.EVMChainID, fundedKey, subnet.WSClient, + ) + Expect(err).Should(BeNil()) + } +} From 2207e65cb2b4d8e5de7841661f12aa6db7376b21 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 8 Oct 2024 06:17:16 -0500 Subject: [PATCH 02/34] use tagged subnet-evm --- scripts/local/e2e_test.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index 16ddc818b..f45c931d2 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -20,8 +20,7 @@ rm -rf $BASEDIR/avalanchego BASEDIR=$BASEDIR AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego "${TELEPORTER_PATH}/scripts/install_avalanchego_release.sh" BASEDIR=$BASEDIR "${TELEPORTER_PATH}/scripts/install_subnetevm_release.sh" -# cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy -cp /Users/cameron.schultz/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy echo "Copied ${BASEDIR}/subnet-evm/subnet-evm binary to ${BASEDIR}/avalanchego/plugins/" export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego From b553d96094bff5c5f695aa2506ee061165e28823 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 8 Oct 2024 13:41:33 -0500 Subject: [PATCH 03/34] lengthen timeout --- tests/utils/chain.go | 9 +++------ tests/utils/validator_manager.go | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/utils/chain.go b/tests/utils/chain.go index 61b3d33eb..4244a4bf0 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -214,7 +214,7 @@ func waitForTransaction( txHash common.Hash, success bool, ) *types.Receipt { - cctx, cancel := context.WithTimeout(ctx, 10*time.Second) + cctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() receipt, err := WaitMined(cctx, subnetInfo.RPCClient, txHash) @@ -317,10 +317,7 @@ func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash co // Takes a tx hash instead of the full tx in the subnet-evm version of this function. // Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { - cctx, cancel := context.WithTimeout(ctx, 20*time.Second) - defer cancel() - - receipt, err := waitForTransactionReceipt(cctx, rpcClient, txHash) + receipt, err := waitForTransactionReceipt(ctx, rpcClient, txHash) if err != nil { return nil, err } @@ -332,7 +329,7 @@ func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Ha // configured to return the lowest value currently returned by any node behind the load balancer, so waiting for // it to be at least as high as the block height specified in the receipt should provide a relatively strong // indication that the transaction has been seen widely throughout the network. - err = waitForBlockHeight(cctx, rpcClient, receipt.BlockNumber.Uint64()) + err = waitForBlockHeight(ctx, rpcClient, receipt.BlockNumber.Uint64()) if err != nil { return nil, err } diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 92fd128c6..e678d57a0 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -1437,7 +1437,6 @@ func InitializeAndCompleteEndERC20Validation( // Deliver the Warp message to the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) PChainProposerVMWorkaround(network) - PChainProposerVMWorkaround(network) AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain From f90c70d9d5822d9e41f7c33d802ed4af242622e5 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 8 Oct 2024 17:23:14 -0500 Subject: [PATCH 04/34] new justification format --- go.mod | 2 +- go.sum | 2 + scripts/local/e2e_test.sh | 3 +- .../validator-manager/erc20_token_staking.go | 88 +++++----- tests/utils/chain.go | 4 + tests/utils/validator_manager.go | 151 ++++++++++++++++-- 6 files changed, 194 insertions(+), 56 deletions(-) diff --git a/go.mod b/go.mod index b5f26550b..2bb91e6ad 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ava-labs/teleporter go 1.22.8 require ( - github.com/ava-labs/avalanchego v1.12.0-initial-poc.3 + github.com/ava-labs/avalanchego v1.12.0-initial-poc.4 github.com/supranational/blst v0.3.11 // indirect ) diff --git a/go.sum b/go.sum index 2cbb2c7e3..06a4b5cce 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ava-labs/avalanchego v1.12.0-initial-poc.3 h1:JfVooBCdMzpeGUT9/phJNl2GHflkGehlMJokXeWKa2A= github.com/ava-labs/avalanchego v1.12.0-initial-poc.3/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= +github.com/ava-labs/avalanchego v1.12.0-initial-poc.4 h1:0g1+aJS6f4I2m8oEF3djlfyNbL9UrQTS+6A0eXbRLtM= +github.com/ava-labs/avalanchego v1.12.0-initial-poc.4/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6 h1:v7k5wQxcvnYcMaz+zoO1OLAcU8REDD1EhfPZdl4Q+aI= github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6/go.mod h1:sSXpQtgiduMdZw5IVTSa1v418VCjb8GDLyrcGwJZ/HE= github.com/ava-labs/coreth v0.13.8 h1:f14X3KgwHl9LwzfxlN6S4bbn5VA2rhEsNnHaRLSTo/8= diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index f45c931d2..16ddc818b 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -20,7 +20,8 @@ rm -rf $BASEDIR/avalanchego BASEDIR=$BASEDIR AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego "${TELEPORTER_PATH}/scripts/install_avalanchego_release.sh" BASEDIR=$BASEDIR "${TELEPORTER_PATH}/scripts/install_subnetevm_release.sh" -cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +# cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +cp /Users/cameron.schultz/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy echo "Copied ${BASEDIR}/subnet-evm/subnet-evm binary to ${BASEDIR}/avalanchego/plugins/" export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 3abb97f18..10c57baa0 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -94,31 +94,13 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { destAddrStr := "P-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u" destAddr, err := address.ParseToID(destAddrStr) Expect(err).Should(BeNil()) - // vdrs := make([]*txs.ConvertSubnetValidator, len(nodes)) - // for i, node := range nodes { - // vdrs[i] = &txs.ConvertSubnetValidator{ - // NodeID: node.NodeID.Bytes(), - // Weight: weights[i], - // Balance: units.Avax * 100, - // Signer: *node.NodePoP, - // RemainingBalanceOwner: message.PChainOwner{ - // Threshold: 1, - // Addresses: []ids.ShortID{destAddr}, - // }, - // DeactivationOwner: message.PChainOwner{ - // Threshold: 1, - // Addresses: []ids.ShortID{destAddr}, - // }, - // } - // } - - // Set just the last node (with a high weight) to the initial validator list - vdrs := []*txs.ConvertSubnetValidator{ - { - NodeID: nodes[len(nodes)-1].NodeID.Bytes(), - Weight: weights[len(nodes)-1], + vdrs := make([]*txs.ConvertSubnetValidator, len(nodes)) + for i, node := range nodes { + vdrs[i] = &txs.ConvertSubnetValidator{ + NodeID: node.NodeID.Bytes(), + Weight: weights[i], Balance: units.Avax * 100, - Signer: *nodes[len(nodes)-1].NodePoP, + Signer: *node.NodePoP, RemainingBalanceOwner: message.PChainOwner{ Threshold: 1, Addresses: []ids.ShortID{destAddr}, @@ -127,9 +109,27 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { Threshold: 1, Addresses: []ids.ShortID{destAddr}, }, - }, + } } + // Set just the last node (with a high weight) to the initial validator list + // vdrs := []*txs.ConvertSubnetValidator{ + // { + // NodeID: nodes[len(nodes)-1].NodeID.Bytes(), + // Weight: weights[len(nodes)-1], + // Balance: units.Avax * 100, + // Signer: *nodes[len(nodes)-1].NodePoP, + // RemainingBalanceOwner: message.PChainOwner{ + // Threshold: 1, + // Addresses: []ids.ShortID{destAddr}, + // }, + // DeactivationOwner: message.PChainOwner{ + // Threshold: 1, + // Addresses: []ids.ShortID{destAddr}, + // }, + // }, + // } + log.Println("Issuing ConvertSubnetTx") _, err = network.GetPChainWallet().IssueConvertSubnetTx( subnetAInfo.SubnetID, @@ -145,7 +145,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // Initialize the validator set on the subnet log.Println("Initializing validator set") - _ = utils.InitializeERC20TokenValidatorSet( + initialValidationIDs := utils.InitializeERC20TokenValidatorSet( ctx, fundedKey, subnetAInfo, @@ -154,27 +154,31 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { stakingManagerAddress, network, signatureAggregator, - nodes[len(nodes)-1:], - weights[len(nodes)-1:], + nodes, + weights, ) // Delisting an initial validator does not work due to the way Warp signatures are requested for inital validators // // Delist one initial validators // - // utils.InitializeAndCompleteEndERC20Validation( - // ctx, - // network, - // signatureAggregator, - // fundedKey, - // subnetAInfo, - // pChainInfo, - // stakingManager, - // stakingManagerAddress, - // initialValidationIDs[0], - // weights[0], - // 1, - // ) + expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) + utils.InitializeAndCompleteEndInitialERC20Validation( + ctx, + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + initialValidationIDs[0], + 0, + expiry, + nodes[0], + weights[0], + 1, + ) // // Register a validator @@ -185,7 +189,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { ) Expect(err).Should(BeNil()) // TODONOW: pass the validatorID pre image to the signature aggregator - expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) + // expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) validationID := utils.InitializeAndCompleteERC20ValidatorRegistration( ctx, network, diff --git a/tests/utils/chain.go b/tests/utils/chain.go index 4244a4bf0..dada1a2ec 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + goLog "log" "math/big" "os" "strconv" @@ -317,10 +318,13 @@ func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash co // Takes a tx hash instead of the full tx in the subnet-evm version of this function. // Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { + now := time.Now() receipt, err := waitForTransactionReceipt(ctx, rpcClient, txHash) if err != nil { return nil, err } + since := time.Since(now) + goLog.Println("Transaction mined", "txHash", txHash.Hex(), "duration", since) // Check that the block height endpoint returns a block height as high as the block number that the transaction was // included in. This is to workaround the issue where multiple nodes behind a public RPC endpoint see diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index e678d57a0..acca033e0 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -12,6 +12,7 @@ import ( "time" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/platformvm" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/units" @@ -34,6 +35,7 @@ import ( poavalidatormanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/PoAValidatorManager" "github.com/ava-labs/teleporter/tests/interfaces" "github.com/ethereum/go-ethereum/common" + "google.golang.org/protobuf/proto" . "github.com/onsi/gomega" ) @@ -390,7 +392,7 @@ func InitializeERC20TokenValidatorSet( Expect(err).Should(BeNil()) var validationIDs []ids.ID for i := range nodes { - validationIDs = append(validationIDs, CalculateSubnetConversionValidationId(subnetInfo.SubnetID, uint32(i))) + validationIDs = append(validationIDs, subnetInfo.SubnetID.Append(uint32(i))) } // TODONOW: Validate all nodes @@ -781,6 +783,8 @@ func InitializeAndCompleteNativeValidatorRegistration( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, + false, + 0, 0, Node{}, 0, @@ -871,6 +875,8 @@ func InitializeAndCompleteERC20ValidatorRegistration( log.Println("Completing validator registration") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, + false, + 0, expiry, node, weight, @@ -941,6 +947,8 @@ func InitializeAndCompletePoAValidatorRegistration( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, + false, + 0, 0, Node{}, 0, @@ -1359,6 +1367,8 @@ func InitializeAndCompleteEndNativeValidation( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, + false, + 0, 0, Node{}, 0, @@ -1387,6 +1397,93 @@ func InitializeAndCompleteEndNativeValidation( Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) } +func InitializeAndCompleteEndInitialERC20Validation( + ctx context.Context, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + stakingManagerAddress common.Address, + validationID ids.ID, + index uint32, + expiry uint64, + node Node, + weight uint64, + nonce uint64, +) { + log.Println("Initializing initial validator removal") + WaitMinStakeDuration(ctx, subnetInfo, fundedKey) + receipt := ForceInitializeEndERC20Validation( + ctx, + fundedKey, + subnetInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + unsignedMessage := network.ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + subnetInfo.SubnetID, + 100, + ) + Expect(err).Should(BeNil()) + log.Println("SetSubnetValidatorWeightMessage") + log.Println(signedWarpMessage.Signature.NumSigners()) + log.Println(signedWarpMessage.Signature.String()) + log.Println(signedWarpMessage.SourceChainID.String()) + + // Deliver the Warp message to the P-Chain + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator removal") + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + true, + index, + expiry, + node, + weight, + false, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteEndERC20Validation( + ctx, + fundedKey, + subnetInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + validationEndedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + func InitializeAndCompleteEndERC20Validation( ctx context.Context, network interfaces.LocalNetwork, @@ -1443,6 +1540,8 @@ func InitializeAndCompleteEndERC20Validation( log.Println("Completing validator removal") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, + false, + 0, expiry, node, weight, @@ -1511,6 +1610,8 @@ func InitializeAndCompleteEndPoAValidation( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, + false, + 0, 0, Node{}, 0, @@ -1545,6 +1646,8 @@ func InitializeAndCompleteEndPoAValidation( func ConstructSubnetValidatorRegistrationMessage( validationID ids.ID, + initialValidator bool, + index uint32, expiry uint64, node Node, weight uint64, @@ -1554,16 +1657,40 @@ func ConstructSubnetValidatorRegistrationMessage( network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, ) *avalancheWarp.Message { - justification, err := warpMessages.NewRegisterSubnetValidator( - subnet.SubnetID, - node.NodeID, - node.NodePoP.PublicKey, - expiry, - warpMessages.PChainOwner{}, - warpMessages.PChainOwner{}, - weight, - ) - Expect(err).Should(BeNil()) + var ( + justificationBytes []byte + err error + ) + if !initialValidator { + msg, err := warpMessages.NewRegisterSubnetValidator( + subnet.SubnetID, + node.NodeID, + node.NodePoP.PublicKey, + expiry, + warpMessages.PChainOwner{}, + warpMessages.PChainOwner{}, + weight, + ) + Expect(err).Should(BeNil()) + justification := platformvm.SubnetValidatorRegistrationJustification{ + Preimage: &platformvm.SubnetValidatorRegistrationJustification_RegisterSubnetValidatorMessage{ + RegisterSubnetValidatorMessage: msg.Bytes(), + }, + } + justificationBytes, err = proto.Marshal(&justification) + Expect(err).Should(BeNil()) + } else { + justification := platformvm.SubnetValidatorRegistrationJustification{ + Preimage: &platformvm.SubnetValidatorRegistrationJustification_ConvertSubnetTxData{ + ConvertSubnetTxData: &platformvm.SubnetIDIndex{ + SubnetId: subnet.SubnetID[:], + Index: index, + }, + }, + } + justificationBytes, err = proto.Marshal(&justification) + Expect(err).Should(BeNil()) + } registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) Expect(err).Should(BeNil()) @@ -1578,7 +1705,7 @@ func ConstructSubnetValidatorRegistrationMessage( registrationSignedMessage, err := signatureAggregator.CreateSignedMessage( registrationUnsignedMessage, - justification.Bytes(), + justificationBytes, subnet.SubnetID, 100, ) From f4bb683ec129ef3094b6ccfd3021aeeb918b48ef Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 09:06:53 -0500 Subject: [PATCH 05/34] bump avago --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2bb91e6ad..9f5fc6f72 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ava-labs/teleporter go 1.22.8 require ( - github.com/ava-labs/avalanchego v1.12.0-initial-poc.4 + github.com/ava-labs/avalanchego v1.12.0-initial-poc.5 github.com/supranational/blst v0.3.11 // indirect ) diff --git a/go.sum b/go.sum index 06a4b5cce..28835e100 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,8 @@ github.com/ava-labs/avalanchego v1.12.0-initial-poc.3 h1:JfVooBCdMzpeGUT9/phJNl2 github.com/ava-labs/avalanchego v1.12.0-initial-poc.3/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= github.com/ava-labs/avalanchego v1.12.0-initial-poc.4 h1:0g1+aJS6f4I2m8oEF3djlfyNbL9UrQTS+6A0eXbRLtM= github.com/ava-labs/avalanchego v1.12.0-initial-poc.4/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= +github.com/ava-labs/avalanchego v1.12.0-initial-poc.5 h1:gW4xAqZNvkA4gP8M9yDyd7YUzuwfQbbCR+hgd1ztOto= +github.com/ava-labs/avalanchego v1.12.0-initial-poc.5/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6 h1:v7k5wQxcvnYcMaz+zoO1OLAcU8REDD1EhfPZdl4Q+aI= github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6/go.mod h1:sSXpQtgiduMdZw5IVTSa1v418VCjb8GDLyrcGwJZ/HE= github.com/ava-labs/coreth v0.13.8 h1:f14X3KgwHl9LwzfxlN6S4bbn5VA2rhEsNnHaRLSTo/8= From f28117952f94061a696a657497aed4fb68168a97 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 13:40:53 -0500 Subject: [PATCH 06/34] add delegation to erc20 staking flow --- .../validator-manager/erc20_token_staking.go | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 10c57baa0..564cce850 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -3,6 +3,7 @@ package staking import ( "context" "log" + "math/big" "sort" "time" @@ -206,6 +207,152 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { nodes[0], ) + // // + // Register a delegator + // + var delegationID ids.ID + { + // delegatorStake := big.NewInt(1e17) + log.Println("Registering delegator") + delegatorStake, err := stakingManager.WeightToValue( + &bind.CallOpts{}, + weights[0], + ) + Expect(err).Should(BeNil()) + delegatorStake.Div(delegatorStake, big.NewInt(10)) + delegatorWeight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + newValidatorWeight := weights[0] + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitializeERC20DelegatorRegistration( + ctx, + fundedKey, + subnetAInfo, + validationID, + delegatorStake, + erc20, + stakingManagerAddress, + stakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorAdded, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + // utils.ValidateSubnetValidatorWeightMessage( + // signedWarpMessage, + // validationID, + // newValidatorWeight, + // nonce, + // ) + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network) + utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + newValidatorWeight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteERC20DelegatorRegistration( + ctx, + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // + // Delist the delegator + // + { + log.Println("Delisting delegator") + nonce := uint64(2) + receipt := utils.InitializeEndERC20Delegation( + ctx, + fundedKey, + subnetAInfo, + stakingManager, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + // utils.ValidateSubnetValidatorWeightMessage(signedWarpMessage, validationID, weights[0], 2) + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network) + utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + weights[0], + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteEndERC20Delegation( + ctx, + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegationEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // // Delist the validator // From 06a244e0b422e4e9d02775730eb0610f44c4410b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 13:46:01 -0500 Subject: [PATCH 07/34] resolve todos --- .../validator-manager/erc20_token_staking.go | 47 ++++--------------- tests/local/network.go | 10 ---- tests/utils/validator_manager.go | 24 ++-------- 3 files changed, 12 insertions(+), 69 deletions(-) diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 564cce850..2b39e129d 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -60,6 +60,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { var nodes []utils.Node + // Remove the current validators before converting the subnet for _, uri := range subnetAInfo.NodeURIs { infoClient := info.NewClient(uri) nodeID, nodePoP, err := infoClient.GetNodeID(ctx) @@ -69,7 +70,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { NodePoP: nodePoP, }) - // Remove the current validators before converting the subnet _, err = network.GetPChainWallet().IssueRemoveSubnetValidatorTx( nodeID, subnetAInfo.SubnetID, @@ -91,9 +91,8 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // Set the last node's weight such that removing any other node will not violate the churn limit weights[len(nodes)-1] = 4 * totalWeight - // TODONOW: issue a P-Chain ConvertSubnetTx - destAddrStr := "P-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u" - destAddr, err := address.ParseToID(destAddrStr) + // Construct the convert subnet info + destAddr, err := address.ParseToID(utils.DefaultPChainAddress) Expect(err).Should(BeNil()) vdrs := make([]*txs.ConvertSubnetValidator, len(nodes)) for i, node := range nodes { @@ -113,24 +112,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { } } - // Set just the last node (with a high weight) to the initial validator list - // vdrs := []*txs.ConvertSubnetValidator{ - // { - // NodeID: nodes[len(nodes)-1].NodeID.Bytes(), - // Weight: weights[len(nodes)-1], - // Balance: units.Avax * 100, - // Signer: *nodes[len(nodes)-1].NodePoP, - // RemainingBalanceOwner: message.PChainOwner{ - // Threshold: 1, - // Addresses: []ids.ShortID{destAddr}, - // }, - // DeactivationOwner: message.PChainOwner{ - // Threshold: 1, - // Addresses: []ids.ShortID{destAddr}, - // }, - // }, - // } - log.Println("Issuing ConvertSubnetTx") _, err = network.GetPChainWallet().IssueConvertSubnetTx( subnetAInfo.SubnetID, @@ -141,7 +122,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { Expect(err).Should(BeNil()) utils.PChainProposerVMWorkaround(network) - utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) // Initialize the validator set on the subnet @@ -159,7 +139,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { weights, ) - // Delisting an initial validator does not work due to the way Warp signatures are requested for inital validators // // Delist one initial validators // @@ -182,15 +161,13 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { ) // - // Register a validator + // Register the validator as PoS // stakeAmount, err := stakingManager.WeightToValue( &bind.CallOpts{}, weights[0], ) Expect(err).Should(BeNil()) - // TODONOW: pass the validatorID pre image to the signature aggregator - // expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) validationID := utils.InitializeAndCompleteERC20ValidatorRegistration( ctx, network, @@ -207,12 +184,11 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { nodes[0], ) - // // + // // Register a delegator // var delegationID ids.ID { - // delegatorStake := big.NewInt(1e17) log.Println("Registering delegator") delegatorStake, err := stakingManager.WeightToValue( &bind.CallOpts{}, @@ -250,13 +226,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // (Sending to the P-Chain will be skipped for now) signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) - // Validate the Warp message, (this will be done on the P-Chain in the future) - // utils.ValidateSubnetValidatorWeightMessage( - // signedWarpMessage, - // validationID, - // newValidatorWeight, - // nonce, - // ) + // Issue a tx to update the validator's weight on the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) utils.PChainProposerVMWorkaround(network) utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) @@ -290,6 +260,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) } + // // Delist the delegator // @@ -316,9 +287,9 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) Expect(err).Should(BeNil()) - // Validate the Warp message, (this will be done on the P-Chain in the future) - // utils.ValidateSubnetValidatorWeightMessage(signedWarpMessage, validationID, weights[0], 2) + // Issue a tx to update the validator's weight on the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network) utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) diff --git a/tests/local/network.go b/tests/local/network.go index f97770193..8ef2cb9de 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -97,15 +97,6 @@ func NewLocalNetwork( globalFundedECDSAKey := globalFundedKey.ToECDSA() Expect(err).Should(BeNil()) - g, err := crypto.HexToECDSA(fundedKeyStr) - Expect(err).Should(BeNil()) - // TODONOW: remove these once txs are verified - Expect(g.PublicKey.X).Should(Equal(globalFundedECDSAKey.PublicKey.X)) - Expect(g.PublicKey.Y).Should(Equal(globalFundedECDSAKey.PublicKey.Y)) - Expect(g.X).Should(Equal(globalFundedECDSAKey.X)) - Expect(g.Y).Should(Equal(globalFundedECDSAKey.Y)) - Expect(g.D).Should(Equal(globalFundedECDSAKey.D)) - var subnets []*tmpnet.Subnet for _, subnetSpec := range subnetSpecs { nodes := subnetEvmTestUtils.NewTmpnetNodes(subnetSpec.NodeCount) @@ -166,7 +157,6 @@ func NewLocalNetwork( setupProposerVM(ctx, globalFundedECDSAKey, network, subnet.SubnetID) } - // TODONOW: add Wallet LocalNetwork struct localNetwork := &LocalNetwork{ primaryNetworkInfo: &interfaces.SubnetTestInfo{}, subnetsInfo: make(map[ids.ID]*interfaces.SubnetTestInfo), diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index acca033e0..9c6616307 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -48,6 +48,7 @@ const ( DefaultMaxStakeMultiplier uint8 = 4 DefaultMaxChurnPercentage uint8 = 20 DefaultChurnPeriodSeconds uint64 = 1 + DefaultPChainAddress string = "P-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u" ) // @@ -395,10 +396,6 @@ func InitializeERC20TokenValidatorSet( validationIDs = append(validationIDs, subnetInfo.SubnetID.Append(uint32(i))) } - // TODONOW: Validate all nodes - // for i := range nodes { - // TODONOW: Fix this validation - // Expect(initialValidatorCreatedEvent.NodeID).Should(Equal(subnetConversionData.Validators[i].NodeID)) Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeights[0]))) emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) @@ -847,22 +844,8 @@ func InitializeAndCompleteERC20ValidatorRegistration( // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - // TODONOW: construct the pre-image of the validationID as the justification signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) - // weight, err := stakingManager.ValueToWeight( - // &bind.CallOpts{}, - // stakeAmount, - // ) - // Expect(err).Should(BeNil()) - // Validate the Warp message, (this will be done on the P-Chain in the future) - // ValidateRegisterSubnetValidatorMessage( - // signedWarpMessage, - // nodeID, - // weight, - // subnetInfo.SubnetID, - // blsPublicKey, - // ) _, err := network.GetPChainWallet().IssueRegisterSubnetValidatorTx( 100*units.Avax, node.NodePoP.ProofOfPossession, @@ -1976,9 +1959,8 @@ func PackInitialValidator(iv interface{}) ([]byte, error) { func PChainProposerVMWorkaround( network interfaces.LocalNetwork, ) { - // // Workaround current block map rules - destAddrStr := "P-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u" - destAddr, err := address.ParseToID(destAddrStr) + // Workaround current block map rules + destAddr, err := address.ParseToID(DefaultPChainAddress) Expect(err).Should(BeNil()) log.Println("Waiting for P-Chain...") time.Sleep(30 * time.Second) From d6e063238a479296cea9365ab172ad3776fbf395 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 14:03:20 -0500 Subject: [PATCH 08/34] separate init vdr helpers --- .../validator-manager/erc20_token_staking.go | 5 +- tests/utils/validator_manager.go | 145 ++++++++---------- 2 files changed, 64 insertions(+), 86 deletions(-) diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 2b39e129d..4279d8e96 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -142,7 +142,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // // Delist one initial validators // - expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) utils.InitializeAndCompleteEndInitialERC20Validation( ctx, network, @@ -154,10 +153,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { stakingManagerAddress, initialValidationIDs[0], 0, - expiry, - nodes[0], weights[0], - 1, ) // @@ -168,6 +164,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { weights[0], ) Expect(err).Should(BeNil()) + expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) validationID := utils.InitializeAndCompleteERC20ValidatorRegistration( ctx, network, diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 9c6616307..43630b8db 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -359,9 +359,6 @@ func InitializeERC20TokenValidatorSet( InitialValidators: initialValidatorsABI, } subnetConversionID, err := warpMessages.SubnetConversionID(subnetConversionData) - log.Println("Reconstructed SubnetConversionID") - log.Println(subnetConversionData) - log.Printf("conversionID: %s\n", subnetConversionID.String()) Expect(err).Should(BeNil()) // subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) // Expect(err).Should(BeNil()) @@ -373,10 +370,7 @@ func InitializeERC20TokenValidatorSet( network, signatureAggregator, ) - log.Println("SubnetConversionSignedMessage") - log.Println(subnetConversionSignedMessage.Signature.NumSigners()) - log.Println(subnetConversionSignedMessage.Signature.String()) - log.Println(subnetConversionSignedMessage.SourceChainID.String()) + // Deliver the Warp message to the subnet receipt := DeliverERC20TokenSubnetConversion( ctx, @@ -400,10 +394,7 @@ func InitializeERC20TokenValidatorSet( emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) Expect(emittedValidationID).Should(Equal(validationIDs[0])) - log.Println("Expected Validation ID", validationIDs[0]) - log.Println("Emitted Validation ID", emittedValidationID) - // } - log.Println("Validation IDs", validationIDs) + return validationIDs } @@ -780,8 +771,6 @@ func InitializeAndCompleteNativeValidatorRegistration( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - false, - 0, 0, Node{}, 0, @@ -858,8 +847,6 @@ func InitializeAndCompleteERC20ValidatorRegistration( log.Println("Completing validator registration") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - false, - 0, expiry, node, weight, @@ -930,8 +917,6 @@ func InitializeAndCompletePoAValidatorRegistration( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - false, - 0, 0, Node{}, 0, @@ -1350,8 +1335,6 @@ func InitializeAndCompleteEndNativeValidation( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - false, - 0, 0, Node{}, 0, @@ -1391,10 +1374,7 @@ func InitializeAndCompleteEndInitialERC20Validation( stakingManagerAddress common.Address, validationID ids.ID, index uint32, - expiry uint64, - node Node, weight uint64, - nonce uint64, ) { log.Println("Initializing initial validator removal") WaitMinStakeDuration(ctx, subnetInfo, fundedKey) @@ -1423,10 +1403,6 @@ func InitializeAndCompleteEndInitialERC20Validation( 100, ) Expect(err).Should(BeNil()) - log.Println("SetSubnetValidatorWeightMessage") - log.Println(signedWarpMessage.Signature.NumSigners()) - log.Println(signedWarpMessage.Signature.String()) - log.Println(signedWarpMessage.SourceChainID.String()) // Deliver the Warp message to the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) @@ -1434,14 +1410,10 @@ func InitializeAndCompleteEndInitialERC20Validation( AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain - log.Println("Completing validator removal") - registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + log.Println("Completing initial validator removal") + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessageForInitialValidator( validationID, - true, index, - expiry, - node, - weight, false, subnetInfo, pChainInfo, @@ -1509,10 +1481,6 @@ func InitializeAndCompleteEndERC20Validation( 100, ) Expect(err).Should(BeNil()) - log.Println("SetSubnetValidatorWeightMessage") - log.Println(signedWarpMessage.Signature.NumSigners()) - log.Println(signedWarpMessage.Signature.String()) - log.Println(signedWarpMessage.SourceChainID.String()) // Deliver the Warp message to the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) @@ -1523,8 +1491,6 @@ func InitializeAndCompleteEndERC20Validation( log.Println("Completing validator removal") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - false, - 0, expiry, node, weight, @@ -1593,8 +1559,6 @@ func InitializeAndCompleteEndPoAValidation( // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - false, - 0, 0, Node{}, 0, @@ -1627,10 +1591,50 @@ func InitializeAndCompleteEndPoAValidation( // P-Chain utils // -func ConstructSubnetValidatorRegistrationMessage( +func ConstructSubnetValidatorRegistrationMessageForInitialValidator( validationID ids.ID, - initialValidator bool, index uint32, + valid bool, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, +) *avalancheWarp.Message { + justification := platformvm.SubnetValidatorRegistrationJustification{ + Preimage: &platformvm.SubnetValidatorRegistrationJustification_ConvertSubnetTxData{ + ConvertSubnetTxData: &platformvm.SubnetIDIndex{ + SubnetId: subnet.SubnetID[:], + Index: index, + }, + }, + } + justificationBytes, err := proto.Marshal(&justification) + Expect(err).Should(BeNil()) + + registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) + Expect(err).Should(BeNil()) + registrationAddressedCall, err := warpPayload.NewAddressedCall(nil, registrationPayload.Bytes()) + Expect(err).Should(BeNil()) + registrationUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + network.GetNetworkID(), + pChainInfo.BlockchainID, + registrationAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + registrationSignedMessage, err := signatureAggregator.CreateSignedMessage( + registrationUnsignedMessage, + justificationBytes, + subnet.SubnetID, + 100, + ) + Expect(err).Should(BeNil()) + + return registrationSignedMessage +} + +func ConstructSubnetValidatorRegistrationMessage( + validationID ids.ID, expiry uint64, node Node, weight uint64, @@ -1640,40 +1644,23 @@ func ConstructSubnetValidatorRegistrationMessage( network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, ) *avalancheWarp.Message { - var ( - justificationBytes []byte - err error - ) - if !initialValidator { - msg, err := warpMessages.NewRegisterSubnetValidator( - subnet.SubnetID, - node.NodeID, - node.NodePoP.PublicKey, - expiry, - warpMessages.PChainOwner{}, - warpMessages.PChainOwner{}, - weight, - ) - Expect(err).Should(BeNil()) - justification := platformvm.SubnetValidatorRegistrationJustification{ - Preimage: &platformvm.SubnetValidatorRegistrationJustification_RegisterSubnetValidatorMessage{ - RegisterSubnetValidatorMessage: msg.Bytes(), - }, - } - justificationBytes, err = proto.Marshal(&justification) - Expect(err).Should(BeNil()) - } else { - justification := platformvm.SubnetValidatorRegistrationJustification{ - Preimage: &platformvm.SubnetValidatorRegistrationJustification_ConvertSubnetTxData{ - ConvertSubnetTxData: &platformvm.SubnetIDIndex{ - SubnetId: subnet.SubnetID[:], - Index: index, - }, - }, - } - justificationBytes, err = proto.Marshal(&justification) - Expect(err).Should(BeNil()) + msg, err := warpMessages.NewRegisterSubnetValidator( + subnet.SubnetID, + node.NodeID, + node.NodePoP.PublicKey, + expiry, + warpMessages.PChainOwner{}, + warpMessages.PChainOwner{}, + weight, + ) + Expect(err).Should(BeNil()) + justification := platformvm.SubnetValidatorRegistrationJustification{ + Preimage: &platformvm.SubnetValidatorRegistrationJustification_RegisterSubnetValidatorMessage{ + RegisterSubnetValidatorMessage: msg.Bytes(), + }, } + justificationBytes, err := proto.Marshal(&justification) + Expect(err).Should(BeNil()) registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) Expect(err).Should(BeNil()) @@ -1693,13 +1680,7 @@ func ConstructSubnetValidatorRegistrationMessage( 100, ) Expect(err).Should(BeNil()) - log.Println("SubnetValidatorRegistrationMessage") - log.Printf("valid=%t", valid) - numSigners, err := registrationSignedMessage.Signature.NumSigners() - Expect(err).Should(BeNil()) - log.Println("numSigners", numSigners) - log.Println("signature", registrationSignedMessage.Signature.String()) - log.Println("sourceChain", registrationSignedMessage.SourceChainID.String()) + return registrationSignedMessage } From ead93bcaec9fe540584e2c080777f5647a4c3a43 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 14:10:50 -0500 Subject: [PATCH 09/34] reduce to 67 quorum --- tests/utils/validator_manager.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 43630b8db..389e760da 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -1400,7 +1400,7 @@ func InitializeAndCompleteEndInitialERC20Validation( unsignedMessage, nil, subnetInfo.SubnetID, - 100, + 67, ) Expect(err).Should(BeNil()) @@ -1478,7 +1478,7 @@ func InitializeAndCompleteEndERC20Validation( unsignedMessage, nil, subnetInfo.SubnetID, - 100, + 67, ) Expect(err).Should(BeNil()) @@ -1626,7 +1626,7 @@ func ConstructSubnetValidatorRegistrationMessageForInitialValidator( registrationUnsignedMessage, justificationBytes, subnet.SubnetID, - 100, + 67, ) Expect(err).Should(BeNil()) @@ -1677,7 +1677,7 @@ func ConstructSubnetValidatorRegistrationMessage( registrationUnsignedMessage, justificationBytes, subnet.SubnetID, - 100, + 67, ) Expect(err).Should(BeNil()) @@ -1739,7 +1739,7 @@ func ConstructSubnetConversionMessage( subnetConversionUnsignedMessage, subnet.SubnetID[:], subnet.SubnetID, - 100, + 67, ) Expect(err).Should(BeNil()) return subnetConversionSignedMessage From 7c1e007b72c05ea24aeb99db4ea2de8c03823da4 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 15:07:39 -0500 Subject: [PATCH 10/34] separate e2e suites --- scripts/local/e2e_test.sh | 54 +++- tests/local/e2e_test.go | 232 ------------------ .../local/governance/governance_suite_test.go | 114 +++++++++ tests/local/network.go | 5 + .../local/teleporter/teleporter_suite_test.go | 192 +++++++++++++++ .../validator_manager_suite_test.go | 139 +++++++++++ 6 files changed, 500 insertions(+), 236 deletions(-) delete mode 100644 tests/local/e2e_test.go create mode 100644 tests/local/governance/governance_suite_test.go create mode 100644 tests/local/teleporter/teleporter_suite_test.go create mode 100644 tests/local/validator-manager/validator_manager_suite_test.go diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index 16ddc818b..a7d0beffc 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -9,6 +9,53 @@ TELEPORTER_PATH=$( cd ../.. && pwd ) +function printHelp() { + echo "Usage: ./scripts/local/e2e_test.sh [--component component]" + echo "" + printUsage +} + +function printUsage() { + cat << EOF +Arguments: + --component Component test suite to run. If omitted, runs all tests. +Options: + --help Print this help message +EOF +} + +valid_components="teleporter governance validator-manager" +component= + +while [ $# -gt 0 ]; do + case "$1" in + --component) + if [[ $2 != --* ]]; then + component=$2 + else + echo "Invalid component $2" && printHelp && exit 1 + fi + shift;; + --help) + printHelp && exit 0 ;; + *) + echo "Invalid option: $1" && printHelp && exit 1;; + esac + shift +done + +# Exit if no component is provided +# TODONOW: Run all tests if no component is provided +if [ -z "$component" ]; then + echo "No component provided" && exit 1 +fi + +if echo "$valid_components" | grep -q "\b$component\b"; then + echo "" > /dev/null +else + echo "Invalid component" && exit 1 +fi + source "$TELEPORTER_PATH"/scripts/constants.sh source "$TELEPORTER_PATH"/scripts/versions.sh @@ -20,8 +67,7 @@ rm -rf $BASEDIR/avalanchego BASEDIR=$BASEDIR AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego "${TELEPORTER_PATH}/scripts/install_avalanchego_release.sh" BASEDIR=$BASEDIR "${TELEPORTER_PATH}/scripts/install_subnetevm_release.sh" -# cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy -cp /Users/cameron.schultz/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy echo "Copied ${BASEDIR}/subnet-evm/subnet-evm binary to ${BASEDIR}/avalanchego/plugins/" export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego @@ -39,11 +85,11 @@ cd "$TELEPORTER_PATH" # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} -ginkgo build ./tests/local/ +ginkgo build ./tests/local/$component # Run the tests echo "Running e2e tests $RUN_E2E" -RUN_E2E=true ./tests/local/local.test \ +RUN_E2E=true ./tests/local//$component/$component.test \ --ginkgo.vv \ --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ --ginkgo.focus=${GINKGO_FOCUS:-""} \ diff --git a/tests/local/e2e_test.go b/tests/local/e2e_test.go deleted file mode 100644 index aad4ccefa..000000000 --- a/tests/local/e2e_test.go +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package local - -import ( - "context" - "os" - "testing" - "time" - - validatorManager "github.com/ava-labs/teleporter/tests/flows/validator-manager" - deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" - "github.com/ethereum/go-ethereum/log" - "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -const ( - teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" - warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" - - teleporterMessengerLabel = "TeleporterMessenger" - upgradabilityLabel = "upgradability" - utilsLabel = "utils" - validatorSetSigLabel = "ValidatorSetSig" - validatorManagerLabel = "ValidatorManager" -) - -var ( - LocalNetworkInstance *LocalNetwork -) - -func TestE2E(t *testing.T) { - if os.Getenv("RUN_E2E") == "" { - t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") - } - - RegisterFailHandler(ginkgo.Fail) - ginkgo.RunSpecs(t, "Teleporter e2e test") -} - -// Define the Teleporter before and after suite functions. -var _ = ginkgo.BeforeSuite(func() { - // Generate the Teleporter deployment values - teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := - deploymentUtils.ConstructKeylessTransaction( - teleporterByteCodeFile, - false, - deploymentUtils.GetDefaultContractCreationGasPrice(), - ) - Expect(err).Should(BeNil()) - - // Create the local network instance - ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) - defer cancel() - LocalNetworkInstance = NewLocalNetwork( - ctx, - "teleporter-test-local-network", - warpGenesisTemplateFile, - []SubnetSpec{ - { - Name: "A", - EVMChainID: 12345, - TeleporterContractAddress: teleporterContractAddress, - TeleporterDeployedBytecode: teleporterDeployedBytecode, - TeleporterDeployerAddress: teleporterDeployerAddress, - NodeCount: 2, - }, - { - Name: "B", - EVMChainID: 54321, - TeleporterContractAddress: teleporterContractAddress, - TeleporterDeployedBytecode: teleporterDeployedBytecode, - TeleporterDeployerAddress: teleporterDeployerAddress, - NodeCount: 2, - }, - }, - 2, - ) - log.Info("Started local network") - - // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the subnet chains. - _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() - LocalNetworkInstance.DeployTeleporterContractToCChain( - teleporterDeployerTransaction, - teleporterDeployerAddress, - teleporterContractAddress, - fundedKey, - ) - LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) - - // Deploy the Teleporter registry contracts to all subnets and the C-Chain. - LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) - - ginkgo.AddReportEntry( - "network directory with node logs & configs; useful in the case of failures", - LocalNetworkInstance.tmpnet.Dir, - ginkgo.ReportEntryVisibilityFailureOrVerbose, - ) - - log.Info("Set up ginkgo before suite") -}) - -var _ = ginkgo.AfterSuite(func() { - LocalNetworkInstance.TearDownNetwork() -}) - -var _ = ginkgo.Describe("[Teleporter integration tests]", func() { - // // Teleporter tests - // ginkgo.It("Send a message from Subnet A to Subnet B, and one from B to A", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.BasicSendReceive(LocalNetworkInstance) - // }) - // ginkgo.It("Deliver to the wrong chain", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.DeliverToWrongChain(LocalNetworkInstance) - // }) - // ginkgo.It("Deliver to non-existent contract", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.DeliverToNonExistentContract(LocalNetworkInstance) - // }) - // ginkgo.It("Retry successful execution", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.RetrySuccessfulExecution(LocalNetworkInstance) - // }) - // ginkgo.It("Unallowed relayer", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.UnallowedRelayer(LocalNetworkInstance) - // }) - // ginkgo.It("Relay message twice", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.RelayMessageTwice(LocalNetworkInstance) - // }) - // ginkgo.It("Add additional fee amount", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.AddFeeAmount(LocalNetworkInstance) - // }) - // ginkgo.It("Send specific receipts", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.SendSpecificReceipts(LocalNetworkInstance) - // }) - // ginkgo.It("Insufficient gas", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.InsufficientGas(LocalNetworkInstance) - // }) - // ginkgo.It("Resubmit altered message", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.ResubmitAlteredMessage(LocalNetworkInstance) - // }) - // ginkgo.It("Calculate Teleporter message IDs", - // ginkgo.Label(utilsLabel), - // func() { - // teleporter.CalculateMessageID(LocalNetworkInstance) - // }) - // ginkgo.It("Relayer modifies message", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.RelayerModifiesMessage(LocalNetworkInstance) - // }) - // ginkgo.It("Validator churn", - // ginkgo.Label(teleporterMessengerLabel), - // func() { - // teleporter.ValidatorChurn(LocalNetworkInstance) - // }) - - // // Teleporter Registry tests - // ginkgo.It("Teleporter registry", - // ginkgo.Label(upgradabilityLabel), - // func() { - // registry.TeleporterRegistry(LocalNetworkInstance) - // }) - // ginkgo.It("Check upgrade access", - // ginkgo.Label(upgradabilityLabel), - // func() { - // registry.CheckUpgradeAccess(LocalNetworkInstance) - // }) - // ginkgo.It("Pause and Unpause Teleporter", - // ginkgo.Label(upgradabilityLabel), - // func() { - // registry.PauseTeleporter(LocalNetworkInstance) - // }) - - // // Governance tests - // ginkgo.It("Deliver ValidatorSetSig signed message", - // ginkgo.Label(validatorSetSigLabel), - // func() { - // governance.ValidatorSetSig(LocalNetworkInstance) - // }) - - // // Validator Manager tests - // ginkgo.It("Native token staking manager", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManager.NativeTokenStakingManager(LocalNetworkInstance) - // }) - ginkgo.It("ERC20 token staking manager", - ginkgo.Label(validatorManagerLabel), - func() { - validatorManager.ERC20TokenStakingManager(LocalNetworkInstance) - }) - // ginkgo.It("PoA validator manager", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManager.PoAValidatorManager(LocalNetworkInstance) - // }) - // ginkgo.It("ERC20 delegation", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManager.ERC20Delegation(LocalNetworkInstance) - // }) - // ginkgo.It("Native token delegation", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManager.NativeDelegation(LocalNetworkInstance) - // }) - // ginkgo.It("PoA migration to PoS", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManager.PoAMigrationToPoS(LocalNetworkInstance) - // }) -}) diff --git a/tests/local/governance/governance_suite_test.go b/tests/local/governance/governance_suite_test.go new file mode 100644 index 000000000..31da93101 --- /dev/null +++ b/tests/local/governance/governance_suite_test.go @@ -0,0 +1,114 @@ +package governance_test + +import ( + "context" + "os" + "testing" + "time" + + governanceFlows "github.com/ava-labs/teleporter/tests/flows/governance" + "github.com/ava-labs/teleporter/tests/local" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + "github.com/ethereum/go-ethereum/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" + warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" + + teleporterMessengerLabel = "TeleporterMessenger" + upgradabilityLabel = "upgradability" + utilsLabel = "utils" + validatorSetSigLabel = "ValidatorSetSig" + validatorManagerLabel = "ValidatorManager" +) + +var ( + LocalNetworkInstance *local.LocalNetwork +) + +func TestGovernance(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "Teleporter e2e test") +} + +// Define the Teleporter before and after suite functions. +var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := + deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + LocalNetworkInstance = local.NewLocalNetwork( + ctx, + "teleporter-test-local-network", + warpGenesisTemplateFile, + []local.SubnetSpec{ + { + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + { + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + }, + 2, + ) + log.Info("Started local network") + + // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the subnet chains. + _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() + LocalNetworkInstance.DeployTeleporterContractToCChain( + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) + + // Deploy the Teleporter registry contracts to all subnets and the C-Chain. + LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) + + ginkgo.AddReportEntry( + "network directory with node logs & configs; useful in the case of failures", + LocalNetworkInstance.TmpNet().Dir, + ginkgo.ReportEntryVisibilityFailureOrVerbose, + ) + + log.Info("Set up ginkgo before suite") +}) + +var _ = ginkgo.AfterSuite(func() { + LocalNetworkInstance.TearDownNetwork() +}) + +var _ = ginkgo.Describe("[Governance integration tests]", func() { + // Governance tests + ginkgo.It("Deliver ValidatorSetSig signed message", + ginkgo.Label(validatorSetSigLabel), + func() { + governanceFlows.ValidatorSetSig(LocalNetworkInstance) + }) +}) diff --git a/tests/local/network.go b/tests/local/network.go index 8ef2cb9de..6f667082f 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -74,6 +74,7 @@ type SubnetSpec struct { NodeCount int } +// TODONOW: Decouple Teleporter from the network interface func NewLocalNetwork( ctx context.Context, name string, @@ -188,6 +189,10 @@ func NewLocalNetwork( return localNetwork } +func (n *LocalNetwork) TmpNet() *tmpnet.Network { + return n.tmpnet +} + // Should be called after setSubnetValues for all subnets func (n *LocalNetwork) setPrimaryNetworkValues() { // Get the C-Chain node URIs. diff --git a/tests/local/teleporter/teleporter_suite_test.go b/tests/local/teleporter/teleporter_suite_test.go new file mode 100644 index 000000000..c93a07541 --- /dev/null +++ b/tests/local/teleporter/teleporter_suite_test.go @@ -0,0 +1,192 @@ +package teleporter_test + +import ( + "context" + "os" + "testing" + "time" + + teleporterFlows "github.com/ava-labs/teleporter/tests/flows/teleporter" + registryFlows "github.com/ava-labs/teleporter/tests/flows/teleporter/registry" + "github.com/ava-labs/teleporter/tests/local" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + "github.com/ethereum/go-ethereum/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" + warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" + + teleporterMessengerLabel = "TeleporterMessenger" + upgradabilityLabel = "upgradability" + utilsLabel = "utils" + validatorSetSigLabel = "ValidatorSetSig" + validatorManagerLabel = "ValidatorManager" +) + +var ( + LocalNetworkInstance *local.LocalNetwork +) + +func TestTeleporter(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "Teleporter e2e test") +} + +// Define the Teleporter before and after suite functions. +var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := + deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + LocalNetworkInstance = local.NewLocalNetwork( + ctx, + "teleporter-test-local-network", + warpGenesisTemplateFile, + []local.SubnetSpec{ + { + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + { + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + }, + 2, + ) + log.Info("Started local network") + + // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the subnet chains. + _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() + LocalNetworkInstance.DeployTeleporterContractToCChain( + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) + + // Deploy the Teleporter registry contracts to all subnets and the C-Chain. + LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) + + ginkgo.AddReportEntry( + "network directory with node logs & configs; useful in the case of failures", + LocalNetworkInstance.TmpNet().Dir, + ginkgo.ReportEntryVisibilityFailureOrVerbose, + ) + + log.Info("Set up ginkgo before suite") +}) + +var _ = ginkgo.AfterSuite(func() { + LocalNetworkInstance.TearDownNetwork() +}) + +var _ = ginkgo.Describe("[Teleporter integration tests]", func() { + // Teleporter tests + ginkgo.It("Send a message from Subnet A to Subnet B, and one from B to A", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.BasicSendReceive(LocalNetworkInstance) + }) + ginkgo.It("Deliver to the wrong chain", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.DeliverToWrongChain(LocalNetworkInstance) + }) + ginkgo.It("Deliver to non-existent contract", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.DeliverToNonExistentContract(LocalNetworkInstance) + }) + ginkgo.It("Retry successful execution", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.RetrySuccessfulExecution(LocalNetworkInstance) + }) + ginkgo.It("Unallowed relayer", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.UnallowedRelayer(LocalNetworkInstance) + }) + ginkgo.It("Relay message twice", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.RelayMessageTwice(LocalNetworkInstance) + }) + ginkgo.It("Add additional fee amount", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.AddFeeAmount(LocalNetworkInstance) + }) + ginkgo.It("Send specific receipts", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.SendSpecificReceipts(LocalNetworkInstance) + }) + ginkgo.It("Insufficient gas", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.InsufficientGas(LocalNetworkInstance) + }) + ginkgo.It("Resubmit altered message", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.ResubmitAlteredMessage(LocalNetworkInstance) + }) + ginkgo.It("Calculate Teleporter message IDs", + ginkgo.Label(utilsLabel), + func() { + teleporterFlows.CalculateMessageID(LocalNetworkInstance) + }) + ginkgo.It("Relayer modifies message", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.RelayerModifiesMessage(LocalNetworkInstance) + }) + ginkgo.It("Validator churn", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.ValidatorChurn(LocalNetworkInstance) + }) + + // Teleporter Registry tests + ginkgo.It("Teleporter registry", + ginkgo.Label(upgradabilityLabel), + func() { + registryFlows.TeleporterRegistry(LocalNetworkInstance) + }) + ginkgo.It("Check upgrade access", + ginkgo.Label(upgradabilityLabel), + func() { + registryFlows.CheckUpgradeAccess(LocalNetworkInstance) + }) + ginkgo.It("Pause and Unpause Teleporter", + ginkgo.Label(upgradabilityLabel), + func() { + registryFlows.PauseTeleporter(LocalNetworkInstance) + }) +}) diff --git a/tests/local/validator-manager/validator_manager_suite_test.go b/tests/local/validator-manager/validator_manager_suite_test.go new file mode 100644 index 000000000..ce273c69d --- /dev/null +++ b/tests/local/validator-manager/validator_manager_suite_test.go @@ -0,0 +1,139 @@ +package validator_manager_test + +import ( + "context" + "os" + "testing" + "time" + + validatorManagerFlows "github.com/ava-labs/teleporter/tests/flows/validator-manager" + "github.com/ava-labs/teleporter/tests/local" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + "github.com/ethereum/go-ethereum/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" + warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" + + teleporterMessengerLabel = "TeleporterMessenger" + upgradabilityLabel = "upgradability" + utilsLabel = "utils" + validatorSetSigLabel = "ValidatorSetSig" + validatorManagerLabel = "ValidatorManager" +) + +var ( + LocalNetworkInstance *local.LocalNetwork +) + +func TestValidatorManager(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "Teleporter e2e test") +} + +// Define the Teleporter before and after suite functions. +var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := + deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + LocalNetworkInstance = local.NewLocalNetwork( + ctx, + "teleporter-test-local-network", + warpGenesisTemplateFile, + []local.SubnetSpec{ + { + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + { + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + }, + 2, + ) + log.Info("Started local network") + + // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the subnet chains. + _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() + LocalNetworkInstance.DeployTeleporterContractToCChain( + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) + + // Deploy the Teleporter registry contracts to all subnets and the C-Chain. + LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) + + ginkgo.AddReportEntry( + "network directory with node logs & configs; useful in the case of failures", + LocalNetworkInstance.TmpNet().Dir, + ginkgo.ReportEntryVisibilityFailureOrVerbose, + ) + + log.Info("Set up ginkgo before suite") +}) + +var _ = ginkgo.AfterSuite(func() { + LocalNetworkInstance.TearDownNetwork() +}) + +var _ = ginkgo.Describe("[Validator manager integration tests]", func() { + // Validator Manager tests + ginkgo.It("Native token staking manager", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.NativeTokenStakingManager(LocalNetworkInstance) + }) + ginkgo.It("ERC20 token staking manager", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.ERC20TokenStakingManager(LocalNetworkInstance) + }) + ginkgo.It("PoA validator manager", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.PoAValidatorManager(LocalNetworkInstance) + }) + ginkgo.It("ERC20 delegation", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.ERC20Delegation(LocalNetworkInstance) + }) + ginkgo.It("Native token delegation", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.NativeDelegation(LocalNetworkInstance) + }) + ginkgo.It("PoA migration to PoS", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.PoAMigrationToPoS(LocalNetworkInstance) + }) +}) From 72ea62d60e30b7924743f70d8c3f0169fd1a272b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 15:48:51 -0500 Subject: [PATCH 11/34] init chainid before tests --- tests/local/network.go | 14 ++++++++++++++ tests/local/teleporter/teleporter_suite_test.go | 2 ++ .../validator_manager_suite_test.go | 2 ++ utils/deployment-utils/deployment_utils.go | 2 -- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/local/network.go b/tests/local/network.go index 6f667082f..23c03fbd3 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -360,6 +360,20 @@ func (n *LocalNetwork) DeployTeleporterContractToAllChains( log.Info("Deployed Teleporter contracts to C-Chain and all subnets") } +func (n *LocalNetwork) InitializeBlockchainIDOnAllChains( + fundedKey *ecdsa.PrivateKey, +) { + log.Info("Initializing blockchainID on C-Chain and all subnets") + ctx := context.Background() + for _, subnetInfo := range n.GetAllSubnetsInfo() { + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, subnetInfo.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := subnetInfo.TeleporterMessenger.InitializeBlockchainID(opts) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, subnetInfo, tx.Hash()) + } +} + func (n *LocalNetwork) DeployTeleporterRegistryContracts( teleporterAddress common.Address, deployerKey *ecdsa.PrivateKey, diff --git a/tests/local/teleporter/teleporter_suite_test.go b/tests/local/teleporter/teleporter_suite_test.go index c93a07541..923ee6c4d 100644 --- a/tests/local/teleporter/teleporter_suite_test.go +++ b/tests/local/teleporter/teleporter_suite_test.go @@ -88,6 +88,7 @@ var _ = ginkgo.BeforeSuite(func() { fundedKey, ) LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) + LocalNetworkInstance.InitializeBlockchainIDOnAllChains(fundedKey) // Deploy the Teleporter registry contracts to all subnets and the C-Chain. LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) @@ -103,6 +104,7 @@ var _ = ginkgo.BeforeSuite(func() { var _ = ginkgo.AfterSuite(func() { LocalNetworkInstance.TearDownNetwork() + LocalNetworkInstance = nil }) var _ = ginkgo.Describe("[Teleporter integration tests]", func() { diff --git a/tests/local/validator-manager/validator_manager_suite_test.go b/tests/local/validator-manager/validator_manager_suite_test.go index ce273c69d..50e360da3 100644 --- a/tests/local/validator-manager/validator_manager_suite_test.go +++ b/tests/local/validator-manager/validator_manager_suite_test.go @@ -39,6 +39,7 @@ func TestValidatorManager(t *testing.T) { } // Define the Teleporter before and after suite functions. +// TODONOW: Tear down the network in between each spec so that we start with a fresh subnet each time. var _ = ginkgo.BeforeSuite(func() { // Generate the Teleporter deployment values teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := @@ -87,6 +88,7 @@ var _ = ginkgo.BeforeSuite(func() { fundedKey, ) LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) + LocalNetworkInstance.InitializeBlockchainIDOnAllChains(fundedKey) // Deploy the Teleporter registry contracts to all subnets and the C-Chain. LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) diff --git a/utils/deployment-utils/deployment_utils.go b/utils/deployment-utils/deployment_utils.go index a12dbaf12..3f0ba81ca 100644 --- a/utils/deployment-utils/deployment_utils.go +++ b/utils/deployment-utils/deployment_utils.go @@ -126,8 +126,6 @@ func ConstructKeylessTransaction( contractAddress := crypto.CreateAddress(senderAddress, 0) contractAddressString := contractAddress.Hex() // "0x" prepended by Hex() already. - log.Println("Raw Teleporter Contract Creation Transaction:") - log.Println(contractCreationTxString) log.Println("Teleporter Contract Keyless Deployer Address: ", senderAddressString) log.Println("Teleporter Messenger Universal Contract Address: ", contractAddressString) From 63bad1afb0e689236735805716d28e026bd9735d Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 16:04:23 -0500 Subject: [PATCH 12/34] init chainid before tests --- tests/local/governance/governance_suite_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/local/governance/governance_suite_test.go b/tests/local/governance/governance_suite_test.go index 31da93101..ac2314aa3 100644 --- a/tests/local/governance/governance_suite_test.go +++ b/tests/local/governance/governance_suite_test.go @@ -87,6 +87,7 @@ var _ = ginkgo.BeforeSuite(func() { fundedKey, ) LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) + LocalNetworkInstance.InitializeBlockchainIDOnAllChains(fundedKey) // Deploy the Teleporter registry contracts to all subnets and the C-Chain. LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) From 406caf7ffd00e1700bf64d2545213b0b3e948de5 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 16:29:58 -0500 Subject: [PATCH 13/34] simplify local network --- .../teleporter/relayer_modifies_message.go | 2 +- tests/flows/teleporter/validator_churn.go | 2 +- .../validator-manager/erc20_delegation.go | 4 +- .../validator-manager/erc20_token_staking.go | 4 +- .../validator-manager/native_delegation.go | 4 +- tests/interfaces/local_network.go | 14 -- tests/interfaces/network.go | 10 -- .../local/governance/governance_suite_test.go | 6 - tests/local/network.go | 88 +----------- tests/local/network_utils.go | 62 --------- .../local/teleporter/teleporter_suite_test.go | 6 - .../validator_manager_suite_test.go | 6 - tests/utils/chain.go | 131 ++++++++++++++++++ tests/utils/governance.go | 2 +- tests/utils/teleporter.go | 2 +- tests/utils/validator_manager.go | 14 +- 16 files changed, 149 insertions(+), 208 deletions(-) delete mode 100644 tests/local/network_utils.go diff --git a/tests/flows/teleporter/relayer_modifies_message.go b/tests/flows/teleporter/relayer_modifies_message.go index 4011ebc6f..df9a77d43 100644 --- a/tests/flows/teleporter/relayer_modifies_message.go +++ b/tests/flows/teleporter/relayer_modifies_message.go @@ -71,7 +71,7 @@ func relayAlteredMessage( sendEvent, err := utils.GetEventFromLogs(sourceReceipt.Logs, source.TeleporterMessenger.ParseSendCrossChainMessage) Expect(err).Should(BeNil()) - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, sourceReceipt, source, destination) + signedWarpMessage := utils.ConstructSignedWarpMessage(ctx, sourceReceipt, source, destination) // Construct the transaction to send the Warp message to the destination chain _, fundedKey := network.GetFundedAccountInfo() diff --git a/tests/flows/teleporter/validator_churn.go b/tests/flows/teleporter/validator_churn.go index 2f84c7552..8737c8770 100644 --- a/tests/flows/teleporter/validator_churn.go +++ b/tests/flows/teleporter/validator_churn.go @@ -53,7 +53,7 @@ func ValidatorChurn(network interfaces.LocalNetwork) { sentTeleporterMessage := sendEvent.Message // Construct the signed warp message - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetAInfo, subnetBInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(ctx, receipt, subnetAInfo, subnetBInfo) // // Modify the validator set on Subnet A diff --git a/tests/flows/validator-manager/erc20_delegation.go b/tests/flows/validator-manager/erc20_delegation.go index 5e1b25009..125b5548a 100644 --- a/tests/flows/validator-manager/erc20_delegation.go +++ b/tests/flows/validator-manager/erc20_delegation.go @@ -114,7 +114,7 @@ func ERC20Delegation(network interfaces.LocalNetwork) { // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) // Validate the Warp message, (this will be done on the P-Chain in the future) utils.ValidateSubnetValidatorWeightMessage( @@ -175,7 +175,7 @@ func ERC20Delegation(network interfaces.LocalNetwork) { // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) Expect(err).Should(BeNil()) // Validate the Warp message, (this will be done on the P-Chain in the future) diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 4279d8e96..6f5c7fc04 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -221,7 +221,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) // Issue a tx to update the validator's weight on the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) @@ -281,7 +281,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) Expect(err).Should(BeNil()) // Issue a tx to update the validator's weight on the P-Chain diff --git a/tests/flows/validator-manager/native_delegation.go b/tests/flows/validator-manager/native_delegation.go index d584064d2..280be4af6 100644 --- a/tests/flows/validator-manager/native_delegation.go +++ b/tests/flows/validator-manager/native_delegation.go @@ -114,7 +114,7 @@ func NativeDelegation(network interfaces.LocalNetwork) { // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) // Validate the Warp message, (this will be done on the P-Chain in the future) utils.ValidateSubnetValidatorWeightMessage( @@ -175,7 +175,7 @@ func NativeDelegation(network interfaces.LocalNetwork) { // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) Expect(err).Should(BeNil()) // Validate the Warp message, (this will be done on the P-Chain in the future) diff --git a/tests/interfaces/local_network.go b/tests/interfaces/local_network.go index 80b72f095..96c41751e 100644 --- a/tests/interfaces/local_network.go +++ b/tests/interfaces/local_network.go @@ -5,26 +5,13 @@ import ( "crypto/ecdsa" "github.com/ava-labs/avalanchego/ids" - avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" pwallet "github.com/ava-labs/avalanchego/wallet/chain/p/wallet" - "github.com/ava-labs/subnet-evm/core/types" "github.com/ethereum/go-ethereum/common" ) type LocalNetwork interface { Network AddSubnetValidators(ctx context.Context, subnetID ids.ID, count uint) - ExtractWarpMessageFromLog( - ctx context.Context, - sourceReceipt *types.Receipt, - source SubnetTestInfo, - ) *avalancheWarp.UnsignedMessage - ConstructSignedWarpMessage( - ctx context.Context, - sourceReceipt *types.Receipt, - source SubnetTestInfo, - destination SubnetTestInfo, - ) *avalancheWarp.Message GetAllNodeIDs() []ids.NodeID SetChainConfigs(chainConfigs map[string]string) RestartNodes(ctx context.Context, nodeIDs []ids.NodeID) @@ -41,6 +28,5 @@ type LocalNetwork interface { fundedKey *ecdsa.PrivateKey, ) GetNetworkID() uint32 - Dir() string GetPChainWallet() pwallet.Wallet } diff --git a/tests/interfaces/network.go b/tests/interfaces/network.go index f71afdfef..7bd84b60c 100644 --- a/tests/interfaces/network.go +++ b/tests/interfaces/network.go @@ -4,8 +4,6 @@ import ( "context" "crypto/ecdsa" - "github.com/ava-labs/avalanchego/ids" - avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/subnet-evm/core/types" "github.com/ethereum/go-ethereum/common" ) @@ -41,14 +39,6 @@ type Network interface { // connections with each validator. SupportsIndependentRelaying() bool - // GetSignedMessage returns the signed Warp message for the specified Warp message ID. - GetSignedMessage( - ctx context.Context, - source SubnetTestInfo, - destination SubnetTestInfo, - messageID ids.ID, - ) *avalancheWarp.Message - // For implementations where SupportsIndependentRelaying() is true, relays the specified message between the // two subnets,and returns the receipt of the transaction the message was delivered in. // For implementations where SupportsIndependentRelaying() is false, waits for the specific message to be relayed diff --git a/tests/local/governance/governance_suite_test.go b/tests/local/governance/governance_suite_test.go index ac2314aa3..add3d0e57 100644 --- a/tests/local/governance/governance_suite_test.go +++ b/tests/local/governance/governance_suite_test.go @@ -92,12 +92,6 @@ var _ = ginkgo.BeforeSuite(func() { // Deploy the Teleporter registry contracts to all subnets and the C-Chain. LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) - ginkgo.AddReportEntry( - "network directory with node logs & configs; useful in the case of failures", - LocalNetworkInstance.TmpNet().Dir, - ginkgo.ReportEntryVisibilityFailureOrVerbose, - ) - log.Info("Set up ginkgo before suite") }) diff --git a/tests/local/network.go b/tests/local/network.go index 23c03fbd3..1b38e6bad 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -20,18 +20,14 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/platformvm" - avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/secp256k1fx" pwallet "github.com/ava-labs/avalanchego/wallet/chain/p/wallet" "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/ethclient" - subnetEvmInterfaces "github.com/ava-labs/subnet-evm/interfaces" - "github.com/ava-labs/subnet-evm/precompile/contracts/warp" "github.com/ava-labs/subnet-evm/rpc" subnetEvmTestUtils "github.com/ava-labs/subnet-evm/tests/utils" - warpBackend "github.com/ava-labs/subnet-evm/warp" teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/TeleporterMessenger" teleporterregistry "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/registry/TeleporterRegistry" "github.com/ava-labs/teleporter/tests/interfaces" @@ -155,7 +151,7 @@ func NewLocalNetwork( // Issue transactions to activate the proposerVM fork on the chains for _, subnet := range network.Subnets { - setupProposerVM(ctx, globalFundedECDSAKey, network, subnet.SubnetID) + utils.SetupProposerVM(ctx, globalFundedECDSAKey, network, subnet.SubnetID) } localNetwork := &LocalNetwork{ @@ -189,10 +185,6 @@ func NewLocalNetwork( return localNetwork } -func (n *LocalNetwork) TmpNet() *tmpnet.Network { - return n.tmpnet -} - // Should be called after setSubnetValues for all subnets func (n *LocalNetwork) setPrimaryNetworkValues() { // Get the C-Chain node URIs. @@ -658,84 +650,6 @@ func (n *LocalNetwork) SetChainConfigs(chainConfigs map[string]string) { } } -func (n *LocalNetwork) ExtractWarpMessageFromLog( - ctx context.Context, - sourceReceipt *types.Receipt, - source interfaces.SubnetTestInfo, -) *avalancheWarp.UnsignedMessage { - log.Info("Fetching relevant warp logs from the newly produced block") - logs, err := source.RPCClient.FilterLogs(ctx, subnetEvmInterfaces.FilterQuery{ - BlockHash: &sourceReceipt.BlockHash, - Addresses: []common.Address{warp.Module.Address}, - }) - Expect(err).Should(BeNil()) - Expect(len(logs)).Should(Equal(1)) - - // Check for relevant warp log from subscription and ensure that it matches - // the log extracted from the last block. - txLog := logs[0] - log.Info("Parsing logData as unsigned warp message") - unsignedMsg, err := warp.UnpackSendWarpEventDataToMessage(txLog.Data) - Expect(err).Should(BeNil()) - return unsignedMsg -} - -func (n *LocalNetwork) ConstructSignedWarpMessage( - ctx context.Context, - sourceReceipt *types.Receipt, - source interfaces.SubnetTestInfo, - destination interfaces.SubnetTestInfo, -) *avalancheWarp.Message { - unsignedMsg := n.ExtractWarpMessageFromLog(ctx, sourceReceipt, source) - - // Set local variables for the duration of the test - unsignedWarpMessageID := unsignedMsg.ID() - log.Info( - "Parsed unsignedWarpMsg", - "unsignedWarpMessageID", unsignedWarpMessageID, - "unsignedWarpMessage", unsignedMsg, - ) - - // Loop over each client on source chain to ensure they all have time to accept the block. - // Note: if we did not confirm this here, the next stage could be racy since it assumes every node - // has accepted the block. - waitForAllValidatorsToAcceptBlock(ctx, source.NodeURIs, source.BlockchainID, sourceReceipt.BlockNumber.Uint64()) - - // Get the aggregate signature for the Warp message - log.Info("Fetching aggregate signature from the source chain validators") - return n.GetSignedMessage(ctx, source, destination, unsignedWarpMessageID) -} - -func (n *LocalNetwork) GetSignedMessage( - ctx context.Context, - source interfaces.SubnetTestInfo, - destination interfaces.SubnetTestInfo, - unsignedWarpMessageID ids.ID, -) *avalancheWarp.Message { - Expect(len(source.NodeURIs)).Should(BeNumerically(">", 0)) - warpClient, err := warpBackend.NewClient(source.NodeURIs[0], source.BlockchainID.String()) - Expect(err).Should(BeNil()) - - signingSubnetID := source.SubnetID - if source.SubnetID == constants.PrimaryNetworkID { - signingSubnetID = destination.SubnetID - } - - // Get the aggregate signature for the Warp message - signedWarpMessageBytes, err := warpClient.GetMessageAggregateSignature( - ctx, - unsignedWarpMessageID, - warp.WarpDefaultQuorumNumerator, - signingSubnetID.String(), - ) - Expect(err).Should(BeNil()) - - signedWarpMsg, err := avalancheWarp.ParseMessage(signedWarpMessageBytes) - Expect(err).Should(BeNil()) - - return signedWarpMsg -} - func (n *LocalNetwork) GetNetworkID() uint32 { return n.tmpnet.Genesis.NetworkID } diff --git a/tests/local/network_utils.go b/tests/local/network_utils.go deleted file mode 100644 index da166a6e0..000000000 --- a/tests/local/network_utils.go +++ /dev/null @@ -1,62 +0,0 @@ -package local - -import ( - "context" - "crypto/ecdsa" - "slices" - "time" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/subnet-evm/ethclient" - subnetEvmUtils "github.com/ava-labs/subnet-evm/tests/utils" - "github.com/ava-labs/teleporter/tests/utils" - "github.com/ethereum/go-ethereum/log" - - . "github.com/onsi/gomega" -) - -// Issues txs to activate the proposer VM fork on the specified subnet index in the manager -func setupProposerVM(ctx context.Context, fundedKey *ecdsa.PrivateKey, network *tmpnet.Network, subnetID ids.ID) { - subnetDetails := network.Subnets[slices.IndexFunc( - network.Subnets, - func(s *tmpnet.Subnet) bool { return s.SubnetID == subnetID }, - )] - - chainID := subnetDetails.Chains[0].ChainID - - nodeURI, err := network.GetURIForNodeID(subnetDetails.ValidatorIDs[0]) - Expect(err).Should(BeNil()) - uri := utils.HttpToWebsocketURI(nodeURI, chainID.String()) - - client, err := ethclient.Dial(uri) - Expect(err).Should(BeNil()) - chainIDInt, err := client.ChainID(ctx) - Expect(err).Should(BeNil()) - - err = subnetEvmUtils.IssueTxsToActivateProposerVMFork(ctx, chainIDInt, fundedKey, client) - Expect(err).Should(BeNil()) -} - -// Blocks until all validators specified in nodeURIs have reached the specified block height -func waitForAllValidatorsToAcceptBlock(ctx context.Context, nodeURIs []string, blockchainID ids.ID, height uint64) { - cctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - for i, uri := range nodeURIs { - chainAWSURI := utils.HttpToWebsocketURI(uri, blockchainID.String()) - log.Debug("Creating ethclient for blockchain", "blockchainID", blockchainID.String(), "wsURI", chainAWSURI) - client, err := ethclient.Dial(chainAWSURI) - Expect(err).Should(BeNil()) - defer client.Close() - - // Loop until each node has advanced to >= the height of the block that emitted the warp log - for { - block, err := client.BlockByNumber(cctx, nil) - Expect(err).Should(BeNil()) - if block.NumberU64() >= height { - log.Debug("Client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) - break - } - } - } -} diff --git a/tests/local/teleporter/teleporter_suite_test.go b/tests/local/teleporter/teleporter_suite_test.go index 923ee6c4d..34d646f6b 100644 --- a/tests/local/teleporter/teleporter_suite_test.go +++ b/tests/local/teleporter/teleporter_suite_test.go @@ -93,12 +93,6 @@ var _ = ginkgo.BeforeSuite(func() { // Deploy the Teleporter registry contracts to all subnets and the C-Chain. LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) - ginkgo.AddReportEntry( - "network directory with node logs & configs; useful in the case of failures", - LocalNetworkInstance.TmpNet().Dir, - ginkgo.ReportEntryVisibilityFailureOrVerbose, - ) - log.Info("Set up ginkgo before suite") }) diff --git a/tests/local/validator-manager/validator_manager_suite_test.go b/tests/local/validator-manager/validator_manager_suite_test.go index 50e360da3..b2a4539b6 100644 --- a/tests/local/validator-manager/validator_manager_suite_test.go +++ b/tests/local/validator-manager/validator_manager_suite_test.go @@ -93,12 +93,6 @@ var _ = ginkgo.BeforeSuite(func() { // Deploy the Teleporter registry contracts to all subnets and the C-Chain. LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) - ginkgo.AddReportEntry( - "network directory with node logs & configs; useful in the case of failures", - LocalNetworkInstance.TmpNet().Dir, - ginkgo.ReportEntryVisibilityFailureOrVerbose, - ) - log.Info("Set up ginkgo before suite") }) diff --git a/tests/utils/chain.go b/tests/utils/chain.go index dada1a2ec..1ba071c9b 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -9,6 +9,7 @@ import ( goLog "log" "math/big" "os" + "slices" "strconv" "strings" "time" @@ -33,6 +34,9 @@ import ( "github.com/ava-labs/subnet-evm/ethclient" subnetEvmInterfaces "github.com/ava-labs/subnet-evm/interfaces" "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + subnetEvmUtils "github.com/ava-labs/subnet-evm/tests/utils" + warpBackend "github.com/ava-labs/subnet-evm/warp" nativeMinter "github.com/ava-labs/teleporter/abi-bindings/go/INativeMinter" "github.com/ava-labs/teleporter/tests/interfaces" gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" @@ -587,6 +591,10 @@ func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.Signatu return agg } +// +// Native minter utils +// + // Funded key must have admin access to set new admin. func AddNativeMinterAdmin( ctx context.Context, @@ -603,3 +611,126 @@ func AddNativeMinterAdmin( Expect(err).Should(BeNil()) WaitForTransactionSuccess(ctx, subnet, tx.Hash()) } + +// Blocks until all validators specified in nodeURIs have reached the specified block height +func WaitForAllValidatorsToAcceptBlock(ctx context.Context, nodeURIs []string, blockchainID ids.ID, height uint64) { + cctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + for i, uri := range nodeURIs { + chainAWSURI := HttpToWebsocketURI(uri, blockchainID.String()) + log.Debug("Creating ethclient for blockchain", "blockchainID", blockchainID.String(), "wsURI", chainAWSURI) + client, err := ethclient.Dial(chainAWSURI) + Expect(err).Should(BeNil()) + defer client.Close() + + // Loop until each node has advanced to >= the height of the block that emitted the warp log + for { + block, err := client.BlockByNumber(cctx, nil) + Expect(err).Should(BeNil()) + if block.NumberU64() >= height { + log.Debug("Client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) + break + } + } + } +} + +func ExtractWarpMessageFromLog( + ctx context.Context, + sourceReceipt *types.Receipt, + source interfaces.SubnetTestInfo, +) *avalancheWarp.UnsignedMessage { + log.Info("Fetching relevant warp logs from the newly produced block") + logs, err := source.RPCClient.FilterLogs(ctx, subnetEvmInterfaces.FilterQuery{ + BlockHash: &sourceReceipt.BlockHash, + Addresses: []common.Address{warp.Module.Address}, + }) + Expect(err).Should(BeNil()) + Expect(len(logs)).Should(Equal(1)) + + // Check for relevant warp log from subscription and ensure that it matches + // the log extracted from the last block. + txLog := logs[0] + log.Info("Parsing logData as unsigned warp message") + unsignedMsg, err := warp.UnpackSendWarpEventDataToMessage(txLog.Data) + Expect(err).Should(BeNil()) + return unsignedMsg +} + +func ConstructSignedWarpMessage( + ctx context.Context, + sourceReceipt *types.Receipt, + source interfaces.SubnetTestInfo, + destination interfaces.SubnetTestInfo, +) *avalancheWarp.Message { + unsignedMsg := ExtractWarpMessageFromLog(ctx, sourceReceipt, source) + + // Set local variables for the duration of the test + unsignedWarpMessageID := unsignedMsg.ID() + log.Info( + "Parsed unsignedWarpMsg", + "unsignedWarpMessageID", unsignedWarpMessageID, + "unsignedWarpMessage", unsignedMsg, + ) + + // Loop over each client on source chain to ensure they all have time to accept the block. + // Note: if we did not confirm this here, the next stage could be racy since it assumes every node + // has accepted the block. + WaitForAllValidatorsToAcceptBlock(ctx, source.NodeURIs, source.BlockchainID, sourceReceipt.BlockNumber.Uint64()) + + // Get the aggregate signature for the Warp message + log.Info("Fetching aggregate signature from the source chain validators") + return GetSignedMessage(ctx, source, destination, unsignedWarpMessageID) +} + +func GetSignedMessage( + ctx context.Context, + source interfaces.SubnetTestInfo, + destination interfaces.SubnetTestInfo, + unsignedWarpMessageID ids.ID, +) *avalancheWarp.Message { + Expect(len(source.NodeURIs)).Should(BeNumerically(">", 0)) + warpClient, err := warpBackend.NewClient(source.NodeURIs[0], source.BlockchainID.String()) + Expect(err).Should(BeNil()) + + signingSubnetID := source.SubnetID + if source.SubnetID == constants.PrimaryNetworkID { + signingSubnetID = destination.SubnetID + } + + // Get the aggregate signature for the Warp message + // TODONOW: use signature aggregator + signedWarpMessageBytes, err := warpClient.GetMessageAggregateSignature( + ctx, + unsignedWarpMessageID, + warp.WarpDefaultQuorumNumerator, + signingSubnetID.String(), + ) + Expect(err).Should(BeNil()) + + signedWarpMsg, err := avalancheWarp.ParseMessage(signedWarpMessageBytes) + Expect(err).Should(BeNil()) + + return signedWarpMsg +} + +func SetupProposerVM(ctx context.Context, fundedKey *ecdsa.PrivateKey, network *tmpnet.Network, subnetID ids.ID) { + subnetDetails := network.Subnets[slices.IndexFunc( + network.Subnets, + func(s *tmpnet.Subnet) bool { return s.SubnetID == subnetID }, + )] + + chainID := subnetDetails.Chains[0].ChainID + + nodeURI, err := network.GetURIForNodeID(subnetDetails.ValidatorIDs[0]) + Expect(err).Should(BeNil()) + uri := HttpToWebsocketURI(nodeURI, chainID.String()) + + client, err := ethclient.Dial(uri) + Expect(err).Should(BeNil()) + chainIDInt, err := client.ChainID(ctx) + Expect(err).Should(BeNil()) + + err = subnetEvmUtils.IssueTxsToActivateProposerVMFork(ctx, chainIDInt, fundedKey, client) + Expect(err).Should(BeNil()) +} diff --git a/tests/utils/governance.go b/tests/utils/governance.go index 177d3f017..96d03555d 100644 --- a/tests/utils/governance.go +++ b/tests/utils/governance.go @@ -48,7 +48,7 @@ func ExecuteValidatorSetSigCallAndVerify( unsignedMessage *avalancheWarp.UnsignedMessage, expectSuccess bool, ) *types.Receipt { - signedWarpMsg := network.GetSignedMessage(ctx, source, destination, unsignedMessage.ID()) + signedWarpMsg := GetSignedMessage(ctx, source, destination, unsignedMessage.ID()) log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) signedPredicateTx := CreateExecuteCallPredicateTransaction( diff --git a/tests/utils/teleporter.go b/tests/utils/teleporter.go index 1647bd0fa..7f9840824 100644 --- a/tests/utils/teleporter.go +++ b/tests/utils/teleporter.go @@ -250,7 +250,7 @@ func AddProtocolVersionAndWaitForAcceptance( senderKey *ecdsa.PrivateKey, unsignedMessage *avalancheWarp.UnsignedMessage, ) { - signedWarpMsg := network.GetSignedMessage(ctx, subnet, subnet, unsignedMessage.ID()) + signedWarpMsg := GetSignedMessage(ctx, subnet, subnet, unsignedMessage.ID()) log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) // Construct tx to add protocol version and send to destination chain diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 389e760da..9c13bccdc 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -752,7 +752,7 @@ func InitializeAndCompleteNativeValidatorRegistration( // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) weight, err := stakingManager.ValueToWeight( &bind.CallOpts{}, @@ -833,7 +833,7 @@ func InitializeAndCompleteERC20ValidatorRegistration( // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) _, err := network.GetPChainWallet().IssueRegisterSubnetValidatorTx( 100*units.Avax, @@ -903,7 +903,7 @@ func InitializeAndCompletePoAValidatorRegistration( // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) // Validate the Warp message, (this will be done on the P-Chain in the future) ValidateRegisterSubnetValidatorMessage( @@ -1326,7 +1326,7 @@ func InitializeAndCompleteEndNativeValidation( // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) Expect(err).Should(BeNil()) // Validate the Warp message, (this will be done on the P-Chain in the future) @@ -1395,7 +1395,7 @@ func InitializeAndCompleteEndInitialERC20Validation( // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - unsignedMessage := network.ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) signedWarpMessage, err := signatureAggregator.CreateSignedMessage( unsignedMessage, nil, @@ -1473,7 +1473,7 @@ func InitializeAndCompleteEndERC20Validation( // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - unsignedMessage := network.ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) signedWarpMessage, err := signatureAggregator.CreateSignedMessage( unsignedMessage, nil, @@ -1550,7 +1550,7 @@ func InitializeAndCompleteEndPoAValidation( // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := network.ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) Expect(err).Should(BeNil()) // Validate the Warp message, (this will be done on the P-Chain in the future) From 2d5bbb35fedfcfd71f4d621b1eac38f6835cb189 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 17:27:48 -0500 Subject: [PATCH 14/34] cleanup --- tests/flows/governance/validator_set_sig.go | 2 +- .../registry/teleporter_registry.go | 2 +- tests/interfaces/local_network.go | 1 - .../local/governance/governance_suite_test.go | 44 +++---------------- tests/local/network.go | 26 +++++------ 5 files changed, 19 insertions(+), 56 deletions(-) diff --git a/tests/flows/governance/validator_set_sig.go b/tests/flows/governance/validator_set_sig.go index c715c02f3..cb32a09e8 100644 --- a/tests/flows/governance/validator_set_sig.go +++ b/tests/flows/governance/validator_set_sig.go @@ -143,7 +143,7 @@ func ValidatorSetSig(network interfaces.LocalNetwork) { network.SetChainConfigs(chainConfigs) restartCtx, cancel := context.WithTimeout(ctx, time.Second*30) defer cancel() - network.RestartNodes(restartCtx, network.GetAllNodeIDs()) + network.RestartNodes(restartCtx, nil) // ************************************************************************************************ // Test Case 1: validatorChain (subnetB) != targetChain (subnetA) diff --git a/tests/flows/teleporter/registry/teleporter_registry.go b/tests/flows/teleporter/registry/teleporter_registry.go index bca4de651..d6d6c14dc 100644 --- a/tests/flows/teleporter/registry/teleporter_registry.go +++ b/tests/flows/teleporter/registry/teleporter_registry.go @@ -79,7 +79,7 @@ func TeleporterRegistry(network interfaces.LocalNetwork) { network.SetChainConfigs(chainConfigs) restartCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - network.RestartNodes(restartCtx, network.GetAllNodeIDs()) + network.RestartNodes(restartCtx, nil) // Call addProtocolVersion on subnetB to register the new Teleporter version utils.AddProtocolVersionAndWaitForAcceptance( diff --git a/tests/interfaces/local_network.go b/tests/interfaces/local_network.go index 96c41751e..7b9e6aa7e 100644 --- a/tests/interfaces/local_network.go +++ b/tests/interfaces/local_network.go @@ -12,7 +12,6 @@ import ( type LocalNetwork interface { Network AddSubnetValidators(ctx context.Context, subnetID ids.ID, count uint) - GetAllNodeIDs() []ids.NodeID SetChainConfigs(chainConfigs map[string]string) RestartNodes(ctx context.Context, nodeIDs []ids.NodeID) DeployTeleporterContractToCChain( diff --git a/tests/local/governance/governance_suite_test.go b/tests/local/governance/governance_suite_test.go index add3d0e57..731b61330 100644 --- a/tests/local/governance/governance_suite_test.go +++ b/tests/local/governance/governance_suite_test.go @@ -8,7 +8,6 @@ import ( governanceFlows "github.com/ava-labs/teleporter/tests/flows/governance" "github.com/ava-labs/teleporter/tests/local" - deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -40,15 +39,6 @@ func TestGovernance(t *testing.T) { // Define the Teleporter before and after suite functions. var _ = ginkgo.BeforeSuite(func() { - // Generate the Teleporter deployment values - teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := - deploymentUtils.ConstructKeylessTransaction( - teleporterByteCodeFile, - false, - deploymentUtils.GetDefaultContractCreationGasPrice(), - ) - Expect(err).Should(BeNil()) - // Create the local network instance ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) defer cancel() @@ -58,41 +48,19 @@ var _ = ginkgo.BeforeSuite(func() { warpGenesisTemplateFile, []local.SubnetSpec{ { - Name: "A", - EVMChainID: 12345, - TeleporterContractAddress: teleporterContractAddress, - TeleporterDeployedBytecode: teleporterDeployedBytecode, - TeleporterDeployerAddress: teleporterDeployerAddress, - NodeCount: 2, + Name: "A", + EVMChainID: 12345, + NodeCount: 2, }, { - Name: "B", - EVMChainID: 54321, - TeleporterContractAddress: teleporterContractAddress, - TeleporterDeployedBytecode: teleporterDeployedBytecode, - TeleporterDeployerAddress: teleporterDeployerAddress, - NodeCount: 2, + Name: "B", + EVMChainID: 54321, + NodeCount: 2, }, }, 2, ) log.Info("Started local network") - - // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the subnet chains. - _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() - LocalNetworkInstance.DeployTeleporterContractToCChain( - teleporterDeployerTransaction, - teleporterDeployerAddress, - teleporterContractAddress, - fundedKey, - ) - LocalNetworkInstance.SetTeleporterContractAddress(teleporterContractAddress) - LocalNetworkInstance.InitializeBlockchainIDOnAllChains(fundedKey) - - // Deploy the Teleporter registry contracts to all subnets and the C-Chain. - LocalNetworkInstance.DeployTeleporterRegistryContracts(teleporterContractAddress, fundedKey) - - log.Info("Set up ginkgo before suite") }) var _ = ginkgo.AfterSuite(func() { diff --git a/tests/local/network.go b/tests/local/network.go index 1b38e6bad..2157a74ae 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -65,7 +65,7 @@ type SubnetSpec struct { Name string EVMChainID uint64 TeleporterContractAddress common.Address - TeleporterDeployedBytecode string + TeleporterDeployedBytecode []byte TeleporterDeployerAddress common.Address NodeCount int } @@ -475,7 +475,7 @@ func (n *LocalNetwork) RelayMessage(ctx context.Context, sendEvent, err := utils.GetEventFromLogs(sourceReceipt.Logs, source.TeleporterMessenger.ParseSendCrossChainMessage) Expect(err).Should(BeNil()) - signedWarpMessage := n.ConstructSignedWarpMessage(ctx, sourceReceipt, source, destination) + signedWarpMessage := utils.ConstructSignedWarpMessage(ctx, sourceReceipt, source, destination) // Construct the transaction to send the Warp message to the destination chain signedTx := utils.CreateReceiveCrossChainMessageTransaction( @@ -570,22 +570,18 @@ func (n *LocalNetwork) AddSubnetValidators(ctx context.Context, subnetID ids.ID, n.setAllSubnetValues() } -// GetAllNodeIDs returns a slice that copies the NodeID's of all nodes in the network -func (n *LocalNetwork) GetAllNodeIDs() []ids.NodeID { - nodeIDs := make([]ids.NodeID, len(n.tmpnet.Nodes)) - for i, node := range n.tmpnet.Nodes { - nodeIDs[i] = node.NodeID - } - return nodeIDs -} - +// Restarts the nodes with the given nodeIDs. If nodeIDs is empty, restarts all nodes. func (n *LocalNetwork) RestartNodes(ctx context.Context, nodeIDs []ids.NodeID) { log.Info("Restarting nodes", "nodeIDs", nodeIDs) var nodes []*tmpnet.Node - for _, nodeID := range nodeIDs { - for _, node := range n.tmpnet.Nodes { - if node.NodeID == nodeID { - nodes = append(nodes, node) + if len(nodeIDs) == 0 { + nodes = n.tmpnet.Nodes + } else { + for _, nodeID := range nodeIDs { + for _, node := range n.tmpnet.Nodes { + if node.NodeID == nodeID { + nodes = append(nodes, node) + } } } } From 3b62b9be710a6611b77e02d89a5e89bf4bbb7c6e Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 17:31:28 -0500 Subject: [PATCH 15/34] build fix --- tests/local/network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/local/network.go b/tests/local/network.go index 2157a74ae..0909cd42f 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -65,7 +65,7 @@ type SubnetSpec struct { Name string EVMChainID uint64 TeleporterContractAddress common.Address - TeleporterDeployedBytecode []byte + TeleporterDeployedBytecode string TeleporterDeployerAddress common.Address NodeCount int } From c8ebfd262f1fe171933d1c441a476584f02aff71 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 18:02:24 -0500 Subject: [PATCH 16/34] add back in teleporter setup --- .../local/governance/governance_suite_test.go | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/local/governance/governance_suite_test.go b/tests/local/governance/governance_suite_test.go index 731b61330..f157dc224 100644 --- a/tests/local/governance/governance_suite_test.go +++ b/tests/local/governance/governance_suite_test.go @@ -8,6 +8,7 @@ import ( governanceFlows "github.com/ava-labs/teleporter/tests/flows/governance" "github.com/ava-labs/teleporter/tests/local" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -39,6 +40,15 @@ func TestGovernance(t *testing.T) { // Define the Teleporter before and after suite functions. var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + _, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := + deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + // Create the local network instance ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) defer cancel() @@ -48,14 +58,20 @@ var _ = ginkgo.BeforeSuite(func() { warpGenesisTemplateFile, []local.SubnetSpec{ { - Name: "A", - EVMChainID: 12345, - NodeCount: 2, + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, }, { - Name: "B", - EVMChainID: 54321, - NodeCount: 2, + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, }, }, 2, From 5a76c0742383c2a0e11224e6a0ee9a9a76a1e71d Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Wed, 9 Oct 2024 18:26:24 -0500 Subject: [PATCH 17/34] recover subnet helper --- .../validator-manager/erc20_token_staking.go | 91 ++---------- .../validator_manager_suite_test.go | 40 ++--- tests/utils/chain.go | 1 + tests/utils/validator_manager.go | 140 +++++++++++++----- 4 files changed, 131 insertions(+), 141 deletions(-) diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index 6f5c7fc04..d960f1726 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -4,15 +4,9 @@ import ( "context" "log" "math/big" - "sort" "time" - "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/formatting/address" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/warp/message" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/teleporter/tests/interfaces" "github.com/ava-labs/teleporter/tests/utils" @@ -58,71 +52,13 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { pChainInfo, ) - var nodes []utils.Node - - // Remove the current validators before converting the subnet - for _, uri := range subnetAInfo.NodeURIs { - infoClient := info.NewClient(uri) - nodeID, nodePoP, err := infoClient.GetNodeID(ctx) - Expect(err).Should(BeNil()) - nodes = append(nodes, utils.Node{ - NodeID: nodeID, - NodePoP: nodePoP, - }) - - _, err = network.GetPChainWallet().IssueRemoveSubnetValidatorTx( - nodeID, - subnetAInfo.SubnetID, - ) - Expect(err).Should(BeNil()) - } - - // Sort the nodeIDs so that the subnet conversion ID matches the P-Chain - sort.Slice(nodes, func(i, j int) bool { - return string(nodes[i].NodeID.Bytes()) < string(nodes[j].NodeID.Bytes()) - }) - - weights := make([]uint64, len(nodes)) - totalWeight := uint64(len(nodes)-1) * units.Schmeckle - for i := 0; i < len(nodes)-1; i++ { - weights[i] = units.Schmeckle - totalWeight += units.Schmeckle - } - // Set the last node's weight such that removing any other node will not violate the churn limit - weights[len(nodes)-1] = 4 * totalWeight - - // Construct the convert subnet info - destAddr, err := address.ParseToID(utils.DefaultPChainAddress) - Expect(err).Should(BeNil()) - vdrs := make([]*txs.ConvertSubnetValidator, len(nodes)) - for i, node := range nodes { - vdrs[i] = &txs.ConvertSubnetValidator{ - NodeID: node.NodeID.Bytes(), - Weight: weights[i], - Balance: units.Avax * 100, - Signer: *node.NodePoP, - RemainingBalanceOwner: message.PChainOwner{ - Threshold: 1, - Addresses: []ids.ShortID{destAddr}, - }, - DeactivationOwner: message.PChainOwner{ - Threshold: 1, - Addresses: []ids.ShortID{destAddr}, - }, - } - } - - log.Println("Issuing ConvertSubnetTx") - _, err = network.GetPChainWallet().IssueConvertSubnetTx( - subnetAInfo.SubnetID, - subnetAInfo.BlockchainID, - stakingManagerAddress[:], - vdrs, + nodes := utils.ConvertSubnet( + ctx, + subnetAInfo, + network, + stakingManagerAddress, + fundedKey, ) - Expect(err).Should(BeNil()) - - utils.PChainProposerVMWorkaround(network) - utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) // Initialize the validator set on the subnet log.Println("Initializing validator set") @@ -136,11 +72,10 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { network, signatureAggregator, nodes, - weights, ) // - // Delist one initial validators + // Delist one initial validator // utils.InitializeAndCompleteEndInitialERC20Validation( ctx, @@ -153,7 +88,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { stakingManagerAddress, initialValidationIDs[0], 0, - weights[0], + nodes[0].Weight, ) // @@ -161,7 +96,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // stakeAmount, err := stakingManager.WeightToValue( &bind.CallOpts{}, - weights[0], + nodes[0].Weight, ) Expect(err).Should(BeNil()) expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) @@ -176,7 +111,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { stakingManagerAddress, erc20, stakeAmount, - weights[0], expiry, nodes[0], ) @@ -189,7 +123,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { log.Println("Registering delegator") delegatorStake, err := stakingManager.WeightToValue( &bind.CallOpts{}, - weights[0], + nodes[0].Weight, ) Expect(err).Should(BeNil()) delegatorStake.Div(delegatorStake, big.NewInt(10)) @@ -198,7 +132,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { delegatorStake, ) Expect(err).Should(BeNil()) - newValidatorWeight := weights[0] + delegatorWeight + newValidatorWeight := nodes[0].Weight + delegatorWeight nonce := uint64(1) @@ -294,7 +228,7 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( validationID, nonce, - weights[0], + nodes[0].Weight, subnetAInfo, pChainInfo, network, @@ -336,7 +270,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { validationID, expiry, nodes[0], - weights[0], 1, ) } diff --git a/tests/local/validator-manager/validator_manager_suite_test.go b/tests/local/validator-manager/validator_manager_suite_test.go index b2a4539b6..f7b169b34 100644 --- a/tests/local/validator-manager/validator_manager_suite_test.go +++ b/tests/local/validator-manager/validator_manager_suite_test.go @@ -102,34 +102,24 @@ var _ = ginkgo.AfterSuite(func() { var _ = ginkgo.Describe("[Validator manager integration tests]", func() { // Validator Manager tests - ginkgo.It("Native token staking manager", - ginkgo.Label(validatorManagerLabel), - func() { - validatorManagerFlows.NativeTokenStakingManager(LocalNetworkInstance) - }) + // ginkgo.It("Native token staking manager", + // ginkgo.Label(validatorManagerLabel), + // func() { + // validatorManagerFlows.NativeTokenStakingManager(LocalNetworkInstance) + // }) ginkgo.It("ERC20 token staking manager", ginkgo.Label(validatorManagerLabel), func() { validatorManagerFlows.ERC20TokenStakingManager(LocalNetworkInstance) }) - ginkgo.It("PoA validator manager", - ginkgo.Label(validatorManagerLabel), - func() { - validatorManagerFlows.PoAValidatorManager(LocalNetworkInstance) - }) - ginkgo.It("ERC20 delegation", - ginkgo.Label(validatorManagerLabel), - func() { - validatorManagerFlows.ERC20Delegation(LocalNetworkInstance) - }) - ginkgo.It("Native token delegation", - ginkgo.Label(validatorManagerLabel), - func() { - validatorManagerFlows.NativeDelegation(LocalNetworkInstance) - }) - ginkgo.It("PoA migration to PoS", - ginkgo.Label(validatorManagerLabel), - func() { - validatorManagerFlows.PoAMigrationToPoS(LocalNetworkInstance) - }) + // ginkgo.It("PoA validator manager", + // ginkgo.Label(validatorManagerLabel), + // func() { + // validatorManagerFlows.PoAValidatorManager(LocalNetworkInstance) + // }) + // ginkgo.It("PoA migration to PoS", + // ginkgo.Label(validatorManagerLabel), + // func() { + // validatorManagerFlows.PoAMigrationToPoS(LocalNetworkInstance) + // }) }) diff --git a/tests/utils/chain.go b/tests/utils/chain.go index 1ba071c9b..d6f185810 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -80,6 +80,7 @@ var WarpEnabledChainConfig = tmpnet.FlagsMap{ type Node struct { NodeID ids.NodeID NodePoP *signer.ProofOfPossession + Weight uint64 } // diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 9c13bccdc..431be0a49 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -9,8 +9,10 @@ import ( "log" "math/big" "reflect" + "sort" "time" + "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/platformvm" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -18,8 +20,9 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" - warpMessages "github.com/ava-labs/avalanchego/vms/platformvm/warp/message" + warpMessage "github.com/ava-labs/avalanchego/vms/platformvm/warp/message" warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/awm-relayer/signature-aggregator/aggregator" @@ -328,25 +331,23 @@ func InitializeERC20TokenValidatorSet( network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, nodes []Node, - initialValidatorWeights []uint64, ) []ids.ID { - Expect(len(nodes)).Should(Equal(len(initialValidatorWeights))) - initialValidators := make([]warpMessages.SubnetConversionValidatorData, len(nodes)) + initialValidators := make([]warpMessage.SubnetConversionValidatorData, len(nodes)) initialValidatorsABI := make([]erc20tokenstakingmanager.InitialValidator, len(nodes)) for i, node := range nodes { - initialValidators[i] = warpMessages.SubnetConversionValidatorData{ + initialValidators[i] = warpMessage.SubnetConversionValidatorData{ NodeID: node.NodeID.Bytes(), BLSPublicKey: node.NodePoP.PublicKey, - Weight: initialValidatorWeights[i], + Weight: nodes[i].Weight, } initialValidatorsABI[i] = erc20tokenstakingmanager.InitialValidator{ NodeID: node.NodeID.Bytes(), BlsPublicKey: node.NodePoP.PublicKey[:], - Weight: initialValidatorWeights[i], + Weight: nodes[i].Weight, } } - subnetConversionData := warpMessages.SubnetConversionData{ + subnetConversionData := warpMessage.SubnetConversionData{ SubnetID: subnetInfo.SubnetID, ManagerChainID: subnetInfo.BlockchainID, ManagerAddress: validatorManagerAddress[:], @@ -358,7 +359,7 @@ func InitializeERC20TokenValidatorSet( ValidatorManagerAddress: validatorManagerAddress, InitialValidators: initialValidatorsABI, } - subnetConversionID, err := warpMessages.SubnetConversionID(subnetConversionData) + subnetConversionID, err := warpMessage.SubnetConversionID(subnetConversionData) Expect(err).Should(BeNil()) // subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) // Expect(err).Should(BeNil()) @@ -390,7 +391,7 @@ func InitializeERC20TokenValidatorSet( validationIDs = append(validationIDs, subnetInfo.SubnetID.Append(uint32(i))) } - Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeights[0]))) + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(nodes[0].Weight))) emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) Expect(emittedValidationID).Should(Equal(validationIDs[0])) @@ -773,7 +774,6 @@ func InitializeAndCompleteNativeValidatorRegistration( validationID, 0, Node{}, - 0, true, subnetInfo, pChainInfo, @@ -811,7 +811,6 @@ func InitializeAndCompleteERC20ValidatorRegistration( stakingManagerAddress common.Address, erc20 *exampleerc20.ExampleERC20, stakeAmount *big.Int, - weight uint64, expiry uint64, node Node, ) ids.ID { @@ -849,7 +848,6 @@ func InitializeAndCompleteERC20ValidatorRegistration( validationID, expiry, node, - weight, true, subnetInfo, pChainInfo, @@ -919,7 +917,6 @@ func InitializeAndCompletePoAValidatorRegistration( validationID, 0, Node{}, - 0, true, subnetInfo, pChainInfo, @@ -1337,7 +1334,6 @@ func InitializeAndCompleteEndNativeValidation( validationID, 0, Node{}, - 0, false, subnetInfo, pChainInfo, @@ -1451,7 +1447,6 @@ func InitializeAndCompleteEndERC20Validation( validationID ids.ID, expiry uint64, node Node, - weight uint64, nonce uint64, ) { log.Println("Initializing validator removal") @@ -1469,7 +1464,7 @@ func InitializeAndCompleteEndERC20Validation( ) Expect(err).Should(BeNil()) Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(weight)) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(node.Weight)) // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) @@ -1493,7 +1488,6 @@ func InitializeAndCompleteEndERC20Validation( validationID, expiry, node, - weight, false, subnetInfo, pChainInfo, @@ -1561,7 +1555,6 @@ func InitializeAndCompleteEndPoAValidation( validationID, 0, Node{}, - 0, false, subnetInfo, pChainInfo, @@ -1611,7 +1604,7 @@ func ConstructSubnetValidatorRegistrationMessageForInitialValidator( justificationBytes, err := proto.Marshal(&justification) Expect(err).Should(BeNil()) - registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) + registrationPayload, err := warpMessage.NewSubnetValidatorRegistration(validationID, valid) Expect(err).Should(BeNil()) registrationAddressedCall, err := warpPayload.NewAddressedCall(nil, registrationPayload.Bytes()) Expect(err).Should(BeNil()) @@ -1637,21 +1630,20 @@ func ConstructSubnetValidatorRegistrationMessage( validationID ids.ID, expiry uint64, node Node, - weight uint64, valid bool, subnet interfaces.SubnetTestInfo, pChainInfo interfaces.SubnetTestInfo, network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, ) *avalancheWarp.Message { - msg, err := warpMessages.NewRegisterSubnetValidator( + msg, err := warpMessage.NewRegisterSubnetValidator( subnet.SubnetID, node.NodeID, node.NodePoP.PublicKey, expiry, - warpMessages.PChainOwner{}, - warpMessages.PChainOwner{}, - weight, + warpMessage.PChainOwner{}, + warpMessage.PChainOwner{}, + node.Weight, ) Expect(err).Should(BeNil()) justification := platformvm.SubnetValidatorRegistrationJustification{ @@ -1662,7 +1654,7 @@ func ConstructSubnetValidatorRegistrationMessage( justificationBytes, err := proto.Marshal(&justification) Expect(err).Should(BeNil()) - registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) + registrationPayload, err := warpMessage.NewSubnetValidatorRegistration(validationID, valid) Expect(err).Should(BeNil()) registrationAddressedCall, err := warpPayload.NewAddressedCall(nil, registrationPayload.Bytes()) Expect(err).Should(BeNil()) @@ -1693,7 +1685,7 @@ func ConstructSubnetValidatorWeightUpdateMessage( network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, ) *avalancheWarp.Message { - payload, err := warpMessages.NewSubnetValidatorWeight(validationID, nonce, weight) + payload, err := warpMessage.NewSubnetValidatorWeight(validationID, nonce, weight) Expect(err).Should(BeNil()) updateAddressedCall, err := warpPayload.NewAddressedCall(nil, payload.Bytes()) Expect(err).Should(BeNil()) @@ -1721,7 +1713,7 @@ func ConstructSubnetConversionMessage( network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, ) *avalancheWarp.Message { - subnetConversionPayload, err := warpMessages.NewSubnetConversion(subnetConversionID) + subnetConversionPayload, err := warpMessage.NewSubnetConversion(subnetConversionID) Expect(err).Should(BeNil()) subnetConversionAddressedCall, err := warpPayload.NewAddressedCall( nil, @@ -1761,13 +1753,13 @@ func ValidateRegisterSubnetValidatorMessage( msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) Expect(err).Should(BeNil()) // Check that the addressed call payload is a registered Warp message type - var payloadInterface warpMessages.Payload - ver, err := warpMessages.Codec.Unmarshal(msg.Payload, &payloadInterface) + var payloadInterface warpMessage.Payload + ver, err := warpMessage.Codec.Unmarshal(msg.Payload, &payloadInterface) Expect(err).Should(BeNil()) - payload, ok := payloadInterface.(*warpMessages.RegisterSubnetValidator) + payload, ok := payloadInterface.(*warpMessage.RegisterSubnetValidator) Expect(ok).Should(BeTrue()) - Expect(ver).Should(Equal(uint16(warpMessages.CodecVersion))) + Expect(ver).Should(Equal(uint16(warpMessage.CodecVersion))) Expect(payload.NodeID).Should(Equal(nodeID)) Expect(payload.Weight).Should(Equal(weight)) Expect(payload.SubnetID).Should(Equal(subnetID)) @@ -1783,13 +1775,13 @@ func ValidateSubnetValidatorWeightMessage( msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) Expect(err).Should(BeNil()) // Check that the addressed call payload is a registered Warp message type - var payloadInterface warpMessages.Payload - ver, err := warpMessages.Codec.Unmarshal(msg.Payload, &payloadInterface) + var payloadInterface warpMessage.Payload + ver, err := warpMessage.Codec.Unmarshal(msg.Payload, &payloadInterface) Expect(err).Should(BeNil()) - payload, ok := payloadInterface.(*warpMessages.SubnetValidatorWeight) + payload, ok := payloadInterface.(*warpMessage.SubnetValidatorWeight) Expect(ok).Should(BeTrue()) - Expect(ver).Should(Equal(uint16(warpMessages.CodecVersion))) + Expect(ver).Should(Equal(uint16(warpMessage.CodecVersion))) Expect(payload.ValidationID).Should(Equal(validationID)) Expect(payload.Weight).Should(Equal(weight)) Expect(payload.Nonce).Should(Equal(nonce)) @@ -1876,7 +1868,7 @@ func PackSubnetConversionData(data interface{}) ([]byte, error) { } b := make([]byte, 94+packedInitialValidatorsLen) - binary.BigEndian.PutUint16(b[0:2], uint16(warpMessages.CodecVersion)) + binary.BigEndian.PutUint16(b[0:2], uint16(warpMessage.CodecVersion)) copy(b[2:34], subnetID[:]) copy(b[34:66], validatorManagerBlockchainID[:]) // These are evm addresses and have lengths of 20 so hardcoding here @@ -2007,3 +1999,77 @@ func AdvanceProposerVM( Expect(err).Should(BeNil()) } } + +func ConvertSubnet( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + network interfaces.LocalNetwork, + stakingManagerAddress common.Address, + fundedKey *ecdsa.PrivateKey, +) []Node { + // Remove the current validators before converting the subnet + var nodes []Node + for _, uri := range subnetInfo.NodeURIs { + infoClient := info.NewClient(uri) + nodeID, nodePoP, err := infoClient.GetNodeID(ctx) + Expect(err).Should(BeNil()) + nodes = append(nodes, Node{ + NodeID: nodeID, + NodePoP: nodePoP, + }) + + _, err = network.GetPChainWallet().IssueRemoveSubnetValidatorTx( + nodeID, + subnetInfo.SubnetID, + ) + Expect(err).Should(BeNil()) + } + + // Sort the nodeIDs so that the subnet conversion ID matches the P-Chain + sort.Slice(nodes, func(i, j int) bool { + return string(nodes[i].NodeID.Bytes()) < string(nodes[j].NodeID.Bytes()) + }) + + totalWeight := uint64(len(nodes)-1) * units.Schmeckle + for i := 0; i < len(nodes)-1; i++ { + nodes[i].Weight = units.Schmeckle + totalWeight += units.Schmeckle + } + // Set the last node's weight such that removing any other node will not violate the churn limit + nodes[len(nodes)-1].Weight = 4 * totalWeight + + // Construct the convert subnet info + destAddr, err := address.ParseToID(DefaultPChainAddress) + Expect(err).Should(BeNil()) + vdrs := make([]*txs.ConvertSubnetValidator, len(nodes)) + for i, node := range nodes { + vdrs[i] = &txs.ConvertSubnetValidator{ + NodeID: node.NodeID.Bytes(), + Weight: nodes[i].Weight, + Balance: units.Avax * 100, + Signer: *node.NodePoP, + RemainingBalanceOwner: warpMessage.PChainOwner{ + Threshold: 1, + Addresses: []ids.ShortID{destAddr}, + }, + DeactivationOwner: warpMessage.PChainOwner{ + Threshold: 1, + Addresses: []ids.ShortID{destAddr}, + }, + } + } + + log.Println("Issuing ConvertSubnetTx") + _, err = network.GetPChainWallet().IssueConvertSubnetTx( + subnetInfo.SubnetID, + subnetInfo.BlockchainID, + stakingManagerAddress[:], + vdrs, + ) + Expect(err).Should(BeNil()) + + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) + + return nodes +} From 0fa2ae8fc1d9e6d461543410a4fbceb468e4519e Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 09:09:39 -0500 Subject: [PATCH 18/34] native staking e2e --- .../validator-manager/erc20_token_staking.go | 8 - .../validator-manager/native_token_staking.go | 193 ++++++++++++++-- tests/utils/validator_manager.go | 214 +++++++++++++----- 3 files changed, 334 insertions(+), 81 deletions(-) diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go index d960f1726..b720b475b 100644 --- a/tests/flows/validator-manager/erc20_token_staking.go +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -94,11 +94,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // // Register the validator as PoS // - stakeAmount, err := stakingManager.WeightToValue( - &bind.CallOpts{}, - nodes[0].Weight, - ) - Expect(err).Should(BeNil()) expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) validationID := utils.InitializeAndCompleteERC20ValidatorRegistration( ctx, @@ -110,7 +105,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { stakingManager, stakingManagerAddress, erc20, - stakeAmount, expiry, nodes[0], ) @@ -154,7 +148,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { delegationID = initRegistrationEvent.DelegationID // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) // Issue a tx to update the validator's weight on the P-Chain @@ -220,7 +213,6 @@ func ERC20TokenStakingManager(network interfaces.LocalNetwork) { // Issue a tx to update the validator's weight on the P-Chain network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) - utils.PChainProposerVMWorkaround(network) utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) diff --git a/tests/flows/validator-manager/native_token_staking.go b/tests/flows/validator-manager/native_token_staking.go index f6ec14ba3..80a7961b0 100644 --- a/tests/flows/validator-manager/native_token_staking.go +++ b/tests/flows/validator-manager/native_token_staking.go @@ -2,7 +2,9 @@ package staking import ( "context" + "log" "math/big" + "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/subnet-evm/accounts/abi/bind" @@ -43,37 +45,58 @@ func NativeTokenStakingManager(network interfaces.LocalNetwork) { ctx := context.Background() // Deploy the staking manager contract - stakingManagerContractAddress, stakingManager := utils.DeployAndInitializeNativeTokenStakingManager( + stakingManagerAddress, stakingManager := utils.DeployAndInitializeNativeTokenStakingManager( ctx, fundedKey, subnetAInfo, pChainInfo, ) - utils.AddNativeMinterAdmin(ctx, subnetAInfo, fundedKey, stakingManagerContractAddress) + utils.AddNativeMinterAdmin(ctx, subnetAInfo, fundedKey, stakingManagerAddress) - _ = utils.InitializeNativeTokenValidatorSet( + nodes := utils.ConvertSubnet( + ctx, + subnetAInfo, + network, + stakingManagerAddress, + fundedKey, + ) + + // Initialize the validator set on the subnet + log.Println("Initializing validator set") + initialValidationIDs := utils.InitializeNativeTokenValidatorSet( ctx, fundedKey, subnetAInfo, pChainInfo, stakingManager, - stakingManagerContractAddress, + stakingManagerAddress, network, signatureAggregator, - utils.DefaultMinStakeAmount*10, + nodes, ) // - // Register a validator + // Delist one initial validator // - stakeAmount := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) - weight, err := stakingManager.ValueToWeight( - &bind.CallOpts{}, - stakeAmount, + utils.InitializeAndCompleteEndInitialNativeValidation( + ctx, + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + initialValidationIDs[0], + 0, + nodes[0].Weight, ) - Expect(err).Should(BeNil()) - // Iniatiate validator registration + + // + // Register the validator as PoS + // + expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) validationID := utils.InitializeAndCompleteNativeValidatorRegistration( ctx, network, @@ -82,10 +105,147 @@ func NativeTokenStakingManager(network interfaces.LocalNetwork) { subnetAInfo, pChainInfo, stakingManager, - stakingManagerContractAddress, - stakeAmount, + stakingManagerAddress, + expiry, + nodes[0], ) + // + // Register a delegator + // + var delegationID ids.ID + { + log.Println("Registering delegator") + delegatorStake, err := stakingManager.WeightToValue( + &bind.CallOpts{}, + nodes[0].Weight, + ) + Expect(err).Should(BeNil()) + delegatorStake.Div(delegatorStake, big.NewInt(10)) + delegatorWeight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + newValidatorWeight := nodes[0].Weight + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitializeNativeDelegatorRegistration( + ctx, + fundedKey, + subnetAInfo, + validationID, + delegatorStake, + stakingManagerAddress, + stakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorAdded, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + + // Issue a tx to update the validator's weight on the P-Chain + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network) + utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + newValidatorWeight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteNativeDelegatorRegistration( + ctx, + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // + // Delist the delegator + // + { + log.Println("Delisting delegator") + nonce := uint64(2) + receipt := utils.InitializeEndNativeDelegation( + ctx, + fundedKey, + subnetAInfo, + stakingManager, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Issue a tx to update the validator's weight on the P-Chain + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network) + utils.AdvanceProposerVM(ctx, subnetAInfo, fundedKey, 5) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + nodes[0].Weight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteEndNativeDelegation( + ctx, + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegationEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // // Delist the validator // @@ -97,9 +257,10 @@ func NativeTokenStakingManager(network interfaces.LocalNetwork) { subnetAInfo, pChainInfo, stakingManager, - stakingManagerContractAddress, + stakingManagerAddress, validationID, - weight, + expiry, + nodes[0], 1, ) } diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 431be0a49..b2fc10efb 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -271,25 +271,37 @@ func InitializeNativeTokenValidatorSet( validatorManagerAddress common.Address, network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, - initialValidatorWeight uint64, -) ids.ID { - nodeID := ids.GenerateTestID() - blsPublicKey := [bls.PublicKeyLen]byte{} - subnetConversionData := nativetokenstakingmanager.SubnetConversionData{ + nodes []Node, +) []ids.ID { + initialValidators := make([]warpMessage.SubnetConversionValidatorData, len(nodes)) + initialValidatorsABI := make([]nativetokenstakingmanager.InitialValidator, len(nodes)) + for i, node := range nodes { + initialValidators[i] = warpMessage.SubnetConversionValidatorData{ + NodeID: node.NodeID.Bytes(), + BLSPublicKey: node.NodePoP.PublicKey, + Weight: nodes[i].Weight, + } + initialValidatorsABI[i] = nativetokenstakingmanager.InitialValidator{ + NodeID: node.NodeID.Bytes(), + BlsPublicKey: node.NodePoP.PublicKey[:], + Weight: nodes[i].Weight, + } + } + + subnetConversionData := warpMessage.SubnetConversionData{ + SubnetID: subnetInfo.SubnetID, + ManagerChainID: subnetInfo.BlockchainID, + ManagerAddress: validatorManagerAddress[:], + Validators: initialValidators, + } + subnetConversionDataABI := nativetokenstakingmanager.SubnetConversionData{ SubnetID: subnetInfo.SubnetID, ValidatorManagerBlockchainID: subnetInfo.BlockchainID, ValidatorManagerAddress: validatorManagerAddress, - InitialValidators: []nativetokenstakingmanager.InitialValidator{ - { - NodeID: nodeID[:], - Weight: initialValidatorWeight, - BlsPublicKey: blsPublicKey[:], - }, - }, + InitialValidators: initialValidatorsABI, } - subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) + subnetConversionID, err := warpMessage.SubnetConversionID(subnetConversionData) Expect(err).Should(BeNil()) - subnetConversionID := sha256.Sum256(subnetConversionDataBytes) subnetConversionSignedMessage := ConstructSubnetConversionMessage( subnetConversionID, subnetInfo, @@ -304,21 +316,24 @@ func InitializeNativeTokenValidatorSet( subnetInfo, validatorManagerAddress, subnetConversionSignedMessage, - subnetConversionData, + subnetConversionDataABI, ) initialValidatorCreatedEvent, err := GetEventFromLogs( receipt.Logs, validatorManager.ParseInitialValidatorCreated, ) Expect(err).Should(BeNil()) - Expect(initialValidatorCreatedEvent.NodeID).Should(Equal(subnetConversionData.InitialValidators[0].NodeID)) - Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeight))) + var validationIDs []ids.ID + for i := range nodes { + validationIDs = append(validationIDs, subnetInfo.SubnetID.Append(uint32(i))) + } + + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(nodes[0].Weight))) - expectedValidationID := CalculateSubnetConversionValidationId(subnetInfo.SubnetID, 0) emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) - Expect(emittedValidationID).Should(Equal(expectedValidationID)) + Expect(emittedValidationID).Should(Equal(validationIDs[0])) - return emittedValidationID + return validationIDs } func InitializeERC20TokenValidatorSet( @@ -361,9 +376,6 @@ func InitializeERC20TokenValidatorSet( } subnetConversionID, err := warpMessage.SubnetConversionID(subnetConversionData) Expect(err).Should(BeNil()) - // subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) - // Expect(err).Should(BeNil()) - // subnetConversionID := sha256.Sum256(subnetConversionDataBytes) subnetConversionSignedMessage := ConstructSubnetConversionMessage( subnetConversionID, subnetInfo, @@ -534,8 +546,8 @@ func InitializeNativeValidatorRegistration( senderKey *ecdsa.PrivateKey, subnet interfaces.SubnetTestInfo, stakeAmount *big.Int, - nodeID ids.ID, - blsPublicKey [bls.PublicKeyLen]byte, + node Node, + expiry uint64, stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, ) (*types.Receipt, ids.ID) { opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) @@ -545,9 +557,9 @@ func InitializeNativeValidatorRegistration( tx, err := stakingManager.InitializeValidatorRegistration( opts, nativetokenstakingmanager.ValidatorRegistrationInput{ - NodeID: nodeID[:], - RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), - BlsPublicKey: blsPublicKey[:], + NodeID: node.NodeID[:], + RegistrationExpiry: expiry, + BlsPublicKey: node.NodePoP.PublicKey[:], }, DefaultMinDelegateFeeBips, DefaultMinStakeDurationSeconds, @@ -736,18 +748,22 @@ func InitializeAndCompleteNativeValidatorRegistration( pChainInfo interfaces.SubnetTestInfo, stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, stakingManagerContractAddress common.Address, - stakeAmount *big.Int, + expiry uint64, + node Node, ) ids.ID { + stakeAmount, err := stakingManager.WeightToValue( + &bind.CallOpts{}, + node.Weight, + ) + Expect(err).Should(BeNil()) // Initiate validator registration - nodeID := ids.GenerateTestID() - blsPublicKey := [bls.PublicKeyLen]byte{} receipt, validationID := InitializeNativeValidatorRegistration( ctx, fundedKey, subnetInfo, stakeAmount, - nodeID, - blsPublicKey, + node, + expiry, stakingManager, ) @@ -755,25 +771,21 @@ func InitializeAndCompleteNativeValidatorRegistration( // (Sending to the P-Chain will be skipped for now) signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) - weight, err := stakingManager.ValueToWeight( - &bind.CallOpts{}, - stakeAmount, + _, err = network.GetPChainWallet().IssueRegisterSubnetValidatorTx( + 100*units.Avax, + node.NodePoP.ProofOfPossession, + signedWarpMessage.Bytes(), ) Expect(err).Should(BeNil()) - // Validate the Warp message, (this will be done on the P-Chain in the future) - ValidateRegisterSubnetValidatorMessage( - signedWarpMessage, - nodeID, - weight, - subnetInfo.SubnetID, - blsPublicKey, - ) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator registration") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - 0, - Node{}, + expiry, + node, true, subnetInfo, pChainInfo, @@ -810,11 +822,14 @@ func InitializeAndCompleteERC20ValidatorRegistration( stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, stakingManagerAddress common.Address, erc20 *exampleerc20.ExampleERC20, - stakeAmount *big.Int, expiry uint64, node Node, ) ids.ID { - + stakeAmount, err := stakingManager.WeightToValue( + &bind.CallOpts{}, + node.Weight, + ) + Expect(err).Should(BeNil()) // Initiate validator registration var receipt *types.Receipt log.Println("Initializing validator registration") @@ -834,7 +849,7 @@ func InitializeAndCompleteERC20ValidatorRegistration( // (Sending to the P-Chain will be skipped for now) signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) - _, err := network.GetPChainWallet().IssueRegisterSubnetValidatorTx( + _, err = network.GetPChainWallet().IssueRegisterSubnetValidatorTx( 100*units.Avax, node.NodePoP.ProofOfPossession, signedWarpMessage.Bytes(), @@ -1292,7 +1307,7 @@ func CompleteEndNativeDelegation( ) } -func InitializeAndCompleteEndNativeValidation( +func InitializeAndCompleteEndInitialNativeValidation( ctx context.Context, network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, @@ -1302,9 +1317,10 @@ func InitializeAndCompleteEndNativeValidation( stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, stakingManagerAddress common.Address, validationID ids.ID, + index uint32, weight uint64, - nonce uint64, ) { + log.Println("Initializing initial validator removal") WaitMinStakeDuration(ctx, subnetInfo, fundedKey) receipt := ForceInitializeEndNativeValidation( ctx, @@ -1323,17 +1339,102 @@ func InitializeAndCompleteEndNativeValidation( // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + subnetInfo.SubnetID, + 67, + ) Expect(err).Should(BeNil()) - // Validate the Warp message, (this will be done on the P-Chain in the future) - ValidateSubnetValidatorWeightMessage(signedWarpMessage, validationID, 0, nonce) + // Deliver the Warp message to the P-Chain + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing initial validator removal") + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessageForInitialValidator( + validationID, + index, + false, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteEndNativeValidation( + ctx, + fundedKey, + subnetInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + validationEndedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +func InitializeAndCompleteEndNativeValidation( + ctx context.Context, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + stakingManagerAddress common.Address, + validationID ids.ID, + expiry uint64, + node Node, + nonce uint64, +) { + log.Println("Initializing validator removal") + WaitMinStakeDuration(ctx, subnetInfo, fundedKey) + receipt := ForceInitializeEndNativeValidation( + ctx, + fundedKey, + subnetInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(node.Weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + subnetInfo.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + // Deliver the Warp message to the P-Chain + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator removal") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - 0, - Node{}, + expiry, + node, false, subnetInfo, pChainInfo, @@ -1467,7 +1568,6 @@ func InitializeAndCompleteEndERC20Validation( Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(node.Weight)) // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) signedWarpMessage, err := signatureAggregator.CreateSignedMessage( unsignedMessage, From c3a06404f545f278533e094fb637eac79753be8b Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 09:10:06 -0500 Subject: [PATCH 19/34] remove delegation flows --- .../validator-manager/erc20_delegation.go | 214 ------------------ .../validator-manager/native_delegation.go | 214 ------------------ 2 files changed, 428 deletions(-) delete mode 100644 tests/flows/validator-manager/erc20_delegation.go delete mode 100644 tests/flows/validator-manager/native_delegation.go diff --git a/tests/flows/validator-manager/erc20_delegation.go b/tests/flows/validator-manager/erc20_delegation.go deleted file mode 100644 index 125b5548a..000000000 --- a/tests/flows/validator-manager/erc20_delegation.go +++ /dev/null @@ -1,214 +0,0 @@ -package staking - -import ( - "context" - "math/big" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/subnet-evm/accounts/abi/bind" - "github.com/ava-labs/teleporter/tests/interfaces" - "github.com/ava-labs/teleporter/tests/utils" - . "github.com/onsi/gomega" -) - -/* - * Registers a delegator with an ERC20 token staking validator on a subnet. The steps are as follows: - * - Deploy the ERCTokenStakingManager - * - Register a validator - * - Register a delegator - * - Deleist the delegator - * - * TODO: as delegation gets built out, this test will need to be updated to cover: - * - Delegator rewards - * - Implicit delegation end at validation end - */ -func ERC20Delegation(network interfaces.LocalNetwork) { - // Get the subnets info - cChainInfo := network.GetPrimaryNetworkInfo() - subnetAInfo, _ := utils.GetTwoSubnets(network) - _, fundedKey := network.GetFundedAccountInfo() - pChainInfo := utils.GetPChainInfo(cChainInfo) - - signatureAggregator := utils.NewSignatureAggregator( - cChainInfo.NodeURIs[0], - []ids.ID{ - subnetAInfo.SubnetID, - }, - ) - ctx := context.Background() - - // Deploy the staking manager contract - stakingManagerAddress, stakingManager, _, erc20 := utils.DeployAndInitializeERC20TokenStakingManager( - ctx, - fundedKey, - subnetAInfo, - pChainInfo, - ) - - // _ = utils.InitializeERC20TokenValidatorSet( - // ctx, - // fundedKey, - // subnetAInfo, - // pChainInfo, - // stakingManager, - // stakingManagerAddress, - // network, - // signatureAggregator, - // utils.DefaultMinStakeAmount*10, - // ) - - // - // Register a validator - // - var validationID ids.ID // To be used in the delisting step - validatorStake := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) - validatorWeight, err := stakingManager.ValueToWeight( - &bind.CallOpts{}, - validatorStake, - ) - Expect(err).Should(BeNil()) - // validationID = utils.InitializeAndCompleteERC20ValidatorRegistration( - // ctx, - // network, - // signatureAggregator, - // fundedKey, - // subnetAInfo, - // pChainInfo, - // stakingManager, - // stakingManagerAddress, - // erc20, - // validatorStake, - // ) - - // // - // Register a delegator - // - var delegationID ids.ID - { - delegatorStake := big.NewInt(1e17) - delegatorWeight, err := stakingManager.ValueToWeight( - &bind.CallOpts{}, - delegatorStake, - ) - Expect(err).Should(BeNil()) - newValidatorWeight := validatorWeight + delegatorWeight - - nonce := uint64(1) - - receipt := utils.InitializeERC20DelegatorRegistration( - ctx, - fundedKey, - subnetAInfo, - validationID, - delegatorStake, - erc20, - stakingManagerAddress, - stakingManager, - ) - initRegistrationEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegatorAdded, - ) - Expect(err).Should(BeNil()) - delegationID = initRegistrationEvent.DelegationID - - // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) - - // Validate the Warp message, (this will be done on the P-Chain in the future) - utils.ValidateSubnetValidatorWeightMessage( - signedWarpMessage, - validationID, - newValidatorWeight, - nonce, - ) - - // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain - registrationSignedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( - validationID, - nonce, - newValidatorWeight, - subnetAInfo, - pChainInfo, - network, - signatureAggregator, - ) - - // Deliver the Warp message to the subnet - receipt = utils.CompleteERC20DelegatorRegistration( - ctx, - fundedKey, - delegationID, - subnetAInfo, - stakingManagerAddress, - registrationSignedMessage, - ) - // Check that the validator is registered in the staking contract - registrationEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegatorRegistered, - ) - Expect(err).Should(BeNil()) - Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) - } - // - // Delist the delegator - // - { - nonce := uint64(2) - receipt := utils.InitializeEndERC20Delegation( - ctx, - fundedKey, - subnetAInfo, - stakingManager, - delegationID, - ) - delegatorRemovalEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegatorRemovalInitialized, - ) - Expect(err).Should(BeNil()) - Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) - - // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) - Expect(err).Should(BeNil()) - - // Validate the Warp message, (this will be done on the P-Chain in the future) - utils.ValidateSubnetValidatorWeightMessage(signedWarpMessage, validationID, validatorWeight, 2) - - // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain - signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( - validationID, - nonce, - validatorWeight, - subnetAInfo, - pChainInfo, - network, - signatureAggregator, - ) - - // Deliver the Warp message to the subnet - receipt = utils.CompleteEndERC20Delegation( - ctx, - fundedKey, - delegationID, - subnetAInfo, - stakingManagerAddress, - signedMessage, - ) - - // Check that the delegator has been delisted from the staking contract - registrationEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegationEnded, - ) - Expect(err).Should(BeNil()) - Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) - } -} diff --git a/tests/flows/validator-manager/native_delegation.go b/tests/flows/validator-manager/native_delegation.go deleted file mode 100644 index 280be4af6..000000000 --- a/tests/flows/validator-manager/native_delegation.go +++ /dev/null @@ -1,214 +0,0 @@ -package staking - -import ( - "context" - "math/big" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/subnet-evm/accounts/abi/bind" - "github.com/ava-labs/teleporter/tests/interfaces" - "github.com/ava-labs/teleporter/tests/utils" - . "github.com/onsi/gomega" -) - -/* - * Registers a delegator with a native token staking validator on a subnet. The steps are as follows: - * - Deploy the NativeTokenStakingManager - * - Register a validator - * - Register a delegator - * - Deleist the delegator - * - * TODO: as delegation gets built out, this test will need to be updated to cover: - * - Delegator rewards - * - Implicit delegation end at validation end - */ -func NativeDelegation(network interfaces.LocalNetwork) { - // Get the subnets info - cChainInfo := network.GetPrimaryNetworkInfo() - subnetAInfo, _ := utils.GetTwoSubnets(network) - _, fundedKey := network.GetFundedAccountInfo() - pChainInfo := utils.GetPChainInfo(cChainInfo) - - signatureAggregator := utils.NewSignatureAggregator( - cChainInfo.NodeURIs[0], - []ids.ID{ - subnetAInfo.SubnetID, - }, - ) - ctx := context.Background() - - // Deploy the staking manager contract - stakingManagerAddress, stakingManager := utils.DeployAndInitializeNativeTokenStakingManager( - ctx, - fundedKey, - subnetAInfo, - pChainInfo, - ) - - utils.AddNativeMinterAdmin(ctx, subnetAInfo, fundedKey, stakingManagerAddress) - - _ = utils.InitializeNativeTokenValidatorSet( - ctx, - fundedKey, - subnetAInfo, - pChainInfo, - stakingManager, - stakingManagerAddress, - network, - signatureAggregator, - utils.DefaultMinStakeAmount*10, - ) - - // - // Register a validator - // - var validationID ids.ID // To be used in the delisting step - validatorStake := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) - validatorWeight, err := stakingManager.ValueToWeight( - &bind.CallOpts{}, - validatorStake, - ) - Expect(err).Should(BeNil()) - stakeAmount := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) - validationID = utils.InitializeAndCompleteNativeValidatorRegistration( - ctx, - network, - signatureAggregator, - fundedKey, - subnetAInfo, - pChainInfo, - stakingManager, - stakingManagerAddress, - stakeAmount, - ) - // - // Register a delegator - // - var delegationID ids.ID - { - delegatorStake := big.NewInt(1e17) - delegatorWeight, err := stakingManager.ValueToWeight( - &bind.CallOpts{}, - delegatorStake, - ) - Expect(err).Should(BeNil()) - newValidatorWeight := validatorWeight + delegatorWeight - - nonce := uint64(1) - - receipt := utils.InitializeNativeDelegatorRegistration( - ctx, - fundedKey, - subnetAInfo, - validationID, - delegatorStake, - stakingManagerAddress, - stakingManager, - ) - initRegistrationEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegatorAdded, - ) - Expect(err).Should(BeNil()) - delegationID = initRegistrationEvent.DelegationID - - // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) - - // Validate the Warp message, (this will be done on the P-Chain in the future) - utils.ValidateSubnetValidatorWeightMessage( - signedWarpMessage, - validationID, - newValidatorWeight, - nonce, - ) - - // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain - registrationSignedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( - validationID, - nonce, - newValidatorWeight, - subnetAInfo, - pChainInfo, - network, - signatureAggregator, - ) - - // Deliver the Warp message to the subnet - receipt = utils.CompleteNativeDelegatorRegistration( - ctx, - fundedKey, - delegationID, - subnetAInfo, - stakingManagerAddress, - registrationSignedMessage, - ) - // Check that the validator is registered in the staking contract - registrationEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegatorRegistered, - ) - Expect(err).Should(BeNil()) - Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) - } - // - // Delist the delegator - // - { - nonce := uint64(2) - receipt := utils.InitializeEndNativeDelegation( - ctx, - fundedKey, - subnetAInfo, - stakingManager, - delegationID, - ) - delegatorRemovalEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegatorRemovalInitialized, - ) - Expect(err).Should(BeNil()) - Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) - - // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) - signedWarpMessage := utils.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) - Expect(err).Should(BeNil()) - - // Validate the Warp message, (this will be done on the P-Chain in the future) - utils.ValidateSubnetValidatorWeightMessage(signedWarpMessage, validationID, validatorWeight, 2) - - // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain - signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( - validationID, - nonce, - validatorWeight, - subnetAInfo, - pChainInfo, - network, - signatureAggregator, - ) - - // Deliver the Warp message to the subnet - receipt = utils.CompleteEndNativeDelegation( - ctx, - fundedKey, - delegationID, - subnetAInfo, - stakingManagerAddress, - signedMessage, - ) - - // Check that the delegator has been delisted from the staking contract - registrationEvent, err := utils.GetEventFromLogs( - receipt.Logs, - stakingManager.ParseDelegationEnded, - ) - Expect(err).Should(BeNil()) - Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) - Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) - } -} From 70b85e935d12487f511e5fa7844f8f44039d2014 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 10:55:38 -0500 Subject: [PATCH 20/34] tear down network between validator manager tests --- .../local/validator-manager/validator_manager_suite_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/local/validator-manager/validator_manager_suite_test.go b/tests/local/validator-manager/validator_manager_suite_test.go index f7b169b34..c6403aa43 100644 --- a/tests/local/validator-manager/validator_manager_suite_test.go +++ b/tests/local/validator-manager/validator_manager_suite_test.go @@ -40,7 +40,7 @@ func TestValidatorManager(t *testing.T) { // Define the Teleporter before and after suite functions. // TODONOW: Tear down the network in between each spec so that we start with a fresh subnet each time. -var _ = ginkgo.BeforeSuite(func() { +var _ = ginkgo.BeforeEach(func() { // Generate the Teleporter deployment values teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := deploymentUtils.ConstructKeylessTransaction( @@ -96,8 +96,9 @@ var _ = ginkgo.BeforeSuite(func() { log.Info("Set up ginkgo before suite") }) -var _ = ginkgo.AfterSuite(func() { +var _ = ginkgo.AfterEach(func() { LocalNetworkInstance.TearDownNetwork() + LocalNetworkInstance = nil }) var _ = ginkgo.Describe("[Validator manager integration tests]", func() { From b4710e511b88c476beb04408d79ba8dc43d029a5 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 10:55:55 -0500 Subject: [PATCH 21/34] create new default registerer at runtime --- tests/utils/chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils/chain.go b/tests/utils/chain.go index d6f185810..869fc70fd 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -583,7 +583,7 @@ func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.Signatu appRequestNetwork, logger, 1024, - metrics.NewSignatureAggregatorMetrics(prometheus.DefaultRegisterer), + metrics.NewSignatureAggregatorMetrics(prometheus.NewRegistry()), messageCreator, // Setting the etnaTime to a minute ago so that the post-etna code path is used in the test time.Now().Add(-1*time.Minute), From c9320a9cbcd012468ceee25210daac0fcb15def3 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:13:51 -0500 Subject: [PATCH 22/34] bump awm-relayer --- go.mod | 6 +++--- go.sum | 16 ++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 9f5fc6f72..2f5799829 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( ) require ( - github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6 + github.com/ava-labs/awm-relayer v1.4.1-0.20241010161724-2db445c994d6 github.com/ava-labs/subnet-evm v0.6.10 github.com/ethereum/go-ethereum v1.13.14 github.com/onsi/ginkgo/v2 v2.20.2 @@ -19,6 +19,7 @@ require ( github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 golang.org/x/tools v0.25.0 + google.golang.org/protobuf v1.35.1 ) require ( @@ -144,8 +145,7 @@ require ( gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 28835e100..d1eee2ad6 100644 --- a/go.sum +++ b/go.sum @@ -56,14 +56,10 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.3 h1:JfVooBCdMzpeGUT9/phJNl2GHflkGehlMJokXeWKa2A= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.3/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.4 h1:0g1+aJS6f4I2m8oEF3djlfyNbL9UrQTS+6A0eXbRLtM= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.4/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= github.com/ava-labs/avalanchego v1.12.0-initial-poc.5 h1:gW4xAqZNvkA4gP8M9yDyd7YUzuwfQbbCR+hgd1ztOto= github.com/ava-labs/avalanchego v1.12.0-initial-poc.5/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= -github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6 h1:v7k5wQxcvnYcMaz+zoO1OLAcU8REDD1EhfPZdl4Q+aI= -github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6/go.mod h1:sSXpQtgiduMdZw5IVTSa1v418VCjb8GDLyrcGwJZ/HE= +github.com/ava-labs/awm-relayer v1.4.1-0.20241010161724-2db445c994d6 h1:WdFWoZ8clWfTPp3cKyWYTsveMKW/0SQzWk8U1aCcdnw= +github.com/ava-labs/awm-relayer v1.4.1-0.20241010161724-2db445c994d6/go.mod h1:6eqh3V1Og40gXmZUOP6tCrlmMEcVuj9l737yYh1s8uw= github.com/ava-labs/coreth v0.13.8 h1:f14X3KgwHl9LwzfxlN6S4bbn5VA2rhEsNnHaRLSTo/8= github.com/ava-labs/coreth v0.13.8/go.mod h1:t3BSv/eQv0AlDPMfEDCMMoD/jq1RkUsbFzQAFg5qBcE= github.com/ava-labs/subnet-evm v0.6.10 h1:uIh6bFMA4GCMVMQ3agBPxTMlYHL8FBR5FrhMR+drfKI= @@ -995,8 +991,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1009,8 +1005,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 713666908e3ce2b6e733b8b6cb860ed7a70b60fb Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:14:03 -0500 Subject: [PATCH 23/34] poa->pos migration e2e --- tests/flows/validator-manager/poa_to_pos.go | 94 ++++++--- .../poa_validator_manager.go | 150 --------------- .../validator_manager_suite_test.go | 26 +-- tests/utils/validator_manager.go | 178 +++++++++++++----- 4 files changed, 214 insertions(+), 234 deletions(-) delete mode 100644 tests/flows/validator-manager/poa_validator_manager.go diff --git a/tests/flows/validator-manager/poa_to_pos.go b/tests/flows/validator-manager/poa_to_pos.go index af2bb8072..9cce8b401 100644 --- a/tests/flows/validator-manager/poa_to_pos.go +++ b/tests/flows/validator-manager/poa_to_pos.go @@ -2,7 +2,9 @@ package staking import ( "context" + "log" "math/big" + "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/subnet-evm/accounts/abi/bind" @@ -54,7 +56,8 @@ func PoAMigrationToPoS(network interfaces.LocalNetwork) { // Transfer native assets to the owner account ctx := context.Background() - fundAmount := big.NewInt(1e18) // 1avax + fundAmount := big.NewInt(1e18) // 10avax + fundAmount.Mul(fundAmount, big.NewInt(10)) utils.SendNativeTransfer( ctx, subnetAInfo, @@ -96,7 +99,17 @@ func PoAMigrationToPoS(network interfaces.LocalNetwork) { Expect(err).Should(BeNil()) utils.WaitForTransactionSuccess(context.Background(), subnetAInfo, tx.Hash()) - _ = utils.InitializePoAValidatorSet( + nodes := utils.ConvertSubnet( + ctx, + subnetAInfo, + network, + proxyAddress, + fundedKey, + ) + + // Initialize the validator set on the subnet + log.Println("Initializing validator set") + initialValidationIDs := utils.InitializePoAValidatorSet( ctx, fundedKey, subnetAInfo, @@ -105,11 +118,46 @@ func PoAMigrationToPoS(network interfaces.LocalNetwork) { proxyAddress, network, signatureAggregator, - utils.DefaultMinStakeAmount*10, + nodes, + ) + + // + // Delist one initial validator + // + utils.InitializeAndCompleteEndInitialPoAValidation( + ctx, + network, + signatureAggregator, + ownerKey, + fundedKey, + subnetAInfo, + pChainInfo, + poaValidatorManager, + proxyAddress, + initialValidationIDs[0], + 0, + nodes[0].Weight, + ) + + // Try to call with invalid owner + opts, err = bind.NewKeyedTransactorWithChainID(fundedKey, subnetAInfo.EVMChainID) + Expect(err).Should(BeNil()) + + _, err = poaValidatorManager.InitializeValidatorRegistration( + opts, + poavalidatormanager.ValidatorRegistrationInput{ + NodeID: nodes[0].NodeID[:], + RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), + BlsPublicKey: nodes[0].NodePoP.PublicKey[:], + }, + nodes[0].Weight, ) + Expect(err).ShouldNot(BeNil()) - // Register a validator - poaWeight := uint64(1) + // + // Re-register the validator as a SoV validator + // + expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) poaValidationID := utils.InitializeAndCompletePoAValidatorRegistration( ctx, network, @@ -120,7 +168,8 @@ func PoAMigrationToPoS(network interfaces.LocalNetwork) { pChainInfo, poaValidatorManager, proxyAddress, - poaWeight, + expiry, + nodes[0], ) poaValidator, err := poaValidatorManager.GetValidator(&bind.CallOpts{}, poaValidationID) Expect(err).Should(BeNil()) @@ -184,39 +233,37 @@ func PoAMigrationToPoS(network interfaces.LocalNetwork) { Expect(err).Should(BeNil()) Expect(validationID[:]).Should(Equal(poaValidationID[:])) - // Register a PoS validator - stakeAmount := big.NewInt(1e18) - posWeight, err := posValidatorManager.ValueToWeight( - &bind.CallOpts{}, - stakeAmount, - ) - Expect(err).Should(BeNil()) + // + // Remove the PoA validator and re-register as a PoS validator + // - posValidationID := utils.InitializeAndCompleteNativeValidatorRegistration( + utils.InitializeAndCompleteEndNativeValidation( ctx, network, signatureAggregator, - fundedKey, + ownerKey, subnetAInfo, pChainInfo, posValidatorManager, proxyAddress, - stakeAmount, + poaValidationID, + expiry, + nodes[0], + 1, ) - // Delist the previous PoA validator - utils.InitializeAndCompleteEndNativeValidation( + expiry2 := uint64(time.Now().Add(24 * time.Hour).Unix()) + posValidationID := utils.InitializeAndCompleteNativeValidatorRegistration( ctx, network, signatureAggregator, - ownerKey, + fundedKey, subnetAInfo, pChainInfo, posValidatorManager, proxyAddress, - poaValidationID, - poaWeight, - 1, + expiry2, + nodes[0], ) // Delist the PoS validator @@ -230,7 +277,8 @@ func PoAMigrationToPoS(network interfaces.LocalNetwork) { posValidatorManager, proxyAddress, posValidationID, - posWeight, + expiry2, + nodes[0], 1, ) } diff --git a/tests/flows/validator-manager/poa_validator_manager.go b/tests/flows/validator-manager/poa_validator_manager.go deleted file mode 100644 index a7733b449..000000000 --- a/tests/flows/validator-manager/poa_validator_manager.go +++ /dev/null @@ -1,150 +0,0 @@ -package staking - -import ( - "context" - "math/big" - "time" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/subnet-evm/accounts/abi/bind" - poavalidatormanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/PoAValidatorManager" - "github.com/ava-labs/teleporter/tests/interfaces" - "github.com/ava-labs/teleporter/tests/utils" - "github.com/ethereum/go-ethereum/crypto" - . "github.com/onsi/gomega" -) - -/* - * Register a PoA validator manager on a L1. The steps are as follows: - * - Generate random address to be the owner address - * - Fund native assets to the owner address - * - Deploy the PoAValidatorManager contract - * - Attempt to initiate with non owner and check that it fails - * - Initiate validator registration - * - Deliver the Warp message to the P-Chain (not implemented) - * - Aggregate P-Chain signatures on the response Warp message - * - Deliver the Warp message to the L1 - * - Verify that the validator is registered in the validator manager contract - * - * Delists the validator from the L1. The steps are as follows: - * - Attempt to initiate with non owner and check that it fails - * - Initiate validator delisting - * - Deliver the Warp message to the P-Chain (not implemented) - * - Aggregate P-Chain signatures on the response Warp message - * - Deliver the Warp message to the L1 - * - Verify that the validator is delisted from the validator manager contract - */ -func PoAValidatorManager(network interfaces.LocalNetwork) { - cChainInfo := network.GetPrimaryNetworkInfo() - subnetAInfo, _ := utils.GetTwoSubnets(network) - _, fundedKey := network.GetFundedAccountInfo() - pChainInfo := utils.GetPChainInfo(cChainInfo) - - signatureAggregator := utils.NewSignatureAggregator( - cChainInfo.NodeURIs[0], - []ids.ID{ - subnetAInfo.SubnetID, - }, - ) - - // Generate random address to be the owner address - ownerKey, err := crypto.GenerateKey() - Expect(err).Should(BeNil()) - ownerAddress := crypto.PubkeyToAddress(ownerKey.PublicKey) - - // Transfer native assets to the owner account - ctx := context.Background() - fundAmount := big.NewInt(1e18) // 1avax - utils.SendNativeTransfer( - ctx, - subnetAInfo, - fundedKey, - ownerAddress, - fundAmount, - ) - - validatorManagerAddress, validatorManager := utils.DeployAndInitializePoAValidatorManager( - ctx, - fundedKey, - subnetAInfo, - pChainInfo, - ownerAddress, - ) - _ = utils.InitializePoAValidatorSet( - ctx, - fundedKey, - subnetAInfo, - pChainInfo, - validatorManager, - validatorManagerAddress, - network, - signatureAggregator, - 5, - ) - - var validationID ids.ID // To be used in the delisting step - weight := uint64(1) - - { - // Try to call with invalid owner - opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, subnetAInfo.EVMChainID) - Expect(err).Should(BeNil()) - - nodeID := ids.GenerateTestID() - blsPublicKey := [bls.PublicKeyLen]byte{} - _, err = validatorManager.InitializeValidatorRegistration( - opts, - poavalidatormanager.ValidatorRegistrationInput{ - NodeID: nodeID[:], - RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), - BlsPublicKey: blsPublicKey[:], - }, - weight, - ) - Expect(err).ShouldNot(BeNil()) - - // Initiate validator registration - validationID = utils.InitializeAndCompletePoAValidatorRegistration( - ctx, - network, - signatureAggregator, - ownerKey, - fundedKey, - subnetAInfo, - pChainInfo, - validatorManager, - validatorManagerAddress, - weight, - ) - } - - // - // Delist the validator - // - { - // Try with invalid validator owner - opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, subnetAInfo.EVMChainID) - Expect(err).Should(BeNil()) - _, err = validatorManager.InitializeEndValidation( - opts, - validationID, - ) - Expect(err).ShouldNot(BeNil()) - - utils.InitializeAndCompleteEndPoAValidation( - ctx, - network, - signatureAggregator, - ownerKey, - fundedKey, - subnetAInfo, - pChainInfo, - validatorManager, - validatorManagerAddress, - validationID, - weight, - 1, - ) - } -} diff --git a/tests/local/validator-manager/validator_manager_suite_test.go b/tests/local/validator-manager/validator_manager_suite_test.go index c6403aa43..25d780c21 100644 --- a/tests/local/validator-manager/validator_manager_suite_test.go +++ b/tests/local/validator-manager/validator_manager_suite_test.go @@ -39,7 +39,6 @@ func TestValidatorManager(t *testing.T) { } // Define the Teleporter before and after suite functions. -// TODONOW: Tear down the network in between each spec so that we start with a fresh subnet each time. var _ = ginkgo.BeforeEach(func() { // Generate the Teleporter deployment values teleporterDeployerTransaction, teleporterDeployedBytecode, teleporterDeployerAddress, teleporterContractAddress, err := @@ -103,24 +102,19 @@ var _ = ginkgo.AfterEach(func() { var _ = ginkgo.Describe("[Validator manager integration tests]", func() { // Validator Manager tests - // ginkgo.It("Native token staking manager", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManagerFlows.NativeTokenStakingManager(LocalNetworkInstance) - // }) + ginkgo.It("Native token staking manager", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.NativeTokenStakingManager(LocalNetworkInstance) + }) ginkgo.It("ERC20 token staking manager", ginkgo.Label(validatorManagerLabel), func() { validatorManagerFlows.ERC20TokenStakingManager(LocalNetworkInstance) }) - // ginkgo.It("PoA validator manager", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManagerFlows.PoAValidatorManager(LocalNetworkInstance) - // }) - // ginkgo.It("PoA migration to PoS", - // ginkgo.Label(validatorManagerLabel), - // func() { - // validatorManagerFlows.PoAMigrationToPoS(LocalNetworkInstance) - // }) + ginkgo.It("PoA migration to PoS", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.PoAMigrationToPoS(LocalNetworkInstance) + }) }) diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index b2fc10efb..b856d8aa8 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -420,26 +420,37 @@ func InitializePoAValidatorSet( validatorManagerAddress common.Address, network interfaces.LocalNetwork, signatureAggregator *aggregator.SignatureAggregator, - initialValidatorWeight uint64, -) ids.ID { - nodeID := ids.GenerateTestID() - blsPublicKey := [bls.PublicKeyLen]byte{} - subnetConversionData := poavalidatormanager.SubnetConversionData{ + nodes []Node, +) []ids.ID { + initialValidators := make([]warpMessage.SubnetConversionValidatorData, len(nodes)) + initialValidatorsABI := make([]poavalidatormanager.InitialValidator, len(nodes)) + for i, node := range nodes { + initialValidators[i] = warpMessage.SubnetConversionValidatorData{ + NodeID: node.NodeID.Bytes(), + BLSPublicKey: node.NodePoP.PublicKey, + Weight: nodes[i].Weight, + } + initialValidatorsABI[i] = poavalidatormanager.InitialValidator{ + NodeID: node.NodeID.Bytes(), + BlsPublicKey: node.NodePoP.PublicKey[:], + Weight: nodes[i].Weight, + } + } + + subnetConversionData := warpMessage.SubnetConversionData{ + SubnetID: subnetInfo.SubnetID, + ManagerChainID: subnetInfo.BlockchainID, + ManagerAddress: validatorManagerAddress[:], + Validators: initialValidators, + } + subnetConversionDataABI := poavalidatormanager.SubnetConversionData{ SubnetID: subnetInfo.SubnetID, ValidatorManagerBlockchainID: subnetInfo.BlockchainID, ValidatorManagerAddress: validatorManagerAddress, - InitialValidators: []poavalidatormanager.InitialValidator{ - { - NodeID: nodeID[:], - Weight: initialValidatorWeight, - BlsPublicKey: blsPublicKey[:], - }, - }, + InitialValidators: initialValidatorsABI, } - - subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) + subnetConversionID, err := warpMessage.SubnetConversionID(subnetConversionData) Expect(err).Should(BeNil()) - subnetConversionID := sha256.Sum256(subnetConversionDataBytes) subnetConversionSignedMessage := ConstructSubnetConversionMessage( subnetConversionID, subnetInfo, @@ -454,21 +465,24 @@ func InitializePoAValidatorSet( subnetInfo, validatorManagerAddress, subnetConversionSignedMessage, - subnetConversionData, + subnetConversionDataABI, ) initialValidatorCreatedEvent, err := GetEventFromLogs( receipt.Logs, validatorManager.ParseInitialValidatorCreated, ) Expect(err).Should(BeNil()) - Expect(initialValidatorCreatedEvent.NodeID).Should(Equal(subnetConversionData.InitialValidators[0].NodeID)) - Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeight))) + var validationIDs []ids.ID + for i := range nodes { + validationIDs = append(validationIDs, subnetInfo.SubnetID.Append(uint32(i))) + } + + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(nodes[0].Weight))) - expectedValidationID := CalculateSubnetConversionValidationId(subnetInfo.SubnetID, 0) emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) - Expect(emittedValidationID).Should(Equal(expectedValidationID)) + Expect(emittedValidationID).Should(Equal(validationIDs[0])) - return emittedValidationID + return validationIDs } func DeliverNativeTokenSubnetConversion( @@ -622,9 +636,8 @@ func InitializePoAValidatorRegistration( ctx context.Context, senderKey *ecdsa.PrivateKey, subnet interfaces.SubnetTestInfo, - weight uint64, - nodeID ids.ID, - blsPublicKey [bls.PublicKeyLen]byte, + node Node, + expiry uint64, validatorManager *poavalidatormanager.PoAValidatorManager, ) (*types.Receipt, ids.ID) { opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) @@ -633,11 +646,11 @@ func InitializePoAValidatorRegistration( tx, err := validatorManager.InitializeValidatorRegistration( opts, poavalidatormanager.ValidatorRegistrationInput{ - NodeID: nodeID[:], - RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), - BlsPublicKey: blsPublicKey[:], + NodeID: node.NodeID[:], + RegistrationExpiry: expiry, + BlsPublicKey: node.NodePoP.PublicKey[:], }, - weight, + node.Weight, ) Expect(err).Should(BeNil()) receipt := WaitForTransactionSuccess(ctx, subnet, tx.Hash()) @@ -846,7 +859,6 @@ func InitializeAndCompleteERC20ValidatorRegistration( ) // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) _, err = network.GetPChainWallet().IssueRegisterSubnetValidatorTx( @@ -857,6 +869,7 @@ func InitializeAndCompleteERC20ValidatorRegistration( Expect(err).Should(BeNil()) PChainProposerVMWorkaround(network) AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain log.Println("Completing validator registration") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( @@ -899,39 +912,37 @@ func InitializeAndCompletePoAValidatorRegistration( pChainInfo interfaces.SubnetTestInfo, validatorManager *poavalidatormanager.PoAValidatorManager, validatorManagerAddress common.Address, - weight uint64, + expiry uint64, + node Node, ) ids.ID { // Initiate validator registration - nodeID := ids.GenerateTestID() - blsPublicKey := [bls.PublicKeyLen]byte{} receipt, validationID := InitializePoAValidatorRegistration( ctx, ownerKey, subnetInfo, - weight, - nodeID, - blsPublicKey, + node, + expiry, validatorManager, ) // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain - // (Sending to the P-Chain will be skipped for now) signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, subnetInfo, pChainInfo) - // Validate the Warp message, (this will be done on the P-Chain in the future) - ValidateRegisterSubnetValidatorMessage( - signedWarpMessage, - nodeID, - weight, - subnetInfo.SubnetID, - blsPublicKey, + _, err := network.GetPChainWallet().IssueRegisterSubnetValidatorTx( + 100*units.Avax, + node.NodePoP.ProofOfPossession, + signedWarpMessage.Bytes(), ) + Expect(err).Should(BeNil()) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator registration") registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( validationID, - 0, - Node{}, + expiry, + node, true, subnetInfo, pChainInfo, @@ -1613,6 +1624,83 @@ func InitializeAndCompleteEndERC20Validation( Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) } +func InitializeAndCompleteEndInitialPoAValidation( + ctx context.Context, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + ownerKey *ecdsa.PrivateKey, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *poavalidatormanager.PoAValidatorManager, + stakingManagerAddress common.Address, + validationID ids.ID, + index uint32, + weight uint64, +) { + log.Println("Initializing initial validator removal") + WaitMinStakeDuration(ctx, subnetInfo, fundedKey) + receipt := InitializeEndPoAValidation( + ctx, + ownerKey, + subnetInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, subnetInfo) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + subnetInfo.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + // Deliver the Warp message to the P-Chain + network.GetPChainWallet().IssueSetSubnetValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(network) + AdvanceProposerVM(ctx, subnetInfo, fundedKey, 5) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing initial validator removal") + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessageForInitialValidator( + validationID, + index, + false, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteEndPoAValidation( + ctx, + fundedKey, + subnetInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + validationEndedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + func InitializeAndCompleteEndPoAValidation( ctx context.Context, network interfaces.LocalNetwork, From 3ecdb462ee47c77cf6c016319c4758e625ab0aa3 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:26:20 -0500 Subject: [PATCH 24/34] remove debug logs --- tests/utils/chain.go | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/utils/chain.go b/tests/utils/chain.go index 869fc70fd..1e8bedb8c 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -545,14 +545,6 @@ func InstantiateGenesisTemplate( // func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.SignatureAggregator { - logger := logging.NewLogger( - "test-debug", - logging.NewWrappedCore( - logging.Debug, - os.Stdout, - logging.JSON.ConsoleEncoder(), - ), - ) cfg := sigAggConfig.Config{ PChainAPI: &relayerConfig.APIConfig{ BaseURL: apiUri, @@ -565,7 +557,7 @@ func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.Signatu trackedSubnets.Add(subnets...) registry := prometheus.NewRegistry() appRequestNetwork, err := peers.NewNetwork( - logging.Debug, + logging.Info, registry, trackedSubnets, &cfg, @@ -581,7 +573,7 @@ func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.Signatu Expect(err).Should(BeNil()) agg, err := aggregator.NewSignatureAggregator( appRequestNetwork, - logger, + logging.NoLog{}, 1024, metrics.NewSignatureAggregatorMetrics(prometheus.NewRegistry()), messageCreator, From 2f3390ad9c6ae40b09859d34a9d24f441ea95e15 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:26:31 -0500 Subject: [PATCH 25/34] add todo --- tests/local/network.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/local/network.go b/tests/local/network.go index 0909cd42f..3fda50c8a 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -182,6 +182,8 @@ func NewLocalNetwork( Expect(err).Should(BeNil()) localNetwork.pChainWallet = wallet.P() + // TODONOW: Convert all subnets to permissionless validation + return localNetwork } From e033da049df964f87986aa5161f3724554407c05 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:26:56 -0500 Subject: [PATCH 26/34] component-wise e2e test jobs --- .github/workflows/test.yml | 74 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 198badfc5..7ee649b52 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,7 +45,7 @@ jobs: source scripts/constants.sh go test ./... - e2e_tests: + teleporter_e2e: name: e2e_tests runs-on: ubuntu-22.04 steps: @@ -67,7 +67,7 @@ jobs: run: | export PATH=$PATH:$HOME/.foundry/bin export PATH="$PATH:$GOPATH/bin" - ./scripts/local/e2e_test.sh + ./scripts/local/e2e_test.sh --component teleporter - name: Upload tmpnet network dir uses: actions/upload-artifact@v4 @@ -79,3 +79,73 @@ jobs: ~/.tmpnet/prometheus/prometheus.log ~/.tmpnet/promtail/promtail.log if-no-files-found: error + + governance_e2e: + name: e2e_tests + runs-on: ubuntu-22.04 + steps: + - name: Checkout repositories and submodules + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run E2E Tests + # Forge installs to BASE_DIR, but updates the PATH definition in $HOME/.bashrc + run: | + export PATH=$PATH:$HOME/.foundry/bin + export PATH="$PATH:$GOPATH/bin" + ./scripts/local/e2e_test.sh --component governance + + - name: Upload tmpnet network dir + uses: actions/upload-artifact@v4 + if: always() + with: + name: e2e-tmpnet-data + path: | + ~/.tmpnet/networks + ~/.tmpnet/prometheus/prometheus.log + ~/.tmpnet/promtail/promtail.log + if-no-files-found: error + + validator_manager_e2e: + name: e2e_tests + runs-on: ubuntu-22.04 + steps: + - name: Checkout repositories and submodules + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run E2E Tests + # Forge installs to BASE_DIR, but updates the PATH definition in $HOME/.bashrc + run: | + export PATH=$PATH:$HOME/.foundry/bin + export PATH="$PATH:$GOPATH/bin" + ./scripts/local/e2e_test.sh --component validator-manager + + - name: Upload tmpnet network dir + uses: actions/upload-artifact@v4 + if: always() + with: + name: e2e-tmpnet-data + path: | + ~/.tmpnet/networks + ~/.tmpnet/prometheus/prometheus.log + ~/.tmpnet/promtail/promtail.log + if-no-files-found: error \ No newline at end of file From e0e108b4105bdf50fced85671ef9852aef652c34 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:29:48 -0500 Subject: [PATCH 27/34] update job names --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7ee649b52..2151c40af 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: go test ./... teleporter_e2e: - name: e2e_tests + name: teleporter-e2e-tests runs-on: ubuntu-22.04 steps: - name: Checkout repositories and submodules @@ -81,7 +81,7 @@ jobs: if-no-files-found: error governance_e2e: - name: e2e_tests + name: governance-e2e-tests runs-on: ubuntu-22.04 steps: - name: Checkout repositories and submodules @@ -116,7 +116,7 @@ jobs: if-no-files-found: error validator_manager_e2e: - name: e2e_tests + name: validator-manager-e2e-tests runs-on: ubuntu-22.04 steps: - name: Checkout repositories and submodules From f57c8601b8bde8a692312ad9e538406940391b90 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 14:37:22 -0500 Subject: [PATCH 28/34] remove upload artifact --- .github/workflows/test.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2151c40af..fa69605e1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -69,17 +69,6 @@ jobs: export PATH="$PATH:$GOPATH/bin" ./scripts/local/e2e_test.sh --component teleporter - - name: Upload tmpnet network dir - uses: actions/upload-artifact@v4 - if: always() - with: - name: e2e-tmpnet-data - path: | - ~/.tmpnet/networks - ~/.tmpnet/prometheus/prometheus.log - ~/.tmpnet/promtail/promtail.log - if-no-files-found: error - governance_e2e: name: governance-e2e-tests runs-on: ubuntu-22.04 @@ -104,17 +93,6 @@ jobs: export PATH="$PATH:$GOPATH/bin" ./scripts/local/e2e_test.sh --component governance - - name: Upload tmpnet network dir - uses: actions/upload-artifact@v4 - if: always() - with: - name: e2e-tmpnet-data - path: | - ~/.tmpnet/networks - ~/.tmpnet/prometheus/prometheus.log - ~/.tmpnet/promtail/promtail.log - if-no-files-found: error - validator_manager_e2e: name: validator-manager-e2e-tests runs-on: ubuntu-22.04 @@ -138,14 +116,3 @@ jobs: export PATH=$PATH:$HOME/.foundry/bin export PATH="$PATH:$GOPATH/bin" ./scripts/local/e2e_test.sh --component validator-manager - - - name: Upload tmpnet network dir - uses: actions/upload-artifact@v4 - if: always() - with: - name: e2e-tmpnet-data - path: | - ~/.tmpnet/networks - ~/.tmpnet/prometheus/prometheus.log - ~/.tmpnet/promtail/promtail.log - if-no-files-found: error \ No newline at end of file From 11e8a39d7a45a1d930816a00a151398506455ed5 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 15:37:08 -0500 Subject: [PATCH 29/34] lint fixes --- go.mod | 2 +- go.sum | 4 ---- scripts/local/e2e_test.sh | 3 +-- tests/utils/validator_manager.go | 1 - 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 9f5fc6f72..f2c8f350b 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 golang.org/x/tools v0.25.0 + google.golang.org/protobuf v1.34.2 ) require ( @@ -145,7 +146,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 28835e100..09117774e 100644 --- a/go.sum +++ b/go.sum @@ -56,10 +56,6 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.3 h1:JfVooBCdMzpeGUT9/phJNl2GHflkGehlMJokXeWKa2A= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.3/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.4 h1:0g1+aJS6f4I2m8oEF3djlfyNbL9UrQTS+6A0eXbRLtM= -github.com/ava-labs/avalanchego v1.12.0-initial-poc.4/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= github.com/ava-labs/avalanchego v1.12.0-initial-poc.5 h1:gW4xAqZNvkA4gP8M9yDyd7YUzuwfQbbCR+hgd1ztOto= github.com/ava-labs/avalanchego v1.12.0-initial-poc.5/go.mod h1:qSHmog3wMVjo/ruIAQo0ppXAilyni07NIu5K88RyhWE= github.com/ava-labs/awm-relayer v1.4.1-0.20241003183820-366b0dc8cea6 h1:v7k5wQxcvnYcMaz+zoO1OLAcU8REDD1EhfPZdl4Q+aI= diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index 16ddc818b..f45c931d2 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -20,8 +20,7 @@ rm -rf $BASEDIR/avalanchego BASEDIR=$BASEDIR AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego "${TELEPORTER_PATH}/scripts/install_avalanchego_release.sh" BASEDIR=$BASEDIR "${TELEPORTER_PATH}/scripts/install_subnetevm_release.sh" -# cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy -cp /Users/cameron.schultz/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy echo "Copied ${BASEDIR}/subnet-evm/subnet-evm binary to ${BASEDIR}/avalanchego/plugins/" export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go index 389e760da..949f6754e 100644 --- a/tests/utils/validator_manager.go +++ b/tests/utils/validator_manager.go @@ -815,7 +815,6 @@ func InitializeAndCompleteERC20ValidatorRegistration( expiry uint64, node Node, ) ids.ID { - // Initiate validator registration var receipt *types.Receipt log.Println("Initializing validator registration") From 380fc9a731866b62cc513f6a1d2ab58c26563b9c Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Thu, 10 Oct 2024 15:41:06 -0500 Subject: [PATCH 30/34] resolve todos --- scripts/local/e2e_test.sh | 8 ++++---- tests/local/network.go | 5 ++--- tests/utils/chain.go | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index a7d0beffc..948f1a8a8 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -15,16 +15,17 @@ function printHelp() { printUsage } +valid_components="teleporter governance validator-manager" + function printUsage() { cat << EOF Arguments: - --component Component test suite to run. If omitted, runs all tests. + --component Component test suite to run. Valid components are: $valid_components Options: --help Print this help message EOF } -valid_components="teleporter governance validator-manager" component= while [ $# -gt 0 ]; do @@ -45,7 +46,6 @@ while [ $# -gt 0 ]; do done # Exit if no component is provided -# TODONOW: Run all tests if no component is provided if [ -z "$component" ]; then echo "No component provided" && exit 1 fi @@ -53,7 +53,7 @@ fi if echo "$valid_components" | grep -q "\b$component\b"; then echo "" > /dev/null else - echo "Invalid component" && exit 1 + echo "Invalid component" && printHelp && exit 1 fi source "$TELEPORTER_PATH"/scripts/constants.sh diff --git a/tests/local/network.go b/tests/local/network.go index 3fda50c8a..a8a574c63 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -70,7 +70,7 @@ type SubnetSpec struct { NodeCount int } -// TODONOW: Decouple Teleporter from the network interface +// TODO: Decouple Teleporter from the network interface func NewLocalNetwork( ctx context.Context, name string, @@ -182,8 +182,7 @@ func NewLocalNetwork( Expect(err).Should(BeNil()) localNetwork.pChainWallet = wallet.P() - // TODONOW: Convert all subnets to permissionless validation - + // TODO: Convert all subnets to permissionless validation return localNetwork } diff --git a/tests/utils/chain.go b/tests/utils/chain.go index 1e8bedb8c..27778d27b 100644 --- a/tests/utils/chain.go +++ b/tests/utils/chain.go @@ -692,7 +692,7 @@ func GetSignedMessage( } // Get the aggregate signature for the Warp message - // TODONOW: use signature aggregator + // TODO: use signature aggregator signedWarpMessageBytes, err := warpClient.GetMessageAggregateSignature( ctx, unsignedWarpMessageID, From 4bd2158b08efa2768ee53476d1e270d9e43642fc Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Mon, 14 Oct 2024 14:43:34 -0500 Subject: [PATCH 31/34] simplify component check --- scripts/local/e2e_test.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index 948f1a8a8..6927b6eb6 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -15,8 +15,6 @@ function printHelp() { printUsage } -valid_components="teleporter governance validator-manager" - function printUsage() { cat << EOF Arguments: @@ -50,10 +48,8 @@ if [ -z "$component" ]; then echo "No component provided" && exit 1 fi -if echo "$valid_components" | grep -q "\b$component\b"; then - echo "" > /dev/null -else - echo "Invalid component" && printHelp && exit 1 +if [ ! -d "./tests/local/$component" ]; then + echo "Component test suite not found" && exit 1 fi source "$TELEPORTER_PATH"/scripts/constants.sh @@ -89,7 +85,7 @@ ginkgo build ./tests/local/$component # Run the tests echo "Running e2e tests $RUN_E2E" -RUN_E2E=true ./tests/local//$component/$component.test \ +RUN_E2E=true ./tests/local/$component/$component.test \ --ginkgo.vv \ --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ --ginkgo.focus=${GINKGO_FOCUS:-""} \ From 098442e22f22738d5033f28c8cf455cfe616c390 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 15 Oct 2024 08:48:52 -0500 Subject: [PATCH 32/34] remove ref to unused var --- scripts/local/e2e_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index 6927b6eb6..7bd5acbbc 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -18,7 +18,7 @@ function printHelp() { function printUsage() { cat << EOF Arguments: - --component Component test suite to run. Valid components are: $valid_components + --component Component test suite to run. Must be a valid directory in tests/local/ Options: --help Print this help message EOF From 646e4ddd10f67cb1dbd36f499bf8f7183a65fd12 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 15 Oct 2024 09:39:39 -0500 Subject: [PATCH 33/34] test all suites by default --- scripts/local/e2e_test.sh | 51 +++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index 7bd5acbbc..783a898f2 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -18,21 +18,24 @@ function printHelp() { function printUsage() { cat << EOF Arguments: - --component Component test suite to run. Must be a valid directory in tests/local/ + --components component1,component2 Comma separated list of test suites to run. Valid components are: + $(echo $valid_components | tr ' ' '\n' | sort | tr '\n' ' ') + (default: all) Options: - --help Print this help message + --help Print this help message EOF } -component= +valid_components=$(ls -d $TELEPORTER_PATH/tests/local/*/ | xargs -n 1 basename) +components= while [ $# -gt 0 ]; do case "$1" in - --component) + --components) if [[ $2 != --* ]]; then - component=$2 + components=$2 else - echo "Invalid component $2" && printHelp && exit 1 + echo "Invalid components $2" && printHelp && exit 1 fi shift;; --help) @@ -43,14 +46,17 @@ while [ $# -gt 0 ]; do shift done -# Exit if no component is provided -if [ -z "$component" ]; then - echo "No component provided" && exit 1 +# Run all suites if no component is provided +if [ -z "$components" ]; then + components=$valid_components fi -if [ ! -d "./tests/local/$component" ]; then - echo "Component test suite not found" && exit 1 -fi +# Exit if invalid component is provided +for component in $(echo $components | tr ',' ' '); do + if [[ $valid_components != *$component* ]]; then + echo "Invalid component $component" && exit 1 + fi +done source "$TELEPORTER_PATH"/scripts/constants.sh source "$TELEPORTER_PATH"/scripts/versions.sh @@ -81,15 +87,18 @@ cd "$TELEPORTER_PATH" # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION} -ginkgo build ./tests/local/$component +for component in $(echo $components | tr ',' ' '); do + echo "Building e2e tests for $component" + ginkgo build ./tests/local/$component -# Run the tests -echo "Running e2e tests $RUN_E2E" -RUN_E2E=true ./tests/local/$component/$component.test \ - --ginkgo.vv \ - --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ - --ginkgo.focus=${GINKGO_FOCUS:-""} \ - --ginkgo.trace + echo "Running e2e tests for $component" + RUN_E2E=true ./tests/local/$component/$component.test \ + --ginkgo.vv \ + --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ + --ginkgo.focus=${GINKGO_FOCUS:-""} \ + --ginkgo.trace -echo "e2e tests passed" + echo "$component e2e tests passed" + echo "" +done exit 0 From 4cbde546ff4c7726dffe3ea145f3a0e7e44fdb73 Mon Sep 17 00:00:00 2001 From: cam-schultz Date: Tue, 15 Oct 2024 09:42:13 -0500 Subject: [PATCH 34/34] correct arg --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fa69605e1..a5edf0aed 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -67,7 +67,7 @@ jobs: run: | export PATH=$PATH:$HOME/.foundry/bin export PATH="$PATH:$GOPATH/bin" - ./scripts/local/e2e_test.sh --component teleporter + ./scripts/local/e2e_test.sh --components teleporter governance_e2e: name: governance-e2e-tests @@ -91,7 +91,7 @@ jobs: run: | export PATH=$PATH:$HOME/.foundry/bin export PATH="$PATH:$GOPATH/bin" - ./scripts/local/e2e_test.sh --component governance + ./scripts/local/e2e_test.sh --components governance validator_manager_e2e: name: validator-manager-e2e-tests @@ -115,4 +115,4 @@ jobs: run: | export PATH=$PATH:$HOME/.foundry/bin export PATH="$PATH:$GOPATH/bin" - ./scripts/local/e2e_test.sh --component validator-manager + ./scripts/local/e2e_test.sh --components validator-manager