diff --git a/command/bridge/deploy/deploy.go b/command/bridge/deploy/deploy.go index 20803db4e4..4d80258f11 100644 --- a/command/bridge/deploy/deploy.go +++ b/command/bridge/deploy/deploy.go @@ -41,8 +41,6 @@ const ( rootERC1155PredicateName = "RootERC1155Predicate" childERC1155MintablePredicateName = "ChildERC1155MintablePredicate" erc1155TemplateName = "ERC1155Template" - customSupernetManagerName = "CustomSupernetManager" - stakeManagerName = "StakeManager" ) var ( @@ -100,9 +98,6 @@ var ( erc1155TemplateName: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) { rootchainConfig.ChildERC1155Address = addr }, - getProxyNameForImpl(customSupernetManagerName): func(rootchainConfig *polybft.RootchainConfig, addr types.Address) { - rootchainConfig.CustomSupernetManagerAddress = addr - }, } // initializersMap maps rootchain contract names to initializer function callbacks @@ -251,20 +246,6 @@ func GetCommand() *cobra.Command { " (otherwise provided secrets are used to resolve deployer account)", ) - cmd.Flags().StringVar( - ¶ms.stakeTokenAddr, - helper.StakeTokenFlag, - "", - helper.StakeTokenFlagDesc, - ) - - cmd.Flags().StringVar( - ¶ms.stakeManagerAddr, - helper.StakeManagerFlag, - "", - helper.StakeManagerFlagDesc, - ) - cmd.Flags().StringVar( ¶ms.proxyContractsAdmin, helper.ProxyContractsAdminFlag, @@ -273,8 +254,6 @@ func GetCommand() *cobra.Command { ) cmd.MarkFlagsMutuallyExclusive(helper.TestModeFlag, deployerKeyFlag) - _ = cmd.MarkFlagRequired(helper.StakeManagerFlag) - _ = cmd.MarkFlagRequired(helper.StakeTokenFlag) return cmd } @@ -341,15 +320,7 @@ func runCommand(cmd *cobra.Command, _ []string) { } // populate bridge configuration - bridgeConfig := deploymentResultInfo.RootchainCfg.ToBridgeConfig() - if consensusCfg.Bridge != nil { - // only true if stake-manager-deploy command was executed - // users can still deploy stake manager manually - // only used for e2e tests - bridgeConfig.StakeTokenAddr = consensusCfg.Bridge.StakeTokenAddr - } - - consensusCfg.Bridge = bridgeConfig + consensusCfg.Bridge = deploymentResultInfo.RootchainCfg.ToBridgeConfig() consensusCfg.Bridge.EventTrackerStartBlocks = map[types.Address]uint64{ deploymentResultInfo.RootchainCfg.StateSenderAddress: blockNum, @@ -402,11 +373,7 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client, byteCodeBuilder func() ([]byte, error) } - rootchainConfig := &polybft.RootchainConfig{ - JSONRPCAddr: params.jsonRPCAddress, - // update stake manager address in genesis in case if stake manager was deployed manually - StakeManagerAddress: types.StringToAddress(params.stakeManagerAddr), - } + rootchainConfig := &polybft.RootchainConfig{JSONRPCAddr: params.jsonRPCAddress} allContracts := []*contractInfo{ { diff --git a/command/bridge/deploy/deploy_test.go b/command/bridge/deploy/deploy_test.go index 3c899067af..37cd824dd2 100644 --- a/command/bridge/deploy/deploy_test.go +++ b/command/bridge/deploy/deploy_test.go @@ -6,14 +6,11 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/jsonrpc" "github.com/umbracle/ethgo/testutil" "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/bridge/helper" - "github.com/0xPolygon/polygon-edge/consensus/polybft" - "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/types" ) @@ -38,26 +35,8 @@ func TestDeployContracts_NoPanics(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) - txn := ðgo.Transaction{ - To: nil, // contract deployment - Input: contractsapi.StakeManager.Bytecode, - } - - receipt, err = server.SendTxn(txn) - require.NoError(t, err) - require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status) - outputter := command.InitializeOutputter(GetCommand()) - params.stakeManagerAddr = receipt.ContractAddress.String() - params.stakeTokenAddr = types.StringToAddress("0x123456789").String() params.proxyContractsAdmin = "0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed" - consensusCfg = polybft.PolyBFTConfig{ - NativeTokenConfig: &polybft.TokenConfig{ - Name: "Test", - Symbol: "TST", - Decimals: 18, - }, - } require.NotPanics(t, func() { _, err = deployContracts(outputter, client, 1, []*validator.GenesisValidator{}, context.Background()) diff --git a/command/bridge/deploy/params.go b/command/bridge/deploy/params.go index 8e71ea0408..15626537a9 100644 --- a/command/bridge/deploy/params.go +++ b/command/bridge/deploy/params.go @@ -1,7 +1,6 @@ package deploy import ( - "errors" "fmt" "os" @@ -18,8 +17,6 @@ type deployParams struct { genesisPath string deployerKey string jsonRPCAddress string - stakeTokenAddr string - stakeManagerAddr string proxyContractsAdmin string isTestMode bool } @@ -36,13 +33,5 @@ func (ip *deployParams) validateFlags() error { return err } - if consensusCfg.NativeTokenConfig == nil { - return errors.New("native token configuration is undefined") - } - - if params.stakeTokenAddr == "" { - return errors.New("stake token address is not provided") - } - return helper.ValidateProxyContractsAdmin(ip.proxyContractsAdmin) } diff --git a/command/bridge/fund/fund.go b/command/bridge/fund/fund.go index 2c8b48a8cf..3e4b5759de 100644 --- a/command/bridge/fund/fund.go +++ b/command/bridge/fund/fund.go @@ -54,20 +54,6 @@ func setFlags(cmd *cobra.Command) { "the rootchain JSON RPC endpoint", ) - cmd.Flags().StringVar( - ¶ms.stakeTokenAddr, - helper.StakeTokenFlag, - "", - helper.StakeTokenFlagDesc, - ) - - cmd.Flags().BoolVar( - ¶ms.mintStakeToken, - mintStakeTokenFlag, - false, - "indicates if stake token deployer should mint root tokens to given validators", - ) - cmd.Flags().StringVar( ¶ms.deployerPrivateKey, polybftsecrets.PrivateKeyFlag, @@ -98,12 +84,6 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - var stakeTokenAddr types.Address - - if params.mintStakeToken { - stakeTokenAddr = types.StringToAddress(params.stakeTokenAddr) - } - results := make([]command.CommandResult, len(params.addresses)) g, ctx := errgroup.WithContext(cmd.Context()) @@ -139,28 +119,9 @@ func runCommand(cmd *cobra.Command, _ []string) { return fmt.Errorf("failed to fund validator '%s'", validatorAddr) } - if params.mintStakeToken { - // mint tokens to validator, so he is able to send them - mintTxn, err := helper.CreateMintTxn(validatorAddr, stakeTokenAddr, params.amountValues[i], true) - if err != nil { - return fmt.Errorf("failed to create mint native tokens transaction for validator '%s'. err: %w", - validatorAddr, err) - } - - receipt, err := txRelayer.SendTransaction(mintTxn, deployerKey) - if err != nil { - return fmt.Errorf("failed to send mint native tokens transaction to validator '%s'. err: %w", validatorAddr, err) - } - - if receipt.Status == uint64(types.ReceiptFailed) { - return fmt.Errorf("failed to mint native tokens to validator '%s'", validatorAddr) - } - } - results[i] = &result{ ValidatorAddr: validatorAddr, TxHash: types.Hash(receipt.TransactionHash), - IsMinted: params.mintStakeToken, } } diff --git a/command/bridge/fund/params.go b/command/bridge/fund/params.go index a1253e9672..a5d5cf6173 100644 --- a/command/bridge/fund/params.go +++ b/command/bridge/fund/params.go @@ -2,7 +2,6 @@ package fund import ( "errors" - "fmt" "math/big" bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" @@ -23,9 +22,7 @@ var ( type fundParams struct { addresses []string amounts []string - stakeTokenAddr string deployerPrivateKey string - mintStakeToken bool jsonRPCAddress string amountValues []*big.Int @@ -56,15 +53,5 @@ func (fp *fundParams) validateFlags() error { fp.amountValues[i] = amountValue } - if fp.mintStakeToken { - if fp.stakeTokenAddr == "" { - return bridgeHelper.ErrMandatoryStakeToken - } - - if err := types.IsValidAddress(fp.stakeTokenAddr); err != nil { - return fmt.Errorf("invalid stake token address is provided: %w", err) - } - } - return nil } diff --git a/command/bridge/fund/params_test.go b/command/bridge/fund/params_test.go index 5d5d141bc7..1477bf7609 100644 --- a/command/bridge/fund/params_test.go +++ b/command/bridge/fund/params_test.go @@ -6,7 +6,6 @@ import ( "github.com/stretchr/testify/require" - bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/types" ) @@ -44,33 +43,6 @@ func Test_validateFlags(t *testing.T) { }, err: "address \x10 has invalid length", }, - { - // stake token address omitted - buildParamsFn: func() *fundParams { - return &fundParams{ - mintStakeToken: true, - addresses: []string{ - types.StringToAddress("0x10").String(), - types.StringToAddress("0x20").String()}, - amounts: []string{"10", "20"}, - } - }, - err: bridgeHelper.ErrMandatoryStakeToken.Error(), - }, - { - // stake token address omitted - buildParamsFn: func() *fundParams { - return &fundParams{ - mintStakeToken: true, - stakeTokenAddr: "0xA", - addresses: []string{ - types.StringToAddress("0x10").String(), - types.StringToAddress("0x20").String()}, - amounts: []string{"10", "20"}, - } - }, - err: "invalid stake token address is provided", - }, { // valid scenario buildParamsFn: func() *fundParams { diff --git a/command/bridge/fund/result.go b/command/bridge/fund/result.go index add7a63fa5..608cf64907 100644 --- a/command/bridge/fund/result.go +++ b/command/bridge/fund/result.go @@ -11,16 +11,14 @@ import ( type result struct { ValidatorAddr types.Address `json:"address"` TxHash types.Hash `json:"tx_hash"` - IsMinted bool `json:"mint"` } func (r *result) GetOutput() string { var buffer bytes.Buffer - vals := make([]string, 0, 3) + vals := make([]string, 0, 2) vals = append(vals, fmt.Sprintf("Validator (address)|%s", r.ValidatorAddr)) vals = append(vals, fmt.Sprintf("Transaction (hash)|%s", r.TxHash)) - vals = append(vals, fmt.Sprintf("Is minted|%v", r.IsMinted)) buffer.WriteString("\n[ROOTCHAIN FUND]\n") buffer.WriteString(helper.FormatKV(vals)) diff --git a/command/bridge/helper/utils.go b/command/bridge/helper/utils.go index 0ae771d5f9..31f5ce5bdd 100644 --- a/command/bridge/helper/utils.go +++ b/command/bridge/helper/utils.go @@ -26,29 +26,22 @@ import ( const ( TestAccountPrivKey = "aa75e9a7d427efc732f8e4f1a5b7646adcc61fd5bae40f80d13c8419c9f43d6d" TestModeFlag = "test" - SupernetManagerFlag = "supernet-manager" - SupernetManagerFlagDesc = "address of supernet manager contract" - StakeManagerFlag = "stake-manager" - StakeManagerFlagDesc = "address of stake manager contract" - NativeRootTokenFlag = "native-root-token" - NativeRootTokenFlagDesc = "address of native root token" GenesisPathFlag = "genesis" GenesisPathFlagDesc = "genesis file path, which contains chain configuration" DefaultGenesisPath = "./genesis.json" - StakeTokenFlag = "stake-token" - StakeTokenFlagDesc = "address of ERC20 token used for staking on rootchain" ProxyContractsAdminFlag = "proxy-contracts-admin" ProxyContractsAdminDesc = "admin for proxy contracts" + StakeTokenFlag = "stake-token" + StakeTokenFlagDesc = "address of ERC20 token used for staking" AddressesFlag = "addresses" AmountsFlag = "amounts" Erc20TokenFlag = "erc20-token" //nolint:gosec ) var ( - ErrRootchainNotFound = errors.New("rootchain not found") - ErrRootchainPortBind = errors.New("port 8545 is not bind with localhost") - ErrMandatoryStakeToken = errors.New("stake token address is mandatory") - errTestModeSecrets = errors.New("rootchain test mode does not imply specifying secrets parameters") + ErrRootchainNotFound = errors.New("rootchain not found") + ErrRootchainPortBind = errors.New("port 8545 is not bind with localhost") + errTestModeSecrets = errors.New("rootchain test mode does not imply specifying secrets parameters") ErrNoAddressesProvided = errors.New("no addresses provided") ErrInconsistentLength = errors.New("addresses and amounts must be equal length") diff --git a/command/genesis/params.go b/command/genesis/params.go index 78a48f470e..9c663d91c4 100644 --- a/command/genesis/params.go +++ b/command/genesis/params.go @@ -208,11 +208,14 @@ func (p *genesisParams) initGenesisConfig() error { chainConfig := &chain.Chain{ Name: p.name, Genesis: &chain.Genesis{ - GasLimit: p.blockGasLimit, - Difficulty: 1, - Alloc: map[types.Address]*chain.GenesisAccount{}, - ExtraData: p.extraData, - GasUsed: command.DefaultGenesisGasUsed, + GasLimit: p.blockGasLimit, + Difficulty: 1, + Alloc: map[types.Address]*chain.GenesisAccount{}, + ExtraData: p.extraData, + GasUsed: command.DefaultGenesisGasUsed, + BaseFee: p.parsedBaseFeeConfig.baseFee, + BaseFeeEM: p.parsedBaseFeeConfig.baseFeeEM, + BaseFeeChangeDenom: p.parsedBaseFeeConfig.baseFeeChangeDenom, }, Params: &chain.Params{ ChainID: int64(p.chainID), diff --git a/command/genesis/polybft_params.go b/command/genesis/polybft_params.go index 3e999074d4..cc4efb1925 100644 --- a/command/genesis/polybft_params.go +++ b/command/genesis/polybft_params.go @@ -480,11 +480,17 @@ func (p *genesisParams) getValidatorAccounts() ([]*validator.GenesisValidator, e } addr := types.StringToAddress(trimmedAddress) + + stake, exists := p.stakeInfos[addr] + if !exists { + stake = command.DefaultStake + } + validators[i] = &validator.GenesisValidator{ MultiAddr: parts[0], Address: addr, BlsKey: trimmedBLSKey, - Stake: p.stakeInfos[addr], + Stake: stake, } } diff --git a/command/genesis/utils.go b/command/genesis/utils.go index 64ddfea74c..e53e403830 100644 --- a/command/genesis/utils.go +++ b/command/genesis/utils.go @@ -198,7 +198,7 @@ func ReadValidatorsByPrefix(dir, prefix string, stake, exists := stakeInfos[types.Address(account.Ecdsa.Address())] if !exists { - stake = big.NewInt(0) + stake = command.DefaultStake } validators[i] = &validator.GenesisValidator{ diff --git a/command/mint/mint_erc20.go b/command/mint/mint_erc20.go index 364307ff01..3650a743d8 100644 --- a/command/mint/mint_erc20.go +++ b/command/mint/mint_erc20.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/0xPolygon/polygon-edge/command" - rootHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" + bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" "github.com/0xPolygon/polygon-edge/command/helper" polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init" "github.com/0xPolygon/polygon-edge/txrelayer" @@ -40,33 +40,51 @@ func preRunCommand(cmd *cobra.Command, _ []string) error { } func setFlags(cmd *cobra.Command) { + cmd.Flags().StringVar( + ¶ms.accountDir, + polybftsecrets.AccountDirFlag, + "", + polybftsecrets.AccountDirFlagDesc, + ) + + cmd.Flags().StringVar( + ¶ms.accountConfig, + polybftsecrets.AccountConfigFlag, + "", + polybftsecrets.AccountConfigFlagDesc, + ) + + cmd.Flags().StringVar( + ¶ms.deployerPrivateKey, + polybftsecrets.PrivateKeyFlag, + "", + "private key of the token deployer (minter)", + ) + cmd.Flags().StringSliceVar( ¶ms.addresses, - rootHelper.AddressesFlag, + bridgeHelper.AddressesFlag, nil, "addresses to which tokens should be minted", ) cmd.Flags().StringSliceVar( ¶ms.amounts, - rootHelper.AmountsFlag, + bridgeHelper.AmountsFlag, nil, "token amounts which should be minted to given addresses", ) cmd.Flags().StringVar( ¶ms.tokenAddr, - rootHelper.Erc20TokenFlag, + bridgeHelper.Erc20TokenFlag, "", "address of the erc20 token to be minted", ) - cmd.Flags().StringVar( - ¶ms.deployerPrivateKey, - polybftsecrets.PrivateKeyFlag, - "", - "private key of the token deployer (minter)", - ) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountConfigFlag) + cmd.MarkFlagsMutuallyExclusive(polybftsecrets.PrivateKeyFlag, polybftsecrets.AccountDirFlag) } func runCommand(cmd *cobra.Command, _ []string) { @@ -80,7 +98,7 @@ func runCommand(cmd *cobra.Command, _ []string) { return } - deployerKey, err := rootHelper.DecodePrivateKey(params.deployerPrivateKey) + deployerKey, err := bridgeHelper.GetECDSAKey(params.deployerPrivateKey, params.accountDir, params.accountConfig) if err != nil { outputter.SetError(fmt.Errorf("failed to initialize deployer private key: %w", err)) @@ -105,7 +123,7 @@ func runCommand(cmd *cobra.Command, _ []string) { addr := types.StringToAddress(params.addresses[i]) amount := params.amountValues[i] - mintTxn, err := rootHelper.CreateMintTxn(addr, tokenAddr, amount, true) + mintTxn, err := bridgeHelper.CreateMintTxn(addr, tokenAddr, amount, true) if err != nil { return fmt.Errorf("failed to create mint native tokens transaction for validator '%s'. err: %w", addr, err) diff --git a/command/mint/params.go b/command/mint/params.go index 4f22e6c2df..70efa0481d 100644 --- a/command/mint/params.go +++ b/command/mint/params.go @@ -13,6 +13,8 @@ import ( type mintParams struct { addresses []string amounts []string + accountDir string + accountConfig string tokenAddr string deployerPrivateKey string jsonRPCAddress string diff --git a/command/validator/registration/params.go b/command/validator/registration/params.go index 0edbfc0611..d212e3d5d5 100644 --- a/command/validator/registration/params.go +++ b/command/validator/registration/params.go @@ -9,10 +9,9 @@ import ( ) type registerParams struct { - accountDir string - accountConfig string - supernetManagerAddress string - jsonRPC string + accountDir string + accountConfig string + jsonRPC string } func (rp *registerParams) validateFlags() error { diff --git a/command/validator/registration/register_validator.go b/command/validator/registration/register_validator.go index 16855ad542..f3aec2b7e8 100644 --- a/command/validator/registration/register_validator.go +++ b/command/validator/registration/register_validator.go @@ -13,6 +13,7 @@ import ( "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/consensus/polybft/signer" "github.com/0xPolygon/polygon-edge/consensus/polybft/wallet" + "github.com/0xPolygon/polygon-edge/contracts" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" "github.com/spf13/cobra" @@ -49,13 +50,6 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) - cmd.Flags().StringVar( - ¶ms.supernetManagerAddress, - bridgeHelper.SupernetManagerFlag, - "", - bridgeHelper.SupernetManagerFlagDesc, - ) - helper.RegisterJSONRPCFlag(cmd) cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountConfigFlag, polybftsecrets.AccountDirFlag) } @@ -92,7 +86,7 @@ func runCommand(cmd *cobra.Command, _ []string) error { koskSignature, err := signer.MakeKOSKSignature( newValidatorAccount.Bls, newValidatorAccount.Address(), - rootChainID.Int64(), signer.DomainValidatorSet, types.StringToAddress(params.supernetManagerAddress)) + rootChainID.Int64(), signer.DomainValidatorSet, contracts.StakeManagerContract) if err != nil { return err } @@ -159,8 +153,8 @@ func registerValidator(sender txrelayer.TxRelayer, account *wallet.Account, return nil, fmt.Errorf("register validator failed: %w", err) } - supernetAddr := ethgo.Address(types.StringToAddress(params.supernetManagerAddress)) - txn := bridgeHelper.CreateTransaction(ethgo.ZeroAddress, &supernetAddr, input, nil, true) + stakeManagerAddr := ethgo.Address(contracts.StakeManagerContract) + txn := bridgeHelper.CreateTransaction(ethgo.ZeroAddress, &stakeManagerAddr, input, nil, true) return sender.SendTransaction(txn, account.Ecdsa) } diff --git a/command/validator/withdraw/params.go b/command/validator/withdraw/params.go index 9ccaba31a0..95baa417ca 100644 --- a/command/validator/withdraw/params.go +++ b/command/validator/withdraw/params.go @@ -3,7 +3,6 @@ package withdraw import ( "bytes" "fmt" - "math/big" "github.com/0xPolygon/polygon-edge/command/helper" validatorHelper "github.com/0xPolygon/polygon-edge/command/validator/helper" @@ -14,21 +13,12 @@ var ( ) type withdrawParams struct { - accountDir string - accountConfig string - jsonRPC string - stakeManagerAddr string - addressTo string - amount string - - amountValue *big.Int + accountDir string + accountConfig string + jsonRPC string } func (v *withdrawParams) validateFlags() (err error) { - if v.amountValue, err = helper.ParseAmount(v.amount); err != nil { - return err - } - if _, err = helper.ParseJSONRPCAddress(v.jsonRPC); err != nil { return fmt.Errorf("failed to parse json rpc address. Error: %w", err) } @@ -39,7 +29,6 @@ func (v *withdrawParams) validateFlags() (err error) { type withdrawResult struct { ValidatorAddress string `json:"validatorAddress"` Amount uint64 `json:"amount"` - WithdrawnTo string `json:"withdrawnTo"` } func (wr withdrawResult) GetOutput() string { @@ -47,10 +36,9 @@ func (wr withdrawResult) GetOutput() string { buffer.WriteString("\n[WITHDRAWN AMOUNT]\n") - vals := make([]string, 0, 3) + vals := make([]string, 0, 2) vals = append(vals, fmt.Sprintf("Validator Address|%s", wr.ValidatorAddress)) vals = append(vals, fmt.Sprintf("Amount Withdrawn|%v", wr.Amount)) - vals = append(vals, fmt.Sprintf("Withdrawn To|%s", wr.WithdrawnTo)) buffer.WriteString(helper.FormatKV(vals)) buffer.WriteString("\n") diff --git a/command/validator/withdraw/withdraw.go b/command/validator/withdraw/withdraw.go index e193f5cca8..75d727d4e9 100644 --- a/command/validator/withdraw/withdraw.go +++ b/command/validator/withdraw/withdraw.go @@ -21,8 +21,8 @@ var params withdrawParams func GetCommand() *cobra.Command { withdrawCmd := &cobra.Command{ - Use: "withdraw-root", - Short: "Withdraws sender's withdrawable amount to specified address on the root chain", + Use: "withdraw", + Short: "Withdraws validator's withdrawable stake", PreRunE: runPreRun, RunE: runCommand, } @@ -47,27 +47,6 @@ func setFlags(cmd *cobra.Command) { polybftsecrets.AccountConfigFlagDesc, ) - cmd.Flags().StringVar( - ¶ms.addressTo, - addressToFlag, - "", - "address where to withdraw withdrawable amount", - ) - - cmd.Flags().StringVar( - ¶ms.stakeManagerAddr, - bridgeHelper.StakeManagerFlag, - "", - bridgeHelper.StakeManagerFlagDesc, - ) - - cmd.Flags().StringVar( - ¶ms.amount, - validatorHelper.AmountFlag, - "", - "amount to withdraw", - ) - cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag) helper.RegisterJSONRPCFlag(cmd) } diff --git a/consensus/polybft/contracts_initializer.go b/consensus/polybft/contracts_initializer.go index ab001c8f9f..ac9aba85e6 100644 --- a/consensus/polybft/contracts_initializer.go +++ b/consensus/polybft/contracts_initializer.go @@ -270,9 +270,9 @@ func mintRewardTokensToWallet(polyBFTConfig PolyBFTConfig, transition *state.Tra "RewardToken.mint", transition) } -// approveRewardPoolAsSpender approves reward pool contract as reward token spender -// since reward pool distributes rewards. -func approveRewardPoolAsSpender(polyBFTConfig PolyBFTConfig, transition *state.Transition) error { +// approveEpochManagerAsSpender approves EpochManager contract as reward token spender +// since EpochManager distributes rewards +func approveEpochManagerAsSpender(polyBFTConfig PolyBFTConfig, transition *state.Transition) error { approveFn := &contractsapi.ApproveRootERC20Fn{ Spender: contracts.EpochManagerContract, Amount: polyBFTConfig.RewardConfig.WalletAmount, diff --git a/consensus/polybft/helpers_test.go b/consensus/polybft/helpers_test.go index f224eb39a0..a30f7c348d 100644 --- a/consensus/polybft/helpers_test.go +++ b/consensus/polybft/helpers_test.go @@ -188,8 +188,6 @@ func createTestBridgeConfig() *BridgeConfig { ChildMintableERC721PredicateAddr: types.StringToAddress("9"), RootERC1155PredicateAddr: types.StringToAddress("11"), ChildMintableERC1155PredicateAddr: types.StringToAddress("12"), - CustomSupernetManagerAddr: types.StringToAddress("13"), - StakeManagerAddr: types.StringToAddress("14"), JSONRPCEndpoint: "http://localhost:8545", } } diff --git a/consensus/polybft/polybft.go b/consensus/polybft/polybft.go index 4f352b5640..5cb942b0a6 100644 --- a/consensus/polybft/polybft.go +++ b/consensus/polybft/polybft.go @@ -162,8 +162,8 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st return err } - // approve reward pool - if err = approveRewardPoolAsSpender(polyBFTConfig, transition); err != nil { + // approve EpochManager + if err = approveEpochManagerAsSpender(polyBFTConfig, transition); err != nil { return err } @@ -172,7 +172,7 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st return err } - // initialize RewardPool SC + // initialize EpochManager SC if err = initEpochManager(polyBFTConfig, transition); err != nil { return err } @@ -342,27 +342,27 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st return err } } + } - // initialize NativeERC20 SC - params := &contractsapi.InitializeNativeERC20Fn{ - Predicate_: contracts.ChildERC20PredicateContract, - Owner_: polyBFTConfig.BladeAdmin, - RootToken_: types.ZeroAddress, // in case native mintable token is used, it is always root token - Name_: polyBFTConfig.NativeTokenConfig.Name, - Symbol_: polyBFTConfig.NativeTokenConfig.Symbol, - Decimals_: polyBFTConfig.NativeTokenConfig.Decimals, - TokenSupply_: initialTotalSupply, - } + // initialize NativeERC20 SC + params := &contractsapi.InitializeNativeERC20Fn{ + Predicate_: contracts.ChildERC20PredicateContract, + Owner_: polyBFTConfig.BladeAdmin, + RootToken_: types.ZeroAddress, // in case native mintable token is used, it is always root token + Name_: polyBFTConfig.NativeTokenConfig.Name, + Symbol_: polyBFTConfig.NativeTokenConfig.Symbol, + Decimals_: polyBFTConfig.NativeTokenConfig.Decimals, + TokenSupply_: initialTotalSupply, + } - input, err := params.EncodeAbi() - if err != nil { - return err - } + input, err := params.EncodeAbi() + if err != nil { + return err + } - if err = callContract(contracts.SystemCaller, - contracts.NativeERC20TokenContract, input, "NativeERC20", transition); err != nil { - return err - } + if err = callContract(contracts.SystemCaller, + contracts.NativeERC20TokenContract, input, "NativeERC20", transition); err != nil { + return err } return nil @@ -564,24 +564,18 @@ func (p *Polybft) startConsensusProtocol() { for { latestHeader := p.blockchain.CurrentHeader() - p.logger.Error(fmt.Sprintf("Latest header %+v", latestHeader)) currentValidators, err := p.GetValidators(latestHeader.Number, nil) - p.logger.Error(fmt.Sprintf("Current Validators %+v", currentValidators)) - if err != nil { p.logger.Error("failed to query current validator set", "block number", latestHeader.Number, "error", err) } - p.logger.Error(fmt.Sprintf("Key is... %+v", p.key)) - isValidator := currentValidators.ContainsNodeID(p.key.String()) p.runtime.setIsActiveValidator(isValidator) p.txPool.SetSealing(isValidator) // update tx pool if isValidator { - p.logger.Error("neko je validator") // initialize FSM as a stateless ibft backend via runtime as an adapter err = p.runtime.FSM() if err != nil { diff --git a/consensus/polybft/polybft_config.go b/consensus/polybft/polybft_config.go index 821fc7b35e..9a452389fc 100644 --- a/consensus/polybft/polybft_config.go +++ b/consensus/polybft/polybft_config.go @@ -131,10 +131,7 @@ type BridgeConfig struct { ChildERC20Addr types.Address `json:"childERC20Address"` ChildERC721Addr types.Address `json:"childERC721Address"` ChildERC1155Addr types.Address `json:"childERC1155Address"` - CustomSupernetManagerAddr types.Address `json:"customSupernetManagerAddr"` - StakeManagerAddr types.Address `json:"stakeManagerAddr"` // only populated if stake-manager-deploy command is executed, and used for e2e tests - StakeTokenAddr types.Address `json:"stakeTokenAddr,omitempty"` BLSAddress types.Address `json:"blsAddr"` BN256G2Address types.Address `json:"bn256G2Addr"` @@ -164,9 +161,6 @@ type RootchainConfig struct { RootERC1155PredicateAddress types.Address ChildMintableERC1155PredicateAddress types.Address ChildERC1155Address types.Address - CustomSupernetManagerAddress types.Address - StakeManagerAddress types.Address - StakeTokenAddress types.Address } // ToBridgeConfig creates BridgeConfig instance @@ -186,8 +180,6 @@ func (r *RootchainConfig) ToBridgeConfig() *BridgeConfig { ChildERC20Addr: r.ChildERC20Address, ChildERC721Addr: r.ChildERC721Address, ChildERC1155Addr: r.ChildERC1155Address, - CustomSupernetManagerAddr: r.CustomSupernetManagerAddress, - StakeManagerAddr: r.StakeManagerAddress, BLSAddress: r.BLSAddress, BN256G2Address: r.BN256G2Address, } diff --git a/consensus/polybft/sc_integration_test.go b/consensus/polybft/sc_integration_test.go index 4fe920c920..9eb072878f 100644 --- a/consensus/polybft/sc_integration_test.go +++ b/consensus/polybft/sc_integration_test.go @@ -301,6 +301,9 @@ func TestIntegration_CommitEpoch(t *testing.T) { contracts.NativeERC20TokenContract: { Code: contractsapi.NativeERC20.DeployedBytecode, }, + contracts.StakeManagerContract: { + Code: contractsapi.StakeManager.DeployedBytecode, + }, walletAddress: { Balance: new(big.Int).SetUint64(initialBalance), }, @@ -332,20 +335,18 @@ func TestIntegration_CommitEpoch(t *testing.T) { WalletAddress: walletAddress, WalletAmount: new(big.Int).SetUint64(initialBalance), }, - Bridge: &BridgeConfig{ - CustomSupernetManagerAddr: types.StringToAddress("0x12312451"), - }, } transition := newTestTransition(t, alloc) - // init RewardPool - err := initEpochManager(polyBFTConfig, transition) - require.NoError(t, err) + // init StakeManager + require.NoError(t, initStakeManager(polyBFTConfig, transition)) - // approve reward pool as reward token spender - err = approveRewardPoolAsSpender(polyBFTConfig, transition) - require.NoError(t, err) + // init EpochManager + require.NoError(t, initEpochManager(polyBFTConfig, transition)) + + // approve EpochManager as reward token spender + require.NoError(t, approveEpochManagerAsSpender(polyBFTConfig, transition)) // create input for commit epoch commitEpoch := createTestCommitEpochInput(t, 1, polyBFTConfig.EpochSize) diff --git a/consensus/polybft/signer/utils.go b/consensus/polybft/signer/utils.go index 5628167667..cd3eee4a75 100644 --- a/consensus/polybft/signer/utils.go +++ b/consensus/polybft/signer/utils.go @@ -36,13 +36,13 @@ var ( // MakeKOSKSignature creates KOSK signature which prevents rogue attack func MakeKOSKSignature(privateKey *bls.PrivateKey, address types.Address, - chainID int64, domain []byte, supernetManagerAddr types.Address) (*bls.Signature, error) { + chainID int64, domain []byte, stakeManagerAddr types.Address) (*bls.Signature, error) { spenderABI, err := addressABIType.Encode(address) if err != nil { return nil, err } - supernetManagerABI, err := addressABIType.Encode(supernetManagerAddr) + supernetManagerABI, err := addressABIType.Encode(stakeManagerAddr) if err != nil { return nil, err } diff --git a/consensus/polybft/stake_manager.go b/consensus/polybft/stake_manager.go index f4135bb85f..7cabc5af0b 100644 --- a/consensus/polybft/stake_manager.go +++ b/consensus/polybft/stake_manager.go @@ -362,15 +362,22 @@ func (s *stakeManager) getBlsKey(address types.Address) (*bls.PublicKey, error) stakeManagerContractContract := contract.NewContract( ethgo.Address(s.stakeManagerContractAddr), - contractsapi.EpochManager.Abi, contract.WithProvider(provider), + contractsapi.StakeManager.Abi, contract.WithProvider(provider), ) - rawResult, err := stakeManagerContractContract.Call("currentEpochId", ethgo.Latest) + rawResult, err := stakeManagerContractContract.Call("getValidator", ethgo.Latest, address) if err != nil { return nil, err } - blsKey, ok := rawResult["blsKey"].([4]*big.Int) + validatorData, ok := rawResult["0"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("could not collect validator: %s data from StakeManager", address) + } + + s.logger.Info("[Aaaa] Validator data", validatorData) + + blsKey, ok := validatorData["blsKey"].([4]*big.Int) if !ok { return nil, fmt.Errorf("failed to decode blskey") } diff --git a/e2e-polybft/e2e/bridge_test.go b/e2e-polybft/e2e/bridge_test.go index 5f19c85260..6de6d2c526 100644 --- a/e2e-polybft/e2e/bridge_test.go +++ b/e2e-polybft/e2e/bridge_test.go @@ -863,7 +863,7 @@ func TestE2E_Bridge_ChildChainMintableTokensTransfer(t *testing.T) { childEthEndpoint := validatorSrv.JSONRPC().Eth() // fund accounts on rootchain - require.NoError(t, validatorSrv.RootchainFundFor(depositors, funds, polybftCfg.Bridge.StakeTokenAddr)) + require.NoError(t, validatorSrv.RootchainFundFor(depositors, funds)) cluster.WaitForReady(t) @@ -1259,7 +1259,7 @@ func TestE2E_Bridge_ChangeVotingPower(t *testing.T) { validatorSrv := cluster.Servers[idx] // fund validators (send accumulated rewards amount) - require.NoError(t, validatorSrv.RootchainFund(polybftCfg.Bridge.StakeTokenAddr, validator.WithdrawableRewards)) + require.NoError(t, validatorSrv.RootchainFund(validator.WithdrawableRewards)) // stake previously funded amount require.NoError(t, validatorSrv.Stake(polybftCfg, validator.WithdrawableRewards)) @@ -1356,8 +1356,7 @@ func TestE2E_Bridge_Transfers_AccessLists(t *testing.T) { var stateSyncedResult contractsapi.StateSyncResultEvent // fund admin on rootchain - require.NoError(t, cluster.Servers[0].RootchainFundFor([]types.Address{adminAddr}, []*big.Int{ethgo.Ether(10)}, - polybftCfg.Bridge.StakeTokenAddr)) + require.NoError(t, cluster.Servers[0].RootchainFundFor([]types.Address{adminAddr}, []*big.Int{ethgo.Ether(10)})) adminBalanceOnChild := ethgo.Ether(5) diff --git a/e2e-polybft/e2e/consensus_test.go b/e2e-polybft/e2e/consensus_test.go index 53f9677e90..7aabc64fe3 100644 --- a/e2e-polybft/e2e/consensus_test.go +++ b/e2e-polybft/e2e/consensus_test.go @@ -1,6 +1,7 @@ package e2e import ( + "bytes" "fmt" "math/big" "path" @@ -34,55 +35,66 @@ func TestE2E_Consensus_Basic(t *testing.T) { validatorsNum = 5 ) - var ( - premineBalance = ethgo.Ether(2) + cluster := framework.NewTestCluster(t, validatorsNum, + framework.WithEpochSize(epochSize), + framework.WithNonValidators(2), ) - - cluster := framework.NewTestCluster(t, 5, - framework.WithEpochSize(epochSize), framework.WithTestRewardToken(), - framework.WithSecretsCallback(func(addresses []types.Address, config *framework.TestClusterConfig) { - for _, a := range addresses { - config.Premine = append(config.Premine, fmt.Sprintf("%s:%s", a, premineBalance)) - } - })) defer cluster.Stop() cluster.WaitForReady(t) // initialize tx relayer - //relayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(cluster.Servers[0].JSONRPC())) - //require.NoError(t, err) + relayer, err := txrelayer.NewTxRelayer(txrelayer.WithClient(cluster.Servers[0].JSONRPC())) + require.NoError(t, err) - // because we are using native token as reward wallet, and it has default premine balance - //initialTotalSupply := new(big.Int).Set(command.DefaultPremineBalance) + initialTotalSupply := new(big.Int).Mul(big.NewInt(validatorsNum+1 /*because of reward token*/), + command.DefaultPremineBalance) // check if initial total supply of native ERC20 token is the same as expected - //totalSupply := queryNativeERC20Metadata(t, "totalSupply", uint256ABIType, relayer) - //require.True(t, initialTotalSupply.Cmp(totalSupply.(*big.Int)) == 0) //nolint:forcetypeassert + totalSupply := queryNativeERC20Metadata(t, "totalSupply", uint256ABIType, relayer) + require.True(t, initialTotalSupply.Cmp(totalSupply.(*big.Int)) == 0) //nolint:forcetypeassert - require.NoError(t, cluster.WaitForBlock(10, 1*time.Minute)) + t.Run("consensus protocol", func(t *testing.T) { + require.NoError(t, cluster.WaitForBlock(2*epochSize+1, 1*time.Minute)) + }) - polybftConfig, err := polybft.LoadPolyBFTConfig(path.Join(cluster.Config.TmpDir, chainConfigFileName)) - require.NoError(t, err) + t.Run("sync protocol, drop single validator node", func(t *testing.T) { + // query the current block number, as it is a starting point for the test + currentBlockNum, err := cluster.Servers[0].JSONRPC().Eth().BlockNumber() + require.NoError(t, err) - srv := cluster.Servers[0] + // stop one node + node := cluster.Servers[0] + node.Stop() - childChainRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(srv.JSONRPCAddr())) - require.NoError(t, err) + // wait for 2 epochs to elapse, so that rest of the network progresses + require.NoError(t, cluster.WaitForBlock(currentBlockNum+2*epochSize, 2*time.Minute)) + + // start the node again + node.Start() - require.NoError(t, srv.Stake(polybftConfig, big.NewInt(500))) + // wait 2 more epochs to elapse and make sure that stopped node managed to catch up + require.NoError(t, cluster.WaitForBlock(currentBlockNum+4*epochSize, 2*time.Minute)) + }) - require.NoError(t, cluster.WaitForBlock(26, 1*time.Minute)) + t.Run("sync protocol, drop single non-validator node", func(t *testing.T) { + // query the current block number, as it is a starting point for the test + currentBlockNum, err := cluster.Servers[0].JSONRPC().Eth().BlockNumber() + require.NoError(t, err) - validatorAcc, err := validatorHelper.GetAccountFromDir(srv.DataDir()) - require.NoError(t, err) - // check that validator is no longer active (out of validator set) - validatorInfo, err := validatorHelper.GetValidatorInfo(validatorAcc.Ecdsa.Address(), childChainRelayer) - require.NoError(t, err) + // stop one non-validator node + node := cluster.Servers[6] + node.Stop() + + // wait for 2 epochs to elapse, so that rest of the network progresses + require.NoError(t, cluster.WaitForBlock(currentBlockNum+2*epochSize, 2*time.Minute)) - t.Log(validatorInfo.Stake) + // start the node again + node.Start() - require.NoError(t, cluster.WaitForBlock(35, 1*time.Minute)) + // wait 2 more epochs to elapse and make sure that stopped node managed to catch up + require.NoError(t, cluster.WaitForBlock(currentBlockNum+4*epochSize, 2*time.Minute)) + }) } func TestE2E_Consensus_BulkDrop(t *testing.T) { @@ -95,7 +107,6 @@ func TestE2E_Consensus_BulkDrop(t *testing.T) { cluster := framework.NewTestCluster(t, clusterSize, framework.WithEpochSize(epochSize), framework.WithBlockTime(time.Second), - framework.WithTestRewardToken(), ) defer cluster.Stop() @@ -156,10 +167,7 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { // first validator is the owner of ChildValidator set smart contract owner := cluster.Servers[0] - childChainRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(owner.JSONRPCAddr())) - require.NoError(t, err) - - rootChainRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr())) + relayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(owner.JSONRPCAddr())) require.NoError(t, err) polybftConfig, err := polybft.LoadPolyBFTConfig(path.Join(cluster.Config.TmpDir, chainConfigFileName)) @@ -182,10 +190,6 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { require.NoError(t, err) require.Equal(t, validatorSetSize+2, len(validatorSecrets)) - // collect owners validator secrets - firstValidatorSecrets := validatorSecrets[validatorSetSize] - secondValidatorSecrets := validatorSecrets[validatorSetSize+1] - genesisBlock, err := owner.JSONRPC().Eth().GetBlockByNumber(0, false) require.NoError(t, err) @@ -196,28 +200,22 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { require.NoError(t, owner.WhitelistValidators([]string{ firstValidatorAddr.String(), secondValidatorAddr.String(), - }, polybftConfig.Bridge.CustomSupernetManagerAddr)) + })) - // set the initial balance of the new validators at the rootchain + // set the initial balance of the new validators initialBalance := ethgo.Ether(500) - // fund first new validator - err = cluster.Bridge.FundValidators(polybftConfig.Bridge.StakeTokenAddr, - []string{path.Join(cluster.Config.TmpDir, firstValidatorSecrets)}, []*big.Int{initialBalance}) - require.NoError(t, err) - - // fund second new validator - err = cluster.Bridge.FundValidators(polybftConfig.Bridge.StakeTokenAddr, - []string{path.Join(cluster.Config.TmpDir, secondValidatorSecrets)}, []*big.Int{initialBalance}) - require.NoError(t, err) + // mint tokens to new validators + require.NoError(t, owner.MintNativeERC20Token([]string{firstValidatorAddr.String(), secondValidatorAddr.String()}, + []*big.Int{initialBalance, initialBalance})) // first validator's balance to be received - firstBalance, err := rootChainRelayer.Client().Eth().GetBalance(firstValidatorAddr, ethgo.Latest) + firstBalance, err := relayer.Client().Eth().GetBalance(firstValidatorAddr, ethgo.Latest) require.NoError(t, err) t.Logf("First validator balance=%d\n", firstBalance) // second validator's balance to be received - secondBalance, err := rootChainRelayer.Client().Eth().GetBalance(secondValidatorAddr, ethgo.Latest) + secondBalance, err := relayer.Client().Eth().GetBalance(secondValidatorAddr, ethgo.Latest) require.NoError(t, err) t.Logf("Second validator balance=%d\n", secondBalance) @@ -228,6 +226,9 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { cluster.InitTestServer(t, cluster.Config.ValidatorPrefix+strconv.Itoa(validatorSetSize+2), cluster.Bridge.JSONRPCAddr(), framework.Validator) + // wait for couple of epochs until new validators start + require.NoError(t, cluster.WaitForBlock(epochSize*3, time.Minute)) + // collect the first and the second validator from the cluster firstValidator := cluster.Servers[validatorSetSize] secondValidator := cluster.Servers[validatorSetSize+1] @@ -235,10 +236,10 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { initialStake := ethgo.Ether(499) // register the first validator with stake - require.NoError(t, firstValidator.RegisterValidator(polybftConfig.Bridge.CustomSupernetManagerAddr)) + require.NoError(t, firstValidator.RegisterValidator()) // register the second validator without stake - require.NoError(t, secondValidator.RegisterValidator(polybftConfig.Bridge.CustomSupernetManagerAddr)) + require.NoError(t, secondValidator.RegisterValidator()) // stake manually for the first validator require.NoError(t, firstValidator.Stake(polybftConfig, initialStake)) @@ -246,52 +247,16 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { // stake manually for the second validator require.NoError(t, secondValidator.Stake(polybftConfig, initialStake)) - firstValidatorInfo, err := validatorHelper.GetValidatorInfo(firstValidatorAddr, childChainRelayer) + firstValidatorInfo, err := validatorHelper.GetValidatorInfo(firstValidatorAddr, relayer) require.NoError(t, err) require.True(t, firstValidatorInfo.IsActive) require.True(t, firstValidatorInfo.Stake.Cmp(initialStake) == 0) - secondValidatorInfo, err := validatorHelper.GetValidatorInfo(secondValidatorAddr, childChainRelayer) + secondValidatorInfo, err := validatorHelper.GetValidatorInfo(secondValidatorAddr, relayer) require.NoError(t, err) require.True(t, secondValidatorInfo.IsActive) require.True(t, secondValidatorInfo.Stake.Cmp(initialStake) == 0) - // wait for the stake to be bridged - require.NoError(t, cluster.WaitForBlock(polybftConfig.EpochSize*4, time.Minute)) - - checkpointManagerAddr := ethgo.Address(polybftConfig.Bridge.CheckpointManagerAddr) - - // check if the validators are added to active validator set - rootchainValidators := []*polybft.ValidatorInfo{} - err = cluster.Bridge.WaitUntil(time.Second, time.Minute, func() (bool, error) { - rootchainValidators, err = getCheckpointManagerValidators(rootChainRelayer, checkpointManagerAddr) - if err != nil { - return true, err - } - - return len(rootchainValidators) == validatorSetSize+2, nil - }) - - require.NoError(t, err) - require.Equal(t, validatorSetSize+2, len(rootchainValidators)) - - var ( - isFirstValidatorFound bool - isSecondValidatorFound bool - ) - - for _, v := range rootchainValidators { - if v.Address == firstValidatorAddr { - isFirstValidatorFound = true - } else if v.Address == secondValidatorAddr { - isSecondValidatorFound = true - } - } - - // new validators should be in the active validator set - require.True(t, isFirstValidatorFound) - require.True(t, isSecondValidatorFound) - currentBlock, err := owner.JSONRPC().Eth().GetBlockByNumber(ethgo.Latest, false) require.NoError(t, err) @@ -300,15 +265,26 @@ func TestE2E_Consensus_RegisterValidator(t *testing.T) { bigZero := big.NewInt(0) - firstValidatorInfo, err = validatorHelper.GetValidatorInfo(firstValidatorAddr, childChainRelayer) + firstValidatorInfo, err = validatorHelper.GetValidatorInfo(firstValidatorAddr, relayer) require.NoError(t, err) require.True(t, firstValidatorInfo.IsActive) require.True(t, firstValidatorInfo.WithdrawableRewards.Cmp(bigZero) > 0) - secondValidatorInfo, err = validatorHelper.GetValidatorInfo(secondValidatorAddr, childChainRelayer) + secondValidatorInfo, err = validatorHelper.GetValidatorInfo(secondValidatorAddr, relayer) require.NoError(t, err) require.True(t, secondValidatorInfo.IsActive) require.True(t, secondValidatorInfo.WithdrawableRewards.Cmp(bigZero) > 0) + + // wait until one of the validators mine one block to check if they joined consensus + require.NoError(t, cluster.WaitUntil(3*time.Minute, 2*time.Second, func() bool { + latestBlock, err := cluster.Servers[0].JSONRPC().Eth().GetBlockByNumber(ethgo.Latest, false) + require.NoError(t, err) + + blockMiner := latestBlock.Miner.Bytes() + + return bytes.Equal(firstValidatorAddr.Bytes(), blockMiner) || + bytes.Equal(secondValidatorAddr.Bytes(), blockMiner) + })) } func TestE2E_Consensus_Validator_Unstake(t *testing.T) { @@ -332,10 +308,7 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { srv := cluster.Servers[0] - childChainRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(srv.JSONRPCAddr())) - require.NoError(t, err) - - rootChainRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr())) + relayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(srv.JSONRPCAddr())) require.NoError(t, err) validatorAcc, err := validatorHelper.GetAccountFromDir(srv.DataDir()) @@ -352,7 +325,7 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { // wait for some rewards to get accumulated require.NoError(t, cluster.WaitForBlock(polybftCfg.EpochSize*3, time.Minute)) - validatorInfo, err := validatorHelper.GetValidatorInfo(validatorAddr, childChainRelayer) + validatorInfo, err := validatorHelper.GetValidatorInfo(validatorAddr, relayer) require.NoError(t, err) require.True(t, validatorInfo.IsActive) @@ -366,39 +339,20 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { // unstake entire balance (which should remove validator from the validator set in next epoch) require.NoError(t, srv.Unstake(initialStake)) - // wait for one epoch to withdraw from child - require.NoError(t, cluster.WaitForBlock(polybftCfg.EpochSize*4, time.Minute)) - - // withdraw from child - require.NoError(t, srv.WithdrawChildChain()) - currentBlock, err := srv.JSONRPC().Eth().GetBlockByNumber(ethgo.Latest, false) require.NoError(t, err) - currentExtra, err := polybft.GetIbftExtra(currentBlock.ExtraData) - require.NoError(t, err) - - t.Logf("Latest block number: %d, epoch number: %d\n", currentBlock.Number, currentExtra.Checkpoint.EpochNumber) - - currentEpoch := currentExtra.Checkpoint.EpochNumber - - // wait for checkpoint to be submitted - require.NoError(t, waitForRootchainEpoch(currentEpoch, time.Minute, - rootChainRelayer, polybftCfg.Bridge.CheckpointManagerAddr)) - - exitEventID := uint64(1) - - // send exit transaction to exit helper - err = cluster.Bridge.SendExitTransaction(polybftCfg.Bridge.ExitHelperAddr, exitEventID, srv.JSONRPCAddr()) - require.NoError(t, err) + // wait for couple of epochs to withdraw stake + require.NoError(t, cluster.WaitForBlock(currentBlock.Number+(polybftCfg.EpochSize*2), time.Minute)) + require.NoError(t, srv.WithdrawChildChain()) // check that validator is no longer active (out of validator set) - validatorInfo, err = validatorHelper.GetValidatorInfo(validatorAddr, childChainRelayer) + validatorInfo, err = validatorHelper.GetValidatorInfo(validatorAddr, relayer) require.NoError(t, err) require.False(t, validatorInfo.IsActive) require.True(t, validatorInfo.Stake.Cmp(big.NewInt(0)) == 0) - t.Logf("Stake (after unstake)=%d\n", validatorInfo.Stake) + t.Logf("Stake (after unstake and withdraw)=%d\n", validatorInfo.Stake) balanceBeforeRewardsWithdraw, err := srv.JSONRPC().Eth().GetBalance(validatorAcc.Ecdsa.Address(), ethgo.Latest) require.NoError(t, err) @@ -411,31 +365,6 @@ func TestE2E_Consensus_Validator_Unstake(t *testing.T) { require.NoError(t, err) t.Logf("Balance (after withdrawal of rewards)=%s\n", newValidatorBalance) require.True(t, newValidatorBalance.Cmp(balanceBeforeRewardsWithdraw) > 0) - - l1Relayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr())) - require.NoError(t, err) - - checkpointManagerAddr := ethgo.Address(polybftCfg.Bridge.CheckpointManagerAddr) - - // query rootchain validator set and make sure that validator which unstaked all the funds isn't present in validator set anymore - // (execute it multiple times if needed, because it is unknown in advance how much time it is going to take until checkpoint is submitted) - rootchainValidators := []*polybft.ValidatorInfo{} - err = cluster.Bridge.WaitUntil(time.Second, 10*time.Second, func() (bool, error) { - rootchainValidators, err = getCheckpointManagerValidators(l1Relayer, checkpointManagerAddr) - if err != nil { - return true, err - } - - return len(rootchainValidators) == 4, nil - }) - require.NoError(t, err) - require.Equal(t, 4, len(rootchainValidators)) - - for _, validator := range rootchainValidators { - if validator.Address == validatorAddr { - t.Fatalf("not expected to find validator %v in the current validator set", validator.Address) - } - } } func TestE2E_Consensus_MintableERC20NativeToken(t *testing.T) { @@ -598,7 +527,6 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { // first account should have some matics premined cluster := framework.NewTestCluster(t, 5, - framework.WithNativeTokenConfig(fmt.Sprintf(framework.NativeTokenMintableTestCfg, sender1.Address())), framework.WithPremine(types.Address(sender1.Address()), types.Address(sender2.Address())), ) defer cluster.Stop() @@ -678,8 +606,8 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { receiverFinalBalance, _ := client.GetBalance(recipient, ethgo.Latest) burnContractFinalBalance, _ := client.GetBalance(ethgo.Address(types.ZeroAddress), ethgo.Latest) - diffReciverBalance := new(big.Int).Sub(receiverFinalBalance, receiverInitialBalance) - assert.Equal(t, sendAmount, diffReciverBalance, "Receiver balance should be increased by send amount") + diffReceiverBalance := new(big.Int).Sub(receiverFinalBalance, receiverInitialBalance) + assert.Equal(t, sendAmount, diffReceiverBalance, "Receiver balance should be increased by send amount") if i == 1 && prevMiner != block.Miner { initialMinerBalance = big.NewInt(0) @@ -689,7 +617,7 @@ func TestE2E_Consensus_EIP1559Check(t *testing.T) { diffSenderBalance := new(big.Int).Sub(senderInitialBalance, senderFinalBalance) diffMinerBalance := new(big.Int).Sub(finalMinerFinalBalance, initialMinerBalance) - diffSenderBalance.Sub(diffSenderBalance, diffReciverBalance) + diffSenderBalance.Sub(diffSenderBalance, diffReceiverBalance) diffSenderBalance.Sub(diffSenderBalance, diffBurnContractBalance) diffSenderBalance.Sub(diffSenderBalance, diffMinerBalance) diff --git a/e2e-polybft/e2e/migration_test.go b/e2e-polybft/e2e/migration_test.go index f3a931e9d4..c1a38cfe95 100644 --- a/e2e-polybft/e2e/migration_test.go +++ b/e2e-polybft/e2e/migration_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "os" "path/filepath" "testing" @@ -32,8 +33,11 @@ func TestE2E_Migration(t *testing.T) { config.SetConsensus(framework.ConsensusDev) config.Premine(types.Address(userAddr), initialBalance) }) + srv := srvs[0] + require.NoError(t, srv.WaitForReady(context.TODO())) + rpcClient := srv.JSONRPC() // Fetch the balances before sending diff --git a/e2e-polybft/e2e/network_test.go b/e2e-polybft/e2e/network_test.go index 7129244d70..c04a1320c1 100644 --- a/e2e-polybft/e2e/network_test.go +++ b/e2e-polybft/e2e/network_test.go @@ -21,7 +21,6 @@ func TestE2E_NetworkDiscoveryProtocol(t *testing.T) { // create cluster cluster := framework.NewTestCluster(t, validatorCount, - framework.WithTestRewardToken(), framework.WithNonValidators(nonValidatorCount), framework.WithBootnodeCount(1)) defer cluster.Stop() diff --git a/e2e-polybft/framework/test-bridge.go b/e2e-polybft/framework/test-bridge.go index d2a1f957ea..a8dd25870c 100644 --- a/e2e-polybft/framework/test-bridge.go +++ b/e2e-polybft/framework/test-bridge.go @@ -307,16 +307,9 @@ func (t *TestBridge) cmdRun(args ...string) error { // deployRootchainContracts deploys and initializes rootchain contracts func (t *TestBridge) deployRootchainContracts(genesisPath string) error { - polybftConfig, err := polybft.LoadPolyBFTConfig(genesisPath) - if err != nil { - return err - } - args := []string{ "bridge", "deploy", - "--stake-manager", polybftConfig.Bridge.StakeManagerAddr.String(), - "--stake-token", polybftConfig.Bridge.StakeTokenAddr.String(), "--proxy-contracts-admin", t.clusterConfig.GetProxyContractsAdmin(), "--genesis", genesisPath, "--test", @@ -345,7 +338,7 @@ func (t *TestBridge) fundAddressesOnRoot(tokenConfig *polybft.TokenConfig, polyb balances[i] = command.DefaultPremineBalance } - if err := t.FundValidators(polybftConfig.Bridge.StakeTokenAddr, + if err := t.FundValidators( secrets, balances); err != nil { return fmt.Errorf("failed to fund validators on the rootchain: %w", err) } @@ -389,7 +382,6 @@ func (t *TestBridge) whitelistValidators(validatorAddresses []types.Address, "whitelist-validators", "--addresses", strings.Join(addressesAsString, ","), "--jsonrpc", t.JSONRPCAddr(), - "--supernet-manager", polybftConfig.Bridge.CustomSupernetManagerAddr.String(), "--private-key", bridgeHelper.TestAccountPrivKey, } @@ -420,7 +412,6 @@ func (t *TestBridge) registerGenesisValidators(polybftConfig polybft.PolyBFTConf "validator", "register-validator", "--jsonrpc", t.JSONRPCAddr(), - "--supernet-manager", polybftConfig.Bridge.CustomSupernetManagerAddr.String(), "--" + polybftsecrets.AccountDirFlag, path.Join(t.clusterConfig.TmpDir, secret), } @@ -457,10 +448,8 @@ func (t *TestBridge) initialStakingOfGenesisValidators(polybftConfig polybft.Pol "validator", "stake", "--jsonrpc", t.JSONRPCAddr(), - "--stake-manager", polybftConfig.Bridge.StakeManagerAddr.String(), "--" + polybftsecrets.AccountDirFlag, path.Join(t.clusterConfig.TmpDir, secret), "--amount", t.getStakeAmount(i).String(), - "--stake-token", polybftConfig.Bridge.StakeTokenAddr.String(), } if err := t.cmdRun(args...); err != nil { @@ -485,17 +474,12 @@ func (t *TestBridge) getStakeAmount(validatorIndex int) *big.Int { } // FundValidators sends tokens to a rootchain validators -func (t *TestBridge) FundValidators(tokenAddress types.Address, secretsPaths []string, amounts []*big.Int) error { +func (t *TestBridge) FundValidators(secretsPaths []string, amounts []*big.Int) error { if len(secretsPaths) != len(amounts) { return errors.New("expected the same length of secrets paths and amounts") } - args := []string{ - "bridge", - "fund", - "--stake-token", tokenAddress.String(), - "--mint", - } + args := []string{"bridge", "fund"} for i := 0; i < len(secretsPaths); i++ { secretsManager, err := polybftsecrets.GetSecretsManager(secretsPaths[i], "", true) diff --git a/e2e-polybft/framework/test-cluster.go b/e2e-polybft/framework/test-cluster.go index 8bb8cd3b68..abbec11900 100644 --- a/e2e-polybft/framework/test-cluster.go +++ b/e2e-polybft/framework/test-cluster.go @@ -516,11 +516,8 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T args = append(args, "--native-token-config", cluster.Config.NativeTokenConfigRaw) } - if len(cluster.Config.Premine) != 0 { - // only add premine flags in genesis if token is mintable - for _, premine := range cluster.Config.Premine { - args = append(args, "--premine", premine) - } + for _, premine := range cluster.Config.Premine { + args = append(args, "--premine", premine) } validators, err := genesis.ReadValidatorsByPrefix( @@ -600,12 +597,6 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T } } - if len(validators) != 0 { - for _, validator := range validators { - args = append(args, "--stake", fmt.Sprintf("%s:%s", validator.Address.String(), "1000000000000000")) - } - } - proxyAdminAddr := cluster.Config.ProxyContractsAdmin if proxyAdminAddr == "" { proxyAdminAddr = ProxyContractAdminAddr diff --git a/e2e-polybft/framework/test-server.go b/e2e-polybft/framework/test-server.go index a9f402f52b..e3f298ff60 100644 --- a/e2e-polybft/framework/test-server.go +++ b/e2e-polybft/framework/test-server.go @@ -11,11 +11,11 @@ import ( "testing" "time" - bridgeHelper "github.com/0xPolygon/polygon-edge/command/bridge/helper" polybftsecrets "github.com/0xPolygon/polygon-edge/command/secrets/init" "github.com/0xPolygon/polygon-edge/consensus/polybft" "github.com/0xPolygon/polygon-edge/consensus/polybft/validator" "github.com/0xPolygon/polygon-edge/consensus/polybft/wallet" + "github.com/0xPolygon/polygon-edge/contracts" "github.com/0xPolygon/polygon-edge/server/proto" txpoolProto "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" @@ -196,12 +196,12 @@ func (t *TestServer) Stop() { } // RootchainFund funds given validator account on the rootchain -func (t *TestServer) RootchainFund(stakeToken types.Address, amount *big.Int) error { - return t.RootchainFundFor([]types.Address{t.address}, []*big.Int{amount}, stakeToken) +func (t *TestServer) RootchainFund(amount *big.Int) error { + return t.RootchainFundFor([]types.Address{t.address}, []*big.Int{amount}) } // RootchainFundFor funds given account on the rootchain -func (t *TestServer) RootchainFundFor(accounts []types.Address, amounts []*big.Int, stakeToken types.Address) error { +func (t *TestServer) RootchainFundFor(accounts []types.Address, amounts []*big.Int) error { if len(accounts) != len(amounts) { return errors.New("same size for accounts and amounts must be provided to the rootchain funding") } @@ -210,8 +210,6 @@ func (t *TestServer) RootchainFundFor(accounts []types.Address, amounts []*big.I "bridge", "fund", "--json-rpc", t.BridgeJSONRPCAddr(), - "--stake-token", stakeToken.String(), - "--mint", } for i := 0; i < len(accounts); i++ { @@ -258,45 +256,63 @@ func (t *TestServer) Unstake(amount *big.Int) error { } // RegisterValidator is a wrapper function which registers new validator on a root chain -func (t *TestServer) RegisterValidator(supernetManagerAddr types.Address) error { +func (t *TestServer) RegisterValidator() error { args := []string{ "validator", "register-validator", - "--jsonrpc", t.BridgeJSONRPCAddr(), - "--supernet-manager", supernetManagerAddr.String(), + "--jsonrpc", t.JSONRPCAddr(), "--" + polybftsecrets.AccountDirFlag, t.DataDir(), } - return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("bridge")) + return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("validator")) } // WhitelistValidators invokes whitelist-validators helper CLI command, // that whitelists validators on the root chain -func (t *TestServer) WhitelistValidators(addresses []string, supernetManager types.Address) error { +func (t *TestServer) WhitelistValidators(addresses []string) error { args := []string{ "validator", "whitelist-validators", - "--private-key", bridgeHelper.TestAccountPrivKey, + "--" + polybftsecrets.AccountDirFlag, t.config.DataDir, "--jsonrpc", t.BridgeJSONRPCAddr(), - "--supernet-manager", supernetManager.String(), } for _, addr := range addresses { args = append(args, "--addresses", addr) } - return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("bridge")) + return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("validator")) +} + +// MintNativeERC20Token mints given amounts of native erc20 token on blade to given addresses +func (t *TestServer) MintNativeERC20Token(addresses []string, amounts []*big.Int) error { + args := []string{ + "mint-erc20", + "--" + polybftsecrets.AccountDirFlag, t.config.DataDir, + "--jsonrpc", t.JSONRPCAddr(), + "--erc20-token", contracts.NativeERC20TokenContract.String(), + } + + for _, addr := range addresses { + args = append(args, "--addresses", addr) + } + + for _, amount := range amounts { + args = append(args, "--amounts", amount.String()) + } + + return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("mint-erc20")) } // WithdrawChildChain withdraws available balance from child chain func (t *TestServer) WithdrawChildChain() error { args := []string{ "validator", - "withdraw-child", + "withdraw", "--" + polybftsecrets.AccountDirFlag, t.config.DataDir, "--jsonrpc", t.JSONRPCAddr(), } - return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("withdraw-child")) + return runCommand(t.clusterConfig.Binary, args, t.clusterConfig.GetStdout("withdraw")) } // WithdrawRootChain withdraws available balance from root chain diff --git a/e2e/framework/testserver.go b/e2e/framework/testserver.go index 436d64e885..7726ade51c 100644 --- a/e2e/framework/testserver.go +++ b/e2e/framework/testserver.go @@ -195,14 +195,6 @@ func (t *TestServer) GenerateGenesis() error { blockGasLimit := strconv.FormatUint(t.Config.BlockGasLimit, 10) args = append(args, "--block-gas-limit", blockGasLimit) - // add base fee - if t.Config.BaseFee != 0 { - args = append(args, "--base-fee-config", *common.EncodeUint64(t.Config.BaseFee)) - } - - // london hardfork is enabled by default so there must be a default burn contract - args = append(args, "--burn-contract", "0:0x0000000000000000000000000000000000000000") - cmd := exec.Command(resolveBinary(), args...) //nolint:gosec cmd.Dir = t.Config.RootDir