From 3dd590005cd88a64699cd90991dc0ccb5d84b0f0 Mon Sep 17 00:00:00 2001 From: Fornax <23104993+0xfornax@users.noreply.github.com> Date: Thu, 13 Aug 2026 18:23:16 -0300 Subject: [PATCH 1/3] Add submit-batch command and generate-json flags for multi-setting proposals --- README.md | 2 + bindings/dao/protocol/proposal-payload.go | 153 ++++++ .../dao/protocol/proposal-payload_test.go | 120 +++++ bindings/dao/protocol/proposal.go | 52 +- bindings/settings/protocol/setting-types.go | 200 ++++++++ bindings/types/dao.go | 13 + bindings/utils/state/pdao.go | 2 +- rocketpool-cli/pdao/commands.go | 480 +++++++++++++++--- rocketpool-cli/pdao/execute-proposal.go | 12 +- rocketpool-cli/pdao/proposals.go | 56 +- rocketpool-cli/pdao/propose-settings-json.go | 94 ++++ .../pdao/propose-settings-json_test.go | 115 +++++ rocketpool-cli/pdao/propose-settings.go | 325 ++++++------ rocketpool-cli/pdao/set-allow-list.go | 5 +- rocketpool-cli/pdao/submit-batch.go | 87 ++++ rocketpool-cli/pdao/vote-proposal.go | 7 +- rocketpool/api/pdao/propose-settings-multi.go | 154 ++++++ rocketpool/api/pdao/routes.go | 44 ++ rocketpool/api/pdao/setting-decode.go | 93 ++++ rocketpool/api/pdao/setting-decode_test.go | 112 ++++ shared/services/rocketpool/pdao.go | 47 ++ shared/types/api/pdao.go | 27 + 22 files changed, 1914 insertions(+), 286 deletions(-) create mode 100644 bindings/dao/protocol/proposal-payload.go create mode 100644 bindings/dao/protocol/proposal-payload_test.go create mode 100644 bindings/settings/protocol/setting-types.go create mode 100644 rocketpool-cli/pdao/propose-settings-json.go create mode 100644 rocketpool-cli/pdao/propose-settings-json_test.go create mode 100644 rocketpool-cli/pdao/submit-batch.go create mode 100644 rocketpool/api/pdao/propose-settings-multi.go create mode 100644 rocketpool/api/pdao/setting-decode.go create mode 100644 rocketpool/api/pdao/setting-decode_test.go diff --git a/README.md b/README.md index 662f0299a..b2ebbe0ba 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,8 @@ The following commands are available via the Smart Node client: - `rocketpool pdao set-voting-delegate, svd` - Set the address you want to use when voting on Rocket Pool on-chain governance proposals, or the address you want to delegate your voting power to. - `rocketpool pdao claim-bonds, cb` - Unlock any bonded RPL you have for a proposal or set of challenges, and claim any bond rewards for defending or defeating the proposal - `rocketpool pdao propose, p` - Make a Protocol DAO proposal + - `rocketpool pdao propose submit-batch, sb` - Submit a single proposal that changes multiple Protocol DAO settings from a JSON file + - Setting propose commands accept `--generate-json ` to write/append a setting change to a JSON file instead of submitting a transaction - `rocketpool pdao proposals, o` - Manage Protocol DAO proposals - **queue**, q - Manage the Rocket Pool deposit queue - `rocketpool queue status, s` - Get the deposit pool and minipool queue status diff --git a/bindings/dao/protocol/proposal-payload.go b/bindings/dao/protocol/proposal-payload.go new file mode 100644 index 000000000..9c21e44a5 --- /dev/null +++ b/bindings/dao/protocol/proposal-payload.go @@ -0,0 +1,153 @@ +package protocol + +import ( + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/rocket-pool/smartnode/bindings/types" + strutils "github.com/rocket-pool/smartnode/bindings/utils/strings" +) + +const proposalSettingMultiMethod = "proposalSettingMulti" + +type DecodedProposalSetting struct { + Contract string `json:"contract"` + Path string `json:"path"` + Type types.ProposalSettingType `json:"type"` + Value string `json:"value"` +} + +func decodeProposalSettingMultiArgs(args []any) ([]DecodedProposalSetting, error) { + if len(args) != 4 { + return nil, fmt.Errorf("proposalSettingMulti expected 4 arguments, got %d", len(args)) + } + + contracts, err := asStringSlice(args[0]) + if err != nil { + return nil, fmt.Errorf("contract names: %w", err) + } + paths, err := asStringSlice(args[1]) + if err != nil { + return nil, fmt.Errorf("setting paths: %w", err) + } + settingTypes, err := asSettingTypes(args[2]) + if err != nil { + return nil, fmt.Errorf("setting types: %w", err) + } + values, err := asBytesSlice(args[3]) + if err != nil { + return nil, fmt.Errorf("setting values: %w", err) + } + + if len(contracts) != len(paths) || len(paths) != len(settingTypes) || len(settingTypes) != len(values) { + return nil, fmt.Errorf("proposalSettingMulti argument lengths do not match") + } + + settings := make([]DecodedProposalSetting, len(contracts)) + for i := range contracts { + value, err := decodeMultiSettingValue(settingTypes[i], values[i]) + if err != nil { + return nil, fmt.Errorf("setting %s: %w", paths[i], err) + } + settings[i] = DecodedProposalSetting{ + Contract: contracts[i], + Path: paths[i], + Type: settingTypes[i], + Value: value, + } + } + return settings, nil +} + +func FormatProposalSettingMulti(settings []DecodedProposalSetting) string { + parts := make([]string, len(settings)) + for i, setting := range settings { + parts[i] = fmt.Sprintf("%s=%s", setting.Path, setting.Value) + } + return strutils.Sanitize(fmt.Sprintf("%s(%s)", proposalSettingMultiMethod, strings.Join(parts, ", "))) +} + +func formatGenericProposalPayload(method *abi.Method, args []any) string { + argStrs := make([]string, 0, len(args)) + for ai, arg := range args { + switch method.Inputs[ai].Type.T { + case abi.AddressTy: + argStrs = append(argStrs, arg.(common.Address).Hex()) + case abi.HashTy: + argStrs = append(argStrs, arg.(common.Hash).Hex()) + case abi.FixedBytesTy: + fallthrough + case abi.BytesTy: + argStrs = append(argStrs, fmt.Sprintf("%x", arg.([]byte))) + default: + argStrs = append(argStrs, fmt.Sprintf("%v", arg)) + } + } + return strutils.Sanitize(fmt.Sprintf("%s(%s)", method.RawName, strings.Join(argStrs, ","))) +} + +func decodeMultiSettingValue(settingType types.ProposalSettingType, data []byte) (string, error) { + switch settingType { + case types.ProposalSettingType_Uint256: + return new(big.Int).SetBytes(data).String(), nil + case types.ProposalSettingType_Bool: + return fmt.Sprint(new(big.Int).SetBytes(data).Sign() != 0), nil + case types.ProposalSettingType_Address: + if len(data) >= common.AddressLength { + return common.BytesToAddress(data[len(data)-common.AddressLength:]).Hex(), nil + } + return common.BytesToAddress(data).Hex(), nil + default: + return "", fmt.Errorf("unknown setting type %d", settingType) + } +} + +func asStringSlice(value any) ([]string, error) { + switch typed := value.(type) { + case []string: + return typed, nil + default: + return nil, fmt.Errorf("expected []string, got %T", value) + } +} + +func asSettingTypes(value any) ([]types.ProposalSettingType, error) { + switch typed := value.(type) { + case []uint8: + out := make([]types.ProposalSettingType, len(typed)) + for i, item := range typed { + out[i] = types.ProposalSettingType(item) + } + return out, nil + case []*big.Int: + out := make([]types.ProposalSettingType, len(typed)) + for i, item := range typed { + if item == nil { + return nil, fmt.Errorf("nil setting type at index %d", i) + } + out[i] = types.ProposalSettingType(item.Uint64()) + } + return out, nil + case []uint16: + out := make([]types.ProposalSettingType, len(typed)) + for i, item := range typed { + out[i] = types.ProposalSettingType(item) + } + return out, nil + default: + return nil, fmt.Errorf("expected uint8 array, got %T", value) + } +} + +func asBytesSlice(value any) ([][]byte, error) { + switch typed := value.(type) { + case [][]byte: + return typed, nil + default: + return nil, fmt.Errorf("expected [][]byte, got %T", value) + } +} diff --git a/bindings/dao/protocol/proposal-payload_test.go b/bindings/dao/protocol/proposal-payload_test.go new file mode 100644 index 000000000..b4770b18b --- /dev/null +++ b/bindings/dao/protocol/proposal-payload_test.go @@ -0,0 +1,120 @@ +package protocol + +import ( + "math/big" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + + "github.com/rocket-pool/smartnode/bindings/types" +) + +const proposalSettingMultiABI = `[{ + "name": "proposalSettingMulti", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + {"name": "_settingContractNames", "type": "string[]"}, + {"name": "_settingPaths", "type": "string[]"}, + {"name": "_types", "type": "uint8[]"}, + {"name": "_data", "type": "bytes[]"} + ], + "outputs": [] +}]` + +func TestDecodeAndFormatProposalSettingMulti(t *testing.T) { + parsed, err := abi.JSON(strings.NewReader(proposalSettingMultiABI)) + if err != nil { + t.Fatalf("parse ABI: %v", err) + } + + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(1)) + address := common.HexToAddress("0x1234567890123456789012345678901234567890") + encoded := [][]byte{ + math.PaddedBigBytes(common.Big1, 32), + math.U256Bytes(new(big.Int).Set(amount)), + common.LeftPadBytes(address.Bytes(), 32), + } + + payload, err := parsed.Pack( + "proposalSettingMulti", + []string{"rocketDAOProtocolSettingsAuction", "rocketDAOProtocolSettingsDeposit", "rocketDAOProtocolSettingsNetwork"}, + []string{"auction.lot.create.enabled", "deposit.minimum", "network.node.fee.target"}, + []uint8{ + uint8(types.ProposalSettingType_Bool), + uint8(types.ProposalSettingType_Uint256), + uint8(types.ProposalSettingType_Address), + }, + encoded, + ) + if err != nil { + t.Fatalf("pack: %v", err) + } + + method, err := parsed.MethodById(payload) + if err != nil { + t.Fatalf("method: %v", err) + } + args, err := method.Inputs.UnpackValues(payload[4:]) + if err != nil { + t.Fatalf("unpack: %v", err) + } + + settings, err := decodeProposalSettingMultiArgs(args) + if err != nil { + t.Fatalf("decode: %v", err) + } + if len(settings) != 3 { + t.Fatalf("got %d settings, want 3", len(settings)) + } + if settings[0].Path != "auction.lot.create.enabled" || settings[0].Value != "true" || settings[0].Type != types.ProposalSettingType_Bool { + t.Fatalf("bool setting = %+v", settings[0]) + } + if settings[1].Path != "deposit.minimum" || settings[1].Value != amount.String() || settings[1].Type != types.ProposalSettingType_Uint256 { + t.Fatalf("uint setting = %+v", settings[1]) + } + if settings[2].Path != "network.node.fee.target" || settings[2].Value != address.Hex() || settings[2].Type != types.ProposalSettingType_Address { + t.Fatalf("address setting = %+v", settings[2]) + } + + formatted := FormatProposalSettingMulti(settings) + if !strings.Contains(formatted, "auction.lot.create.enabled=true") { + t.Fatalf("formatted missing bool setting: %s", formatted) + } + if !strings.Contains(formatted, "deposit.minimum="+amount.String()) { + t.Fatalf("formatted missing uint setting: %s", formatted) + } + if !strings.Contains(formatted, "network.node.fee.target="+address.Hex()) { + t.Fatalf("formatted missing address setting: %s", formatted) + } + if strings.Contains(formatted, "[") || strings.Contains(formatted, "0x000000") { + t.Fatalf("formatted still looks like raw ABI dump: %s", formatted) + } +} + +func TestDecodeProposalSettingMultiArgs_LengthMismatch(t *testing.T) { + _, err := decodeProposalSettingMultiArgs([]any{ + []string{"a"}, + []string{"b", "c"}, + []uint8{0}, + [][]byte{{1}}, + }) + if err == nil { + t.Fatal("expected length mismatch error") + } +} + +func TestProposalSettingTypeString(t *testing.T) { + if types.ProposalSettingType_Bool.String() != "bool" { + t.Fatalf("bool string = %s", types.ProposalSettingType_Bool) + } + if types.ProposalSettingType_Uint256.String() != "uint256" { + t.Fatalf("uint string = %s", types.ProposalSettingType_Uint256) + } + if types.ProposalSettingType_Address.String() != "address" { + t.Fatalf("address string = %s", types.ProposalSettingType_Address) + } +} diff --git a/bindings/dao/protocol/proposal.go b/bindings/dao/protocol/proposal.go index 47b99728d..accb8430b 100644 --- a/bindings/dao/protocol/proposal.go +++ b/bindings/dao/protocol/proposal.go @@ -2,15 +2,12 @@ package protocol import ( "context" - "encoding/hex" "fmt" "math/big" - "strings" "sync" "time" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "golang.org/x/sync/errgroup" @@ -19,7 +16,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/rocketpool" "github.com/rocket-pool/smartnode/bindings/transactions/gaslimit" "github.com/rocket-pool/smartnode/bindings/types" - strutils "github.com/rocket-pool/smartnode/bindings/utils/strings" ) // Settings @@ -57,6 +53,7 @@ type ProtocolDaoProposalDetails struct { VetoQuorum *big.Int `json:"vetoQuorum"` Payload []byte `json:"payload"` PayloadStr string `json:"payloadStr"` + MultiSettings []DecodedProposalSetting `json:"multiSettings,omitempty"` State types.ProtocolDaoProposalState `json:"state"` ProposalBond *big.Int `json:"proposalBond"` ChallengeBond *big.Int `json:"challengeBond"` @@ -238,11 +235,12 @@ func GetProposalDetails(rp *rocketpool.RocketPool, proposalId uint64, opts *bind } // Get proposal payload string - payloadStr, err := GetProposalPayloadString(rp, prop.Payload, opts) + payloadStr, multiSettings, err := ParseProposalPayload(rp, prop.Payload, opts) if err != nil { payloadStr = "(unknown)" } prop.PayloadStr = payloadStr + prop.MultiSettings = multiSettings return prop, nil } @@ -508,45 +506,35 @@ func GetProposalPayload(rp *rocketpool.RocketPool, proposalId uint64, opts *bind // Get a proposal's payload as a human-readable string func GetProposalPayloadString(rp *rocketpool.RocketPool, payload []byte, opts *bind.CallOpts) (string, error) { + payloadStr, _, err := ParseProposalPayload(rp, payload, opts) + return payloadStr, err +} + +func ParseProposalPayload(rp *rocketpool.RocketPool, payload []byte, opts *bind.CallOpts) (string, []DecodedProposalSetting, error) { rocketDAOProtocolProposals, err := getRocketDAOProtocolProposals(rp, nil) if err != nil { - return "", err + return "", nil, err } - // Get proposal DAO contract ABI - daoContractAbi := rocketDAOProtocolProposals.ABI - - // Get proposal payload method - method, err := daoContractAbi.MethodById(payload) + method, err := rocketDAOProtocolProposals.ABI.MethodById(payload) if err != nil { - return "", fmt.Errorf("error getting proposal payload method: %w", err) + return "", nil, fmt.Errorf("error getting proposal payload method: %w", err) } - // Get proposal payload argument values args, err := method.Inputs.UnpackValues(payload[4:]) if err != nil { - return "", fmt.Errorf("error getting proposal payload arguments: %w", err) - } - - // Format argument values as strings - argStrs := []string{} - for ai, arg := range args { - switch method.Inputs[ai].Type.T { - case abi.AddressTy: - argStrs = append(argStrs, arg.(common.Address).Hex()) - case abi.HashTy: - argStrs = append(argStrs, arg.(common.Hash).Hex()) - case abi.FixedBytesTy: - fallthrough - case abi.BytesTy: - argStrs = append(argStrs, hex.EncodeToString(arg.([]byte))) - default: - argStrs = append(argStrs, fmt.Sprintf("%v", arg)) + return "", nil, fmt.Errorf("error getting proposal payload arguments: %w", err) + } + + if method.RawName == proposalSettingMultiMethod { + settings, err := decodeProposalSettingMultiArgs(args) + if err != nil { + return "", nil, err } + return FormatProposalSettingMulti(settings), settings, nil } - // Build & return payload string - return strutils.Sanitize(fmt.Sprintf("%s(%s)", method.RawName, strings.Join(argStrs, ","))), nil + return formatGenericProposalPayload(method, args), nil, nil } // Get the proposal's state diff --git a/bindings/settings/protocol/setting-types.go b/bindings/settings/protocol/setting-types.go new file mode 100644 index 000000000..506870055 --- /dev/null +++ b/bindings/settings/protocol/setting-types.go @@ -0,0 +1,200 @@ +package protocol + +import ( + "fmt" + + protocol131 "github.com/rocket-pool/smartnode/bindings/legacy/v1.3.1/protocol" + "github.com/rocket-pool/smartnode/bindings/types" +) + +// Proposal setting type names written to --generate-json files. +const ( + ProposalSettingTypeNameUint256 = "uint256" + ProposalSettingTypeNameBool = "bool" + ProposalSettingTypeNameAddress = "address" +) + +// Errors for settings that cannot be encoded into a proposalSettingMulti payload. +var ( + ErrUnknownPDAOSetting = fmt.Errorf("unknown protocol DAO setting") + ErrUnsupportedBatchSetting = fmt.Errorf("setting type is not supported in a multi-setting proposal") + ErrHoustonOnlySetting = fmt.Errorf("setting is no longer available after Saturn") + ErrDuplicateBatchSetting = fmt.Errorf("duplicate setting in multi-setting proposal") + ErrEmptyBatchSettings = fmt.Errorf("multi-setting proposal must contain at least one setting") +) + +// settingKind is the on-chain value type of a protocol DAO setting. +type settingKind uint8 + +const ( + settingKindUint256 settingKind = iota + settingKindBool + settingKindAddress + settingKindAddressList +) + +// pdaoSettingKinds maps contract name -> setting path -> value type for every +// setting the Smart Node can propose. +var pdaoSettingKinds = map[string]map[string]settingKind{ + AuctionSettingsContractName: { + CreateLotEnabledSettingPath: settingKindBool, + BidOnLotEnabledSettingPath: settingKindBool, + LotMinimumEthValueSettingPath: settingKindUint256, + LotMaximumEthValueSettingPath: settingKindUint256, + LotDurationSettingPath: settingKindUint256, + LotStartingPriceRatioSettingPath: settingKindUint256, + LotReservePriceRatioSettingPath: settingKindUint256, + }, + DepositSettingsContractName: { + DepositEnabledSettingPath: settingKindBool, + AssignDepositsEnabledSettingPath: settingKindBool, + MinimumDepositSettingPath: settingKindUint256, + MaximumDepositPoolSizeSettingPath: settingKindUint256, + MaximumDepositAssignmentsSettingPath: settingKindUint256, + MaximumSocializedDepositAssignmentsSettingPath: settingKindUint256, + DepositFeeSettingPath: settingKindUint256, + ExpressQueueRatePath: settingKindUint256, + ExpressQueueTicketsBaseProvisionPath: settingKindUint256, + }, + MinipoolSettingsContractName: { + MinipoolSubmitWithdrawableEnabledSettingPath: settingKindBool, + MinipoolLaunchTimeoutSettingPath: settingKindUint256, + BondReductionEnabledSettingPath: settingKindBool, + MaximumMinipoolCountSettingPath: settingKindUint256, + MinipoolUserDistributeWindowStartSettingPath: settingKindUint256, + MinipoolUserDistributeWindowLengthSettingPath: settingKindUint256, + }, + NetworkSettingsContractName: { + NodeConsensusThresholdSettingPath: settingKindUint256, + SubmitBalancesEnabledSettingPath: settingKindBool, + SubmitBalancesFrequencySettingPath: settingKindUint256, + SubmitPricesEnabledSettingPath: settingKindBool, + SubmitPricesFrequencySettingPath: settingKindUint256, + MinimumNodeFeeSettingPath: settingKindUint256, + TargetNodeFeeSettingPath: settingKindUint256, + MaximumNodeFeeSettingPath: settingKindUint256, + NodeFeeDemandRangeSettingPath: settingKindUint256, + TargetRethCollateralRateSettingPath: settingKindUint256, + NetworkPenaltyThresholdSettingPath: settingKindUint256, + NetworkPenaltyPerRateSettingPath: settingKindUint256, + SubmitRewardsEnabledSettingPath: settingKindBool, + NetworkAllowListedControllersPath: settingKindAddressList, + NetworkNodeCommissionSharePath: settingKindUint256, + NetworkNodeCommissionShareSecurityCouncilAdderPath: settingKindUint256, + NetworkVoterSharePath: settingKindUint256, + NetworkPDAOSharePath: settingKindUint256, + NetworkMaxNodeShareSecurityCouncilAdderPath: settingKindUint256, + NetworkMaxRethBalanceDeltaPath: settingKindUint256, + }, + NodeSettingsContractName: { + NodeRegistrationEnabledSettingPath: settingKindBool, + SmoothingPoolRegistrationEnabledSettingPath: settingKindBool, + NodeDepositEnabledSettingPath: settingKindBool, + VacantMinipoolsEnabledSettingPath: settingKindBool, + protocol131.MinimumPerMinipoolStakeSettingPath: settingKindUint256, + protocol131.MaximumPerMinipoolStakeSettingPath: settingKindUint256, + MinimumLegacyRplStakePath: settingKindUint256, + ReducedBondSettingPath: settingKindUint256, + NodeUnstakingPeriodSettingPath: settingKindUint256, + }, + ProposalsSettingsContractName: { + VotePhase1TimeSettingPath: settingKindUint256, + VotePhase2TimeSettingPath: settingKindUint256, + VoteDelayTimeSettingPath: settingKindUint256, + ExecuteTimeSettingPath: settingKindUint256, + ProposalBondSettingPath: settingKindUint256, + ChallengeBondSettingPath: settingKindUint256, + ChallengePeriodSettingPath: settingKindUint256, + ProposalQuorumSettingPath: settingKindUint256, + ProposalVetoQuorumSettingPath: settingKindUint256, + ProposalMaxBlockAgeSettingPath: settingKindUint256, + }, + RewardsSettingsContractName: { + RewardsClaimIntervalPeriodsSettingPath: settingKindUint256, + }, + SecuritySettingsContractName: { + SecurityMembersQuorumSettingPath: settingKindUint256, + SecurityMembersLeaveTimeSettingPath: settingKindUint256, + SecurityProposalVoteTimeSettingPath: settingKindUint256, + SecurityProposalExecuteTimeSettingPath: settingKindUint256, + SecurityProposalActionTimeSettingPath: settingKindUint256, + }, + MegapoolSettingsContractName: { + MegapoolTimeBeforeDissolveSettingsPath: settingKindUint256, + MegapoolMaximumMegapoolEthPenaltyPath: settingKindUint256, + MegapoolNotifyThresholdPath: settingKindUint256, + MegapoolLateNotifyFinePath: settingKindUint256, + MegapoolDissolvePenaltyPath: settingKindUint256, + MegapoolUserDistributeDelayPath: settingKindUint256, + MegapoolUserDistributeDelayShortfallPath: settingKindUint256, + MegapoolPenaltyThreshold: settingKindUint256, + }, +} + +// houstonOnlySettings cannot be proposed after the Saturn upgrade. +var houstonOnlySettings = map[string]struct{}{ + protocol131.MinimumPerMinipoolStakeSettingPath: {}, + protocol131.MaximumPerMinipoolStakeSettingPath: {}, +} + +// IsHoustonOnlySetting reports whether the setting existed only on Houston 1.3.1. +func IsHoustonOnlySetting(setting string) bool { + _, exists := houstonOnlySettings[setting] + return exists +} + +// GetProposalSettingType returns the on-chain type used by proposalSettingMulti +// for the given contract/setting pair. +func GetProposalSettingType(contract string, setting string) (types.ProposalSettingType, error) { + kinds, ok := pdaoSettingKinds[contract] + if !ok { + return 0, fmt.Errorf("%w: [%s - %s]", ErrUnknownPDAOSetting, contract, setting) + } + kind, ok := kinds[setting] + if !ok { + return 0, fmt.Errorf("%w: [%s - %s]", ErrUnknownPDAOSetting, contract, setting) + } + if IsHoustonOnlySetting(setting) { + return 0, fmt.Errorf("%w: %s", ErrHoustonOnlySetting, setting) + } + switch kind { + case settingKindUint256: + return types.ProposalSettingType_Uint256, nil + case settingKindBool: + return types.ProposalSettingType_Bool, nil + case settingKindAddress: + return types.ProposalSettingType_Address, nil + case settingKindAddressList: + return 0, fmt.Errorf("%w: %s (address lists cannot be batched)", ErrUnsupportedBatchSetting, setting) + default: + return 0, fmt.Errorf("%w: [%s - %s]", ErrUnknownPDAOSetting, contract, setting) + } +} + +// ProposalSettingTypeName returns the JSON type string for a setting type. +func ProposalSettingTypeName(settingType types.ProposalSettingType) string { + switch settingType { + case types.ProposalSettingType_Uint256: + return ProposalSettingTypeNameUint256 + case types.ProposalSettingType_Bool: + return ProposalSettingTypeNameBool + case types.ProposalSettingType_Address: + return ProposalSettingTypeNameAddress + default: + return "" + } +} + +// ParseProposalSettingTypeName converts a JSON type string to a setting type. +func ParseProposalSettingTypeName(name string) (types.ProposalSettingType, error) { + switch name { + case ProposalSettingTypeNameUint256, "uint": + return types.ProposalSettingType_Uint256, nil + case ProposalSettingTypeNameBool: + return types.ProposalSettingType_Bool, nil + case ProposalSettingTypeNameAddress: + return types.ProposalSettingType_Address, nil + default: + return 0, fmt.Errorf("unknown setting type %q", name) + } +} diff --git a/bindings/types/dao.go b/bindings/types/dao.go index eb7aef5b4..df8f7fa75 100644 --- a/bindings/types/dao.go +++ b/bindings/types/dao.go @@ -76,6 +76,19 @@ const ( ProposalSettingType_Address ) +func (t ProposalSettingType) String() string { + switch t { + case ProposalSettingType_Uint256: + return "uint256" + case ProposalSettingType_Bool: + return "bool" + case ProposalSettingType_Address: + return "address" + default: + return fmt.Sprintf("unknown(%d)", t) + } +} + // Challenge states type ChallengeState uint8 diff --git a/bindings/utils/state/pdao.go b/bindings/utils/state/pdao.go index 30b81234b..9a988537b 100644 --- a/bindings/utils/state/pdao.go +++ b/bindings/utils/state/pdao.go @@ -216,7 +216,7 @@ func fixupPdaoProposalDetails(rp *rocketpool.RocketPool, rawDetails *protocolDao details.ChallengeWindow = time.Second * time.Duration(rawDetails.ChallengeWindow.Uint64()) var err error - details.PayloadStr, err = protocol.GetProposalPayloadString(rp, rawDetails.Payload, opts) + details.PayloadStr, details.MultiSettings, err = protocol.ParseProposalPayload(rp, rawDetails.Payload, opts) if err != nil { details.PayloadStr = fmt.Sprintf("", err.Error()) } diff --git a/rocketpool-cli/pdao/commands.go b/rocketpool-cli/pdao/commands.go index 6b11403ef..1337acee7 100644 --- a/rocketpool-cli/pdao/commands.go +++ b/rocketpool-cli/pdao/commands.go @@ -557,6 +557,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -570,7 +574,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionIsCreateLotEnabled(value, c.Bool("yes")) + return proposeSettingAuctionIsCreateLotEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -586,6 +590,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -599,7 +607,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionIsBidOnLotEnabled(value, c.Bool("yes")) + return proposeSettingAuctionIsBidOnLotEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -619,6 +627,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -632,7 +644,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotMinimumEthValue(value, c.Bool("yes")) + return proposeSettingAuctionLotMinimumEthValue(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -652,6 +664,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -665,7 +681,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotMaximumEthValue(value, c.Bool("yes")) + return proposeSettingAuctionLotMaximumEthValue(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -681,6 +697,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -694,7 +714,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotDuration(value, c.Bool("yes")) + return proposeSettingAuctionLotDuration(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -714,6 +734,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -727,7 +751,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotStartingPriceRatio(value, c.Bool("yes")) + return proposeSettingAuctionLotStartingPriceRatio(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -747,6 +771,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -760,7 +788,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotReservePriceRatio(value, c.Bool("yes")) + return proposeSettingAuctionLotReservePriceRatio(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -784,6 +812,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -797,7 +829,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositIsDepositingEnabled(value, c.Bool("yes")) + return proposeSettingDepositIsDepositingEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -813,6 +845,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -826,7 +862,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositAreDepositAssignmentsEnabled(value, c.Bool("yes")) + return proposeSettingDepositAreDepositAssignmentsEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -846,6 +882,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -859,7 +899,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMinimumDeposit(value, c.Bool("yes")) + return proposeSettingDepositMinimumDeposit(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -879,6 +919,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -892,7 +936,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMaximumDepositPoolSize(value, c.Bool("yes")) + return proposeSettingDepositMaximumDepositPoolSize(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -908,6 +952,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -921,7 +969,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMaximumAssignmentsPerDeposit(value, c.Bool("yes")) + return proposeSettingDepositMaximumAssignmentsPerDeposit(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -937,6 +985,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -950,7 +1002,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value, c.Bool("yes")) + return proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -970,6 +1022,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -983,7 +1039,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositDepositFee(value, c.Bool("yes")) + return proposeSettingDepositDepositFee(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -999,6 +1055,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { // Validate args @@ -1011,7 +1071,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositExpressQueueRate(value, c.Bool("yes")) + return proposeSettingDepositExpressQueueRate(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1027,6 +1087,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { // Validate args @@ -1039,7 +1103,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositExpressQueueTicketsBaseProvision(value, c.Bool("yes")) + return proposeSettingDepositExpressQueueTicketsBaseProvision(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1063,6 +1127,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1076,7 +1144,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolIsSubmitWithdrawableEnabled(value, c.Bool("yes")) + return proposeSettingMinipoolIsSubmitWithdrawableEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1092,6 +1160,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1105,7 +1177,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolLaunchTimeout(value, c.Bool("yes")) + return proposeSettingMinipoolLaunchTimeout(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1121,6 +1193,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1134,7 +1210,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolIsBondReductionEnabled(value, c.Bool("yes")) + return proposeSettingMinipoolIsBondReductionEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1150,6 +1226,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1163,7 +1243,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolMaximumCount(value, c.Bool("yes")) + return proposeSettingMinipoolMaximumCount(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1179,6 +1259,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1192,7 +1276,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolUserDistributeWindowStart(value, c.Bool("yes")) + return proposeSettingMinipoolUserDistributeWindowStart(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1208,6 +1292,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1221,7 +1309,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolUserDistributeWindowLength(value, c.Bool("yes")) + return proposeSettingMinipoolUserDistributeWindowLength(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1249,6 +1337,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1262,7 +1354,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkOracleDaoConsensusThreshold(value, c.Bool("yes")) + return proposeSettingNetworkOracleDaoConsensusThreshold(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1282,6 +1374,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1295,7 +1391,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkNodePenaltyThreshold(value, c.Bool("yes")) + return proposeSettingNetworkNodePenaltyThreshold(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1315,6 +1411,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1328,7 +1428,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkPerPenaltyRate(value, c.Bool("yes")) + return proposeSettingNetworkPerPenaltyRate(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1344,6 +1444,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1357,7 +1461,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkIsSubmitBalancesEnabled(value, c.Bool("yes")) + return proposeSettingNetworkIsSubmitBalancesEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1373,6 +1477,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1386,7 +1494,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkSubmitBalancesFrequency(value, c.Bool("yes")) + return proposeSettingNetworkSubmitBalancesFrequency(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1402,6 +1510,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1415,7 +1527,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkIsSubmitPricesEnabled(value, c.Bool("yes")) + return proposeSettingNetworkIsSubmitPricesEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1431,6 +1543,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1444,7 +1560,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkSubmitPricesFrequency(value, c.Bool("yes")) + return proposeSettingNetworkSubmitPricesFrequency(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1464,6 +1580,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1477,7 +1597,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkMinimumNodeFee(value, c.Bool("yes")) + return proposeSettingNetworkMinimumNodeFee(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1497,6 +1617,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1510,7 +1634,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkTargetNodeFee(value, c.Bool("yes")) + return proposeSettingNetworkTargetNodeFee(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1530,6 +1654,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1543,7 +1671,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkMaximumNodeFee(value, c.Bool("yes")) + return proposeSettingNetworkMaximumNodeFee(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1563,6 +1691,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1576,7 +1708,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkNodeFeeDemandRange(value, c.Bool("yes")) + return proposeSettingNetworkNodeFeeDemandRange(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1596,6 +1728,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1609,7 +1745,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkTargetRethCollateralRate(value, c.Bool("yes")) + return proposeSettingNetworkTargetRethCollateralRate(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1625,6 +1761,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1638,7 +1778,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkIsSubmitRewardsEnabled(value, c.Bool("yes")) + return proposeSettingNetworkIsSubmitRewardsEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1654,6 +1794,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, &cli.StringFlag{ Name: "addressList, a", Usage: "One or more addresses, separated by commas with no spaces", @@ -1666,7 +1810,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { return err } // Run - return setAllowListedControllers(c.String("addressList"), c.Bool("yes")) + return setAllowListedControllers(c.String("addressList"), c.Bool("yes"), c.String("generate-json")) }, }, @@ -1686,6 +1830,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1699,7 +1847,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeCommissionShare(value, c.Bool("yes")) + return proposeSettingNodeCommissionShare(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1719,6 +1867,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1732,7 +1884,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeCommissionShareSecurityCouncilAdder(value, c.Bool("yes")) + return proposeSettingNodeCommissionShareSecurityCouncilAdder(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1752,6 +1904,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1765,7 +1921,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingVoterShare(value, c.Bool("yes")) + return proposeSettingVoterShare(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1785,6 +1941,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1798,7 +1958,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingPDAOShare(value, c.Bool("yes")) + return proposeSettingPDAOShare(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1818,6 +1978,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1831,7 +1995,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeMaxNodeShareSecurityCouncilAdder(value, c.Bool("yes")) + return proposeMaxNodeShareSecurityCouncilAdder(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1851,6 +2015,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1864,7 +2032,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeMaxRethBalanceDelta(value, c.Bool("yes")) + return proposeMaxRethBalanceDelta(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1888,6 +2056,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1901,7 +2073,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeIsRegistrationEnabled(value, c.Bool("yes")) + return proposeSettingNodeIsRegistrationEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1917,6 +2089,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1930,7 +2106,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value, c.Bool("yes")) + return proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1946,6 +2122,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1959,7 +2139,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeIsDepositingEnabled(value, c.Bool("yes")) + return proposeSettingNodeIsDepositingEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -1975,6 +2155,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -1988,7 +2172,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeAreVacantMinipoolsEnabled(value, c.Bool("yes")) + return proposeSettingNodeAreVacantMinipoolsEnabled(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2008,6 +2192,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2021,7 +2209,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeMinimumPerMinipoolStake(value, c.Bool("yes")) + return proposeSettingNodeMinimumPerMinipoolStake(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2041,6 +2229,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2054,7 +2246,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeMaximumPerMinipoolStake(value, c.Bool("yes")) + return proposeSettingNodeMaximumPerMinipoolStake(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2074,6 +2266,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2087,7 +2283,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeMinimumLegacyRplStake(value, c.Bool("yes")) + return proposeSettingNodeMinimumLegacyRplStake(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2107,6 +2303,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2120,7 +2320,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingReducedBond(value, c.Bool("yes")) + return proposeSettingReducedBond(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2136,6 +2336,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2149,7 +2353,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeUnstakingPeriod(value, c.Bool("yes")) + return proposeSettingNodeUnstakingPeriod(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2173,6 +2377,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2186,7 +2394,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVotePhase1Time(value, c.Bool("yes")) + return proposeSettingProposalsVotePhase1Time(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2202,6 +2410,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2215,7 +2427,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVotePhase2Time(value, c.Bool("yes")) + return proposeSettingProposalsVotePhase2Time(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2231,6 +2443,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2244,7 +2460,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVoteDelayTime(value, c.Bool("yes")) + return proposeSettingProposalsVoteDelayTime(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2260,6 +2476,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2273,7 +2493,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsExecuteTime(value, c.Bool("yes")) + return proposeSettingProposalsExecuteTime(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2293,6 +2513,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2306,7 +2530,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsProposalBond(value, c.Bool("yes")) + return proposeSettingProposalsProposalBond(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2326,6 +2550,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2339,7 +2567,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsChallengeBond(value, c.Bool("yes")) + return proposeSettingProposalsChallengeBond(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2355,6 +2583,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2368,7 +2600,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsChallengePeriod(value, c.Bool("yes")) + return proposeSettingProposalsChallengePeriod(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2388,6 +2620,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2401,7 +2637,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsQuorum(value, c.Bool("yes")) + return proposeSettingProposalsQuorum(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2421,6 +2657,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2434,7 +2674,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVetoQuorum(value, c.Bool("yes")) + return proposeSettingProposalsVetoQuorum(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2450,6 +2690,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2463,7 +2707,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsMaxBlockAge(value, c.Bool("yes")) + return proposeSettingProposalsMaxBlockAge(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2487,6 +2731,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2500,7 +2748,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingRewardsIntervalPeriods(value, c.Bool("yes")) + return proposeSettingRewardsIntervalPeriods(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2528,6 +2776,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2541,7 +2793,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityMembersQuorum(value, c.Bool("yes")) + return proposeSettingSecurityMembersQuorum(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2557,6 +2809,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2570,7 +2826,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityMembersLeaveTime(value, c.Bool("yes")) + return proposeSettingSecurityMembersLeaveTime(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2586,6 +2842,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2599,7 +2859,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityProposalVoteTime(value, c.Bool("yes")) + return proposeSettingSecurityProposalVoteTime(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2615,6 +2875,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2628,7 +2892,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityProposalExecuteTime(value, c.Bool("yes")) + return proposeSettingSecurityProposalExecuteTime(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2644,6 +2908,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2657,7 +2925,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityProposalActionTime(value, c.Bool("yes")) + return proposeSettingSecurityProposalActionTime(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2681,6 +2949,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2694,7 +2966,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolTimeBeforeDissolve(value, c.Bool("yes")) + return proposeSettingMegapoolTimeBeforeDissolve(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2714,6 +2986,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2727,7 +3003,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMaximumMegapoolEthPenalty(value, c.Bool("yes")) + return proposeSettingMaximumMegapoolEthPenalty(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2743,6 +3019,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2756,7 +3036,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolNotifyThreshold(value, c.Bool("yes")) + return proposeSettingMegapoolNotifyThreshold(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2776,6 +3056,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2789,7 +3073,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolLateNotifyFine(value, c.Bool("yes")) + return proposeSettingMegapoolLateNotifyFine(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2805,6 +3089,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2818,7 +3106,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolDissolvePenalty(value, c.Bool("yes")) + return proposeSettingMegapoolDissolvePenalty(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2834,6 +3122,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { // Validate args @@ -2846,7 +3138,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolUserDistributeDelay(value, c.Bool("yes")) + return proposeSettingMegapoolUserDistributeDelay(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2862,6 +3154,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { // Validate args @@ -2874,7 +3170,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolUserDistributeDelayWithShortfall(value, c.Bool("yes")) + return proposeSettingMegapoolUserDistributeDelayWithShortfall(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2894,6 +3190,10 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "generate-json", + Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", + }, }, Action: func(ctx context.Context, c *cli.Command) error { @@ -2907,7 +3207,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingPenaltyThreshold(value, c.Bool("yes")) + return proposeSettingPenaltyThreshold(value, c.Bool("yes"), c.String("generate-json")) }, }, @@ -2915,6 +3215,36 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { }, }, }, + + { + Name: "submit-batch", + Aliases: []string{"sb"}, + Usage: "Submit a single proposal that changes multiple Protocol DAO settings from a JSON file created with --generate-json", + UsageText: "rocketpool pdao propose submit-batch file", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "yes", + Aliases: []string{"y"}, + Usage: "Automatically confirm all interactive questions", + }, + &cli.StringFlag{ + Name: "message", + Aliases: []string{"m"}, + Usage: "A custom proposal message (no blank spaces). If omitted, you will be prompted.", + }, + }, + Action: func(ctx context.Context, c *cli.Command) error { + + // Validate args + if err := cliutils.ValidateArgCount(c, 1); err != nil { + return err + } + + // Run + return submitBatch(c.Args().Get(0), c.String("message"), c.Bool("yes")) + + }, + }, }, }, diff --git a/rocketpool-cli/pdao/execute-proposal.go b/rocketpool-cli/pdao/execute-proposal.go index e5b5f0f20..1555f7f4f 100644 --- a/rocketpool-cli/pdao/execute-proposal.go +++ b/rocketpool-cli/pdao/execute-proposal.go @@ -6,7 +6,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/transactions/gaslimit" "github.com/rocket-pool/smartnode/bindings/types" - "github.com/rocket-pool/smartnode/bindings/utils/strings" cliutils "github.com/rocket-pool/smartnode/rocketpool-cli/cli" "github.com/rocket-pool/smartnode/rocketpool-cli/cli/prompt" @@ -78,11 +77,8 @@ func executeProposal(proposal string, yes bool) error { options := make([]string, len(executableProposals)+1) options[0] = "All available proposals" for pi, proposal := range executableProposals { - if len(proposal.Message) > 200 { - proposal.Message = proposal.Message[:200] - } - proposal.Message = strings.Sanitize(proposal.Message) - options[pi+1] = fmt.Sprintf("proposal %d (message: '%s', payload: %s)", proposal.ID, proposal.Message, proposal.PayloadStr) + message, payload := proposalDisplayText(proposal) + options[pi+1] = fmt.Sprintf("proposal %d (message: '%s', payload: %s)", proposal.ID, message, payload) } selected, _ := prompt.Select("Please select a proposal to execute:", options) @@ -95,6 +91,10 @@ func executeProposal(proposal string, yes bool) error { } + if len(selectedProposals) == 1 { + printSelectedMultiSettings(selectedProposals[0].MultiSettings) + } + // Get the total gas limit estimate var gasLimits gaslimit.Limits for _, proposal := range selectedProposals { diff --git a/rocketpool-cli/pdao/proposals.go b/rocketpool-cli/pdao/proposals.go index 3f7633dc4..a159fdd9f 100644 --- a/rocketpool-cli/pdao/proposals.go +++ b/rocketpool-cli/pdao/proposals.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "github.com/rocket-pool/smartnode/bindings/dao/protocol" "github.com/rocket-pool/smartnode/bindings/types" utilsStrings "github.com/rocket-pool/smartnode/bindings/utils/strings" @@ -79,6 +80,9 @@ func getProposals(stateFilter string) error { } proposal.Message = utilsStrings.Sanitize(proposal.Message) fmt.Printf("%d: %s - Proposed by: %s\n", proposal.ID, proposal.Message, proposal.ProposerAddress) + if summary := formatMultiSettingsSummary(proposal.MultiSettings); summary != "" { + fmt.Printf(" %s\n", summary) + } } count += len(proposals) @@ -132,8 +136,7 @@ func getProposal(id uint64) error { // Main details fmt.Printf("Proposal ID: %d\n", proposal.ID) fmt.Printf("Message: %s\n", proposal.Message) - fmt.Printf("Payload: %s\n", proposal.PayloadStr) - fmt.Printf("Payload (bytes): %s\n", hex.EncodeToString(proposal.Payload)) + printProposalPayload(proposal.ProtocolDaoProposalDetails) fmt.Printf("Proposed by: %s\n", proposal.ProposerAddress.Hex()) fmt.Printf("Created at: %s, %s\n", proposal.CreatedTime.Format(time.RFC822), getTimeDifference(proposal.CreatedTime)) fmt.Printf("State: %s\n", types.ProtocolDaoProposalStates[proposal.State]) @@ -210,3 +213,52 @@ func getTimeDifference(t time.Time) string { return message } + +func printProposalPayload(proposal protocol.ProtocolDaoProposalDetails) { + if len(proposal.MultiSettings) > 0 { + fmt.Printf("Payload: proposalSettingMulti (%d settings)\n", len(proposal.MultiSettings)) + printMultiSettings(proposal.MultiSettings, " ") + } else { + fmt.Printf("Payload: %s\n", proposal.PayloadStr) + } + fmt.Printf("Payload (bytes): %s\n", hex.EncodeToString(proposal.Payload)) +} + +func printMultiSettings(settings []protocol.DecodedProposalSetting, indent string) { + for i, setting := range settings { + fmt.Printf("%s%d. %s / %s = %s (%s)\n", indent, i+1, setting.Contract, setting.Path, setting.Value, setting.Type) + } +} + +func formatMultiSettingsSummary(settings []protocol.DecodedProposalSetting) string { + if len(settings) == 0 { + return "" + } + return protocol.FormatProposalSettingMulti(settings) +} + +func proposalDisplayText(proposal api.PDAOProposalWithNodeVoteDirection) (message string, payload string) { + message = proposal.Message + if len(message) > 200 { + message = message[:200] + } + message = utilsStrings.Sanitize(message) + + payload = proposal.PayloadStr + if len(proposal.MultiSettings) > 0 { + payload = formatMultiSettingsSummary(proposal.MultiSettings) + } + if len(payload) > 200 { + payload = payload[:200] + "..." + } + return message, payload +} + +func printSelectedMultiSettings(settings []protocol.DecodedProposalSetting) { + if len(settings) == 0 { + return + } + fmt.Printf("This proposal updates %d settings:\n", len(settings)) + printMultiSettings(settings, " ") + fmt.Println() +} diff --git a/rocketpool-cli/pdao/propose-settings-json.go b/rocketpool-cli/pdao/propose-settings-json.go new file mode 100644 index 000000000..9b79f58e4 --- /dev/null +++ b/rocketpool-cli/pdao/propose-settings-json.go @@ -0,0 +1,94 @@ +package pdao + +import ( + "encoding/json" + "fmt" + "os" + "strings" + + "github.com/rocket-pool/smartnode/bindings/settings/protocol" + "github.com/rocket-pool/smartnode/shared/types/api" +) + +// writeSettingToBatchJSON creates or appends a setting change to a batch proposal JSON file. +// If the same contract+setting is already present, its value is replaced. +func writeSettingToBatchJSON(path string, contract string, setting string, value string) error { + settingType, err := protocol.GetProposalSettingType(contract, setting) + if err != nil { + return err + } + + entry := api.PDAOBatchSetting{ + Contract: contract, + Setting: setting, + Type: protocol.ProposalSettingTypeName(settingType), + Value: value, + } + + settings, err := readBatchSettingsFileOptional(path, true) + if err != nil { + return err + } + + replaced := false + for i, existing := range settings { + if existing.Contract == contract && existing.Setting == setting { + settings[i] = entry + replaced = true + break + } + } + if !replaced { + settings = append(settings, entry) + } + + if err := writeBatchSettingsFile(path, settings); err != nil { + return err + } + + if replaced { + fmt.Printf("Updated %s in %s (%d setting(s) total).\n", setting, path, len(settings)) + } else { + fmt.Printf("Added %s to %s (%d setting(s) total).\n", setting, path, len(settings)) + } + return nil +} + +func readBatchSettingsFile(path string) ([]api.PDAOBatchSetting, error) { + return readBatchSettingsFileOptional(path, false) +} + +func readBatchSettingsFileOptional(path string, allowMissing bool) ([]api.PDAOBatchSetting, error) { + data, err := os.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + if allowMissing { + return nil, nil + } + return nil, fmt.Errorf("JSON file %s does not exist", path) + } + return nil, fmt.Errorf("could not read JSON file %s: %w", path, err) + } + trimmed := strings.TrimSpace(string(data)) + if trimmed == "" { + return nil, nil + } + + var settings []api.PDAOBatchSetting + if err := json.Unmarshal([]byte(trimmed), &settings); err != nil { + return nil, fmt.Errorf("could not parse JSON file %s: %w", path, err) + } + return settings, nil +} + +func writeBatchSettingsFile(path string, settings []api.PDAOBatchSetting) error { + out, err := json.MarshalIndent(settings, "", " ") + if err != nil { + return fmt.Errorf("could not encode JSON file %s: %w", path, err) + } + out = append(out, '\n') + if err := os.WriteFile(path, out, 0644); err != nil { + return fmt.Errorf("could not write JSON file %s: %w", path, err) + } + return nil +} diff --git a/rocketpool-cli/pdao/propose-settings-json_test.go b/rocketpool-cli/pdao/propose-settings-json_test.go new file mode 100644 index 000000000..60b8f8670 --- /dev/null +++ b/rocketpool-cli/pdao/propose-settings-json_test.go @@ -0,0 +1,115 @@ +package pdao + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" + + "github.com/rocket-pool/smartnode/bindings/settings/protocol" + "github.com/rocket-pool/smartnode/shared/types/api" +) + +func TestWriteSettingToBatchJSON_CreateAndAppend(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "batch.json") + + err := writeSettingToBatchJSON(path, protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, "true") + if err != nil { + t.Fatalf("create: %v", err) + } + + err = writeSettingToBatchJSON(path, protocol.DepositSettingsContractName, protocol.MinimumDepositSettingPath, "1000000000000000000") + if err != nil { + t.Fatalf("append: %v", err) + } + + settings, err := readBatchSettingsFile(path) + if err != nil { + t.Fatalf("read: %v", err) + } + if len(settings) != 2 { + t.Fatalf("got %d settings, want 2", len(settings)) + } + if settings[0].Setting != protocol.CreateLotEnabledSettingPath || settings[0].Type != protocol.ProposalSettingTypeNameBool { + t.Fatalf("unexpected first setting: %+v", settings[0]) + } + if settings[1].Setting != protocol.MinimumDepositSettingPath || settings[1].Type != protocol.ProposalSettingTypeNameUint256 { + t.Fatalf("unexpected second setting: %+v", settings[1]) + } +} + +func TestWriteSettingToBatchJSON_ReplaceDuplicate(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "batch.json") + + if err := writeSettingToBatchJSON(path, protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, "true"); err != nil { + t.Fatal(err) + } + if err := writeSettingToBatchJSON(path, protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, "false"); err != nil { + t.Fatal(err) + } + + settings, err := readBatchSettingsFile(path) + if err != nil { + t.Fatal(err) + } + if len(settings) != 1 { + t.Fatalf("got %d settings, want 1", len(settings)) + } + if settings[0].Value != "false" { + t.Fatalf("got value %q, want false", settings[0].Value) + } +} + +func TestWriteSettingToBatchJSON_RejectsAddressList(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "batch.json") + + err := writeSettingToBatchJSON(path, protocol.NetworkSettingsContractName, protocol.NetworkAllowListedControllersPath, "0x1") + if err == nil { + t.Fatal("expected error for address list setting") + } +} + +func TestReadBatchSettingsFile_MissingRequired(t *testing.T) { + _, err := readBatchSettingsFile(filepath.Join(t.TempDir(), "missing.json")) + if err == nil { + t.Fatal("expected missing file error") + } +} + +func TestReadBatchSettingsFile_InvalidJSON(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "bad.json") + if err := os.WriteFile(path, []byte("{not-an-array}"), 0644); err != nil { + t.Fatal(err) + } + if _, err := readBatchSettingsFile(path); err == nil { + t.Fatal("expected parse error") + } +} + +func TestWriteBatchSettingsFile_RoundTrip(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "roundtrip.json") + + want := []api.PDAOBatchSetting{ + {Contract: "a", Setting: "b", Type: "bool", Value: "true"}, + } + if err := writeBatchSettingsFile(path, want); err != nil { + t.Fatal(err) + } + + data, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + var got []api.PDAOBatchSetting + if err := json.Unmarshal(data, &got); err != nil { + t.Fatal(err) + } + if len(got) != 1 || got[0] != want[0] { + t.Fatalf("got %+v, want %+v", got, want) + } +} diff --git a/rocketpool-cli/pdao/propose-settings.go b/rocketpool-cli/pdao/propose-settings.go index 1efe0dfd7..0f6b68dab 100644 --- a/rocketpool-cli/pdao/propose-settings.go +++ b/rocketpool-cli/pdao/propose-settings.go @@ -16,378 +16,387 @@ import ( "github.com/rocket-pool/smartnode/rocketpool-cli/cli/prompt" ) -func proposeSettingAuctionIsCreateLotEnabled(value bool, yes bool) error { +func proposeSettingAuctionIsCreateLotEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingAuctionIsBidOnLotEnabled(value bool, yes bool) error { +func proposeSettingAuctionIsBidOnLotEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.AuctionSettingsContractName, protocol.BidOnLotEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.BidOnLotEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingAuctionLotMinimumEthValue(value *big.Int, yes bool) error { +func proposeSettingAuctionLotMinimumEthValue(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMinimumEthValueSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMinimumEthValueSettingPath, trueValue, yes, generateJson) } -func proposeSettingAuctionLotMaximumEthValue(value *big.Int, yes bool) error { +func proposeSettingAuctionLotMaximumEthValue(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMaximumEthValueSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMaximumEthValueSettingPath, trueValue, yes, generateJson) } -func proposeSettingAuctionLotDuration(value time.Duration, yes bool) error { +func proposeSettingAuctionLotDuration(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotDurationSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotDurationSettingPath, trueValue, yes, generateJson) } -func proposeSettingAuctionLotStartingPriceRatio(value *big.Int, yes bool) error { +func proposeSettingAuctionLotStartingPriceRatio(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotStartingPriceRatioSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotStartingPriceRatioSettingPath, trueValue, yes, generateJson) } -func proposeSettingAuctionLotReservePriceRatio(value *big.Int, yes bool) error { +func proposeSettingAuctionLotReservePriceRatio(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotReservePriceRatioSettingPath, trueValue, yes) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotReservePriceRatioSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositIsDepositingEnabled(value bool, yes bool) error { +func proposeSettingDepositIsDepositingEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositAreDepositAssignmentsEnabled(value bool, yes bool) error { +func proposeSettingDepositAreDepositAssignmentsEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.AssignDepositsEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.AssignDepositsEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositMinimumDeposit(value *big.Int, yes bool) error { +func proposeSettingDepositMinimumDeposit(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.DepositSettingsContractName, protocol.MinimumDepositSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MinimumDepositSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositMaximumDepositPoolSize(value *big.Int, yes bool) error { +func proposeSettingDepositMaximumDepositPoolSize(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositPoolSizeSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositPoolSizeSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositMaximumAssignmentsPerDeposit(value uint64, yes bool) error { +func proposeSettingDepositMaximumAssignmentsPerDeposit(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositAssignmentsSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositAssignmentsSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value uint64, yes bool) error { +func proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumSocializedDepositAssignmentsSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumSocializedDepositAssignmentsSettingPath, trueValue, yes, generateJson) } -func proposeSettingDepositExpressQueueRate(value uint64, yes bool) error { +func proposeSettingDepositExpressQueueRate(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueRatePath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueRatePath, trueValue, yes, generateJson) } -func proposeSettingDepositExpressQueueTicketsBaseProvision(value uint64, yes bool) error { +func proposeSettingDepositExpressQueueTicketsBaseProvision(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueTicketsBaseProvisionPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueTicketsBaseProvisionPath, trueValue, yes, generateJson) } -func proposeSettingDepositDepositFee(value *big.Int, yes bool) error { +func proposeSettingDepositDepositFee(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositFeeSettingPath, trueValue, yes) + return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositFeeSettingPath, trueValue, yes, generateJson) } -func proposeSettingMinipoolIsSubmitWithdrawableEnabled(value bool, yes bool) error { +func proposeSettingMinipoolIsSubmitWithdrawableEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolSubmitWithdrawableEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolSubmitWithdrawableEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingMinipoolLaunchTimeout(value time.Duration, yes bool) error { +func proposeSettingMinipoolLaunchTimeout(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolLaunchTimeoutSettingPath, trueValue, yes) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolLaunchTimeoutSettingPath, trueValue, yes, generateJson) } -func proposeSettingMinipoolIsBondReductionEnabled(value bool, yes bool) error { +func proposeSettingMinipoolIsBondReductionEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.BondReductionEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.BondReductionEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingMinipoolMaximumCount(value uint64, yes bool) error { +func proposeSettingMinipoolMaximumCount(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MaximumMinipoolCountSettingPath, trueValue, yes) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MaximumMinipoolCountSettingPath, trueValue, yes, generateJson) } -func proposeSettingMinipoolUserDistributeWindowStart(value time.Duration, yes bool) error { +func proposeSettingMinipoolUserDistributeWindowStart(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowStartSettingPath, trueValue, yes) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowStartSettingPath, trueValue, yes, generateJson) } -func proposeSettingMinipoolUserDistributeWindowLength(value time.Duration, yes bool) error { +func proposeSettingMinipoolUserDistributeWindowLength(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowLengthSettingPath, trueValue, yes) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowLengthSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkOracleDaoConsensusThreshold(value *big.Int, yes bool) error { +func proposeSettingNetworkOracleDaoConsensusThreshold(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeConsensusThresholdSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeConsensusThresholdSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkNodePenaltyThreshold(value *big.Int, yes bool) error { +func proposeSettingNetworkNodePenaltyThreshold(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyThresholdSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyThresholdSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkPerPenaltyRate(value *big.Int, yes bool) error { +func proposeSettingNetworkPerPenaltyRate(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyPerRateSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyPerRateSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkIsSubmitBalancesEnabled(value bool, yes bool) error { +func proposeSettingNetworkIsSubmitBalancesEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkSubmitBalancesFrequency(value time.Duration, yes bool) error { +func proposeSettingNetworkSubmitBalancesFrequency(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesFrequencySettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesFrequencySettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkIsSubmitPricesEnabled(value bool, yes bool) error { +func proposeSettingNetworkIsSubmitPricesEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkSubmitPricesFrequency(value time.Duration, yes bool) error { +func proposeSettingNetworkSubmitPricesFrequency(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesFrequencySettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesFrequencySettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkMinimumNodeFee(value *big.Int, yes bool) error { +func proposeSettingNetworkMinimumNodeFee(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.MinimumNodeFeeSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.MinimumNodeFeeSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkTargetNodeFee(value *big.Int, yes bool) error { +func proposeSettingNetworkTargetNodeFee(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetNodeFeeSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetNodeFeeSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkMaximumNodeFee(value *big.Int, yes bool) error { +func proposeSettingNetworkMaximumNodeFee(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.MaximumNodeFeeSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.MaximumNodeFeeSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkNodeFeeDemandRange(value *big.Int, yes bool) error { +func proposeSettingNetworkNodeFeeDemandRange(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeFeeDemandRangeSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeFeeDemandRangeSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkTargetRethCollateralRate(value *big.Int, yes bool) error { +func proposeSettingNetworkTargetRethCollateralRate(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetRethCollateralRateSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetRethCollateralRateSettingPath, trueValue, yes, generateJson) } -func proposeSettingNetworkIsSubmitRewardsEnabled(value bool, yes bool) error { +func proposeSettingNetworkIsSubmitRewardsEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitRewardsEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitRewardsEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeIsRegistrationEnabled(value bool, yes bool) error { +func proposeSettingNodeIsRegistrationEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeRegistrationEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeRegistrationEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value bool, yes bool) error { +func proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.SmoothingPoolRegistrationEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.SmoothingPoolRegistrationEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeIsDepositingEnabled(value bool, yes bool) error { +func proposeSettingNodeIsDepositingEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeDepositEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeDepositEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeAreVacantMinipoolsEnabled(value bool, yes bool) error { +func proposeSettingNodeAreVacantMinipoolsEnabled(value bool, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.VacantMinipoolsEnabledSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.VacantMinipoolsEnabledSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeMinimumPerMinipoolStake(value *big.Int, yes bool) error { +func proposeSettingNodeMinimumPerMinipoolStake(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol131.MinimumPerMinipoolStakeSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol131.MinimumPerMinipoolStakeSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeMaximumPerMinipoolStake(value *big.Int, yes bool) error { +func proposeSettingNodeMaximumPerMinipoolStake(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol131.MaximumPerMinipoolStakeSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol131.MaximumPerMinipoolStakeSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeMinimumLegacyRplStake(value *big.Int, yes bool) error { +func proposeSettingNodeMinimumLegacyRplStake(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol.MinimumLegacyRplStakePath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.MinimumLegacyRplStakePath, trueValue, yes, generateJson) } -func proposeSettingReducedBond(value *big.Int, yes bool) error { +func proposeSettingReducedBond(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol.ReducedBondSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.ReducedBondSettingPath, trueValue, yes, generateJson) } -func proposeSettingNodeUnstakingPeriod(value time.Duration, yes bool) error { +func proposeSettingNodeUnstakingPeriod(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeUnstakingPeriodSettingPath, trueValue, yes) + return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeUnstakingPeriodSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsVotePhase1Time(value time.Duration, yes bool) error { +func proposeSettingProposalsVotePhase1Time(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase1TimeSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase1TimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsVotePhase2Time(value time.Duration, yes bool) error { +func proposeSettingProposalsVotePhase2Time(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase2TimeSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase2TimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsVoteDelayTime(value time.Duration, yes bool) error { +func proposeSettingProposalsVoteDelayTime(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VoteDelayTimeSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VoteDelayTimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsExecuteTime(value time.Duration, yes bool) error { +func proposeSettingProposalsExecuteTime(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ExecuteTimeSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ExecuteTimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsProposalBond(value *big.Int, yes bool) error { +func proposeSettingProposalsProposalBond(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalBondSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalBondSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsChallengeBond(value *big.Int, yes bool) error { +func proposeSettingProposalsChallengeBond(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengeBondSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengeBondSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsChallengePeriod(value time.Duration, yes bool) error { +func proposeSettingProposalsChallengePeriod(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengePeriodSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengePeriodSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsQuorum(value *big.Int, yes bool) error { +func proposeSettingProposalsQuorum(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalQuorumSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalQuorumSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsVetoQuorum(value *big.Int, yes bool) error { +func proposeSettingProposalsVetoQuorum(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalVetoQuorumSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalVetoQuorumSettingPath, trueValue, yes, generateJson) } -func proposeSettingProposalsMaxBlockAge(value uint64, yes bool) error { +func proposeSettingProposalsMaxBlockAge(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalMaxBlockAgeSettingPath, trueValue, yes) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalMaxBlockAgeSettingPath, trueValue, yes, generateJson) } -func proposeSettingRewardsIntervalPeriods(value uint64, yes bool) error { +func proposeSettingRewardsIntervalPeriods(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.RewardsSettingsContractName, protocol.RewardsClaimIntervalPeriodsSettingPath, trueValue, yes) + return proposeSetting(protocol.RewardsSettingsContractName, protocol.RewardsClaimIntervalPeriodsSettingPath, trueValue, yes, generateJson) } -func proposeSettingSecurityMembersQuorum(value *big.Int, yes bool) error { +func proposeSettingSecurityMembersQuorum(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersQuorumSettingPath, trueValue, yes) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersQuorumSettingPath, trueValue, yes, generateJson) } -func proposeSettingSecurityMembersLeaveTime(value time.Duration, yes bool) error { +func proposeSettingSecurityMembersLeaveTime(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersLeaveTimeSettingPath, trueValue, yes) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersLeaveTimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingSecurityProposalVoteTime(value time.Duration, yes bool) error { +func proposeSettingSecurityProposalVoteTime(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalVoteTimeSettingPath, trueValue, yes) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalVoteTimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingSecurityProposalExecuteTime(value time.Duration, yes bool) error { +func proposeSettingSecurityProposalExecuteTime(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalExecuteTimeSettingPath, trueValue, yes) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalExecuteTimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingSecurityProposalActionTime(value time.Duration, yes bool) error { +func proposeSettingSecurityProposalActionTime(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalActionTimeSettingPath, trueValue, yes) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalActionTimeSettingPath, trueValue, yes, generateJson) } -func proposeSettingMegapoolTimeBeforeDissolve(value time.Duration, yes bool) error { +func proposeSettingMegapoolTimeBeforeDissolve(value time.Duration, yes bool, generateJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolTimeBeforeDissolveSettingsPath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolTimeBeforeDissolveSettingsPath, trueValue, yes, generateJson) } -func proposeSettingMaximumMegapoolEthPenalty(value *big.Int, yes bool) error { +func proposeSettingMaximumMegapoolEthPenalty(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolMaximumMegapoolEthPenaltyPath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolMaximumMegapoolEthPenaltyPath, trueValue, yes, generateJson) } -func proposeSettingMegapoolNotifyThreshold(value uint64, yes bool) error { +func proposeSettingMegapoolNotifyThreshold(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolNotifyThresholdPath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolNotifyThresholdPath, trueValue, yes, generateJson) } -func proposeSettingMegapoolLateNotifyFine(value *big.Int, yes bool) error { +func proposeSettingMegapoolLateNotifyFine(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolLateNotifyFinePath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolLateNotifyFinePath, trueValue, yes, generateJson) } -func proposeSettingMegapoolDissolvePenalty(value *big.Int, yes bool) error { +func proposeSettingMegapoolDissolvePenalty(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolDissolvePenaltyPath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolDissolvePenaltyPath, trueValue, yes, generateJson) } -func proposeSettingMegapoolUserDistributeDelay(value uint64, yes bool) error { +func proposeSettingMegapoolUserDistributeDelay(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayPath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayPath, trueValue, yes, generateJson) } -func proposeSettingMegapoolUserDistributeDelayWithShortfall(value uint64, yes bool) error { +func proposeSettingMegapoolUserDistributeDelayWithShortfall(value uint64, yes bool, generateJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayShortfallPath, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayShortfallPath, trueValue, yes, generateJson) } -func proposeSettingPenaltyThreshold(value *big.Int, yes bool) error { +func proposeSettingPenaltyThreshold(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolPenaltyThreshold, trueValue, yes) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolPenaltyThreshold, trueValue, yes, generateJson) } -func proposeSettingNodeCommissionShare(value *big.Int, yes bool) error { +func proposeSettingNodeCommissionShare(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionSharePath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionSharePath, trueValue, yes, generateJson) } -func proposeSettingNodeCommissionShareSecurityCouncilAdder(value *big.Int, yes bool) error { +func proposeSettingNodeCommissionShareSecurityCouncilAdder(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionShareSecurityCouncilAdderPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionShareSecurityCouncilAdderPath, trueValue, yes, generateJson) } -func proposeSettingVoterShare(value *big.Int, yes bool) error { +func proposeSettingVoterShare(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkVoterSharePath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkVoterSharePath, trueValue, yes, generateJson) } -func proposeSettingPDAOShare(value *big.Int, yes bool) error { +func proposeSettingPDAOShare(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPDAOSharePath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPDAOSharePath, trueValue, yes, generateJson) } -func proposeMaxNodeShareSecurityCouncilAdder(value *big.Int, yes bool) error { +func proposeMaxNodeShareSecurityCouncilAdder(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxNodeShareSecurityCouncilAdderPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxNodeShareSecurityCouncilAdderPath, trueValue, yes, generateJson) } -func proposeMaxRethBalanceDelta(value *big.Int, yes bool) error { +func proposeMaxRethBalanceDelta(value *big.Int, yes bool, generateJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxRethBalanceDeltaPath, trueValue, yes) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxRethBalanceDeltaPath, trueValue, yes, generateJson) } // Master general proposal function -func proposeSetting(contract string, setting string, value string, yes bool) error { +func proposeSetting(contract string, setting string, value string, yes bool, generateJson string) error { + if protocol.IsHoustonOnlySetting(setting) { + fmt.Println("This command no longer available in Saturn.") + return nil + } + + if generateJson != "" { + return writeSettingToBatchJSON(generateJson, contract, setting, value) + } + // Get RP client rp, err := rocketpool.NewClient().WithReady() if err != nil { @@ -395,11 +404,6 @@ func proposeSetting(contract string, setting string, value string, yes bool) err } defer rp.Close() - if isHoustonOnlySetting(setting) { - fmt.Println("This command no longer available in Saturn.") - return nil - } - // Check if proposal can be made canPropose, err := rp.PDAOCanProposeSetting(contract, setting, value) if err != nil { @@ -446,16 +450,3 @@ func proposeSetting(contract string, setting string, value string, yes bool) err fmt.Printf("Successfully submitted a %s setting update proposal.\n", setting) return nil } - -// Returns true if the given setting is only available on Houston 1.3.1 (before the Saturn upgrade). -func isHoustonOnlySetting(setting string) bool { - - // Map of Houston only settings - houstonOnlySettings := map[string]struct{}{ - protocol131.MinimumPerMinipoolStakeSettingPath: {}, - protocol131.MaximumPerMinipoolStakeSettingPath: {}, - } - - _, exists := houstonOnlySettings[setting] - return exists -} diff --git a/rocketpool-cli/pdao/set-allow-list.go b/rocketpool-cli/pdao/set-allow-list.go index 02f668530..4e9f4dbf5 100644 --- a/rocketpool-cli/pdao/set-allow-list.go +++ b/rocketpool-cli/pdao/set-allow-list.go @@ -12,7 +12,10 @@ import ( "github.com/rocket-pool/smartnode/shared/services/rocketpool" ) -func setAllowListedControllers(addressListStr string, yes bool) error { +func setAllowListedControllers(addressListStr string, yes bool, generateJson string) error { + if generateJson != "" { + return fmt.Errorf("allow-listed-controllers cannot be included in a multi-setting proposal (the protocol only supports bool, uint256, and address values in batch proposals)") + } // Get RP client rp, err := rocketpool.NewClient().WithReady() diff --git a/rocketpool-cli/pdao/submit-batch.go b/rocketpool-cli/pdao/submit-batch.go new file mode 100644 index 000000000..1f98747c7 --- /dev/null +++ b/rocketpool-cli/pdao/submit-batch.go @@ -0,0 +1,87 @@ +package pdao + +import ( + "fmt" + "math/big" + "strings" + + cliutils "github.com/rocket-pool/smartnode/rocketpool-cli/cli" + "github.com/rocket-pool/smartnode/rocketpool-cli/cli/prompt" + "github.com/rocket-pool/smartnode/shared/math" + "github.com/rocket-pool/smartnode/shared/services/gas" + "github.com/rocket-pool/smartnode/shared/services/rocketpool" +) + +func submitBatch(file string, message string, yes bool) error { + settings, err := readBatchSettingsFile(file) + if err != nil { + return err + } + if len(settings) == 0 { + return fmt.Errorf("JSON file %s does not contain any settings", file) + } + + fmt.Println("The following settings will be submitted as a single proposal:") + for i, setting := range settings { + fmt.Printf(" %d. %s / %s = %s\n", i+1, setting.Contract, setting.Setting, setting.Value) + } + fmt.Println() + + if message == "" { + message = prompt.Prompt("Please enter a custom message for this multi-setting proposal (no blank spaces):", "^\\S*$", "Invalid message") + } + if message == "" { + paths := make([]string, len(settings)) + for i, setting := range settings { + paths[i] = setting.Setting + } + message = "set-" + strings.Join(paths, ",") + } + + rp, err := rocketpool.NewClient().WithReady() + if err != nil { + return err + } + defer rp.Close() + + canPropose, err := rp.PDAOCanProposeSettingMulti(settings, message) + if err != nil { + return err + } + if !canPropose.CanPropose { + fmt.Println("Cannot propose setting update:") + if canPropose.InsufficientRpl { + fmt.Printf("You do not have enough RPL staked but unlocked to make another proposal (unlocked: %.6f RPL, required: %.6f RPL).\n", + math.WeiToEth(big.NewInt(0).Sub(canPropose.StakedRpl, canPropose.LockedRpl)), math.WeiToEth(canPropose.ProposalBond), + ) + } + if canPropose.IsRplLockingDisallowed { + fmt.Println("Please enable RPL locking using the command 'rocketpool node allow-rpl-locking' to raise proposals.") + } + return nil + } + + err = gas.AssignMaxFeeAndLimit(canPropose.GasLimits, rp, yes) + if err != nil { + return err + } + + if prompt.Declined(yes, "Are you sure you want to submit this proposal with %d setting(s)?", len(settings)) { + fmt.Println("Cancelled.") + return nil + } + + response, err := rp.PDAOProposeSettingMulti(settings, message, canPropose.BlockNumber) + if err != nil { + return err + } + + fmt.Printf("Submitting multi-setting proposal...\n") + cliutils.PrintTransactionHash(rp, response.TxHash) + if _, err = rp.WaitForTransaction(response.TxHash); err != nil { + return err + } + + fmt.Printf("Successfully submitted a multi-setting proposal with %d setting(s).\n", len(settings)) + return nil +} diff --git a/rocketpool-cli/pdao/vote-proposal.go b/rocketpool-cli/pdao/vote-proposal.go index f1c15d2bb..daf8c1d97 100644 --- a/rocketpool-cli/pdao/vote-proposal.go +++ b/rocketpool-cli/pdao/vote-proposal.go @@ -84,11 +84,12 @@ func voteOnProposal(proposal, voteDirectionFlag string, yes bool) error { } else { endTime = fmt.Sprintf("phase 2 end: %s", proposal.Phase2EndTime.Format(time.RFC822)) } + message, payload := proposalDisplayText(proposal) options[pi] = fmt.Sprintf( "proposal %d (message: '%s', payload: %s, %s, vp required: %.2f, for: %.2f, against: %.2f, abstained: %.2f, veto: %.2f, proposed by: %s)", proposal.ID, - proposal.Message, - proposal.PayloadStr, + message, + payload, endTime, math.WeiToEth(proposal.VotingPowerRequired), math.WeiToEth(proposal.VotingPowerFor), @@ -102,6 +103,8 @@ func voteOnProposal(proposal, voteDirectionFlag string, yes bool) error { } + printSelectedMultiSettings(selectedProposal.MultiSettings) + // Check if delegate has voted if selectedProposal.DelegateVoteDirection != types.VoteDirection_NoVote && votingDelegateInfo.VotingDelegate != votingDelegateInfo.AccountAddress { fmt.Printf("Your Delegate: %s has voted: %s\n", votingDelegateInfo.VotingDelegate.Hex(), types.VoteDirections[selectedProposal.DelegateVoteDirection]) diff --git a/rocketpool/api/pdao/propose-settings-multi.go b/rocketpool/api/pdao/propose-settings-multi.go new file mode 100644 index 000000000..990c9e292 --- /dev/null +++ b/rocketpool/api/pdao/propose-settings-multi.go @@ -0,0 +1,154 @@ +package pdao + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/urfave/cli/v3" + "golang.org/x/sync/errgroup" + + daoprotocol "github.com/rocket-pool/smartnode/bindings/dao/protocol" + "github.com/rocket-pool/smartnode/bindings/node" + "github.com/rocket-pool/smartnode/bindings/settings/protocol" + "github.com/rocket-pool/smartnode/shared/services" + "github.com/rocket-pool/smartnode/shared/types/api" +) + +func canProposeSettingMulti(c *cli.Command, settings []api.PDAOBatchSetting, customMessage string) (*api.CanProposePDAOSettingMultiResponse, error) { + if err := services.RequireNodeWallet(c); err != nil { + return nil, err + } + if err := services.RequireRocketStorage(c); err != nil { + return nil, err + } + cfg, err := services.GetConfig(c) + if err != nil { + return nil, err + } + w, err := services.GetWallet(c) + if err != nil { + return nil, err + } + rp, err := services.GetRocketPool(c) + if err != nil { + return nil, err + } + bc, err := services.GetBeaconClient(c) + if err != nil { + return nil, err + } + + response := api.CanProposePDAOSettingMultiResponse{} + + nodeAccount, err := w.GetNodeAccount() + if err != nil { + return nil, err + } + + var stakedRpl *big.Int + var lockedRpl *big.Int + var proposalBond *big.Int + var isRplLockingAllowed bool + var wg errgroup.Group + + wg.Go(func() error { + var err error + stakedRpl, err = node.GetNodeStakedRPL(rp, nodeAccount.Address, nil) + return err + }) + wg.Go(func() error { + var err error + lockedRpl, err = node.GetNodeLockedRPL(rp, nodeAccount.Address, nil) + return err + }) + wg.Go(func() error { + var err error + proposalBond, err = protocol.GetProposalBond(rp, nil) + return err + }) + wg.Go(func() error { + var err error + isRplLockingAllowed, err = node.GetRPLLockedAllowed(rp, nodeAccount.Address, nil) + return err + }) + if err := wg.Wait(); err != nil { + return nil, err + } + + response.StakedRpl = stakedRpl + response.LockedRpl = lockedRpl + response.ProposalBond = proposalBond + response.IsRplLockingDisallowed = !isRplLockingAllowed + + freeRpl := big.NewInt(0).Sub(stakedRpl, lockedRpl) + response.InsufficientRpl = freeRpl.Cmp(proposalBond) < 0 + response.CanPropose = !response.InsufficientRpl && !response.IsRplLockingDisallowed + if !response.CanPropose { + return &response, nil + } + + decoded, err := decodeBatchSettings(settings, customMessage) + if err != nil { + return nil, err + } + + blockNumber, pollard, err := createPollard(rp, cfg, bc) + if err != nil { + return nil, fmt.Errorf("error creating pollard: %w", err) + } + response.BlockNumber = blockNumber + + opts, err := w.GetNodeAccountTransactor() + if err != nil { + return nil, err + } + + response.GasLimits, err = daoprotocol.EstimateProposeSetMultiGas(rp, decoded.message, decoded.contractNames, decoded.settingPaths, decoded.settingTypes, decoded.values, blockNumber, pollard, opts) + if err != nil { + return nil, fmt.Errorf("error estimating gas for multi-setting proposal: %w", err) + } + + return &response, nil +} + +func proposeSettingMulti(c *cli.Command, settings []api.PDAOBatchSetting, customMessage string, blockNumber uint32, opts *bind.TransactOpts) (*api.ProposePDAOSettingMultiResponse, error) { + if err := services.RequireNodeWallet(c); err != nil { + return nil, err + } + if err := services.RequireRocketStorage(c); err != nil { + return nil, err + } + cfg, err := services.GetConfig(c) + if err != nil { + return nil, err + } + rp, err := services.GetRocketPool(c) + if err != nil { + return nil, err + } + bc, err := services.GetBeaconClient(c) + if err != nil { + return nil, err + } + + decoded, err := decodeBatchSettings(settings, customMessage) + if err != nil { + return nil, err + } + + pollard, err := getPollard(rp, cfg, bc, blockNumber) + if err != nil { + return nil, fmt.Errorf("error regenerating pollard: %w", err) + } + + proposalID, hash, err := daoprotocol.ProposeSetMulti(rp, decoded.message, decoded.contractNames, decoded.settingPaths, decoded.settingTypes, decoded.values, blockNumber, pollard, opts) + if err != nil { + return nil, fmt.Errorf("error proposing multi-setting update: %w", err) + } + + return &api.ProposePDAOSettingMultiResponse{ + ProposalId: proposalID, + TxHash: hash, + }, nil +} diff --git a/rocketpool/api/pdao/routes.go b/rocketpool/api/pdao/routes.go index 57151516d..54701e511 100644 --- a/rocketpool/api/pdao/routes.go +++ b/rocketpool/api/pdao/routes.go @@ -1,6 +1,7 @@ package pdao import ( + "encoding/json" "fmt" "math/big" "net/http" @@ -15,6 +16,7 @@ import ( cliutils "github.com/rocket-pool/smartnode/rocketpool-cli/cli" "github.com/rocket-pool/smartnode/rocketpool/api/response" "github.com/rocket-pool/smartnode/shared/services" + "github.com/rocket-pool/smartnode/shared/types/api" ) // RegisterRoutes registers the pdao module's HTTP routes onto mux. @@ -145,6 +147,36 @@ func RegisterRoutes(mux *http.ServeMux, c *cli.Command) { response.WriteResponse(w, resp, err) }) + mux.HandleFunc("/api/pdao/can-propose-setting-multi", func(w http.ResponseWriter, r *http.Request) { + settings, customMessage, err := parseBatchSettings(r) + if err != nil { + response.WriteErrorResponse(w, err) + return + } + resp, err := canProposeSettingMulti(c, settings, customMessage) + response.WriteResponse(w, resp, err) + }) + + mux.HandleFunc("/api/pdao/propose-setting-multi", func(w http.ResponseWriter, r *http.Request) { + settings, customMessage, err := parseBatchSettings(r) + if err != nil { + response.WriteErrorResponse(w, err) + return + } + blockNumber, err := parseUint32Param(r, "blockNumber") + if err != nil { + response.WriteErrorResponse(w, err) + return + } + opts, err := services.GetNodeAccountTransactorFromRequest(c, r) + if err != nil { + response.WriteErrorResponse(w, err) + return + } + resp, err := proposeSettingMulti(c, settings, customMessage, blockNumber, opts) + response.WriteResponse(w, resp, err) + }) + mux.HandleFunc("/api/pdao/get-rewards-percentages", func(w http.ResponseWriter, r *http.Request) { resp, err := getRewardsPercentages(c) response.WriteResponse(w, resp, err) @@ -680,6 +712,18 @@ func parseRawAddressList(raw string) []common.Address { return addresses } +func parseBatchSettings(r *http.Request) ([]api.PDAOBatchSetting, string, error) { + raw := paramVal(r, "settings") + if raw == "" { + return nil, "", fmt.Errorf("missing required parameter: settings") + } + var settings []api.PDAOBatchSetting + if err := json.Unmarshal([]byte(raw), &settings); err != nil { + return nil, "", fmt.Errorf("invalid settings JSON: %w", err) + } + return settings, paramVal(r, "customMessage"), nil +} + func parseClaimBondsParams(r *http.Request) (uint64, []uint64, error) { proposalID, err := parseUint64Param(r, "proposalId") if err != nil { diff --git a/rocketpool/api/pdao/setting-decode.go b/rocketpool/api/pdao/setting-decode.go new file mode 100644 index 000000000..fc644f1f7 --- /dev/null +++ b/rocketpool/api/pdao/setting-decode.go @@ -0,0 +1,93 @@ +package pdao + +import ( + "fmt" + "strings" + + "github.com/rocket-pool/smartnode/bindings/settings/protocol" + "github.com/rocket-pool/smartnode/bindings/types" + cliutils "github.com/rocket-pool/smartnode/rocketpool-cli/cli" + "github.com/rocket-pool/smartnode/shared/types/api" +) + +type decodedBatchSettings struct { + contractNames []string + settingPaths []string + settingTypes []types.ProposalSettingType + values []any + message string +} + +func decodeBatchSettings(entries []api.PDAOBatchSetting, customMessage string) (*decodedBatchSettings, error) { + if len(entries) == 0 { + return nil, protocol.ErrEmptyBatchSettings + } + + decoded := &decodedBatchSettings{ + contractNames: make([]string, 0, len(entries)), + settingPaths: make([]string, 0, len(entries)), + settingTypes: make([]types.ProposalSettingType, 0, len(entries)), + values: make([]any, 0, len(entries)), + } + + seen := make(map[string]struct{}, len(entries)) + for i, entry := range entries { + if entry.Contract == "" || entry.Setting == "" { + return nil, fmt.Errorf("setting %d is missing contract or setting path", i) + } + + key := entry.Contract + "\x00" + entry.Setting + if _, exists := seen[key]; exists { + return nil, fmt.Errorf("%w: %s / %s", protocol.ErrDuplicateBatchSetting, entry.Contract, entry.Setting) + } + seen[key] = struct{}{} + + settingType, err := protocol.GetProposalSettingType(entry.Contract, entry.Setting) + if err != nil { + return nil, err + } + if entry.Type != "" { + namedType, err := protocol.ParseProposalSettingTypeName(entry.Type) + if err != nil { + return nil, fmt.Errorf("setting %s: %w", entry.Setting, err) + } + if namedType != settingType { + return nil, fmt.Errorf("setting %s has type %s but JSON claims %s", entry.Setting, protocol.ProposalSettingTypeName(settingType), entry.Type) + } + } + + value, err := decodeSettingValue(settingType, entry.Value) + if err != nil { + return nil, fmt.Errorf("setting %s: %w", entry.Setting, err) + } + + decoded.contractNames = append(decoded.contractNames, entry.Contract) + decoded.settingPaths = append(decoded.settingPaths, entry.Setting) + decoded.settingTypes = append(decoded.settingTypes, settingType) + decoded.values = append(decoded.values, value) + } + + if customMessage != "" { + decoded.message = customMessage + } else { + decoded.message = "set " + strings.Join(decoded.settingPaths, ", ") + } + return decoded, nil +} + +func decodeSettingValue(settingType types.ProposalSettingType, value string) (any, error) { + switch settingType { + case types.ProposalSettingType_Bool: + return cliutils.ValidateBool("value", value) + case types.ProposalSettingType_Uint256: + return cliutils.ValidateBigInt("value", value) + case types.ProposalSettingType_Address: + address, err := cliutils.ValidateAddress("value", value) + if err != nil { + return nil, err + } + return address, nil + default: + return nil, fmt.Errorf("unsupported setting type %v", settingType) + } +} diff --git a/rocketpool/api/pdao/setting-decode_test.go b/rocketpool/api/pdao/setting-decode_test.go new file mode 100644 index 000000000..4fb28292e --- /dev/null +++ b/rocketpool/api/pdao/setting-decode_test.go @@ -0,0 +1,112 @@ +package pdao + +import ( + "errors" + "math/big" + "testing" + + "github.com/rocket-pool/smartnode/bindings/settings/protocol" + "github.com/rocket-pool/smartnode/bindings/types" + "github.com/rocket-pool/smartnode/shared/types/api" +) + +func TestDecodeBatchSettings(t *testing.T) { + entries := []api.PDAOBatchSetting{ + { + Contract: protocol.AuctionSettingsContractName, + Setting: protocol.CreateLotEnabledSettingPath, + Type: protocol.ProposalSettingTypeNameBool, + Value: "true", + }, + { + Contract: protocol.DepositSettingsContractName, + Setting: protocol.MinimumDepositSettingPath, + Value: "1000000000000000000", + }, + } + + decoded, err := decodeBatchSettings(entries, "") + if err != nil { + t.Fatalf("decode: %v", err) + } + if len(decoded.values) != 2 { + t.Fatalf("got %d values, want 2", len(decoded.values)) + } + if decoded.settingTypes[0] != types.ProposalSettingType_Bool { + t.Fatalf("first type = %v", decoded.settingTypes[0]) + } + if decoded.values[0] != true { + t.Fatalf("first value = %v", decoded.values[0]) + } + amount, ok := decoded.values[1].(*big.Int) + if !ok || amount.String() != "1000000000000000000" { + t.Fatalf("second value = %v", decoded.values[1]) + } + if decoded.message != "set auction.lot.create.enabled, deposit.minimum" { + t.Fatalf("message = %q", decoded.message) + } +} + +func TestDecodeBatchSettings_CustomMessage(t *testing.T) { + entries := []api.PDAOBatchSetting{ + { + Contract: protocol.AuctionSettingsContractName, + Setting: protocol.CreateLotEnabledSettingPath, + Value: "false", + }, + } + decoded, err := decodeBatchSettings(entries, "update auction settings") + if err != nil { + t.Fatal(err) + } + if decoded.message != "update auction settings" { + t.Fatalf("message = %q", decoded.message) + } +} + +func TestDecodeBatchSettings_Empty(t *testing.T) { + _, err := decodeBatchSettings(nil, "") + if !errors.Is(err, protocol.ErrEmptyBatchSettings) { + t.Fatalf("got %v, want %v", err, protocol.ErrEmptyBatchSettings) + } +} + +func TestDecodeBatchSettings_Duplicate(t *testing.T) { + entries := []api.PDAOBatchSetting{ + {Contract: protocol.AuctionSettingsContractName, Setting: protocol.CreateLotEnabledSettingPath, Value: "true"}, + {Contract: protocol.AuctionSettingsContractName, Setting: protocol.CreateLotEnabledSettingPath, Value: "false"}, + } + _, err := decodeBatchSettings(entries, "") + if !errors.Is(err, protocol.ErrDuplicateBatchSetting) { + t.Fatalf("got %v, want %v", err, protocol.ErrDuplicateBatchSetting) + } +} + +func TestDecodeBatchSettings_TypeMismatch(t *testing.T) { + entries := []api.PDAOBatchSetting{ + { + Contract: protocol.AuctionSettingsContractName, + Setting: protocol.CreateLotEnabledSettingPath, + Type: protocol.ProposalSettingTypeNameUint256, + Value: "true", + }, + } + _, err := decodeBatchSettings(entries, "") + if err == nil { + t.Fatal("expected type mismatch error") + } +} + +func TestDecodeBatchSettings_AddressListRejected(t *testing.T) { + entries := []api.PDAOBatchSetting{ + { + Contract: protocol.NetworkSettingsContractName, + Setting: protocol.NetworkAllowListedControllersPath, + Value: "0x0000000000000000000000000000000000000001", + }, + } + _, err := decodeBatchSettings(entries, "") + if !errors.Is(err, protocol.ErrUnsupportedBatchSetting) { + t.Fatalf("got %v, want %v", err, protocol.ErrUnsupportedBatchSetting) + } +} diff --git a/shared/services/rocketpool/pdao.go b/shared/services/rocketpool/pdao.go index 7854690ff..1c6eb517e 100644 --- a/shared/services/rocketpool/pdao.go +++ b/shared/services/rocketpool/pdao.go @@ -205,6 +205,53 @@ func (c *Client) PDAOCanProposeSetting(contract string, setting string, value st return response, nil } +// Check whether the node can propose updating multiple PDAO settings +func (c *Client) PDAOCanProposeSettingMulti(settings []api.PDAOBatchSetting, customMessage string) (api.CanProposePDAOSettingMultiResponse, error) { + settingsJSON, err := json.Marshal(settings) + if err != nil { + return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not encode multi-setting proposal: %w", err) + } + responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/can-propose-setting-multi", url.Values{ + "settings": {string(settingsJSON)}, + "customMessage": {customMessage}, + }) + if err != nil { + return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-setting-multi: %w", err) + } + var response api.CanProposePDAOSettingMultiResponse + if err := json.Unmarshal(responseBytes, &response); err != nil { + return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-setting-multi response: %w", err) + } + if response.Error != "" { + return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-setting-multi: %s", response.Error) + } + return response, nil +} + +// Propose updating multiple PDAO settings +func (c *Client) PDAOProposeSettingMulti(settings []api.PDAOBatchSetting, customMessage string, blockNumber uint32) (api.ProposePDAOSettingMultiResponse, error) { + settingsJSON, err := json.Marshal(settings) + if err != nil { + return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not encode multi-setting proposal: %w", err) + } + responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-setting-multi", url.Values{ + "settings": {string(settingsJSON)}, + "customMessage": {customMessage}, + "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, + }) + if err != nil { + return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO propose-setting-multi: %w", err) + } + var response api.ProposePDAOSettingMultiResponse + if err := json.Unmarshal(responseBytes, &response); err != nil { + return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not decode protocol DAO propose-setting-multi response: %w", err) + } + if response.Error != "" { + return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO propose-setting-multi: %s", response.Error) + } + return response, nil +} + // Propose updating a PDAO setting func (c *Client) PDAOProposeSetting(contract string, setting string, value string, blockNumber uint32) (api.ProposePDAOSettingResponse, error) { responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-setting", url.Values{ diff --git a/shared/types/api/pdao.go b/shared/types/api/pdao.go index 3eddf747a..70ec27a52 100644 --- a/shared/types/api/pdao.go +++ b/shared/types/api/pdao.go @@ -206,6 +206,33 @@ type ProposePDAOSettingResponse struct { TxHash common.Hash `json:"txHash"` } +type PDAOBatchSetting struct { + Contract string `json:"contract"` + Setting string `json:"setting"` + Type string `json:"type,omitempty"` + Value string `json:"value"` +} + +type CanProposePDAOSettingMultiResponse struct { + Status string `json:"status"` + Error string `json:"error"` + CanPropose bool `json:"canPropose"` + InsufficientRpl bool `json:"proposalCooldownActive"` + StakedRpl *big.Int `json:"stakedRpl"` + LockedRpl *big.Int `json:"lockedRpl"` + ProposalBond *big.Int `json:"proposalBond"` + BlockNumber uint32 `json:"blockNumber"` + GasLimits gaslimit.Limits `json:"gasLimits"` + IsRplLockingDisallowed bool `json:"isRplLockingDisallowed"` +} + +type ProposePDAOSettingMultiResponse struct { + Status string `json:"status"` + Error string `json:"error"` + ProposalId uint64 `json:"proposalId"` + TxHash common.Hash `json:"txHash"` +} + type PDAOGetRewardsPercentagesResponse struct { Status string `json:"status"` Error string `json:"error"` From 42d973d6eb187a8046229f4768f7634b6d15dbac Mon Sep 17 00:00:00 2001 From: Fornax <23104993+fornax2@users.noreply.github.com> Date: Fri, 14 Aug 2026 10:05:53 -0300 Subject: [PATCH 2/3] Print helper message --- README.md | 2 +- bindings/settings/protocol/setting-types.go | 3 +- rocketpool-cli/pdao/commands.go | 313 ++++++++++---------- rocketpool-cli/pdao/propose-settings.go | 302 +++++++++---------- rocketpool-cli/pdao/set-allow-list.go | 4 +- rocketpool-cli/pdao/submit-batch.go | 36 +++ 6 files changed, 350 insertions(+), 310 deletions(-) diff --git a/README.md b/README.md index b2ebbe0ba..a3d385845 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ The following commands are available via the Smart Node client: - `rocketpool pdao claim-bonds, cb` - Unlock any bonded RPL you have for a proposal or set of challenges, and claim any bond rewards for defending or defeating the proposal - `rocketpool pdao propose, p` - Make a Protocol DAO proposal - `rocketpool pdao propose submit-batch, sb` - Submit a single proposal that changes multiple Protocol DAO settings from a JSON file - - Setting propose commands accept `--generate-json ` to write/append a setting change to a JSON file instead of submitting a transaction + - Setting propose commands accept `--to-json ` to write/append a setting change to a JSON file instead of submitting a transaction - `rocketpool pdao proposals, o` - Manage Protocol DAO proposals - **queue**, q - Manage the Rocket Pool deposit queue - `rocketpool queue status, s` - Get the deposit pool and minipool queue status diff --git a/bindings/settings/protocol/setting-types.go b/bindings/settings/protocol/setting-types.go index 506870055..f9b383a75 100644 --- a/bindings/settings/protocol/setting-types.go +++ b/bindings/settings/protocol/setting-types.go @@ -7,14 +7,13 @@ import ( "github.com/rocket-pool/smartnode/bindings/types" ) -// Proposal setting type names written to --generate-json files. +// Proposal setting type names written to --to-json files. const ( ProposalSettingTypeNameUint256 = "uint256" ProposalSettingTypeNameBool = "bool" ProposalSettingTypeNameAddress = "address" ) -// Errors for settings that cannot be encoded into a proposalSettingMulti payload. var ( ErrUnknownPDAOSetting = fmt.Errorf("unknown protocol DAO setting") ErrUnsupportedBatchSetting = fmt.Errorf("setting type is not supported in a multi-setting proposal") diff --git a/rocketpool-cli/pdao/commands.go b/rocketpool-cli/pdao/commands.go index 1337acee7..ced958c67 100644 --- a/rocketpool-cli/pdao/commands.go +++ b/rocketpool-cli/pdao/commands.go @@ -558,7 +558,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -574,7 +574,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionIsCreateLotEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionIsCreateLotEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -591,7 +591,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -607,7 +607,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionIsBidOnLotEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionIsBidOnLotEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -628,7 +628,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -644,7 +644,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotMinimumEthValue(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionLotMinimumEthValue(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -665,7 +665,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -681,7 +681,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotMaximumEthValue(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionLotMaximumEthValue(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -698,7 +698,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -714,7 +714,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotDuration(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionLotDuration(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -735,7 +735,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -751,7 +751,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotStartingPriceRatio(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionLotStartingPriceRatio(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -772,7 +772,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -788,7 +788,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingAuctionLotReservePriceRatio(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingAuctionLotReservePriceRatio(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -813,7 +813,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -829,7 +829,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositIsDepositingEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositIsDepositingEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -846,7 +846,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -862,7 +862,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositAreDepositAssignmentsEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositAreDepositAssignmentsEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -883,7 +883,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -899,7 +899,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMinimumDeposit(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositMinimumDeposit(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -920,7 +920,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -936,7 +936,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMaximumDepositPoolSize(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositMaximumDepositPoolSize(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -953,7 +953,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -969,7 +969,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMaximumAssignmentsPerDeposit(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositMaximumAssignmentsPerDeposit(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -986,7 +986,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1002,7 +1002,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1023,7 +1023,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1039,7 +1039,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositDepositFee(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositDepositFee(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1056,7 +1056,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1071,7 +1071,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositExpressQueueRate(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositExpressQueueRate(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1088,7 +1088,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1103,7 +1103,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingDepositExpressQueueTicketsBaseProvision(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingDepositExpressQueueTicketsBaseProvision(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1128,7 +1128,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1144,7 +1144,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolIsSubmitWithdrawableEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMinipoolIsSubmitWithdrawableEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1161,7 +1161,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1177,7 +1177,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolLaunchTimeout(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMinipoolLaunchTimeout(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1194,7 +1194,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1210,7 +1210,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolIsBondReductionEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMinipoolIsBondReductionEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1227,7 +1227,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1243,7 +1243,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolMaximumCount(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMinipoolMaximumCount(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1260,7 +1260,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1276,7 +1276,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolUserDistributeWindowStart(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMinipoolUserDistributeWindowStart(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1293,7 +1293,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1309,7 +1309,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMinipoolUserDistributeWindowLength(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMinipoolUserDistributeWindowLength(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1338,7 +1338,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1354,7 +1354,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkOracleDaoConsensusThreshold(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkOracleDaoConsensusThreshold(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1375,7 +1375,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1391,7 +1391,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkNodePenaltyThreshold(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkNodePenaltyThreshold(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1412,7 +1412,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1428,7 +1428,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkPerPenaltyRate(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkPerPenaltyRate(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1445,7 +1445,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1461,7 +1461,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkIsSubmitBalancesEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkIsSubmitBalancesEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1478,7 +1478,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1494,7 +1494,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkSubmitBalancesFrequency(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkSubmitBalancesFrequency(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1511,7 +1511,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1527,7 +1527,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkIsSubmitPricesEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkIsSubmitPricesEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1544,7 +1544,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1560,7 +1560,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkSubmitPricesFrequency(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkSubmitPricesFrequency(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1581,7 +1581,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1597,7 +1597,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkMinimumNodeFee(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkMinimumNodeFee(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1618,7 +1618,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1634,7 +1634,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkTargetNodeFee(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkTargetNodeFee(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1655,7 +1655,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1671,7 +1671,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkMaximumNodeFee(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkMaximumNodeFee(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1692,7 +1692,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1708,7 +1708,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkNodeFeeDemandRange(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkNodeFeeDemandRange(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1729,7 +1729,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1745,7 +1745,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkTargetRethCollateralRate(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkTargetRethCollateralRate(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1762,7 +1762,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1778,7 +1778,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNetworkIsSubmitRewardsEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNetworkIsSubmitRewardsEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1795,7 +1795,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, &cli.StringFlag{ @@ -1810,7 +1810,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { return err } // Run - return setAllowListedControllers(c.String("addressList"), c.Bool("yes"), c.String("generate-json")) + return setAllowListedControllers(c.String("addressList"), c.Bool("yes"), c.String("to-json")) }, }, @@ -1831,7 +1831,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1847,7 +1847,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeCommissionShare(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeCommissionShare(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1868,7 +1868,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1884,7 +1884,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeCommissionShareSecurityCouncilAdder(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeCommissionShareSecurityCouncilAdder(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1905,7 +1905,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1921,7 +1921,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingVoterShare(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingVoterShare(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1942,7 +1942,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1958,7 +1958,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingPDAOShare(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingPDAOShare(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -1979,7 +1979,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -1995,7 +1995,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeMaxNodeShareSecurityCouncilAdder(value, c.Bool("yes"), c.String("generate-json")) + return proposeMaxNodeShareSecurityCouncilAdder(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2016,7 +2016,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2032,7 +2032,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeMaxRethBalanceDelta(value, c.Bool("yes"), c.String("generate-json")) + return proposeMaxRethBalanceDelta(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2057,7 +2057,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2073,7 +2073,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeIsRegistrationEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeIsRegistrationEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2090,7 +2090,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2106,7 +2106,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2123,7 +2123,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2139,7 +2139,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeIsDepositingEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeIsDepositingEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2156,7 +2156,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2172,7 +2172,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeAreVacantMinipoolsEnabled(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeAreVacantMinipoolsEnabled(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2193,7 +2193,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2209,7 +2209,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeMinimumPerMinipoolStake(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeMinimumPerMinipoolStake(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2230,7 +2230,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2246,7 +2246,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeMaximumPerMinipoolStake(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeMaximumPerMinipoolStake(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2267,7 +2267,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2283,7 +2283,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeMinimumLegacyRplStake(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeMinimumLegacyRplStake(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2304,7 +2304,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2320,7 +2320,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingReducedBond(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingReducedBond(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2337,7 +2337,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2353,7 +2353,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingNodeUnstakingPeriod(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingNodeUnstakingPeriod(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2378,7 +2378,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2394,7 +2394,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVotePhase1Time(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsVotePhase1Time(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2411,7 +2411,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2427,7 +2427,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVotePhase2Time(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsVotePhase2Time(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2444,7 +2444,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2460,7 +2460,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVoteDelayTime(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsVoteDelayTime(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2477,7 +2477,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2493,7 +2493,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsExecuteTime(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsExecuteTime(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2514,7 +2514,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2530,7 +2530,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsProposalBond(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsProposalBond(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2551,7 +2551,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2567,7 +2567,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsChallengeBond(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsChallengeBond(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2584,7 +2584,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2600,7 +2600,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsChallengePeriod(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsChallengePeriod(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2621,7 +2621,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2637,7 +2637,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsQuorum(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsQuorum(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2658,7 +2658,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2674,7 +2674,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsVetoQuorum(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsVetoQuorum(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2691,7 +2691,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2707,7 +2707,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingProposalsMaxBlockAge(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingProposalsMaxBlockAge(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2732,7 +2732,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2748,7 +2748,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingRewardsIntervalPeriods(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingRewardsIntervalPeriods(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2777,7 +2777,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2793,7 +2793,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityMembersQuorum(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingSecurityMembersQuorum(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2810,7 +2810,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2826,7 +2826,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityMembersLeaveTime(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingSecurityMembersLeaveTime(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2843,7 +2843,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2859,7 +2859,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityProposalVoteTime(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingSecurityProposalVoteTime(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2876,7 +2876,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2892,7 +2892,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityProposalExecuteTime(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingSecurityProposalExecuteTime(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2909,7 +2909,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2925,7 +2925,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingSecurityProposalActionTime(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingSecurityProposalActionTime(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2950,7 +2950,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -2966,7 +2966,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolTimeBeforeDissolve(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMegapoolTimeBeforeDissolve(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -2987,7 +2987,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3003,7 +3003,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMaximumMegapoolEthPenalty(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMaximumMegapoolEthPenalty(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3020,7 +3020,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3036,7 +3036,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolNotifyThreshold(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMegapoolNotifyThreshold(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3057,7 +3057,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3073,7 +3073,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolLateNotifyFine(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMegapoolLateNotifyFine(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3090,7 +3090,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3106,7 +3106,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolDissolvePenalty(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMegapoolDissolvePenalty(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3123,7 +3123,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3138,7 +3138,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolUserDistributeDelay(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMegapoolUserDistributeDelay(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3155,7 +3155,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3170,7 +3170,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingMegapoolUserDistributeDelayWithShortfall(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingMegapoolUserDistributeDelayWithShortfall(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3191,7 +3191,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Usage: "Automatically confirm all interactive questions", }, &cli.StringFlag{ - Name: "generate-json", + Name: "to-json", Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", }, }, @@ -3207,7 +3207,7 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { } // Run - return proposeSettingPenaltyThreshold(value, c.Bool("yes"), c.String("generate-json")) + return proposeSettingPenaltyThreshold(value, c.Bool("yes"), c.String("to-json")) }, }, @@ -3219,14 +3219,19 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { { Name: "submit-batch", Aliases: []string{"sb"}, - Usage: "Submit a single proposal that changes multiple Protocol DAO settings from a JSON file created with --generate-json", - UsageText: "rocketpool pdao propose submit-batch file", + Usage: "Submit a single proposal that changes multiple Protocol DAO settings from a JSON file created with --to-json", + UsageText: "rocketpool pdao propose submit-batch", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "yes", Aliases: []string{"y"}, Usage: "Automatically confirm all interactive questions", }, + &cli.StringFlag{ + Name: "file", + Aliases: []string{"f"}, + Usage: "The JSON file of setting changes created with --to-json. If omitted, you will be prompted.", + }, &cli.StringFlag{ Name: "message", Aliases: []string{"m"}, @@ -3236,12 +3241,12 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { Action: func(ctx context.Context, c *cli.Command) error { // Validate args - if err := cliutils.ValidateArgCount(c, 1); err != nil { + if err := cliutils.ValidateArgCount(c, 0); err != nil { return err } // Run - return submitBatch(c.Args().Get(0), c.String("message"), c.Bool("yes")) + return submitBatch(c.String("file"), c.String("message"), c.Bool("yes")) }, }, diff --git a/rocketpool-cli/pdao/propose-settings.go b/rocketpool-cli/pdao/propose-settings.go index 0f6b68dab..e1b4f9407 100644 --- a/rocketpool-cli/pdao/propose-settings.go +++ b/rocketpool-cli/pdao/propose-settings.go @@ -16,385 +16,385 @@ import ( "github.com/rocket-pool/smartnode/rocketpool-cli/cli/prompt" ) -func proposeSettingAuctionIsCreateLotEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingAuctionIsCreateLotEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.CreateLotEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingAuctionIsBidOnLotEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingAuctionIsBidOnLotEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.AuctionSettingsContractName, protocol.BidOnLotEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.BidOnLotEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingAuctionLotMinimumEthValue(value *big.Int, yes bool, generateJson string) error { +func proposeSettingAuctionLotMinimumEthValue(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMinimumEthValueSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMinimumEthValueSettingPath, trueValue, yes, toJson) } -func proposeSettingAuctionLotMaximumEthValue(value *big.Int, yes bool, generateJson string) error { +func proposeSettingAuctionLotMaximumEthValue(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMaximumEthValueSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotMaximumEthValueSettingPath, trueValue, yes, toJson) } -func proposeSettingAuctionLotDuration(value time.Duration, yes bool, generateJson string) error { +func proposeSettingAuctionLotDuration(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotDurationSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotDurationSettingPath, trueValue, yes, toJson) } -func proposeSettingAuctionLotStartingPriceRatio(value *big.Int, yes bool, generateJson string) error { +func proposeSettingAuctionLotStartingPriceRatio(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotStartingPriceRatioSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotStartingPriceRatioSettingPath, trueValue, yes, toJson) } -func proposeSettingAuctionLotReservePriceRatio(value *big.Int, yes bool, generateJson string) error { +func proposeSettingAuctionLotReservePriceRatio(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotReservePriceRatioSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.AuctionSettingsContractName, protocol.LotReservePriceRatioSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositIsDepositingEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingDepositIsDepositingEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositAreDepositAssignmentsEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingDepositAreDepositAssignmentsEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.AssignDepositsEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.AssignDepositsEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositMinimumDeposit(value *big.Int, yes bool, generateJson string) error { +func proposeSettingDepositMinimumDeposit(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.DepositSettingsContractName, protocol.MinimumDepositSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MinimumDepositSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositMaximumDepositPoolSize(value *big.Int, yes bool, generateJson string) error { +func proposeSettingDepositMaximumDepositPoolSize(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositPoolSizeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositPoolSizeSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositMaximumAssignmentsPerDeposit(value uint64, yes bool, generateJson string) error { +func proposeSettingDepositMaximumAssignmentsPerDeposit(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositAssignmentsSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumDepositAssignmentsSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value uint64, yes bool, generateJson string) error { +func proposeSettingDepositMaximumSocialisedAssignmentsPerDeposit(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumSocializedDepositAssignmentsSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.MaximumSocializedDepositAssignmentsSettingPath, trueValue, yes, toJson) } -func proposeSettingDepositExpressQueueRate(value uint64, yes bool, generateJson string) error { +func proposeSettingDepositExpressQueueRate(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueRatePath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueRatePath, trueValue, yes, toJson) } -func proposeSettingDepositExpressQueueTicketsBaseProvision(value uint64, yes bool, generateJson string) error { +func proposeSettingDepositExpressQueueTicketsBaseProvision(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueTicketsBaseProvisionPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.ExpressQueueTicketsBaseProvisionPath, trueValue, yes, toJson) } -func proposeSettingDepositDepositFee(value *big.Int, yes bool, generateJson string) error { +func proposeSettingDepositDepositFee(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositFeeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.DepositSettingsContractName, protocol.DepositFeeSettingPath, trueValue, yes, toJson) } -func proposeSettingMinipoolIsSubmitWithdrawableEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingMinipoolIsSubmitWithdrawableEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolSubmitWithdrawableEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolSubmitWithdrawableEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingMinipoolLaunchTimeout(value time.Duration, yes bool, generateJson string) error { +func proposeSettingMinipoolLaunchTimeout(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolLaunchTimeoutSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolLaunchTimeoutSettingPath, trueValue, yes, toJson) } -func proposeSettingMinipoolIsBondReductionEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingMinipoolIsBondReductionEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.BondReductionEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.BondReductionEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingMinipoolMaximumCount(value uint64, yes bool, generateJson string) error { +func proposeSettingMinipoolMaximumCount(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MaximumMinipoolCountSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MaximumMinipoolCountSettingPath, trueValue, yes, toJson) } -func proposeSettingMinipoolUserDistributeWindowStart(value time.Duration, yes bool, generateJson string) error { +func proposeSettingMinipoolUserDistributeWindowStart(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowStartSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowStartSettingPath, trueValue, yes, toJson) } -func proposeSettingMinipoolUserDistributeWindowLength(value time.Duration, yes bool, generateJson string) error { +func proposeSettingMinipoolUserDistributeWindowLength(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowLengthSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MinipoolSettingsContractName, protocol.MinipoolUserDistributeWindowLengthSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkOracleDaoConsensusThreshold(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkOracleDaoConsensusThreshold(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeConsensusThresholdSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeConsensusThresholdSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkNodePenaltyThreshold(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkNodePenaltyThreshold(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyThresholdSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyThresholdSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkPerPenaltyRate(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkPerPenaltyRate(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyPerRateSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPenaltyPerRateSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkIsSubmitBalancesEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNetworkIsSubmitBalancesEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkSubmitBalancesFrequency(value time.Duration, yes bool, generateJson string) error { +func proposeSettingNetworkSubmitBalancesFrequency(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesFrequencySettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitBalancesFrequencySettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkIsSubmitPricesEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNetworkIsSubmitPricesEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkSubmitPricesFrequency(value time.Duration, yes bool, generateJson string) error { +func proposeSettingNetworkSubmitPricesFrequency(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesFrequencySettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitPricesFrequencySettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkMinimumNodeFee(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkMinimumNodeFee(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.MinimumNodeFeeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.MinimumNodeFeeSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkTargetNodeFee(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkTargetNodeFee(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetNodeFeeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetNodeFeeSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkMaximumNodeFee(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkMaximumNodeFee(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.MaximumNodeFeeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.MaximumNodeFeeSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkNodeFeeDemandRange(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkNodeFeeDemandRange(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeFeeDemandRangeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NodeFeeDemandRangeSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkTargetRethCollateralRate(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNetworkTargetRethCollateralRate(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetRethCollateralRateSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.TargetRethCollateralRateSettingPath, trueValue, yes, toJson) } -func proposeSettingNetworkIsSubmitRewardsEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNetworkIsSubmitRewardsEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitRewardsEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.SubmitRewardsEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeIsRegistrationEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNodeIsRegistrationEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeRegistrationEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeRegistrationEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNodeIsSmoothingPoolRegistrationEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.SmoothingPoolRegistrationEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.SmoothingPoolRegistrationEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeIsDepositingEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNodeIsDepositingEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeDepositEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeDepositEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeAreVacantMinipoolsEnabled(value bool, yes bool, generateJson string) error { +func proposeSettingNodeAreVacantMinipoolsEnabled(value bool, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.NodeSettingsContractName, protocol.VacantMinipoolsEnabledSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.VacantMinipoolsEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeMinimumPerMinipoolStake(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNodeMinimumPerMinipoolStake(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol131.MinimumPerMinipoolStakeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol131.MinimumPerMinipoolStakeSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeMaximumPerMinipoolStake(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNodeMaximumPerMinipoolStake(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol131.MaximumPerMinipoolStakeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol131.MaximumPerMinipoolStakeSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeMinimumLegacyRplStake(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNodeMinimumLegacyRplStake(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol.MinimumLegacyRplStakePath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.MinimumLegacyRplStakePath, trueValue, yes, toJson) } -func proposeSettingReducedBond(value *big.Int, yes bool, generateJson string) error { +func proposeSettingReducedBond(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol.ReducedBondSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.ReducedBondSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeUnstakingPeriod(value time.Duration, yes bool, generateJson string) error { +func proposeSettingNodeUnstakingPeriod(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeUnstakingPeriodSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NodeSettingsContractName, protocol.NodeUnstakingPeriodSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsVotePhase1Time(value time.Duration, yes bool, generateJson string) error { +func proposeSettingProposalsVotePhase1Time(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase1TimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase1TimeSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsVotePhase2Time(value time.Duration, yes bool, generateJson string) error { +func proposeSettingProposalsVotePhase2Time(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase2TimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VotePhase2TimeSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsVoteDelayTime(value time.Duration, yes bool, generateJson string) error { +func proposeSettingProposalsVoteDelayTime(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VoteDelayTimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.VoteDelayTimeSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsExecuteTime(value time.Duration, yes bool, generateJson string) error { +func proposeSettingProposalsExecuteTime(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ExecuteTimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ExecuteTimeSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsProposalBond(value *big.Int, yes bool, generateJson string) error { +func proposeSettingProposalsProposalBond(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalBondSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalBondSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsChallengeBond(value *big.Int, yes bool, generateJson string) error { +func proposeSettingProposalsChallengeBond(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengeBondSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengeBondSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsChallengePeriod(value time.Duration, yes bool, generateJson string) error { +func proposeSettingProposalsChallengePeriod(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengePeriodSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ChallengePeriodSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsQuorum(value *big.Int, yes bool, generateJson string) error { +func proposeSettingProposalsQuorum(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalQuorumSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalQuorumSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsVetoQuorum(value *big.Int, yes bool, generateJson string) error { +func proposeSettingProposalsVetoQuorum(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalVetoQuorumSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalVetoQuorumSettingPath, trueValue, yes, toJson) } -func proposeSettingProposalsMaxBlockAge(value uint64, yes bool, generateJson string) error { +func proposeSettingProposalsMaxBlockAge(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalMaxBlockAgeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.ProposalsSettingsContractName, protocol.ProposalMaxBlockAgeSettingPath, trueValue, yes, toJson) } -func proposeSettingRewardsIntervalPeriods(value uint64, yes bool, generateJson string) error { +func proposeSettingRewardsIntervalPeriods(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.RewardsSettingsContractName, protocol.RewardsClaimIntervalPeriodsSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.RewardsSettingsContractName, protocol.RewardsClaimIntervalPeriodsSettingPath, trueValue, yes, toJson) } -func proposeSettingSecurityMembersQuorum(value *big.Int, yes bool, generateJson string) error { +func proposeSettingSecurityMembersQuorum(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersQuorumSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersQuorumSettingPath, trueValue, yes, toJson) } -func proposeSettingSecurityMembersLeaveTime(value time.Duration, yes bool, generateJson string) error { +func proposeSettingSecurityMembersLeaveTime(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersLeaveTimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityMembersLeaveTimeSettingPath, trueValue, yes, toJson) } -func proposeSettingSecurityProposalVoteTime(value time.Duration, yes bool, generateJson string) error { +func proposeSettingSecurityProposalVoteTime(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalVoteTimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalVoteTimeSettingPath, trueValue, yes, toJson) } -func proposeSettingSecurityProposalExecuteTime(value time.Duration, yes bool, generateJson string) error { +func proposeSettingSecurityProposalExecuteTime(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalExecuteTimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalExecuteTimeSettingPath, trueValue, yes, toJson) } -func proposeSettingSecurityProposalActionTime(value time.Duration, yes bool, generateJson string) error { +func proposeSettingSecurityProposalActionTime(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalActionTimeSettingPath, trueValue, yes, generateJson) + return proposeSetting(protocol.SecuritySettingsContractName, protocol.SecurityProposalActionTimeSettingPath, trueValue, yes, toJson) } -func proposeSettingMegapoolTimeBeforeDissolve(value time.Duration, yes bool, generateJson string) error { +func proposeSettingMegapoolTimeBeforeDissolve(value time.Duration, yes bool, toJson string) error { trueValue := fmt.Sprint(uint64(value.Seconds())) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolTimeBeforeDissolveSettingsPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolTimeBeforeDissolveSettingsPath, trueValue, yes, toJson) } -func proposeSettingMaximumMegapoolEthPenalty(value *big.Int, yes bool, generateJson string) error { +func proposeSettingMaximumMegapoolEthPenalty(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolMaximumMegapoolEthPenaltyPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolMaximumMegapoolEthPenaltyPath, trueValue, yes, toJson) } -func proposeSettingMegapoolNotifyThreshold(value uint64, yes bool, generateJson string) error { +func proposeSettingMegapoolNotifyThreshold(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolNotifyThresholdPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolNotifyThresholdPath, trueValue, yes, toJson) } -func proposeSettingMegapoolLateNotifyFine(value *big.Int, yes bool, generateJson string) error { +func proposeSettingMegapoolLateNotifyFine(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolLateNotifyFinePath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolLateNotifyFinePath, trueValue, yes, toJson) } -func proposeSettingMegapoolDissolvePenalty(value *big.Int, yes bool, generateJson string) error { +func proposeSettingMegapoolDissolvePenalty(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolDissolvePenaltyPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolDissolvePenaltyPath, trueValue, yes, toJson) } -func proposeSettingMegapoolUserDistributeDelay(value uint64, yes bool, generateJson string) error { +func proposeSettingMegapoolUserDistributeDelay(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayPath, trueValue, yes, toJson) } -func proposeSettingMegapoolUserDistributeDelayWithShortfall(value uint64, yes bool, generateJson string) error { +func proposeSettingMegapoolUserDistributeDelayWithShortfall(value uint64, yes bool, toJson string) error { trueValue := fmt.Sprint(value) - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayShortfallPath, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolUserDistributeDelayShortfallPath, trueValue, yes, toJson) } -func proposeSettingPenaltyThreshold(value *big.Int, yes bool, generateJson string) error { +func proposeSettingPenaltyThreshold(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolPenaltyThreshold, trueValue, yes, generateJson) + return proposeSetting(protocol.MegapoolSettingsContractName, protocol.MegapoolPenaltyThreshold, trueValue, yes, toJson) } -func proposeSettingNodeCommissionShare(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNodeCommissionShare(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionSharePath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionSharePath, trueValue, yes, toJson) } -func proposeSettingNodeCommissionShareSecurityCouncilAdder(value *big.Int, yes bool, generateJson string) error { +func proposeSettingNodeCommissionShareSecurityCouncilAdder(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionShareSecurityCouncilAdderPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkNodeCommissionShareSecurityCouncilAdderPath, trueValue, yes, toJson) } -func proposeSettingVoterShare(value *big.Int, yes bool, generateJson string) error { +func proposeSettingVoterShare(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkVoterSharePath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkVoterSharePath, trueValue, yes, toJson) } -func proposeSettingPDAOShare(value *big.Int, yes bool, generateJson string) error { +func proposeSettingPDAOShare(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPDAOSharePath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkPDAOSharePath, trueValue, yes, toJson) } -func proposeMaxNodeShareSecurityCouncilAdder(value *big.Int, yes bool, generateJson string) error { +func proposeMaxNodeShareSecurityCouncilAdder(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxNodeShareSecurityCouncilAdderPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxNodeShareSecurityCouncilAdderPath, trueValue, yes, toJson) } -func proposeMaxRethBalanceDelta(value *big.Int, yes bool, generateJson string) error { +func proposeMaxRethBalanceDelta(value *big.Int, yes bool, toJson string) error { trueValue := value.String() - return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxRethBalanceDeltaPath, trueValue, yes, generateJson) + return proposeSetting(protocol.NetworkSettingsContractName, protocol.NetworkMaxRethBalanceDeltaPath, trueValue, yes, toJson) } // Master general proposal function -func proposeSetting(contract string, setting string, value string, yes bool, generateJson string) error { +func proposeSetting(contract string, setting string, value string, yes bool, toJson string) error { if protocol.IsHoustonOnlySetting(setting) { fmt.Println("This command no longer available in Saturn.") return nil } - if generateJson != "" { - return writeSettingToBatchJSON(generateJson, contract, setting, value) + if toJson != "" { + return writeSettingToBatchJSON(toJson, contract, setting, value) } // Get RP client diff --git a/rocketpool-cli/pdao/set-allow-list.go b/rocketpool-cli/pdao/set-allow-list.go index 4e9f4dbf5..b7ba7cdf8 100644 --- a/rocketpool-cli/pdao/set-allow-list.go +++ b/rocketpool-cli/pdao/set-allow-list.go @@ -12,8 +12,8 @@ import ( "github.com/rocket-pool/smartnode/shared/services/rocketpool" ) -func setAllowListedControllers(addressListStr string, yes bool, generateJson string) error { - if generateJson != "" { +func setAllowListedControllers(addressListStr string, yes bool, toJson string) error { + if toJson != "" { return fmt.Errorf("allow-listed-controllers cannot be included in a multi-setting proposal (the protocol only supports bool, uint256, and address values in batch proposals)") } diff --git a/rocketpool-cli/pdao/submit-batch.go b/rocketpool-cli/pdao/submit-batch.go index 1f98747c7..4010196a4 100644 --- a/rocketpool-cli/pdao/submit-batch.go +++ b/rocketpool-cli/pdao/submit-batch.go @@ -12,7 +12,43 @@ import ( "github.com/rocket-pool/smartnode/shared/services/rocketpool" ) +func printSubmitBatchHelp() { + fmt.Print(`submit-batch creates one Protocol DAO proposal that changes multiple settings. + +Build a JSON file with --to-json on the usual setting propose commands (creates the file or appends; the same contract+setting is replaced): + + rocketpool pdao propose setting auction is-create-lot-enabled true --to-json settings.json + rocketpool pdao propose setting deposit minimum-deposit 1.0 --to-json settings.json + +Submit that file as a single proposal: + + rocketpool pdao propose submit-batch --file settings.json + +The file is a JSON array. Each object is one setting: + +[ + { + "contract": "rocketDAOProtocolSettingsAuction", + "setting": "auction.lot.create.enabled", + "type": "bool", + "value": "true" + }, + { + "contract": "rocketDAOProtocolSettingsDeposit", + "setting": "deposit.minimum", + "type": "uint256", + "value": "1000000000000000000" + } +] +`) +} + func submitBatch(file string, message string, yes bool) error { + if file == "" { + printSubmitBatchHelp() + file = prompt.Prompt("Please enter the path to the JSON file:", "^.+$", "Invalid file path") + } + settings, err := readBatchSettingsFile(file) if err != nil { return err From d02107261fd5f93497e60c3ef77b0aff1be56c09 Mon Sep 17 00:00:00 2001 From: Fornax <23104993+fornax2@users.noreply.github.com> Date: Fri, 14 Aug 2026 10:18:38 -0300 Subject: [PATCH 3/3] Remove stale settings --- bindings/settings/protocol/setting-types.go | 33 ++------- rocketpool-cli/pdao/commands.go | 75 --------------------- rocketpool-cli/pdao/propose-settings.go | 16 ----- rocketpool/api/node/status.go | 4 +- rocketpool/api/pdao/propose-settings.go | 42 ------------ shared/types/api/pdao.go | 2 - 6 files changed, 9 insertions(+), 163 deletions(-) diff --git a/bindings/settings/protocol/setting-types.go b/bindings/settings/protocol/setting-types.go index f9b383a75..f90efa86f 100644 --- a/bindings/settings/protocol/setting-types.go +++ b/bindings/settings/protocol/setting-types.go @@ -3,7 +3,6 @@ package protocol import ( "fmt" - protocol131 "github.com/rocket-pool/smartnode/bindings/legacy/v1.3.1/protocol" "github.com/rocket-pool/smartnode/bindings/types" ) @@ -17,7 +16,6 @@ const ( var ( ErrUnknownPDAOSetting = fmt.Errorf("unknown protocol DAO setting") ErrUnsupportedBatchSetting = fmt.Errorf("setting type is not supported in a multi-setting proposal") - ErrHoustonOnlySetting = fmt.Errorf("setting is no longer available after Saturn") ErrDuplicateBatchSetting = fmt.Errorf("duplicate setting in multi-setting proposal") ErrEmptyBatchSettings = fmt.Errorf("multi-setting proposal must contain at least one setting") ) @@ -86,15 +84,13 @@ var pdaoSettingKinds = map[string]map[string]settingKind{ NetworkMaxRethBalanceDeltaPath: settingKindUint256, }, NodeSettingsContractName: { - NodeRegistrationEnabledSettingPath: settingKindBool, - SmoothingPoolRegistrationEnabledSettingPath: settingKindBool, - NodeDepositEnabledSettingPath: settingKindBool, - VacantMinipoolsEnabledSettingPath: settingKindBool, - protocol131.MinimumPerMinipoolStakeSettingPath: settingKindUint256, - protocol131.MaximumPerMinipoolStakeSettingPath: settingKindUint256, - MinimumLegacyRplStakePath: settingKindUint256, - ReducedBondSettingPath: settingKindUint256, - NodeUnstakingPeriodSettingPath: settingKindUint256, + NodeRegistrationEnabledSettingPath: settingKindBool, + SmoothingPoolRegistrationEnabledSettingPath: settingKindBool, + NodeDepositEnabledSettingPath: settingKindBool, + VacantMinipoolsEnabledSettingPath: settingKindBool, + MinimumLegacyRplStakePath: settingKindUint256, + ReducedBondSettingPath: settingKindUint256, + NodeUnstakingPeriodSettingPath: settingKindUint256, }, ProposalsSettingsContractName: { VotePhase1TimeSettingPath: settingKindUint256, @@ -130,18 +126,6 @@ var pdaoSettingKinds = map[string]map[string]settingKind{ }, } -// houstonOnlySettings cannot be proposed after the Saturn upgrade. -var houstonOnlySettings = map[string]struct{}{ - protocol131.MinimumPerMinipoolStakeSettingPath: {}, - protocol131.MaximumPerMinipoolStakeSettingPath: {}, -} - -// IsHoustonOnlySetting reports whether the setting existed only on Houston 1.3.1. -func IsHoustonOnlySetting(setting string) bool { - _, exists := houstonOnlySettings[setting] - return exists -} - // GetProposalSettingType returns the on-chain type used by proposalSettingMulti // for the given contract/setting pair. func GetProposalSettingType(contract string, setting string) (types.ProposalSettingType, error) { @@ -153,9 +137,6 @@ func GetProposalSettingType(contract string, setting string) (types.ProposalSett if !ok { return 0, fmt.Errorf("%w: [%s - %s]", ErrUnknownPDAOSetting, contract, setting) } - if IsHoustonOnlySetting(setting) { - return 0, fmt.Errorf("%w: %s", ErrHoustonOnlySetting, setting) - } switch kind { case settingKindUint256: return types.ProposalSettingType_Uint256, nil diff --git a/rocketpool-cli/pdao/commands.go b/rocketpool-cli/pdao/commands.go index ced958c67..edbe0e057 100644 --- a/rocketpool-cli/pdao/commands.go +++ b/rocketpool-cli/pdao/commands.go @@ -6,7 +6,6 @@ import ( "github.com/urfave/cli/v3" - protocol131 "github.com/rocket-pool/smartnode/bindings/legacy/v1.3.1/protocol" "github.com/rocket-pool/smartnode/bindings/settings/protocol" cliutils "github.com/rocket-pool/smartnode/rocketpool-cli/cli" ) @@ -2177,80 +2176,6 @@ func RegisterCommands(app *cli.Command, name string, aliases []string) { }, }, - { - Name: "minimum-per-minipool-stake", - Aliases: []string{"minpms"}, - Usage: fmt.Sprintf("Propose updating the %s setting; %s", protocol131.MinimumPerMinipoolStakeSettingPath, unboundedPercentUsage), - UsageText: "rocketpool pdao propose setting node minimum-per-minipool-stake value", - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "raw", - Usage: "Add this flag if your setting is an 18-decimal-fixed-point-integer (wei) value instead of a float", - }, - &cli.BoolFlag{ - Name: "yes", - Aliases: []string{"y"}, - Usage: "Automatically confirm all interactive questions", - }, - &cli.StringFlag{ - Name: "to-json", - Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", - }, - }, - Action: func(ctx context.Context, c *cli.Command) error { - - // Validate args - if err := cliutils.ValidateArgCount(c, 1); err != nil { - return err - } - value, err := cliutils.ValidateFloat(c.Bool("raw"), "value", c.Args().Get(0), false, c.Bool("yes")) - if err != nil { - return err - } - - // Run - return proposeSettingNodeMinimumPerMinipoolStake(value, c.Bool("yes"), c.String("to-json")) - - }, - }, - - { - Name: "maximum-per-minipool-stake", - Aliases: []string{"maxpms"}, - Usage: fmt.Sprintf("Propose updating the %s setting; %s", protocol131.MaximumPerMinipoolStakeSettingPath, unboundedPercentUsage), - UsageText: "rocketpool pdao propose setting node maximum-per-minipool-stake value", - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "raw", - Usage: "Add this flag if your setting is an 18-decimal-fixed-point-integer (wei) value instead of a float", - }, - &cli.BoolFlag{ - Name: "yes", - Aliases: []string{"y"}, - Usage: "Automatically confirm all interactive questions", - }, - &cli.StringFlag{ - Name: "to-json", - Usage: "Write this setting to a JSON file instead of submitting a proposal (creates the file or appends to it)", - }, - }, - Action: func(ctx context.Context, c *cli.Command) error { - - // Validate args - if err := cliutils.ValidateArgCount(c, 1); err != nil { - return err - } - value, err := cliutils.ValidateFloat(c.Bool("raw"), "value", c.Args().Get(0), false, c.Bool("yes")) - if err != nil { - return err - } - - // Run - return proposeSettingNodeMaximumPerMinipoolStake(value, c.Bool("yes"), c.String("to-json")) - - }, - }, - { Name: "minimum-legacy-staked-rpl", Aliases: []string{"mlsr"}, diff --git a/rocketpool-cli/pdao/propose-settings.go b/rocketpool-cli/pdao/propose-settings.go index e1b4f9407..7b3fef5e8 100644 --- a/rocketpool-cli/pdao/propose-settings.go +++ b/rocketpool-cli/pdao/propose-settings.go @@ -7,7 +7,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/settings/protocol" - protocol131 "github.com/rocket-pool/smartnode/bindings/legacy/v1.3.1/protocol" cliutils "github.com/rocket-pool/smartnode/rocketpool-cli/cli" "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services/gas" @@ -211,16 +210,6 @@ func proposeSettingNodeAreVacantMinipoolsEnabled(value bool, yes bool, toJson st return proposeSetting(protocol.NodeSettingsContractName, protocol.VacantMinipoolsEnabledSettingPath, trueValue, yes, toJson) } -func proposeSettingNodeMinimumPerMinipoolStake(value *big.Int, yes bool, toJson string) error { - trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol131.MinimumPerMinipoolStakeSettingPath, trueValue, yes, toJson) -} - -func proposeSettingNodeMaximumPerMinipoolStake(value *big.Int, yes bool, toJson string) error { - trueValue := value.String() - return proposeSetting(protocol.NodeSettingsContractName, protocol131.MaximumPerMinipoolStakeSettingPath, trueValue, yes, toJson) -} - func proposeSettingNodeMinimumLegacyRplStake(value *big.Int, yes bool, toJson string) error { trueValue := value.String() return proposeSetting(protocol.NodeSettingsContractName, protocol.MinimumLegacyRplStakePath, trueValue, yes, toJson) @@ -388,11 +377,6 @@ func proposeMaxRethBalanceDelta(value *big.Int, yes bool, toJson string) error { // Master general proposal function func proposeSetting(contract string, setting string, value string, yes bool, toJson string) error { - if protocol.IsHoustonOnlySetting(setting) { - fmt.Println("This command no longer available in Saturn.") - return nil - } - if toJson != "" { return writeSettingToBatchJSON(toJson, contract, setting, value) } diff --git a/rocketpool/api/node/status.go b/rocketpool/api/node/status.go index 4fd73d72e..d6ca3412f 100644 --- a/rocketpool/api/node/status.go +++ b/rocketpool/api/node/status.go @@ -267,7 +267,7 @@ func getStatus(c *cli.Command) (*api.NodeStatusResponse, error) { return err }) - // MinimumLegacyRPLStake and MaximumPerMinipoolStake are both used to compute the RPL amount that a node cannot fall under when withdrawing + // MinimumLegacyRPLStake is used to compute the RPL amount that a node cannot fall under when withdrawing wg.Go(func() error { var err error response.RplStakeThresholdFraction, err = protocol.GetMinimumLegacyRPLStake(rp, nil) @@ -425,7 +425,7 @@ func getStatus(c *cli.Command) (*api.NodeStatusResponse, error) { var wg2 errgroup.Group var rplStakeThresholdFraction *big.Int - // MinimumLegacyRPLStake and MaximumPerMinipoolStake are both used to compute the RPL amount that a node cannot fall under when withdrawing + // MinimumLegacyRPLStake is used to compute the RPL amount that a node cannot fall under when withdrawing wg2.Go(func() error { var err error rplStakeThresholdFraction, err = protocol.GetMinimumLegacyRPLStakeRaw(rp, nil) diff --git a/rocketpool/api/pdao/propose-settings.go b/rocketpool/api/pdao/propose-settings.go index d2593ae58..3c7a935ff 100644 --- a/rocketpool/api/pdao/propose-settings.go +++ b/rocketpool/api/pdao/propose-settings.go @@ -7,8 +7,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - protocol131 "github.com/rocket-pool/smartnode/bindings/legacy/v1.3.1/protocol" - "github.com/urfave/cli/v3" "golang.org/x/sync/errgroup" @@ -606,26 +604,6 @@ func canProposeSetting(c *cli.Command, contractName string, settingName string, if err != nil { return nil, fmt.Errorf("error estimating gas for proposing VacantMinipoolsEnabled: %w", err) } - // MinimumPerMinipoolStake - case protocol131.MinimumPerMinipoolStakeSettingPath: - newValue, err := cliutils.ValidateBigInt(valueName, value) - if err != nil { - return nil, err - } - response.GasLimits, err = protocol131.EstimateProposeMinimumPerMinipoolStakeGas(rp, newValue, blockNumber, pollard, opts) - if err != nil { - return nil, fmt.Errorf("error estimating gas for proposing MinimumPerMinipoolStake: %w", err) - } - // MaximumPerMinipoolStake - case protocol131.MaximumPerMinipoolStakeSettingPath: - newValue, err := cliutils.ValidateBigInt(valueName, value) - if err != nil { - return nil, err - } - response.GasLimits, err = protocol131.EstimateProposeMaximumPerMinipoolStakeGas(rp, newValue, blockNumber, pollard, opts) - if err != nil { - return nil, fmt.Errorf("error estimating gas for proposing MaximumPerMinipoolStake: %w", err) - } // MinimumLegacyRplStake case protocol.MinimumLegacyRplStakePath: newValue, err := cliutils.ValidateBigInt(valueName, value) @@ -1456,26 +1434,6 @@ func proposeSetting(c *cli.Command, contractName string, settingName string, val if err != nil { return nil, fmt.Errorf("error proposing VacantMinipoolsEnabled: %w", err) } - // MinimumPerMinipoolStake - case protocol131.MinimumPerMinipoolStakeSettingPath: - newValue, err := cliutils.ValidateBigInt(valueName, value) - if err != nil { - return nil, err - } - proposalID, hash, err = protocol131.ProposeMinimumPerMinipoolStake(rp, newValue, blockNumber, pollard, opts) - if err != nil { - return nil, fmt.Errorf("error proposing MinimumPerMinipoolStake: %w", err) - } - // MaximumPerMinipoolStake - case protocol131.MaximumPerMinipoolStakeSettingPath: - newValue, err := cliutils.ValidateBigInt(valueName, value) - if err != nil { - return nil, err - } - proposalID, hash, err = protocol131.ProposeMaximumPerMinipoolStake(rp, newValue, blockNumber, pollard, opts) - if err != nil { - return nil, fmt.Errorf("error proposing MaximumPerMinipoolStake: %w", err) - } // MinimumLegacyRplStake case protocol.MinimumLegacyRplStakePath: newValue, err := cliutils.ValidateBigInt(valueName, value) diff --git a/shared/types/api/pdao.go b/shared/types/api/pdao.go index 70ec27a52..b5c910d47 100644 --- a/shared/types/api/pdao.go +++ b/shared/types/api/pdao.go @@ -143,8 +143,6 @@ type GetPDAOSettingsResponse struct { IsSmoothingPoolRegistrationEnabled bool `json:"isSmoothingPoolRegistrationEnabled"` IsDepositingEnabled bool `json:"isDepositingEnabled"` AreVacantMinipoolsEnabled bool `json:"areVacantMinipoolsEnabled"` - MinimumPerMinipoolStake *big.Int `json:"minimumPerMinipoolStake"` - MaximumPerMinipoolStake *big.Int `json:"maximumPerMinipoolStake"` MinimumLegacyRplStake *big.Int `json:"minimumLegacyRplStake"` ReducedBond float64 `json:"reducedBond"` NodeUnstakingPeriod time.Duration `json:"nodeUnstakingPeriod"`