mirror of
https://github.com/luxfi/cli.git
synced 2026-10-30 17:01:20 +00:00
624 lines
19 KiB
Go
624 lines
19 KiB
Go
// Copyright (C) 2022-2025, Lux Industries Inc. All rights reserved.
|
||
// See the file LICENSE for licensing terms.
|
||
|
||
package upgradecmd
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"math"
|
||
"math/big"
|
||
"os"
|
||
"time"
|
||
|
||
"github.com/luxfi/cli/pkg/cobrautils"
|
||
cliprompts "github.com/luxfi/cli/pkg/prompts"
|
||
"github.com/luxfi/cli/pkg/utils"
|
||
"github.com/luxfi/cli/pkg/ux"
|
||
"github.com/luxfi/cli/pkg/vm"
|
||
"github.com/luxfi/constants"
|
||
"github.com/luxfi/evm/commontype"
|
||
"github.com/luxfi/evm/params"
|
||
"github.com/luxfi/evm/params/extras"
|
||
"github.com/luxfi/evm/precompile/contracts/deployerallowlist"
|
||
"github.com/luxfi/evm/precompile/contracts/feemanager"
|
||
"github.com/luxfi/evm/precompile/contracts/nativeminter"
|
||
"github.com/luxfi/evm/precompile/contracts/rewardmanager"
|
||
"github.com/luxfi/evm/precompile/contracts/txallowlist"
|
||
evmutils "github.com/luxfi/evm/utils"
|
||
"github.com/luxfi/geth/common"
|
||
luxlog "github.com/luxfi/log"
|
||
goethereummath "github.com/luxfi/math"
|
||
"github.com/luxfi/sdk/models"
|
||
"github.com/luxfi/sdk/prompts"
|
||
"github.com/spf13/cobra"
|
||
)
|
||
|
||
const (
|
||
feeConfigKey = "initialFeeConfig"
|
||
initialMintKey = "initialMint"
|
||
|
||
managerLabel = "manager"
|
||
adminLabel = "admin"
|
||
|
||
NativeMint = "Native Minting"
|
||
ContractAllowList = "Contract Deployment Allow List"
|
||
TxAllowList = "Transaction Allow List"
|
||
FeeManager = "Adjust Fee Settings Post Deploy"
|
||
RewardManager = "Customize Fees Distribution"
|
||
)
|
||
|
||
var generateConfirm bool
|
||
|
||
// lux blockchain upgrade generate
|
||
func newUpgradeGenerateCmd() *cobra.Command {
|
||
cmd := &cobra.Command{
|
||
Use: "generate [blockchainName]",
|
||
Short: "Generate the configuration file to upgrade blockchain nodes",
|
||
Long: `The blockchain upgrade generate command builds a new upgrade.json file to customize your Blockchain.
|
||
It guides the user through the process using an interactive wizard.
|
||
|
||
IMPORTANT: This command requires interactive mode (TTY) due to the complexity of precompile
|
||
configuration. For non-interactive/CI environments, create the upgrade.json file manually
|
||
or use 'lux blockchain upgrade import' to import a pre-created configuration.
|
||
|
||
Use --yes/-y to skip the initial warning confirmation when running interactively.
|
||
|
||
Examples:
|
||
# Interactive mode (wizard)
|
||
lux blockchain upgrade generate mychain
|
||
|
||
# Skip initial warning
|
||
lux blockchain upgrade generate mychain --yes
|
||
|
||
# For CI/non-interactive: import a pre-created upgrade file instead
|
||
lux blockchain upgrade import mychain --upgrade-filepath ./upgrade.json`,
|
||
RunE: upgradeGenerateCmd,
|
||
Args: cobrautils.ExactArgs(1),
|
||
}
|
||
cmd.Flags().BoolVarP(&generateConfirm, "yes", "y", false, "Skip initial warning confirmation prompt")
|
||
return cmd
|
||
}
|
||
|
||
func upgradeGenerateCmd(_ *cobra.Command, args []string) error {
|
||
blockchainName := args[0]
|
||
if !app.GenesisExists(blockchainName) {
|
||
ux.Logger.PrintToUser("The provided blockchain name %q does not exist", blockchainName)
|
||
return nil
|
||
}
|
||
|
||
// This command requires interactive mode for the wizard
|
||
if !cliprompts.IsInteractive() {
|
||
return fmt.Errorf("this command requires interactive mode (TTY)\n"+
|
||
"For non-interactive/CI environments, create upgrade.json manually or use:\n"+
|
||
" lux blockchain upgrade import %s --upgrade-filepath ./upgrade.json", blockchainName)
|
||
}
|
||
|
||
// print some warning/info message
|
||
ux.Logger.PrintToUser("%s", luxlog.Bold.Wrap(luxlog.Yellow.Wrap(
|
||
"Performing a network upgrade requires coordinating the upgrade network-wide.")))
|
||
ux.Logger.PrintToUser("%s", luxlog.White.Wrap(luxlog.Reset.Wrap(
|
||
"A network upgrade changes the rule set used to process and verify blocks, "+
|
||
"such that any node that upgrades incorrectly or fails to upgrade by the time "+
|
||
"that upgrade goes into effect may become out of sync with the rest of the network.\n")))
|
||
ux.Logger.PrintToUser("%s", luxlog.Bold.Wrap(luxlog.Red.Wrap(
|
||
"Any mistakes in configuring network upgrades or coordinating them on validators "+
|
||
"may cause the network to halt and recovering may be difficult.")))
|
||
ux.Logger.PrintToUser("%s", luxlog.Reset.Wrap(
|
||
"Please consult "+luxlog.Cyan.Wrap(
|
||
"https://docs.lux.network/lux-l1s/upgrade/customize-lux-l1#network-upgrades-enabledisable-precompiles ")+
|
||
luxlog.Reset.Wrap("for more information")))
|
||
|
||
if !generateConfirm {
|
||
txt := "Press [Enter] to continue, or abort by choosing 'no'"
|
||
yes, err := app.Prompt.CaptureYesNo(txt)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if !yes {
|
||
ux.Logger.PrintToUser("Aborted by user")
|
||
return nil
|
||
}
|
||
}
|
||
|
||
allPreComps := []string{
|
||
ContractAllowList,
|
||
FeeManager,
|
||
NativeMint,
|
||
TxAllowList,
|
||
RewardManager,
|
||
}
|
||
|
||
fmt.Println()
|
||
ux.Logger.PrintToUser("%s", luxlog.Yellow.Wrap(
|
||
"Luxgo and this tool support configuring multiple precompiles. "+
|
||
"However, we suggest to only configure one per upgrade."))
|
||
fmt.Println()
|
||
|
||
// use the correct data types from evm right away
|
||
precompiles := extras.UpgradeConfig{
|
||
PrecompileUpgrades: make([]extras.PrecompileUpgrade, 0),
|
||
}
|
||
|
||
for {
|
||
precomp, err := app.Prompt.CaptureList("Select the precompile to configure", allPreComps)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
ux.Logger.PrintToUser("Set parameters for the %q precompile", precomp)
|
||
if cancelled, err := promptParams(blockchainName, precomp, &precompiles.PrecompileUpgrades); err != nil {
|
||
return err
|
||
} else if cancelled {
|
||
continue
|
||
}
|
||
|
||
if len(allPreComps) > 1 {
|
||
yes, err := app.Prompt.CaptureNoYes("Should we configure another precompile?")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if !yes {
|
||
break
|
||
}
|
||
|
||
for i := 0; i < len(allPreComps); i++ {
|
||
if allPreComps[i] == precomp {
|
||
allPreComps = append(allPreComps[:i], allPreComps[i+1:]...)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
upgradeBytes, err := json.Marshal(&precompiles)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return writeUpgrade(blockchainName, upgradeBytes)
|
||
}
|
||
|
||
func writeUpgrade(blockchainName string, upgradeBytes []byte) error {
|
||
upgradeBytesFilePath := app.GetUpgradeBytesFilePath(blockchainName)
|
||
if utils.FileExists(upgradeBytesFilePath) {
|
||
timestamp := time.Now().UTC().Format("20060102150405")
|
||
renamedUpgradeBytesFilePath := upgradeBytesFilePath + "_" + timestamp
|
||
ux.Logger.PrintToUser("")
|
||
ux.Logger.PrintToUser("A previous upgrade is found. Renaming it to %s", renamedUpgradeBytesFilePath)
|
||
if err := os.Rename(upgradeBytesFilePath, renamedUpgradeBytesFilePath); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
ux.Logger.PrintToUser("")
|
||
ux.Logger.PrintToUser("Writing upgrade into %s", upgradeBytesFilePath)
|
||
if err := app.WriteUpgradeFile(blockchainName, upgradeBytes); err != nil {
|
||
return err
|
||
}
|
||
PrintHowToApplyConfChangesMessage(blockchainName)
|
||
return nil
|
||
}
|
||
|
||
func PrintHowToApplyConfChangesMessage(blockchainName string) {
|
||
ux.Logger.PrintToUser("")
|
||
ux.Logger.PrintToUser("To apply the change on Local Network:")
|
||
ux.Logger.PrintToUser(" lux network stop")
|
||
ux.Logger.PrintToUser(" lux network start")
|
||
ux.Logger.PrintToUser("")
|
||
ux.Logger.PrintToUser("To apply the change to local validators on Testnet:")
|
||
ux.Logger.PrintToUser(" lux node local stop %s-local-node-testnet", blockchainName)
|
||
ux.Logger.PrintToUser(" lux node local start %s-local-start-testnet", blockchainName)
|
||
ux.Logger.PrintToUser("")
|
||
ux.Logger.PrintToUser("To apply the change to local validators on Mainnet:")
|
||
ux.Logger.PrintToUser(" lux node local stop %s-local-node-mainnet", blockchainName)
|
||
ux.Logger.PrintToUser(" lux node local start %s-local-start-mainnet", blockchainName)
|
||
}
|
||
|
||
func queryActivationTimestamp() (time.Time, error) {
|
||
const (
|
||
in5min = "In 5 minutes"
|
||
in1day = "In 1 day"
|
||
in1week = "In 1 week"
|
||
in2weeks = "In 2 weeks"
|
||
custom = "Custom"
|
||
)
|
||
options := []string{in5min, in1day, in1week, in2weeks, custom}
|
||
choice, err := app.Prompt.CaptureList("When should the precompile be activated?", options)
|
||
if err != nil {
|
||
return time.Time{}, err
|
||
}
|
||
|
||
var date time.Time
|
||
now := time.Now()
|
||
|
||
switch choice {
|
||
case in5min:
|
||
date = now.Add(5 * time.Minute)
|
||
case in1day:
|
||
date = now.Add(24 * time.Hour)
|
||
case in1week:
|
||
date = now.Add(7 * 24 * time.Hour)
|
||
case in2weeks:
|
||
date = now.Add(14 * 24 * time.Hour)
|
||
case custom:
|
||
date, err = app.Prompt.CaptureFutureDate(
|
||
"Enter the block activation UTC datetime in 'YYYY-MM-DD HH:MM:SS' format", time.Now().Add(time.Minute).UTC())
|
||
if err != nil {
|
||
return time.Time{}, err
|
||
}
|
||
}
|
||
|
||
ux.Logger.PrintToUser("The chosen block activation time is %s", date.Format(constants.TimeParseLayout))
|
||
return date, nil
|
||
}
|
||
|
||
func promptParams(blockchainName string, precomp string, precompiles *[]extras.PrecompileUpgrade) (bool, error) {
|
||
sc, err := app.LoadSidecar(blockchainName)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
date, err := queryActivationTimestamp()
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
switch precomp {
|
||
case ContractAllowList:
|
||
return promptContractAllowListParams(&sc, precompiles, date)
|
||
case TxAllowList:
|
||
return promptTxAllowListParams(&sc, precompiles, date)
|
||
case NativeMint:
|
||
return promptNativeMintParams(&sc, precompiles, date)
|
||
case FeeManager:
|
||
return promptFeeManagerParams(&sc, precompiles, date)
|
||
case RewardManager:
|
||
return promptRewardManagerParams(&sc, precompiles, date)
|
||
default:
|
||
return false, fmt.Errorf("unexpected precompile identifier: %q", precomp)
|
||
}
|
||
}
|
||
|
||
func promptNativeMintParams(
|
||
sc *models.Sidecar,
|
||
precompiles *[]extras.PrecompileUpgrade,
|
||
date time.Time,
|
||
) (bool, error) {
|
||
initialMint := map[common.Address]*goethereummath.HexOrDecimal256{}
|
||
adminAddrs, managerAddrs, enabledAddrs, cancelled, err := promptAdminManagerAndEnabledAddresses(sc, "mint native tokens")
|
||
if cancelled || err != nil {
|
||
return cancelled, err
|
||
}
|
||
yes, err := app.Prompt.CaptureYesNo(fmt.Sprintf("Airdrop more tokens? (`%s` section in file)", initialMintKey))
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
if yes {
|
||
_, cancel, err := prompts.CaptureListDecision(
|
||
app.Prompt,
|
||
"How would you like to distribute your funds",
|
||
func(_ string) (string, error) {
|
||
addr, err := app.Prompt.CaptureAddress("Address to airdrop to")
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
amount, err := app.Prompt.CaptureUint64(fmt.Sprintf("Amount to airdrop (in %s units)", sc.TokenSymbol))
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
// Check for overflow when converting uint64 to int64
|
||
if amount > math.MaxInt64 {
|
||
return "", fmt.Errorf("amount %d exceeds maximum allowed value of %d", amount, math.MaxInt64)
|
||
}
|
||
// Convert crypto.Address to geth common.Address
|
||
gethAddr := common.BytesToAddress(addr.Bytes())
|
||
initialMint[gethAddr] = goethereummath.NewHexOrDecimal256(int64(amount))
|
||
return fmt.Sprintf("%s-%d", addr.Hex(), amount), nil
|
||
},
|
||
"Add an address to amount pair",
|
||
"Address-Amount",
|
||
"Hex-formatted address and it's initial amount value, "+
|
||
"for example: 0x9011E888251AB053B7bD1cdB598Db4f9DEd94714 (address) and 1000000000000000000 (value)",
|
||
)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
if cancel {
|
||
return true, nil
|
||
}
|
||
}
|
||
config := nativeminter.NewConfig(
|
||
evmutils.NewUint64(uint64(date.Unix())), //nolint:gosec // G115: Unix time is positive
|
||
adminAddrs,
|
||
enabledAddrs,
|
||
managerAddrs,
|
||
initialMint,
|
||
)
|
||
upgrade := extras.PrecompileUpgrade{
|
||
Config: config,
|
||
}
|
||
*precompiles = append(*precompiles, upgrade)
|
||
return false, nil
|
||
}
|
||
|
||
func promptRewardManagerParams(
|
||
sc *models.Sidecar,
|
||
precompiles *[]extras.PrecompileUpgrade,
|
||
date time.Time,
|
||
) (bool, error) {
|
||
adminAddrs, managerAddrs, enabledAddrs, cancelled, err := promptAdminManagerAndEnabledAddresses(sc, "customize fee distribution")
|
||
if cancelled || err != nil {
|
||
return cancelled, err
|
||
}
|
||
initialConfig, err := ConfigureInitialRewardConfig()
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
config := rewardmanager.NewConfig(
|
||
evmutils.NewUint64(uint64(date.Unix())), //nolint:gosec // G115: Unix time is positive
|
||
adminAddrs,
|
||
enabledAddrs,
|
||
managerAddrs,
|
||
initialConfig,
|
||
)
|
||
upgrade := extras.PrecompileUpgrade{
|
||
Config: config,
|
||
}
|
||
*precompiles = append(*precompiles, upgrade)
|
||
return false, nil
|
||
}
|
||
|
||
func ConfigureInitialRewardConfig() (*rewardmanager.InitialRewardConfig, error) {
|
||
config := &rewardmanager.InitialRewardConfig{}
|
||
|
||
burnFees := "I am fine with transaction fees being burned
(Reward Manager Precompile OFF)"
|
||
distributeFees := "I want to customize the transaction fee distribution
(Reward Manager Precompile ON)"
|
||
options := []string{burnFees, distributeFees}
|
||
option, err := app.Prompt.CaptureList(
|
||
"By default, all transaction fees on Lux are burned (sent to a blackhole address). (Reward Manager Precompile)",
|
||
options,
|
||
)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
if option == burnFees {
|
||
return config, nil
|
||
}
|
||
|
||
feeRcpdPrompt := "Allow block producers to claim fees?"
|
||
allowFeeRecipients, err := app.Prompt.CaptureYesNo(feeRcpdPrompt)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
if allowFeeRecipients {
|
||
config.AllowFeeRecipients = true
|
||
return config, nil
|
||
}
|
||
|
||
rewardPrompt := "Provide the address to which fees will be sent to"
|
||
rewardAddress, err := app.Prompt.CaptureAddress(rewardPrompt)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
// Convert crypto.Address to geth common.Address
|
||
config.RewardAddress = common.BytesToAddress(rewardAddress.Bytes())
|
||
return config, nil
|
||
}
|
||
|
||
func promptFeeManagerParams(
|
||
sc *models.Sidecar,
|
||
precompiles *[]extras.PrecompileUpgrade,
|
||
date time.Time,
|
||
) (bool, error) {
|
||
adminAddrs, managerAddrs, enabledAddrs, cancelled, err := promptAdminManagerAndEnabledAddresses(sc, "adjust the gas fees")
|
||
if cancelled || err != nil {
|
||
return cancelled, err
|
||
}
|
||
yes, err := app.Prompt.CaptureYesNo(fmt.Sprintf(
|
||
"Do you want to update the fee config upon precompile activation? ('%s' section in file)", feeConfigKey))
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
var feeConfig *commontype.FeeConfig
|
||
if yes {
|
||
// Create default fee configuration
|
||
feeConfig = createFeeConfig(
|
||
big.NewInt(8000000), // gasLimit
|
||
2, // targetBlockRate
|
||
big.NewInt(25000000000), // minBaseFee
|
||
big.NewInt(15000000), // targetGas
|
||
big.NewInt(36), // baseFeeChangeDenominator
|
||
big.NewInt(0), // minBlockGasCost
|
||
big.NewInt(1000000), // maxBlockGasCost
|
||
big.NewInt(200000), // blockGasCostStep
|
||
)
|
||
}
|
||
config := feemanager.NewConfig(
|
||
evmutils.NewUint64(uint64(date.Unix())), //nolint:gosec // G115: Unix time is positive
|
||
adminAddrs,
|
||
enabledAddrs,
|
||
managerAddrs,
|
||
feeConfig,
|
||
)
|
||
upgrade := extras.PrecompileUpgrade{
|
||
Config: config,
|
||
}
|
||
*precompiles = append(*precompiles, upgrade)
|
||
return false, nil
|
||
}
|
||
|
||
func GetFeeConfig(config params.ChainConfig, useDefault bool) (
|
||
params.ChainConfig,
|
||
error,
|
||
) {
|
||
const (
|
||
lowOption = "Low block size / Low Throughput 12 mil gas per block"
|
||
mediumOption = "Medium block size / Medium Throughput 15 mil gas per block (C-Chain's setting)"
|
||
highOption = "High block size / High Throughput 20 mil gas per block"
|
||
customFee = "Customize fee config"
|
||
|
||
setGasLimit = "Set gas limit"
|
||
setBlockRate = "Set target block rate"
|
||
setMinBaseFee = "Set min base fee"
|
||
setTargetGas = "Set target gas"
|
||
setBaseFeeChangeDenominator = "Set base fee change denominator"
|
||
setMinBlockGas = "Set min block gas cost"
|
||
setMaxBlockGas = "Set max block gas cost"
|
||
setGasStep = "Set block gas cost step"
|
||
)
|
||
|
||
// Return default configuration if requested
|
||
if useDefault {
|
||
return config, nil
|
||
}
|
||
|
||
feeConfigOptions := []string{lowOption, mediumOption, highOption, customFee}
|
||
|
||
feeDefault, err := app.Prompt.CaptureList(
|
||
"How would you like to set fees",
|
||
feeConfigOptions,
|
||
)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
// Dynamic fees configuration
|
||
useDynamicFees := false
|
||
if feeDefault != customFee {
|
||
useDynamicFees, err = app.Prompt.CaptureYesNo("Do you want to enable dynamic fees?")
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
}
|
||
|
||
switch feeDefault {
|
||
case lowOption:
|
||
extraConfig := params.GetExtra(&config)
|
||
setLowGasConfig(&extraConfig.FeeConfig, useDynamicFees)
|
||
params.SetExtra(&config, extraConfig)
|
||
return config, nil
|
||
case mediumOption:
|
||
extraConfig := params.GetExtra(&config)
|
||
setMediumGasConfig(&extraConfig.FeeConfig, useDynamicFees)
|
||
params.SetExtra(&config, extraConfig)
|
||
return config, nil
|
||
case highOption:
|
||
extraConfig := params.GetExtra(&config)
|
||
setHighGasConfig(&extraConfig.FeeConfig, useDynamicFees)
|
||
params.SetExtra(&config, extraConfig)
|
||
return config, nil
|
||
default:
|
||
ux.Logger.PrintToUser("Customizing fee config")
|
||
}
|
||
|
||
// Custom fee configuration
|
||
gasLimit, err := app.Prompt.CapturePositiveBigInt(setGasLimit)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
blockRate, err := app.Prompt.CaptureUint64(setBlockRate)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
minBaseFee, err := app.Prompt.CapturePositiveBigInt(setMinBaseFee)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
targetGas, err := app.Prompt.CapturePositiveBigInt(setTargetGas)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
baseFeeChangeDenominator, err := app.Prompt.CapturePositiveBigInt(setBaseFeeChangeDenominator)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
minBlockGas, err := app.Prompt.CapturePositiveBigInt(setMinBlockGas)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
maxBlockGas, err := app.Prompt.CapturePositiveBigInt(setMaxBlockGas)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
gasStep, err := app.Prompt.CapturePositiveBigInt(setGasStep)
|
||
if err != nil {
|
||
return config, err
|
||
}
|
||
|
||
// Apply custom fee configuration
|
||
extraConfig := params.GetExtra(&config)
|
||
extraConfig.FeeConfig = commontype.FeeConfig{
|
||
GasLimit: gasLimit,
|
||
TargetBlockRate: blockRate,
|
||
MinBaseFee: minBaseFee,
|
||
TargetGas: targetGas,
|
||
BaseFeeChangeDenominator: baseFeeChangeDenominator,
|
||
MinBlockGasCost: minBlockGas,
|
||
MaxBlockGasCost: maxBlockGas,
|
||
BlockGasCostStep: gasStep,
|
||
}
|
||
params.SetExtra(&config, extraConfig)
|
||
|
||
return config, nil
|
||
}
|
||
|
||
func promptContractAllowListParams(
|
||
sc *models.Sidecar,
|
||
precompiles *[]extras.PrecompileUpgrade,
|
||
date time.Time,
|
||
) (bool, error) {
|
||
adminAddrs, managerAddrs, enabledAddrs, cancelled, err := promptAdminManagerAndEnabledAddresses(sc, "deploy smart contracts")
|
||
if cancelled || err != nil {
|
||
return cancelled, err
|
||
}
|
||
config := deployerallowlist.NewConfig(
|
||
evmutils.NewUint64(uint64(date.Unix())), //nolint:gosec // G115: Unix time is positive
|
||
adminAddrs,
|
||
enabledAddrs,
|
||
managerAddrs,
|
||
)
|
||
upgrade := extras.PrecompileUpgrade{
|
||
Config: config,
|
||
}
|
||
*precompiles = append(*precompiles, upgrade)
|
||
return false, nil
|
||
}
|
||
|
||
func promptTxAllowListParams(
|
||
sc *models.Sidecar,
|
||
precompiles *[]extras.PrecompileUpgrade,
|
||
date time.Time,
|
||
) (bool, error) {
|
||
adminAddrs, managerAddrs, enabledAddrs, cancelled, err := promptAdminManagerAndEnabledAddresses(sc, "issue transactions")
|
||
if cancelled || err != nil {
|
||
return cancelled, err
|
||
}
|
||
config := txallowlist.NewConfig(
|
||
evmutils.NewUint64(uint64(date.Unix())), //nolint:gosec // G115: Unix time is positive
|
||
adminAddrs,
|
||
enabledAddrs,
|
||
managerAddrs,
|
||
)
|
||
upgrade := extras.PrecompileUpgrade{
|
||
Config: config,
|
||
}
|
||
*precompiles = append(*precompiles, upgrade)
|
||
return false, nil
|
||
}
|
||
|
||
func promptAdminManagerAndEnabledAddresses(
|
||
sc *models.Sidecar,
|
||
action string,
|
||
) ([]common.Address, []common.Address, []common.Address, bool, error) {
|
||
allowList, cancelled, err := vm.GenerateAllowList(app, vm.AllowList{}, action, sc.VMVersion)
|
||
if cancelled || err != nil {
|
||
return nil, nil, nil, cancelled, err
|
||
}
|
||
return allowList.AdminAddresses, allowList.ManagerAddresses, allowList.EnabledAddresses, false, nil
|
||
}
|