Skip to content

Commit

Permalink
Pos v1.0.0 (#2626)
Browse files Browse the repository at this point in the history
* add deploy function

* add deploy into blockchain/convert flow

* deploy contract: ok

* making improvements

* base case working

* encapsulate

* nit

* lint

* rm unused params

* fix e2e

* removing stake param from e2e

* e2e
  • Loading branch information
felipemadero authored Feb 24, 2025
1 parent 0657e11 commit 4976ef2
Show file tree
Hide file tree
Showing 20 changed files with 268 additions and 72 deletions.
21 changes: 1 addition & 20 deletions cmd/blockchaincmd/add_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package blockchaincmd
import (
"errors"
"fmt"
"math/big"
"strings"
"time"

Expand Down Expand Up @@ -108,7 +107,6 @@ Testnet or Mainnet.`,
cmd.Flags().StringVar(&nodeEndpoint, "node-endpoint", "", "gather node id/bls from publicly available avalanchego apis on the given endpoint")
cmd.Flags().StringSliceVar(&aggregatorExtraEndpoints, "aggregator-extra-endpoints", nil, "endpoints for extra nodes that are needed in signature aggregation")
cmd.Flags().BoolVar(&aggregatorAllowPrivatePeers, "aggregator-allow-private-peers", true, "allow the signature aggregator to connect to peers with private IP")
privateKeyFlags.AddToCmd(cmd, "to pay fees for completing the validator's registration (blockchain gas token)")
cmd.Flags().StringVar(&rpcURL, "rpc", "", "connect to validator manager at the given rpc endpoint")
cmd.Flags().StringVar(&aggregatorLogLevel, "aggregator-log-level", constants.DefaultAggregatorLogLevel, "log level to use with signature aggregator")
cmd.Flags().BoolVar(&aggregatorLogToStdout, "aggregator-log-to-stdout", false, "use stdout for signature aggregator logs")
Expand All @@ -120,7 +118,6 @@ Testnet or Mainnet.`,
cmd.Flags().StringSliceVar(&subnetAuthKeys, "subnet-auth-keys", nil, "(for Subnets, not L1s) control keys that will be used to authenticate add validator tx")
cmd.Flags().StringVar(&outputTxPath, "output-tx-path", "", "(for Subnets, not L1s) file path of the add validator tx")
cmd.Flags().BoolVar(&waitForTxAcceptance, "wait-for-tx-acceptance", true, "(for Subnets, not L1s) just issue the add validator tx, without waiting for its acceptance")
cmd.Flags().Uint64Var(&stakeAmount, "stake-amount", 0, "(PoS only) amount of tokens to stake")
cmd.Flags().Uint16Var(&delegationFee, "delegation-fee", 100, "(PoS only) delegation fee (in bips)")

return cmd
Expand Down Expand Up @@ -384,22 +381,7 @@ func CallAddValidator(
pos := sc.PoS()

if pos {
// should take input prior to here for stake amount, delegation fee, and min stake duration
if stakeAmount == 0 {
stakeAmount, err = app.Prompt.CaptureUint64Compare(
fmt.Sprintf("Enter the amount of %s to stake ", sc.TokenName),
[]prompts.Comparator{
{
Label: "Positive",
Type: prompts.MoreThan,
Value: 0,
},
},
)
if err != nil {
return err
}
}
// should take input prior to here for delegation fee, and min stake duration
if duration == 0 {
duration, err = PromptDuration(time.Now(), network, true) // it's pos
if err != nil {
Expand Down Expand Up @@ -521,7 +503,6 @@ func CallAddValidator(
pos,
delegationFee,
duration,
big.NewInt(int64(stakeAmount)),
validatorManagerAddress,
)
if err != nil {
Expand Down
43 changes: 39 additions & 4 deletions cmd/blockchaincmd/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/ava-labs/avalanche-cli/pkg/txutils"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanche-cli/pkg/validatormanager"
"github.com/ava-labs/avalanche-cli/pkg/vm"
blockchainSDK "github.com/ava-labs/avalanche-cli/sdk/blockchain"
sdkutils "github.com/ava-labs/avalanche-cli/sdk/utils"
Expand Down Expand Up @@ -56,8 +57,6 @@ Sovereign L1s require bootstrap validators. avalanche blockchain convert command
Args: cobrautils.ExactArgs(1),
}
networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions)
privateKeyFlags.SetFlagNames("blockchain-private-key", "blockchain-key", "blockchain-genesis-key")
privateKeyFlags.AddToCmd(cmd, "to fund validator manager initialization")
cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet convert to l1 tx only]")
cmd.Flags().StringSliceVar(&subnetAuthKeys, "auth-keys", nil, "control keys that will be used to authenticate convert to L1 tx")
cmd.Flags().StringVar(&outputTxPath, "output-tx-path", "", "file path of the convert to L1 tx (for multi-sig)")
Expand Down Expand Up @@ -249,13 +248,16 @@ func StartLocalMachine(
return nil
}

func InitializeValidatorManager(blockchainName,
func InitializeValidatorManager(
blockchainName,
validatorManagerOwner string,
subnetID, blockchainID ids.ID,
subnetID ids.ID,
blockchainID ids.ID,
network models.Network,
avaGoBootstrapValidators []*txs.ConvertSubnetToL1Validator,
pos bool,
validatorManagerAddrStr string,
proxyContractOwner string,
) (bool, error) {
var err error
clusterName := clusterNameFlagValue
Expand All @@ -280,7 +282,9 @@ func InitializeValidatorManager(blockchainName,
}
}
}

tracked := true

chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
Expand All @@ -302,11 +306,40 @@ func InitializeValidatorManager(blockchainName,
if err != nil {
return tracked, err
}

client, err := evm.GetClient(rpcURL)
if err != nil {
return tracked, err
}
evm.WaitForChainID(client)

if pos {
deployed, err := validatormanager.ProxyHasValidatorManagerSet(rpcURL)
if err != nil {
return tracked, err
}
if !deployed {
// it is not in genesis
ux.Logger.PrintToUser("Deploying Proof of Stake Validator Manager contract on blockchain %s ...", blockchainName)
proxyOwnerPrivateKey, err := GetProxyOwnerPrivateKey(
app,
network,
proxyContractOwner,
ux.Logger.PrintToUser,
)
if err != nil {
return tracked, err
}
if _, err := validatormanager.DeployAndRegisterPoSValidatorManagerContrac(
rpcURL,
genesisPrivateKey,
proxyOwnerPrivateKey,
); err != nil {
return tracked, err
}
}
}

extraAggregatorPeers, err := blockchain.GetAggregatorExtraPeers(app, clusterName, aggregatorExtraEndpoints)
if err != nil {
return tracked, err
Expand Down Expand Up @@ -350,6 +383,7 @@ func InitializeValidatorManager(blockchainName,
MaximumStakeMultiplier: poSMaximumStakeMultiplier,
WeightToValueFactor: big.NewInt(int64(poSWeightToValueFactor)),
RewardCalculatorAddress: validatorManagerSDK.RewardCalculatorAddress,
UptimeBlockchainID: blockchainID,
},
validatorManagerAddrStr,
); err != nil {
Expand Down Expand Up @@ -662,6 +696,7 @@ func convertBlockchain(_ *cobra.Command, args []string) error {
avaGoBootstrapValidators,
sidecar.ValidatorManagement == models.ProofOfStake,
validatorManagerAddress,
sidecar.ProxyContractOwner,
); err != nil {
return err
}
Expand Down
15 changes: 11 additions & 4 deletions cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ var (
icmSpec subnet.ICMSpec
generateNodeID bool
bootstrapValidatorsJSONFilePath string
privateKeyFlags contract.PrivateKeyFlags
bootstrapEndpoints []string
convertOnly bool
numNodes uint32
Expand Down Expand Up @@ -120,8 +119,6 @@ so you can take your locally tested Blockchain and deploy it on Fuji or Mainnet.
Args: cobrautils.ExactArgs(1),
}
networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, networkoptions.DefaultSupportedNetworkOptions)
privateKeyFlags.SetFlagNames("blockchain-private-key", "blockchain-key", "blockchain-genesis-key")
privateKeyFlags.AddToCmd(cmd, "to fund validator manager initialization")
cmd.Flags().StringVar(
&userProvidedAvagoVersion,
"avalanchego-version",
Expand Down Expand Up @@ -806,7 +803,17 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
return nil
}

tracked, err = InitializeValidatorManager(blockchainName, sidecar.ValidatorManagerOwner, subnetID, blockchainID, network, avaGoBootstrapValidators, sidecar.ValidatorManagement == models.ProofOfStake, validatorManagerStr)
tracked, err = InitializeValidatorManager(
blockchainName,
sidecar.ValidatorManagerOwner,
subnetID,
blockchainID,
network,
avaGoBootstrapValidators,
sidecar.ValidatorManagement == models.ProofOfStake,
validatorManagerStr,
sidecar.ProxyContractOwner,
)
if err != nil {
return err
}
Expand Down
40 changes: 38 additions & 2 deletions cmd/blockchaincmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ package blockchaincmd
import (
"fmt"

"github.com/ava-labs/avalanche-cli/pkg/application"
"github.com/ava-labs/avalanche-cli/pkg/binutils"
"github.com/ava-labs/avalanche-cli/pkg/utils"

"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/keychain"
"github.com/ava-labs/avalanche-cli/pkg/models"
"github.com/ava-labs/avalanche-cli/pkg/networkoptions"
"github.com/ava-labs/avalanche-cli/pkg/prompts"
"github.com/ava-labs/avalanche-cli/pkg/txutils"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanchego/ids"

"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -112,3 +116,35 @@ func getLocalBootstrapEndpoints() ([]string, error) {
}
return localBootstrapEndpoints, nil
}

func GetProxyOwnerPrivateKey(
app *application.Avalanche,
network models.Network,
proxyContractOwner string,
printFunc func(msg string, args ...interface{}),
) (string, error) {
found, _, _, proxyOwnerPrivateKey, err := contract.SearchForManagedKey(
app,
network,
common.HexToAddress(proxyContractOwner),
true,
)
if err != nil {
return "", err
}
if !found {
printFunc("Private key for proxy owner address %s was not found", proxyContractOwner)
proxyOwnerPrivateKey, err = prompts.PromptPrivateKey(
app.Prompt,
"configure validator manager proxy for PoS",
app.GetKeyDir(),
app.GetKey,
"",
"",
)
if err != nil {
return "", err
}
}
return proxyOwnerPrivateKey, nil
}
1 change: 0 additions & 1 deletion cmd/blockchaincmd/remove_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ these prompts by providing the values with flags.`,
cmd.Flags().StringVar(&nodeEndpoint, "node-endpoint", "", "remove validator that responds to the given endpoint")
cmd.Flags().StringSliceVar(&aggregatorExtraEndpoints, "aggregator-extra-endpoints", nil, "endpoints for extra nodes that are needed in signature aggregation")
cmd.Flags().BoolVar(&aggregatorAllowPrivatePeers, "aggregator-allow-private-peers", true, "allow the signature aggregator to connect to peers with private IP")
privateKeyFlags.AddToCmd(cmd, "to pay fees for completing the validator's removal (blockchain gas token)")
cmd.Flags().StringVar(&rpcURL, "rpc", "", "connect to validator manager at the given rpc endpoint")
cmd.Flags().StringVar(&aggregatorLogLevel, "aggregator-log-level", constants.DefaultAggregatorLogLevel, "log level to use with signature aggregator")
cmd.Flags().BoolVar(&aggregatorLogToStdout, "aggregator-log-to-stdout", false, "use stdout for signature aggregator logs")
Expand Down
26 changes: 26 additions & 0 deletions cmd/contractcmd/init_validator_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
validatorManagerSDK "github.com/ava-labs/avalanche-cli/sdk/validatormanager"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/logging"

"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -214,6 +215,30 @@ func initValidatorManager(_ *cobra.Command, args []string) error {
}
ux.Logger.GreenCheckmarkToUser("Proof of Authority Validator Manager contract successfully initialized on blockchain %s", blockchainName)
case sc.PoS(): // PoS
deployed, err := validatormanager.ProxyHasValidatorManagerSet(validatorManagerFlags.rpcEndpoint)
if err != nil {
return err
}
if !deployed {
// it is not in genesis
ux.Logger.PrintToUser("Deploying Proof of Stake Validator Manager contract on blockchain %s ...", blockchainName)
proxyOwnerPrivateKey, err := blockchaincmd.GetProxyOwnerPrivateKey(
app,
network,
sc.ProxyContractOwner,
ux.Logger.PrintToUser,
)
if err != nil {
return err
}
if _, err := validatormanager.DeployAndRegisterPoSValidatorManagerContrac(
validatorManagerFlags.rpcEndpoint,
genesisPrivateKey,
proxyOwnerPrivateKey,
); err != nil {
return err
}
}
ux.Logger.PrintToUser(logging.Yellow.Wrap("Initializing Proof of Stake Validator Manager contract on blockchain %s"), blockchainName)
if initPOSManagerFlags.rewardCalculatorAddress == "" {
initPOSManagerFlags.rewardCalculatorAddress = validatorManagerSDK.RewardCalculatorAddress
Expand All @@ -234,6 +259,7 @@ func initValidatorManager(_ *cobra.Command, args []string) error {
MaximumStakeMultiplier: initPOSManagerFlags.maximumStakeMultiplier,
WeightToValueFactor: big.NewInt(int64(initPOSManagerFlags.weightToValueFactor)),
RewardCalculatorAddress: initPOSManagerFlags.rewardCalculatorAddress,
UptimeBlockchainID: blockchainID,
},
validatorManagerAddress,
); err != nil {
Expand Down
2 changes: 0 additions & 2 deletions cmd/nodecmd/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package nodecmd

import (
"fmt"
"math/big"
"path/filepath"
"strings"
"time"
Expand Down Expand Up @@ -561,7 +560,6 @@ func addAsValidator(network models.Network,
true,
delegationFee,
time.Duration(minimumStakeDuration)*time.Second,
big.NewInt(int64(stakeAmount)),
validatorManagerAddressStr,
)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/contract/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ func TxToMethod(
}
if errorFromSignature, err := evm.GetErrorFromTrace(trace, errorSignatureToError); err != nil && !errors.Is(err, evm.ErrUnknownErrorSelector) {
ux.Logger.RedXToUser("failed to match error selector on trace: %s", err)
ux.Logger.PrintToUser("error trace for %s error:", description)
ux.Logger.PrintToUser("%#v", trace)
} else if errorFromSignature != nil {
return tx, nil, errorFromSignature
} else {
Expand Down Expand Up @@ -584,6 +586,9 @@ func DeployContract(
return common.Address{}, err
}
bin := common.FromHex(metadata.Bin)
if len(bin) == 0 {
return common.Address{}, fmt.Errorf("failure on given binary for smart contract: zero len")
}
client, err := evm.GetClient(rpcURL)
if err != nil {
return common.Address{}, err
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0x608060405234801561000f575f80fd5b5060043610610055575f3560e01c80634f22429f146100595780635dcc93911461007f578063a9778a7a1461008a578063afba878a146100a6578063bb65b242146100c0575b5f80fd5b61006c6100673660046101db565b610100565b6040519081526020015b60405180910390f35b61006c6301e1338081565b61009361271081565b60405161ffff9091168152602001610076565b6100ae605081565b60405160ff9091168152602001610076565b6100e77f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610076565b5f605061010d8685610249565b6101179190610271565b67ffffffffffffffff1661012c836064610271565b67ffffffffffffffff16101561014357505f6101b6565b6127106301e133806101558686610249565b67ffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1689610195919061029d565b61019f919061029d565b6101a991906102ba565b6101b391906102ba565b90505b95945050505050565b803567ffffffffffffffff811681146101d6575f80fd5b919050565b5f805f805f60a086880312156101ef575f80fd5b853594506101ff602087016101bf565b935061020d604087016101bf565b925061021b606087016101bf565b9150610229608087016101bf565b90509295509295909350565b634e487b7160e01b5f52601160045260245ffd5b67ffffffffffffffff82811682821603908082111561026a5761026a610235565b5092915050565b67ffffffffffffffff81811683821602808216919082811461029557610295610235565b505092915050565b80820281158282048414176102b4576102b4610235565b92915050565b5f826102d457634e487b7160e01b5f52601260045260245ffd5b50049056fea164736f6c6343000819000a

Large diffs are not rendered by default.

Loading

0 comments on commit 4976ef2

Please sign in to comment.