From 729b5585b51c2586b3e5d4dfc0a98ecce2127d5b Mon Sep 17 00:00:00 2001 From: BigBoss Date: Thu, 29 Jun 2023 23:20:04 -0400 Subject: [PATCH 01/27] scope: add upgrade feature files and todos --- e2e/tests/steps_upgrade_test.go | 59 ++++++++++++++++++++++ e2e/tests/upgrade.feature | 25 +++++++++ e2e/tests/upgrade_cancel.feature | 17 +++++++ persistence/gov.go | 4 +- shared/modules/persistence_module.go | 2 +- shared/node.go | 3 ++ utility/unit_of_work/block.go | 2 + utility/unit_of_work/gov.go | 2 + utility/unit_of_work/tx_message_signers.go | 1 + 9 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 e2e/tests/steps_upgrade_test.go create mode 100644 e2e/tests/upgrade.feature create mode 100644 e2e/tests/upgrade_cancel.feature diff --git a/e2e/tests/steps_upgrade_test.go b/e2e/tests/steps_upgrade_test.go new file mode 100644 index 000000000..a89d405f6 --- /dev/null +++ b/e2e/tests/steps_upgrade_test.go @@ -0,0 +1,59 @@ +//go:build e2e + +package e2e + +func (s *rootSuite) UserHasAValidCancelUpgradeCommandWithSignerAndVersion() { + panic("PENDING") +} + +func (s *rootSuite) UserHasACancelUpgradeCommandForAPastVersion() { + panic("PENDING") +} + +func (s *rootSuite) UserIsAnAclOwner() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldCancelTheScheduledUpgrade() { + panic("PENDING") +} + +func (s *rootSuite) TheSpecifiedUpgradeIsScheduledAndNotYetActivated() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldRejectTheCommandAsItCannotCancelAPastUpgrade() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldValidateTheCommand() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldSuccessfullyAcceptTheCommand() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldReturnTheUpdatedProtocolVersion() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldRejectTheCommandDueToInvalidInput() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldRejectTheCommandDueToTooManyVersionsAhead() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldReturnTheSuccessfulCancellationStatus() { + panic("PENDING") +} + +func (s *rootSuite) UserHasAValidUpgradeProtocolCommandWithSignerHeightAndNewVersion() { + panic("PENDING") +} + +func (s *rootSuite) TheSystemShouldApplyTheProtocolUpgradeAtTheSpecifiedActivationHeight() { + panic("PENDING") +} diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature new file mode 100644 index 000000000..d062b943a --- /dev/null +++ b/e2e/tests/upgrade.feature @@ -0,0 +1,25 @@ +Feature: Upgrade Protocol + + Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI + Given user is an ACL Owner + And user has a valid upgrade protocol command with signer, height, and new version + When the user runs the command "gov upgrade" + Then the system should validate the command + And the system should successfully accept the command + And the system should apply the protocol upgrade at the specified activation height + When user runs the command "query upgrade" + Then the system should return the updated protocol version + + Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI + Given user is an ACL Owner + And user has an invalid upgrade protocol command + When the user runs the command "gov upgrade" + Then the system should validate the command + And the system should reject the command due to invalid input + + Scenario: ACL Owner Submits a Protocol Upgrade with Too Many Versions Ahead Using CLI + Given user is an ACL Owner + And user has a upgrade protocol command with too many versions jump + When the user runs the command "gov upgrade" + Then the system should validate the command + And the system should reject the command due to too many versions ahead diff --git a/e2e/tests/upgrade_cancel.feature b/e2e/tests/upgrade_cancel.feature new file mode 100644 index 000000000..eb26d2c80 --- /dev/null +++ b/e2e/tests/upgrade_cancel.feature @@ -0,0 +1,17 @@ +Feature: Upgrade Protocol Cancel + + Scenario: ACL Owner Successfully Cancels a Scheduled Upgrade using CLI + Given the user has a validator + And user has a valid cancel upgrade command with signer and version + And the specified upgrade is scheduled and not yet activated + When the user runs the command "gov cancel_upgrade" + Then the system should cancel the scheduled upgrade + When user runs the command "gov query upgrade" + Then the system should return the successful cancellation status + + Scenario: ACL Owner Attempts to Cancel a Past Upgrade using CLI + Given the user has a validator + And user has a cancel upgrade command for a past version + When the user runs the command "gov cancel_upgrade" + Then the system should validate the command + And the system should reject the command as it cannot cancel a past upgrade diff --git a/persistence/gov.go b/persistence/gov.go index 73694ac6e..c3f6a7481 100644 --- a/persistence/gov.go +++ b/persistence/gov.go @@ -11,7 +11,7 @@ import ( "github.com/pokt-network/pocket/shared/modules" ) -// TODO: Implement this function +// TODO(0xbigboss): Implement this function func (p *PostgresContext) GetVersionAtHeight(height int64) (string, error) { // This is a placeholder function for the RPC endpoint "v1/query/upgrade" return "", nil @@ -74,7 +74,7 @@ func (p *PostgresContext) SetParam(paramName string, value any) error { } func (p *PostgresContext) InitFlags() error { - // TODO: not implemented + // TODO(0xbigboss): not implemented return nil } diff --git a/shared/modules/persistence_module.go b/shared/modules/persistence_module.go index 38c7681ba..dad6446ac 100644 --- a/shared/modules/persistence_module.go +++ b/shared/modules/persistence_module.go @@ -169,7 +169,7 @@ type PersistenceReadContext interface { Release() // Releases the read context // Version queries - GetVersionAtHeight(height int64) (string, error) // TODO: Implement this + GetVersionAtHeight(height int64) (string, error) // TODO(0xbigboss): Implement this GetRevisionNumber(height int64) uint64 // TODO(#882): Implement this // Supported Chains Queries diff --git a/shared/node.go b/shared/node.go index 39b905e38..93c872096 100644 --- a/shared/node.go +++ b/shared/node.go @@ -39,6 +39,7 @@ func CreateNode(bus modules.Bus, options ...modules.ModuleOption) (modules.Modul } func (m *Node) Create(bus modules.Bus, options ...modules.ModuleOption) (modules.Module, error) { + // TODO(0xbigboss): create the upgrade module for _, mod := range []func(modules.Bus, ...modules.ModuleOption) (modules.Module, error){ state_machine.Create, persistence.Create, @@ -83,6 +84,8 @@ func (node *Node) Start() error { return err } + // TODO(0xbigboss): start the upgrade module, check for upgrades, and apply them + if err := node.GetBus().GetP2PModule().Start(); err != nil { return err } diff --git a/utility/unit_of_work/block.go b/utility/unit_of_work/block.go index 914cf1ac9..76b8d77be 100644 --- a/utility/unit_of_work/block.go +++ b/utility/unit_of_work/block.go @@ -32,6 +32,7 @@ func (uow *baseUtilityUnitOfWork) beginBlock() coreTypes.Error { return err } // INCOMPLETE: Identify what else needs to be done in the begin block lifecycle phase + // TODO(0xbigboss): potential location for pausing if not upgraded to the latest protocol version return nil } @@ -60,6 +61,7 @@ func (uow *baseUtilityUnitOfWork) endBlock(proposer []byte) coreTypes.Error { } // INCOMPLETE: Identify what else needs to be done in the begin block lifecycle phase + // TODO(0xbigboss): potential location for doing state migrations if upgrade occurs at this block height return nil } diff --git a/utility/unit_of_work/gov.go b/utility/unit_of_work/gov.go index 29a561a47..3eba5ea50 100644 --- a/utility/unit_of_work/gov.go +++ b/utility/unit_of_work/gov.go @@ -13,6 +13,8 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) +// TODO(0xbigboss): Consider renaming this to gov_params.go + func init() { govParamTypes = prepareGovParamParamTypesMap() for _, key := range utils.GovParamMetadataKeys { diff --git a/utility/unit_of_work/tx_message_signers.go b/utility/unit_of_work/tx_message_signers.go index 602ef602a..3389cb5af 100644 --- a/utility/unit_of_work/tx_message_signers.go +++ b/utility/unit_of_work/tx_message_signers.go @@ -13,6 +13,7 @@ import ( // the logic in this will likely grow in complexity. // IMPROVE: Consider return a slice of `crypto.Address` types instead of `[][]byte` +// TODO(0xbigboss): Will need signer candidate verification func (u *baseUtilityUnitOfWork) getSignerCandidates(msg typesUtil.Message) ([][]byte, coreTypes.Error) { switch x := msg.(type) { case *typesUtil.MessageSend: From 82399137ce7e37ffad8995adc8c7c6ff71ec77de Mon Sep 17 00:00:00 2001 From: BigBoss Date: Fri, 21 Jul 2023 12:16:30 -0400 Subject: [PATCH 02/27] step: the user is an acl owner --- e2e/tests/steps_gov_test.go | 22 ++++++++++++++++ e2e/tests/steps_upgrade_test.go | 42 +++++++++++++++++------------- e2e/tests/upgrade.feature | 14 +++++----- e2e/tests/upgrade_cancel.feature | 4 +-- runtime/test_artifacts/defaults.go | 2 +- 5 files changed, 56 insertions(+), 28 deletions(-) create mode 100644 e2e/tests/steps_gov_test.go diff --git a/e2e/tests/steps_gov_test.go b/e2e/tests/steps_gov_test.go new file mode 100644 index 000000000..b66a9bec3 --- /dev/null +++ b/e2e/tests/steps_gov_test.go @@ -0,0 +1,22 @@ +package e2e + +import ( + "github.com/pokt-network/pocket/runtime/test_artifacts" + "github.com/stretchr/testify/require" +) + +// Ensures that the test artifact DefaultParamsOwner is imported into the CLI keybase. +func (s *rootSuite) TheUserIsAnAclOwner() { + res, err := s.validator.RunCommand("keys", + "import", + test_artifacts.DefaultParamsOwner.String(), + ) + require.NoError(s, err) + require.Contains(s, res.Stdout, "Key imported") + res, err = s.validator.RunCommand("keys", "get", test_artifacts.DefaultParamsOwner.PublicKey().String()) + if err != nil && res.Stderr != "" { + e2eLogger.Log().Msgf("Error: %v %s", err, res.Stderr) + require.NoError(s, err) + } + require.Contains(s, res.Stdout, test_artifacts.DefaultParamsOwner.PublicKey().String()) +} diff --git a/e2e/tests/steps_upgrade_test.go b/e2e/tests/steps_upgrade_test.go index a89d405f6..5d68ce4a4 100644 --- a/e2e/tests/steps_upgrade_test.go +++ b/e2e/tests/steps_upgrade_test.go @@ -2,58 +2,64 @@ package e2e +import "github.com/stretchr/testify/require" + func (s *rootSuite) UserHasAValidCancelUpgradeCommandWithSignerAndVersion() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) UserHasACancelUpgradeCommandForAPastVersion() { - panic("PENDING") -} - -func (s *rootSuite) UserIsAnAclOwner() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldCancelTheScheduledUpgrade() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSpecifiedUpgradeIsScheduledAndNotYetActivated() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldRejectTheCommandAsItCannotCancelAPastUpgrade() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldValidateTheCommand() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldSuccessfullyAcceptTheCommand() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldReturnTheUpdatedProtocolVersion() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldRejectTheCommandDueToInvalidInput() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldRejectTheCommandDueToTooManyVersionsAhead() { - panic("PENDING") + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldReturnTheSuccessfulCancellationStatus() { - panic("PENDING") + require.Fail(s, "implement me") } -func (s *rootSuite) UserHasAValidUpgradeProtocolCommandWithSignerHeightAndNewVersion() { - panic("PENDING") +func (s *rootSuite) TheUserHasAValidUpgradeProtocolCommandWithSignerHeightAndNewVersion() { + require.Fail(s, "implement me") } func (s *rootSuite) TheSystemShouldApplyTheProtocolUpgradeAtTheSpecifiedActivationHeight() { - panic("PENDING") + require.Fail(s, "implement me") +} + +func (s *rootSuite) TheUserHasAnInvalidUpgradeProtocolCommand() { + require.Fail(s, "implement me") +} + +func (s *rootSuite) TheUserHasAUpgradeProtocolCommandWithTooManyVersionsJump() { + require.Fail(s, "implement me") } diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature index d062b943a..8d7544b5c 100644 --- a/e2e/tests/upgrade.feature +++ b/e2e/tests/upgrade.feature @@ -1,25 +1,25 @@ Feature: Upgrade Protocol Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI - Given user is an ACL Owner - And user has a valid upgrade protocol command with signer, height, and new version + Given the user is an ACL Owner + And the user has a valid upgrade protocol command with signer, height, and new version When the user runs the command "gov upgrade" Then the system should validate the command And the system should successfully accept the command And the system should apply the protocol upgrade at the specified activation height - When user runs the command "query upgrade" + When the user runs the command "query upgrade" Then the system should return the updated protocol version Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI - Given user is an ACL Owner - And user has an invalid upgrade protocol command + Given the user is an ACL Owner + And the user has an invalid upgrade protocol command When the user runs the command "gov upgrade" Then the system should validate the command And the system should reject the command due to invalid input Scenario: ACL Owner Submits a Protocol Upgrade with Too Many Versions Ahead Using CLI - Given user is an ACL Owner - And user has a upgrade protocol command with too many versions jump + Given the user is an ACL Owner + And the user has a upgrade protocol command with too many versions jump When the user runs the command "gov upgrade" Then the system should validate the command And the system should reject the command due to too many versions ahead diff --git a/e2e/tests/upgrade_cancel.feature b/e2e/tests/upgrade_cancel.feature index eb26d2c80..662291c04 100644 --- a/e2e/tests/upgrade_cancel.feature +++ b/e2e/tests/upgrade_cancel.feature @@ -2,7 +2,7 @@ Feature: Upgrade Protocol Cancel Scenario: ACL Owner Successfully Cancels a Scheduled Upgrade using CLI Given the user has a validator - And user has a valid cancel upgrade command with signer and version + And the user has a valid cancel upgrade command with signer and version And the specified upgrade is scheduled and not yet activated When the user runs the command "gov cancel_upgrade" Then the system should cancel the scheduled upgrade @@ -11,7 +11,7 @@ Feature: Upgrade Protocol Cancel Scenario: ACL Owner Attempts to Cancel a Past Upgrade using CLI Given the user has a validator - And user has a cancel upgrade command for a past version + And the user has a cancel upgrade command for a past version When the user runs the command "gov cancel_upgrade" Then the system should validate the command And the system should reject the command as it cannot cancel a past upgrade diff --git a/runtime/test_artifacts/defaults.go b/runtime/test_artifacts/defaults.go index c9c8f3074..26bc1b004 100644 --- a/runtime/test_artifacts/defaults.go +++ b/runtime/test_artifacts/defaults.go @@ -23,7 +23,7 @@ var ( DefaultChainID = "testnet" ServiceURLFormat = "node%d.consensus:42069" DefaultMaxBlockBytes = uint64(4000000) - DefaultParamsOwner, _ = crypto.NewPrivateKey("ff538589deb7f28bbce1ba68b37d2efc0eaa03204b36513cf88422a875559e38d6cbe0430ddd85a5e48e0c99ef3dea47bf0d1a83c6e6ad1640f72201dc8a0120") + DefaultParamsOwner, _ = crypto.NewPrivateKey("ff538589deb7f28bbce1ba68b37d2efc0eaa03204b36513cf88422a875559e38d6cbe0430ddd85a5e48e0c99ef3dea47bf0d1a83c6e6ad1640f72201dc8a0120") // da034209758b78eaea06dd99c07909ab54c99b45 ) func DefaultParams() *genesis.Params { From 15dc15fac8f31bf9baefc504b380629aa8ee1a2d Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 22 Jul 2023 12:04:27 -0400 Subject: [PATCH 03/27] cleanup --- e2e/tests/steps_gov_test.go | 7 +++---- e2e/tests/steps_upgrade_test.go | 4 ---- e2e/tests/upgrade.feature | 15 ++++++++------- e2e/tests/upgrade_cancel.feature | 9 ++++----- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/e2e/tests/steps_gov_test.go b/e2e/tests/steps_gov_test.go index b66a9bec3..69f78becf 100644 --- a/e2e/tests/steps_gov_test.go +++ b/e2e/tests/steps_gov_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package e2e import ( @@ -14,9 +16,6 @@ func (s *rootSuite) TheUserIsAnAclOwner() { require.NoError(s, err) require.Contains(s, res.Stdout, "Key imported") res, err = s.validator.RunCommand("keys", "get", test_artifacts.DefaultParamsOwner.PublicKey().String()) - if err != nil && res.Stderr != "" { - e2eLogger.Log().Msgf("Error: %v %s", err, res.Stderr) - require.NoError(s, err) - } + require.NoError(s, err) require.Contains(s, res.Stdout, test_artifacts.DefaultParamsOwner.PublicKey().String()) } diff --git a/e2e/tests/steps_upgrade_test.go b/e2e/tests/steps_upgrade_test.go index 5d68ce4a4..665a01b60 100644 --- a/e2e/tests/steps_upgrade_test.go +++ b/e2e/tests/steps_upgrade_test.go @@ -48,10 +48,6 @@ func (s *rootSuite) TheSystemShouldReturnTheSuccessfulCancellationStatus() { require.Fail(s, "implement me") } -func (s *rootSuite) TheUserHasAValidUpgradeProtocolCommandWithSignerHeightAndNewVersion() { - require.Fail(s, "implement me") -} - func (s *rootSuite) TheSystemShouldApplyTheProtocolUpgradeAtTheSpecifiedActivationHeight() { require.Fail(s, "implement me") } diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature index 8d7544b5c..8a485e9ac 100644 --- a/e2e/tests/upgrade.feature +++ b/e2e/tests/upgrade.feature @@ -2,13 +2,14 @@ Feature: Upgrade Protocol Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI Given the user is an ACL Owner - And the user has a valid upgrade protocol command with signer, height, and new version - When the user runs the command "gov upgrade" - Then the system should validate the command - And the system should successfully accept the command - And the system should apply the protocol upgrade at the specified activation height - When the user runs the command "query upgrade" - Then the system should return the updated protocol version + When the user runs the command "gov upgrade " + Then the user should be able to see standard output containing "" + When the user runs the command "gov query upgrade" + Then the user should be able to see standard output containing "" + + Examples: + | version | height | chain-id | stdout | + | 2.0.0 | 100 | test | 2.0.0 | Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI Given the user is an ACL Owner diff --git a/e2e/tests/upgrade_cancel.feature b/e2e/tests/upgrade_cancel.feature index 662291c04..c27bb5faf 100644 --- a/e2e/tests/upgrade_cancel.feature +++ b/e2e/tests/upgrade_cancel.feature @@ -1,16 +1,15 @@ Feature: Upgrade Protocol Cancel - Scenario: ACL Owner Successfully Cancels a Scheduled Upgrade using CLI - Given the user has a validator - And the user has a valid cancel upgrade command with signer and version + Scenario: User Successfully Cancels a Scheduled Upgrade using CLI + Given the user is an ACL Owner And the specified upgrade is scheduled and not yet activated When the user runs the command "gov cancel_upgrade" Then the system should cancel the scheduled upgrade When user runs the command "gov query upgrade" Then the system should return the successful cancellation status - Scenario: ACL Owner Attempts to Cancel a Past Upgrade using CLI - Given the user has a validator + Scenario: User Attempts to Cancel a Past Upgrade using CLI + Given the user is an ACL Owner And the user has a cancel upgrade command for a past version When the user runs the command "gov cancel_upgrade" Then the system should validate the command From 68601ba16ecd84d968d1645bcd984e4e7c34b301 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 22 Jul 2023 13:09:40 -0400 Subject: [PATCH 04/27] add message upgrade, start cli --- app/client/cli/gov.go | 76 +++++++++++++++++++++++++-- go.mod | 1 + go.sum | 2 + shared/core/types/error.go | 8 ++- utility/types/message_upgrade.go | 51 ++++++++++++++++++ utility/types/message_upgrade_test.go | 72 +++++++++++++++++++++++++ utility/types/proto/message.proto | 8 +++ 7 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 utility/types/message_upgrade.go create mode 100644 utility/types/message_upgrade_test.go diff --git a/app/client/cli/gov.go b/app/client/cli/gov.go index a0fc30b88..6d81bec6a 100644 --- a/app/client/cli/gov.go +++ b/app/client/cli/gov.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "strconv" "github.com/spf13/cobra" "google.golang.org/protobuf/types/known/anypb" @@ -46,7 +47,7 @@ func govCommands() []*cobra.Command { key := args[1] value := args[2] - // TODO(deblasis): implement RPC client, route and handler + // TODO(0xbigboss): implement RPC client, route and handler fmt.Printf("changing parameter %s owned by %s to %s\n", args[1], args[0], args[2]) kb, err := keybaseForCLI() @@ -87,9 +88,76 @@ func govCommands() []*cobra.Command { if err != nil { return err } - // DISCUSS(#310): define UX for return values - should we return the raw response or a parsed/human readable response? For now, I am simply printing to stdout - fmt.Printf("HTTP status code: %d\n", resp.StatusCode()) - fmt.Println(string(resp.Body)) + + cmd.Printf("HTTP status code: %d\n", resp.StatusCode()) + cmd.Println(string(resp.Body)) + + return nil + }, + }, + { + Use: "Upgrade ", + Short: "Upgrade ", + Long: "Schedules an upgrade to the specified version at the specified height", + Aliases: []string{"upgrade"}, + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + // Unpack CLI arguments + fromAddrHex := args[0] + version := args[1] + heightArg := args[2] + + // TODO(0xbigboss): implement RPC client, route and handler + cmd.Printf("submitting upgrade for version %s at height %s.\n", args[0], args[1]) + + kb, err := keybaseForCLI() + if err != nil { + return err + } + + if !flags.NonInteractive { + pwd = readPassphrase(pwd) + } + + pk, err := kb.GetPrivKey(fromAddrHex, pwd) + if err != nil { + return err + } + if err := kb.Stop(); err != nil { + return err + } + + height, err := strconv.ParseInt(heightArg, 10, 64) + if err != nil { + return err + } + + // TODO(0xbigboss): be nice and validate the inputs before submitting, instead of reverting tx. + + msg := &types.MessageUpgrade{ + Signer: pk.Address(), + Version: version, + Height: height, + } + + err = msg.ValidateBasic() + if err != nil { + cmd.PrintErrf("invalid message: %s\n", err) + return err + } + + tx, err := prepareTxBytes(msg, pk) + if err != nil { + return err + } + + resp, err := postRawTx(cmd.Context(), pk, tx) + if err != nil { + return err + } + + cmd.Printf("HTTP status code: %d\n", resp.StatusCode()) + cmd.Println(string(resp.Body)) return nil }, diff --git a/go.mod b/go.mod index bb68ad331..3e203bce5 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( require ( github.com/benbjohnson/clock v1.3.0 + github.com/blang/semver/v4 v4.0.0 github.com/cosmos/ics23/go v0.10.0 github.com/deepmap/oapi-codegen v1.12.4 github.com/dgraph-io/badger/v3 v3.2103.2 diff --git a/go.sum b/go.sum index 925ffa331..14d7f1b42 100644 --- a/go.sum +++ b/go.sum @@ -76,6 +76,8 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= diff --git a/shared/core/types/error.go b/shared/core/types/error.go index 69369cced..fb2e54a37 100644 --- a/shared/core/types/error.go +++ b/shared/core/types/error.go @@ -48,7 +48,7 @@ func NewError(code Code, msg string) Error { } } -// NextCode: 149 +// NextCode: 150 type Code float64 // CONSIDERATION: Should these be a proto enum or a golang iota? //nolint:gosec // G101 - Not hard-coded credentials @@ -198,6 +198,7 @@ const ( CodeIBCStoreAlreadyExistsError Code = 146 CodeIBCStoreDoesNotExistError Code = 147 CodeIBCKeyDoesNotExistError Code = 148 + CodeInvalidProtocolVersionError Code = 149 ) const ( @@ -344,6 +345,7 @@ const ( IBCStoreAlreadyExistsError = "ibc store already exists in the store manager" IBCStoreDoesNotExistError = "ibc store does not exist in the store manager" IBCKeyDoesNotExistError = "key does not exist in the ibc store" + InvalidProtocolVersionError = "the protocol version is invalid" ) func ErrUnknownParam(paramName string) Error { @@ -922,3 +924,7 @@ func ErrIBCStoreDoesNotExist(name string) Error { func ErrIBCKeyDoesNotExist(key string) Error { return NewError(CodeIBCKeyDoesNotExistError, fmt.Sprintf("%s: %s", IBCKeyDoesNotExistError, key)) } + +func ErrInvalidProtocolVersion(version string) Error { + return NewError(CodeInvalidProtocolVersionError, fmt.Sprintf("%s: %s", InvalidProtocolVersionError, version)) +} diff --git a/utility/types/message_upgrade.go b/utility/types/message_upgrade.go new file mode 100644 index 000000000..2ba7c8a1a --- /dev/null +++ b/utility/types/message_upgrade.go @@ -0,0 +1,51 @@ +package types + +import ( + "log" + + "github.com/blang/semver/v4" + "github.com/pokt-network/pocket/shared/codec" + coreTypes "github.com/pokt-network/pocket/shared/core/types" +) + +var ( + _ Message = &MessageUpgrade{} +) + +func (msg *MessageUpgrade) ValidateBasic() coreTypes.Error { + if err := validateAddress(msg.Signer); err != nil { + return err + } + if _, err := semver.Parse(msg.Version); err != nil { + return coreTypes.ErrInvalidProtocolVersion(msg.Version) + } + if msg.Height < 1 { + return coreTypes.ErrInvalidBlockHeight() + } + return nil +} + +func (msg *MessageUpgrade) SetSigner(signer []byte) { + msg.Signer = signer +} + +func (msg *MessageUpgrade) GetMessageName() string { + return getMessageType(msg) +} + +func (msg *MessageUpgrade) GetMessageRecipient() string { + // Upgrade message does not have a recipient + return "" +} + +func (msg *MessageUpgrade) GetActorType() coreTypes.ActorType { + return coreTypes.ActorType_ACTOR_TYPE_UNSPECIFIED +} + +func (msg *MessageUpgrade) GetCanonicalBytes() []byte { + bz, err := codec.GetCodec().Marshal(msg) + if err != nil { + log.Fatalf("must marshal %v", err) + } + return bz +} diff --git a/utility/types/message_upgrade_test.go b/utility/types/message_upgrade_test.go new file mode 100644 index 000000000..5052436ef --- /dev/null +++ b/utility/types/message_upgrade_test.go @@ -0,0 +1,72 @@ +package types + +import ( + "fmt" + "testing" + + coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/crypto" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +func TestMessageUpgrade_ValidateBasic(t *testing.T) { + signer, err := crypto.GenerateAddress() + require.NoError(t, err) + + validVersion := "1.0.0" + validHeight := int64(1) + + msg := MessageUpgrade{ + Signer: signer, + Version: validVersion, + Height: validHeight, + } + + err = msg.ValidateBasic() + require.NoError(t, err) + + // Test missing signer + msgMissingSigner := proto.Clone(&msg).(*MessageUpgrade) + msgMissingSigner.Signer = nil + coreErr := msgMissingSigner.ValidateBasic() + require.NotNil(t, coreErr) + require.Equal(t, coreTypes.ErrEmptyAddress().Code(), coreErr.Code()) + + // Test invalid signer + msgInvalidSigner := proto.Clone(&msg).(*MessageUpgrade) + invalidSigner := "invalid_signer" + msgInvalidSigner.Signer = []byte(invalidSigner) + coreErr = msgInvalidSigner.ValidateBasic() + require.NotNil(t, coreErr) + require.Equal(t, coreTypes.ErrInvalidAddressLen(crypto.ErrInvalidAddressLen(len(invalidSigner))).Code(), coreErr.Code()) + + // Test invalid version + msgInvalidVersion := proto.Clone(&msg).(*MessageUpgrade) + msgInvalidVersion.Version = "invalid_version" + coreErr = msgInvalidVersion.ValidateBasic() + require.NotNil(t, coreErr) + require.Equal(t, coreTypes.ErrInvalidProtocolVersion(msgInvalidVersion.Version).Code(), coreErr.Code()) + + // Test invalid height + msgInvalidHeight := proto.Clone(&msg).(*MessageUpgrade) + msgInvalidHeight.Height = -1 + require.Equal(t, coreTypes.ErrInvalidBlockHeight().Code(), msgInvalidHeight.ValidateBasic().Code()) +} + +func ExampleMessageUpgrade() { + // Create a new MessageUpgrade + msg := &MessageUpgrade{ + Signer: []byte("da034209758b78eaea06dd99c07909ab54c99b45"), + Version: "1.2.3", + Height: 10, + } + + fmt.Printf("Signer: %s\n", msg.Signer) + fmt.Printf("Version: %s\n", msg.Version) + fmt.Printf("Height: %d\n", msg.Height) + // Output: + // Signer: da034209758b78eaea06dd99c07909ab54c99b45 + // Version: 1.2.3 + // Height: 10 +} diff --git a/utility/types/proto/message.proto b/utility/types/proto/message.proto index af27b92b0..8a0e564a9 100644 --- a/utility/types/proto/message.proto +++ b/utility/types/proto/message.proto @@ -51,3 +51,11 @@ message MessageChangeParameter { string parameter_key = 3; google.protobuf.Any parameter_value = 4; } + +message MessageUpgrade { + bytes signer = 1; + string version = 3; + int64 height = 4; +} + +// TODO(0xbigboss): MessageCancelUpgrade From f21945e5de8792874034d3ad0be7f6a24e511434 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sun, 23 Jul 2023 13:28:35 -0400 Subject: [PATCH 05/27] turn up the debugs --- app/client/cli/gov.go | 25 +++++++++++++++++-------- e2e/tests/steps_gov_test.go | 7 +++++-- e2e/tests/upgrade.feature | 6 +++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/app/client/cli/gov.go b/app/client/cli/gov.go index 6d81bec6a..57656b317 100644 --- a/app/client/cli/gov.go +++ b/app/client/cli/gov.go @@ -89,26 +89,30 @@ func govCommands() []*cobra.Command { return err } - cmd.Printf("HTTP status code: %d\n", resp.StatusCode()) - cmd.Println(string(resp.Body)) + if resp.StatusCode() != 200 { + return fmt.Errorf("HTTP status code: %d\n", resp.StatusCode()) + } + + fmt.Printf("Successfully sent change parameter %s owned by %s to %s\n", args[1], args[0], args[2]) + fmt.Printf("HTTP status code: %d\n", resp.StatusCode()) + fmt.Println(string(resp.Body)) return nil }, }, { - Use: "Upgrade ", + Use: "Upgrade ", Short: "Upgrade ", Long: "Schedules an upgrade to the specified version at the specified height", Aliases: []string{"upgrade"}, - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { // Unpack CLI arguments fromAddrHex := args[0] version := args[1] heightArg := args[2] - // TODO(0xbigboss): implement RPC client, route and handler - cmd.Printf("submitting upgrade for version %s at height %s.\n", args[0], args[1]) + fmt.Printf("submitting upgrade for version %s at height %s.\n", args[0], args[1]) kb, err := keybaseForCLI() if err != nil { @@ -156,8 +160,13 @@ func govCommands() []*cobra.Command { return err } - cmd.Printf("HTTP status code: %d\n", resp.StatusCode()) - cmd.Println(string(resp.Body)) + if resp.StatusCode() != 200 { + return fmt.Errorf("HTTP status code: %d\n", resp.StatusCode()) + } + + fmt.Printf("Successfully submitted upgrade for version %s at height %s.\n", args[0], args[1]) + fmt.Printf("HTTP status code: %d\n", resp.StatusCode()) + fmt.Println(string(resp.Body)) return nil }, diff --git a/e2e/tests/steps_gov_test.go b/e2e/tests/steps_gov_test.go index 69f78becf..1be60dbc6 100644 --- a/e2e/tests/steps_gov_test.go +++ b/e2e/tests/steps_gov_test.go @@ -15,7 +15,10 @@ func (s *rootSuite) TheUserIsAnAclOwner() { ) require.NoError(s, err) require.Contains(s, res.Stdout, "Key imported") - res, err = s.validator.RunCommand("keys", "get", test_artifacts.DefaultParamsOwner.PublicKey().String()) - require.NoError(s, err) + res, err = s.validator.RunCommand("keys", "get", test_artifacts.DefaultParamsOwner.Address().String()) + if err != nil { + e2eLogger.Error().AnErr("error", err).Str("stdout", res.Stdout).Str("stderr", res.Stderr).Msgf("failed to get acl owner key") + require.NoError(s, err) + } require.Contains(s, res.Stdout, test_artifacts.DefaultParamsOwner.PublicKey().String()) } diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature index 8a485e9ac..fcb5c4d4a 100644 --- a/e2e/tests/upgrade.feature +++ b/e2e/tests/upgrade.feature @@ -2,14 +2,14 @@ Feature: Upgrade Protocol Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI Given the user is an ACL Owner - When the user runs the command "gov upgrade " + When the user runs the command "gov upgrade " Then the user should be able to see standard output containing "" When the user runs the command "gov query upgrade" Then the user should be able to see standard output containing "" Examples: - | version | height | chain-id | stdout | - | 2.0.0 | 100 | test | 2.0.0 | + | owner | version | height | stdout | + | da034209758b78eaea06dd99c07909ab54c99b45 | 2.0.0 | 100 | 2.0.0 | Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI Given the user is an ACL Owner From c555dcbab19b46ad84ffc498f702208109b2417c Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sun, 23 Jul 2023 15:05:32 -0400 Subject: [PATCH 06/27] show query mempool failing --- app/client/cli/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/client/cli/utils.go b/app/client/cli/utils.go index 2e3e0263e..359ebe7b5 100644 --- a/app/client/cli/utils.go +++ b/app/client/cli/utils.go @@ -316,12 +316,12 @@ func keybaseForCLI() (keybase.Keybase, error) { func unableToConnectToRpc(err error) error { fmt.Printf("❌ Unable to connect to the RPC @ %s\n\nError: %s", boldText(flags.RemoteCLIURL), err) - return nil + return fmt.Errorf("unable to connect to the RPC @ %s", flags.RemoteCLIURL) } func rpcResponseCodeUnhealthy(statusCode int, response []byte) error { fmt.Printf("❌ RPC reporting unhealthy status HTTP %d @ %s\n\n%s", statusCode, boldText(flags.RemoteCLIURL), response) - return nil + return fmt.Errorf("RPC reporting unhealthy status HTTP %d @ %s", statusCode, flags.RemoteCLIURL) } func boldText[T string | []byte](s T) string { From 8a3a24675cba57fb36c782b0358ce99ed526f42b Mon Sep 17 00:00:00 2001 From: BigBoss Date: Fri, 28 Jul 2023 19:59:30 -0400 Subject: [PATCH 07/27] wip handling upgrade --- persistence/gov.go | 5 +++++ rpc/handlers.go | 2 +- shared/core/types/error.go | 8 +++++++- shared/modules/persistence_module.go | 3 +++ utility/types/message.go | 1 + utility/unit_of_work/module.go | 13 +++++++++---- utility/unit_of_work/transaction.go | 3 +++ utility/unit_of_work/tx_message_handler.go | 10 ++++++++++ 8 files changed, 39 insertions(+), 6 deletions(-) diff --git a/persistence/gov.go b/persistence/gov.go index c3f6a7481..609a8b6d5 100644 --- a/persistence/gov.go +++ b/persistence/gov.go @@ -2,6 +2,7 @@ package persistence import ( "encoding/hex" + "errors" "fmt" "strconv" @@ -189,3 +190,7 @@ func (p *PostgresContext) getLatestParamsOrFlagsQuery(tableName string) string { // Return a query to select all params or queries but only the most recent update for each return fmt.Sprintf("SELECT DISTINCT ON (name) %s FROM %s ORDER BY name ASC,%s.height DESC", fields, tableName, tableName) } + +func (p *PostgresContext) SetUpgrade(version string, height int64) error { + return errors.New("not implemented") +} diff --git a/rpc/handlers.go b/rpc/handlers.go index e222b3e66..9ec429718 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -40,7 +40,7 @@ func (s *rpcServer) PostV1ClientBroadcastTxSync(ctx echo.Context) error { return ctx.String(http.StatusInternalServerError, err.Error()) } - return nil + return ctx.String(http.StatusOK, coreTypes.TxHash(txBz)) } func (s *rpcServer) PostV1ClientGetSession(ctx echo.Context) error { diff --git a/shared/core/types/error.go b/shared/core/types/error.go index fb2e54a37..3d6b91469 100644 --- a/shared/core/types/error.go +++ b/shared/core/types/error.go @@ -48,7 +48,7 @@ func NewError(code Code, msg string) Error { } } -// NextCode: 150 +// NextCode: 151 type Code float64 // CONSIDERATION: Should these be a proto enum or a golang iota? //nolint:gosec // G101 - Not hard-coded credentials @@ -199,6 +199,7 @@ const ( CodeIBCStoreDoesNotExistError Code = 147 CodeIBCKeyDoesNotExistError Code = 148 CodeInvalidProtocolVersionError Code = 149 + CodeSettingUpgradeError Code = 150 ) const ( @@ -346,6 +347,7 @@ const ( IBCStoreDoesNotExistError = "ibc store does not exist in the store manager" IBCKeyDoesNotExistError = "key does not exist in the ibc store" InvalidProtocolVersionError = "the protocol version is invalid" + SettingUpgradeError = "an error occurred setting the upgrade" ) func ErrUnknownParam(paramName string) Error { @@ -928,3 +930,7 @@ func ErrIBCKeyDoesNotExist(key string) Error { func ErrInvalidProtocolVersion(version string) Error { return NewError(CodeInvalidProtocolVersionError, fmt.Sprintf("%s: %s", InvalidProtocolVersionError, version)) } + +func ErrSettingUpgrade(err error) Error { + return NewError(CodeSettingUpgradeError, fmt.Sprintf("%s: %s", SettingUpgradeError, err.Error())) +} diff --git a/shared/modules/persistence_module.go b/shared/modules/persistence_module.go index dad6446ac..39ad6a42c 100644 --- a/shared/modules/persistence_module.go +++ b/shared/modules/persistence_module.go @@ -150,6 +150,9 @@ type PersistenceWriteContext interface { InitFlags() error SetFlag(paramName string, value any, enabled bool) error + // Upgrade Operations + SetUpgrade(version string, height int64) error + // IBC Operations // SetIBCStoreEntry sets the key-value pair in the ibc_entries table at the current height the // key-value pairs represent the same key-value pairings in the IBC state tree. This table is diff --git a/utility/types/message.go b/utility/types/message.go index a02257edb..cb17f692a 100644 --- a/utility/types/message.go +++ b/utility/types/message.go @@ -37,6 +37,7 @@ var ( _ Message = &MessageUnstake{} _ Message = &MessageUnpause{} _ Message = &MessageChangeParameter{} + _ Message = &MessageUpgrade{} ) func (msg *MessageSend) ValidateBasic() coreTypes.Error { diff --git a/utility/unit_of_work/module.go b/utility/unit_of_work/module.go index a654218ac..af337f349 100644 --- a/utility/unit_of_work/module.go +++ b/utility/unit_of_work/module.go @@ -150,16 +150,21 @@ func (uow *baseUtilityUnitOfWork) processProposalBlockTransactions() (err error) if err != nil { return err } - if err := tx.ValidateBasic(); err != nil { + + txHash, err := tx.Hash() + if err != nil { return err } - idxTx, err := uow.HandleTransaction(tx, index) - if err != nil { + if uow.logger.GetLevel().String() == "debug" { + uow.logger.Debug().Str("tx", txHash).Msgf("processing transaction: %+v", tx) + } + + if err := tx.ValidateBasic(); err != nil { return err } - txHash, err := tx.Hash() + idxTx, err := uow.HandleTransaction(tx, index) if err != nil { return err } diff --git a/utility/unit_of_work/transaction.go b/utility/unit_of_work/transaction.go index 6e2d04c87..16edb6df5 100644 --- a/utility/unit_of_work/transaction.go +++ b/utility/unit_of_work/transaction.go @@ -18,6 +18,9 @@ func (u *baseUtilityUnitOfWork) HandleTransaction(tx *coreTypes.Transaction, ind if err != nil { return nil, err } + if u.logger.GetLevel().String() == "debug" { + u.logger.Debug().Msgf("handling transaction: %+v", msg) + } msgHandlingResult := u.handleMessage(msg) return typesUtil.TxToIdxTx(tx, u.height, index, msg, msgHandlingResult) } diff --git a/utility/unit_of_work/tx_message_handler.go b/utility/unit_of_work/tx_message_handler.go index 6c696e14c..03ba5f745 100644 --- a/utility/unit_of_work/tx_message_handler.go +++ b/utility/unit_of_work/tx_message_handler.go @@ -31,6 +31,8 @@ func (u *baseUtilityUnitOfWork) handleMessage(msg typesUtil.Message) (err coreTy return u.handleUpdateIBCStore(x) case *ibcTypes.PruneIBCStore: return u.handlePruneIBCStore(x) + case *typesUtil.MessageUpgrade: + return u.handleMessageUpgrade(x) default: return coreTypes.ErrUnknownMessage(x) } @@ -239,6 +241,14 @@ func (u *baseUtilityUnitOfWork) handlePruneIBCStore(message *ibcTypes.PruneIBCSt return nil } +func (u *baseUtilityUnitOfWork) handleMessageUpgrade(message *typesUtil.MessageUpgrade) coreTypes.Error { + u.logger.Info().Str("version", message.Version).Int64("height", message.Height).Msg("setting upgrade") + if err := u.persistenceRWContext.SetUpgrade(message.Version, message.Height); err != nil { + return coreTypes.ErrSettingUpgrade(err) + } + return nil +} + func (u *baseUtilityUnitOfWork) checkBelowMaxChains(actorType coreTypes.ActorType, chains []string) coreTypes.Error { // validators don't have chains field if actorType == coreTypes.ActorType_ACTOR_TYPE_VAL { From 52ac14f125d0c557d644e9a7f87dcee8e9f4ac76 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 12:41:03 -0400 Subject: [PATCH 08/27] =?UTF-8?q?=F0=9F=93=9D=20message=20upgrade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/client/cli/gov.go | 1 + build/config/genesis.json | 18 +-- build/config/genesis_localhost.json | 4 +- .../pocket/templates/configmap-genesis.yaml | 4 +- persistence/test/state_test.go | 6 +- persistence/types/gov_test.go | 4 +- runtime/genesis/proto/genesis.proto | 116 +++++++++--------- runtime/test_artifacts/defaults.go | 2 + utility/session_test.go | 2 +- utility/types/gov.go | 5 + utility/types/message.go | 1 - utility/types/message_upgrade.go | 2 + utility/unit_of_work/gov.go | 5 + utility/unit_of_work/transaction.go | 3 - utility/unit_of_work/tx_message_handler.go | 3 + utility/unit_of_work/tx_message_signers.go | 10 +- 16 files changed, 107 insertions(+), 79 deletions(-) diff --git a/app/client/cli/gov.go b/app/client/cli/gov.go index 57656b317..f80c1e3bd 100644 --- a/app/client/cli/gov.go +++ b/app/client/cli/gov.go @@ -171,6 +171,7 @@ func govCommands() []*cobra.Command { return nil }, }, + // TODO: 0xbigboss MessageCancelUpgrade } return cmds } diff --git a/build/config/genesis.json b/build/config/genesis.json index 1c8dd19f5..efa8d4ca5 100755 --- a/build/config/genesis.json +++ b/build/config/genesis.json @@ -1589,9 +1589,7 @@ { "actor_type": 1, "address": "00101f2ff54811e84df2d767c661f57a06349b7e", - "chains": [ - "0001" - ], + "chains": ["0001"], "output": "00101f2ff54811e84df2d767c661f57a06349b7e", "paused_height": -1, "public_key": "bb851ac31120a4c8848738582f358599abbc3d84638f8fa79f74aeafad1eede0", @@ -1604,9 +1602,7 @@ { "actor_type": 3, "address": "0010336c3a2cc1ec71fecc45c360214f757194aa", - "chains": [ - "0001" - ], + "chains": ["0001"], "output": "0010336c3a2cc1ec71fecc45c360214f757194aa", "paused_height": -1, "public_key": "d913a05a6f4bde35413bdcc6343238960cfc7d8aff425fb712dcaa52f1476dbf", @@ -1652,6 +1648,8 @@ "fisherman_unstaking_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_change_parameter_fee": "10000", "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", + "message_upgrade_fee": "10000", + "message_upgrade_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_double_sign_fee": "10000", "message_double_sign_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_edit_stake_app_fee": "10000", @@ -1761,9 +1759,7 @@ { "actor_type": 2, "address": "00104055c00bed7c983a48aac7dc6335d7c607a7", - "chains": [ - "0001" - ], + "chains": ["0001"], "output": "00104055c00bed7c983a48aac7dc6335d7c607a7", "paused_height": -1, "public_key": "dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e", @@ -1774,9 +1770,7 @@ { "actor_type": 2, "address": "001022b138896c4c5466ac86b24a9bbe249905c2", - "chains": [ - "0001" - ], + "chains": ["0001"], "output": "001022b138896c4c5466ac86b24a9bbe249905c2", "paused_height": -1, "public_key": "56915c1270bc8d9280a633e0be51647f62388a851318381614877ef2ed84a495", diff --git a/build/config/genesis_localhost.json b/build/config/genesis_localhost.json index 47d3fde0b..d53d19766 100755 --- a/build/config/genesis_localhost.json +++ b/build/config/genesis_localhost.json @@ -195,6 +195,7 @@ "message_pause_servicer_fee": "10000", "message_unpause_servicer_fee": "10000", "message_change_parameter_fee": "10000", + "message_upgrade_fee": "10000", "acl_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "blocks_per_session_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_stake_owner": "da034209758b78eaea06dd99c07909ab54c99b45", @@ -250,7 +251,8 @@ "message_unstake_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_pause_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_unpause_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45" + "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", + "message_upgrade_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45" }, "genesis_time": { "seconds": 1663610702, diff --git a/charts/pocket/templates/configmap-genesis.yaml b/charts/pocket/templates/configmap-genesis.yaml index 29705e497..4f16bf817 100644 --- a/charts/pocket/templates/configmap-genesis.yaml +++ b/charts/pocket/templates/configmap-genesis.yaml @@ -1792,6 +1792,7 @@ data: "message_pause_servicer_fee": "10000", "message_unpause_servicer_fee": "10000", "message_change_parameter_fee": "10000", + "message_upgrade_fee": "10000", "acl_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "blocks_per_session_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_stake_owner": "da034209758b78eaea06dd99c07909ab54c99b45", @@ -1846,7 +1847,8 @@ data: "message_unstake_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_pause_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_unpause_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45" + "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", + "message_upgrade_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45" }, "genesis_time": { "seconds": 1663610702, diff --git a/persistence/test/state_test.go b/persistence/test/state_test.go index d2b67fcf6..9cd767e6f 100644 --- a/persistence/test/state_test.go +++ b/persistence/test/state_test.go @@ -42,9 +42,9 @@ func TestStateHash_DeterministicStateWhenUpdatingAppStake(t *testing.T) { // logic changes, these hashes will need to be updated based on the test output. // TODO: Add an explicit updateSnapshots flag to the test to make this more clear. stateHashes := []string{ - "1e433a8905c7b1cf42222f8d01ba222038653f8ff35ae97cce1fd6a32d18b51e", - "4542dea3eedb99ad46b3c6e0ea901a9ee365b590b2f2ac7f12678ac369a2fe90", - "1524529fa827852e397adf1938eb058848209c4916cdacef929d050efc472c1d", + "379cb08579d2ddd78c8f9c8deddf65c77a9d3bae81d670bb8cbd3c2c394e4e51", + "d6a2ad957b2cb1f91095dde9ca052f180c79ec853c242a6b4ea3c798e5e1e20f", + "f8ef2678a97a3e6ea4c2bdec172af03def9c596dec0db708bd414b0e0c49c25a", } stakeAmount := initialStakeAmount diff --git a/persistence/types/gov_test.go b/persistence/types/gov_test.go index 6a07f7ede..7e51a98f2 100644 --- a/persistence/types/gov_test.go +++ b/persistence/types/gov_test.go @@ -77,6 +77,7 @@ func TestInsertParams(t *testing.T) { "('message_pause_servicer_fee', -1, 'STRING', '10000')," + "('message_unpause_servicer_fee', -1, 'STRING', '10000')," + "('message_change_parameter_fee', -1, 'STRING', '10000')," + + "('message_upgrade_fee', -1, 'STRING', '10000')," + "('acl_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('blocks_per_session_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('app_minimum_stake_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + @@ -131,7 +132,8 @@ func TestInsertParams(t *testing.T) { "('message_unstake_servicer_fee_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('message_pause_servicer_fee_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('message_unpause_servicer_fee_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + - "('message_change_parameter_fee_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45') " + + "('message_change_parameter_fee_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + + "('message_upgrade_fee_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45') " + "ON CONFLICT ON CONSTRAINT params_pkey DO UPDATE SET value=EXCLUDED.value, type=EXCLUDED.type", }, } diff --git a/runtime/genesis/proto/genesis.proto b/runtime/genesis/proto/genesis.proto index 5db5100ea..e4a083cfd 100644 --- a/runtime/genesis/proto/genesis.proto +++ b/runtime/genesis/proto/genesis.proto @@ -138,115 +138,121 @@ message Params { string message_unpause_servicer_fee = 53; //@gotags: pokt:"val_type=STRING,owner=message_change_parameter_fee_owner" string message_change_parameter_fee = 54; + //@gotags: pokt:"val_type=STRING,owner=message_upgrade_fee_owner" + string message_upgrade_fee = 55; + // TODO: 0xbigboss MessageCancelUpgrade //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string acl_owner = 55; + string acl_owner = 56; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string blocks_per_session_owner = 56; + string blocks_per_session_owner = 57; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string app_minimum_stake_owner = 57; + string app_minimum_stake_owner = 58; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string app_max_chains_owner = 58; + string app_max_chains_owner = 59; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string app_session_tokens_multiplier_owner = 59; + string app_session_tokens_multiplier_owner = 60; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string app_unstaking_blocks_owner = 60; + string app_unstaking_blocks_owner = 61; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string app_minimum_pause_blocks_owner = 61; + string app_minimum_pause_blocks_owner = 62; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string app_max_paused_blocks_owner = 62; + string app_max_paused_blocks_owner = 63; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string servicer_minimum_stake_owner = 63; + string servicer_minimum_stake_owner = 64; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string servicer_max_chains_owner = 64; + string servicer_max_chains_owner = 65; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string servicer_unstaking_blocks_owner = 65; + string servicer_unstaking_blocks_owner = 66; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string servicer_minimum_pause_blocks_owner = 66; + string servicer_minimum_pause_blocks_owner = 67; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string servicer_max_paused_blocks_owner = 67; + string servicer_max_paused_blocks_owner = 68; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string servicers_per_session_owner = 68; + string servicers_per_session_owner = 69; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string fisherman_minimum_stake_owner = 69; + string fisherman_minimum_stake_owner = 70; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string fisherman_max_chains_owner = 70; + string fisherman_max_chains_owner = 71; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string fisherman_unstaking_blocks_owner = 71; + string fisherman_unstaking_blocks_owner = 72; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string fisherman_minimum_pause_blocks_owner = 72; + string fisherman_minimum_pause_blocks_owner = 73; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string fisherman_max_paused_blocks_owner = 73; + string fisherman_max_paused_blocks_owner = 74; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string fisherman_per_session_owner = 74; + string fisherman_per_session_owner = 75; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string validator_minimum_stake_owner = 75; + string validator_minimum_stake_owner = 76; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string validator_unstaking_blocks_owner = 76; + string validator_unstaking_blocks_owner = 77; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string validator_minimum_pause_blocks_owner = 77; + string validator_minimum_pause_blocks_owner = 78; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string validator_max_paused_blocks_owner = 78; + string validator_max_paused_blocks_owner = 79; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string validator_maximum_missed_blocks_owner = 79; + string validator_maximum_missed_blocks_owner = 80; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string validator_max_evidence_age_in_blocks_owner = 80; + string validator_max_evidence_age_in_blocks_owner = 81; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string proposer_percentage_of_fees_owner = 81; + string proposer_percentage_of_fees_owner = 82; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string missed_blocks_burn_percentage_owner = 82; + string missed_blocks_burn_percentage_owner = 83; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string double_sign_burn_percentage_owner = 83; + string double_sign_burn_percentage_owner = 84; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_double_sign_fee_owner = 84; + string message_double_sign_fee_owner = 85; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_send_fee_owner = 85; + string message_send_fee_owner = 86; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_stake_fisherman_fee_owner = 86; + string message_stake_fisherman_fee_owner = 87; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_edit_stake_fisherman_fee_owner = 87; + string message_edit_stake_fisherman_fee_owner = 88; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unstake_fisherman_fee_owner = 88; + string message_unstake_fisherman_fee_owner = 89; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_pause_fisherman_fee_owner = 89; + string message_pause_fisherman_fee_owner = 90; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unpause_fisherman_fee_owner = 90; + string message_unpause_fisherman_fee_owner = 91; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_fisherman_pause_servicer_fee_owner = 91; + string message_fisherman_pause_servicer_fee_owner = 92; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_test_score_fee_owner = 92; + string message_test_score_fee_owner = 93; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_prove_test_score_fee_owner = 93; + string message_prove_test_score_fee_owner = 94; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_stake_app_fee_owner = 94; + string message_stake_app_fee_owner = 95; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_edit_stake_app_fee_owner = 95; + string message_edit_stake_app_fee_owner = 96; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unstake_app_fee_owner = 96; + string message_unstake_app_fee_owner = 97; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_pause_app_fee_owner = 97; + string message_pause_app_fee_owner = 98; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unpause_app_fee_owner = 98; + string message_unpause_app_fee_owner = 99; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_stake_validator_fee_owner = 99; + string message_stake_validator_fee_owner = 100; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_edit_stake_validator_fee_owner = 100; + string message_edit_stake_validator_fee_owner = 101; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unstake_validator_fee_owner = 101; + string message_unstake_validator_fee_owner = 102; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_pause_validator_fee_owner = 102; + string message_pause_validator_fee_owner = 103; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unpause_validator_fee_owner = 103; + string message_unpause_validator_fee_owner = 104; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_stake_servicer_fee_owner = 104; + string message_stake_servicer_fee_owner = 105; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_edit_stake_servicer_fee_owner = 105; + string message_edit_stake_servicer_fee_owner = 106; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unstake_servicer_fee_owner = 106; + string message_unstake_servicer_fee_owner = 107; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_pause_servicer_fee_owner = 107; + string message_pause_servicer_fee_owner = 108; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_unpause_servicer_fee_owner = 108; + string message_unpause_servicer_fee_owner = 109; //@gotags: pokt:"val_type=STRING,owner=acl_owner" - string message_change_parameter_fee_owner = 109; + string message_change_parameter_fee_owner = 110; + //@gotags: pokt:"val_type=STRING,owner=acl_owner" + string message_upgrade_fee_owner = 111; + // TODO: 0xbigboss MessageCancelUpgrade } diff --git a/runtime/test_artifacts/defaults.go b/runtime/test_artifacts/defaults.go index 26bc1b004..4693696c6 100644 --- a/runtime/test_artifacts/defaults.go +++ b/runtime/test_artifacts/defaults.go @@ -82,6 +82,7 @@ func DefaultParams() *genesis.Params { MessagePauseServicerFee: utils.BigIntToString(big.NewInt(10000)), MessageUnpauseServicerFee: utils.BigIntToString(big.NewInt(10000)), MessageChangeParameterFee: utils.BigIntToString(big.NewInt(10000)), + MessageUpgradeFee: utils.BigIntToString(big.NewInt(10000)), // TODO: 0xbigboss MessageCancelUpgrade AclOwner: DefaultParamsOwner.Address().String(), BlocksPerSessionOwner: DefaultParamsOwner.Address().String(), AppMinimumStakeOwner: DefaultParamsOwner.Address().String(), @@ -137,5 +138,6 @@ func DefaultParams() *genesis.Params { MessagePauseServicerFeeOwner: DefaultParamsOwner.Address().String(), MessageUnpauseServicerFeeOwner: DefaultParamsOwner.Address().String(), MessageChangeParameterFeeOwner: DefaultParamsOwner.Address().String(), + MessageUpgradeFeeOwner: DefaultParamsOwner.Address().String(), // TODO: 0xbigboss MessageCancelUpgrade } } diff --git a/utility/session_test.go b/utility/session_test.go index 319af206c..0766a09c1 100644 --- a/utility/session_test.go +++ b/utility/session_test.go @@ -25,7 +25,7 @@ func TestSession_GetSession_SingleFishermanSingleServicerBaseCase(t *testing.T) numFishermen := 1 numServicers := 1 // needs to be manually updated if business logic changes - expectedSessionId := "b1e9791358aae070ac7f86fdb74e5a9d26fff025fb737a2114ccf9ad95b624bd" + expectedSessionId := "b21c41eceba7d8b338e6a51f2519373042b0b23ec1dfe9967c5819d57c60db17" runtimeCfg, utilityMod, _ := prepareEnvironment(t, 5, numServicers, 1, numFishermen) diff --git a/utility/types/gov.go b/utility/types/gov.go index 52501f95f..69af50716 100644 --- a/utility/types/gov.go +++ b/utility/types/gov.go @@ -83,6 +83,9 @@ const ( // Parameter / flags gov params MessageChangeParameterFee = "message_change_parameter_fee" + + // Upgrade gov params + MessageUpgradeFee = "message_upgrade_fee" ) // TECHDEBT: The parameters below are equivalent to the list above with the suffix `_owner`. There @@ -154,4 +157,6 @@ const ( MessageUnpauseServicerFeeOwner = "message_unpause_servicer_fee_owner" MessageChangeParameterFeeOwner = "message_change_parameter_fee_owner" + + MessageUpgradeFeeOwner = "message_upgrade_fee_owner" ) diff --git a/utility/types/message.go b/utility/types/message.go index cb17f692a..a02257edb 100644 --- a/utility/types/message.go +++ b/utility/types/message.go @@ -37,7 +37,6 @@ var ( _ Message = &MessageUnstake{} _ Message = &MessageUnpause{} _ Message = &MessageChangeParameter{} - _ Message = &MessageUpgrade{} ) func (msg *MessageSend) ValidateBasic() coreTypes.Error { diff --git a/utility/types/message_upgrade.go b/utility/types/message_upgrade.go index 2ba7c8a1a..e001441fe 100644 --- a/utility/types/message_upgrade.go +++ b/utility/types/message_upgrade.go @@ -49,3 +49,5 @@ func (msg *MessageUpgrade) GetCanonicalBytes() []byte { } return bz } + +// TODO: 0xbigboss MessageCancelUpgrade diff --git a/utility/unit_of_work/gov.go b/utility/unit_of_work/gov.go index 3eba5ea50..85f646874 100644 --- a/utility/unit_of_work/gov.go +++ b/utility/unit_of_work/gov.go @@ -93,6 +93,8 @@ func prepareGovParamParamTypesMap() map[string]int { typesUtil.MessagePauseServicerFee: BIGINT, typesUtil.MessageUnpauseServicerFee: BIGINT, typesUtil.MessageChangeParameterFee: BIGINT, + typesUtil.MessageUpgradeFee: BIGINT, + // TODO: 0xbigboss MessageCancelUpgrade } } @@ -209,6 +211,9 @@ func (u *baseUtilityUnitOfWork) getFee(msg typesUtil.Message, actorType coreType } case *typesUtil.MessageChangeParameter: return getGovParam[*big.Int](u, typesUtil.MessageChangeParameterFee) + // TODO: 0xbigboss MessageCancelUpgrade + case *typesUtil.MessageUpgrade: + return getGovParam[*big.Int](u, typesUtil.MessageUpgradeFee) default: return nil, coreTypes.ErrUnknownMessage(x) } diff --git a/utility/unit_of_work/transaction.go b/utility/unit_of_work/transaction.go index 16edb6df5..6e2d04c87 100644 --- a/utility/unit_of_work/transaction.go +++ b/utility/unit_of_work/transaction.go @@ -18,9 +18,6 @@ func (u *baseUtilityUnitOfWork) HandleTransaction(tx *coreTypes.Transaction, ind if err != nil { return nil, err } - if u.logger.GetLevel().String() == "debug" { - u.logger.Debug().Msgf("handling transaction: %+v", msg) - } msgHandlingResult := u.handleMessage(msg) return typesUtil.TxToIdxTx(tx, u.height, index, msg, msgHandlingResult) } diff --git a/utility/unit_of_work/tx_message_handler.go b/utility/unit_of_work/tx_message_handler.go index 03ba5f745..9fc4489b9 100644 --- a/utility/unit_of_work/tx_message_handler.go +++ b/utility/unit_of_work/tx_message_handler.go @@ -33,6 +33,7 @@ func (u *baseUtilityUnitOfWork) handleMessage(msg typesUtil.Message) (err coreTy return u.handlePruneIBCStore(x) case *typesUtil.MessageUpgrade: return u.handleMessageUpgrade(x) + // TODO: 0xbigboss MessageCancelUpgrade default: return coreTypes.ErrUnknownMessage(x) } @@ -249,6 +250,8 @@ func (u *baseUtilityUnitOfWork) handleMessageUpgrade(message *typesUtil.MessageU return nil } +// TODO: 0xbigboss MessageCancelUpgrade + func (u *baseUtilityUnitOfWork) checkBelowMaxChains(actorType coreTypes.ActorType, chains []string) coreTypes.Error { // validators don't have chains field if actorType == coreTypes.ActorType_ACTOR_TYPE_VAL { diff --git a/utility/unit_of_work/tx_message_signers.go b/utility/unit_of_work/tx_message_signers.go index 3389cb5af..6b81a3d0d 100644 --- a/utility/unit_of_work/tx_message_signers.go +++ b/utility/unit_of_work/tx_message_signers.go @@ -13,7 +13,6 @@ import ( // the logic in this will likely grow in complexity. // IMPROVE: Consider return a slice of `crypto.Address` types instead of `[][]byte` -// TODO(0xbigboss): Will need signer candidate verification func (u *baseUtilityUnitOfWork) getSignerCandidates(msg typesUtil.Message) ([][]byte, coreTypes.Error) { switch x := msg.(type) { case *typesUtil.MessageSend: @@ -30,6 +29,9 @@ func (u *baseUtilityUnitOfWork) getSignerCandidates(msg typesUtil.Message) ([][] return u.getUpdateIBCStoreSingerCandidates(x) case *ibcTypes.PruneIBCStore: return u.getPruneIBCStoreSingerCandidates(x) + case *typesUtil.MessageUpgrade: + return u.getMessageUpgradeSignerCandidates(x) + // TODO: 0xbigboss MessageCancelUpgrade default: return nil, coreTypes.ErrUnknownMessage(x) } @@ -86,3 +88,9 @@ func (u *baseUtilityUnitOfWork) getUpdateIBCStoreSingerCandidates(msg *ibcTypes. func (u *baseUtilityUnitOfWork) getPruneIBCStoreSingerCandidates(msg *ibcTypes.PruneIBCStore) ([][]byte, coreTypes.Error) { return [][]byte{msg.Signer}, nil } + +func (u *baseUtilityUnitOfWork) getMessageUpgradeSignerCandidates(msg *typesUtil.MessageUpgrade) ([][]byte, coreTypes.Error) { + return [][]byte{msg.Signer}, nil +} + +// TODO: 0xbigboss MessageCancelUpgrade From 4408e6adcd49d38d341f9bb53c94ac540c8f3690 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 12:46:47 -0400 Subject: [PATCH 09/27] =?UTF-8?q?=F0=9F=90=B3=20docker=20tweaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/deployments/docker-compose.yaml | 34 ++++++++++++++++++--------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/build/deployments/docker-compose.yaml b/build/deployments/docker-compose.yaml index 366967711..5fbb1abec 100755 --- a/build/deployments/docker-compose.yaml +++ b/build/deployments/docker-compose.yaml @@ -35,6 +35,8 @@ services: build: context: ../.. dockerfile: ./build/Dockerfile.localdev + depends_on: + - db expose: - "7081" # dlv debug - "9000" @@ -52,10 +54,10 @@ services: environment: - POCKET_RPC_USE_CORS=true - LIBP2P_DEBUG=info - # Uncomment to enable the pprof server - # - PPROF_ENABLED=true - # Uncomment to enable DLV debugging - # - DEBUG_PORT=7081 + # Uncomment to enable the pprof server + # - PPROF_ENABLED=true + # Uncomment to enable DLV debugging + - DEBUG_PORT=7081 validator2: logging: *loki-logging @@ -65,6 +67,8 @@ services: build: context: ../.. dockerfile: ./build/Dockerfile.localdev + depends_on: + - db expose: - "7082" # dlv debug - "42069" @@ -80,8 +84,8 @@ services: security_opt: - "seccomp:unconfined" # Uncomment to enable DLV debugging - # environment: - # - DEBUG_PORT=7082 + environment: + - DEBUG_PORT=7082 validator3: logging: *loki-logging @@ -91,6 +95,8 @@ services: build: context: ../.. dockerfile: ./build/Dockerfile.localdev + depends_on: + - db expose: - "7083" # dlv debug - "42069" @@ -106,8 +112,8 @@ services: security_opt: - "seccomp:unconfined" # Uncomment to enable DLV debugging - # environment: - # - DEBUG_PORT=7083 + environment: + - DEBUG_PORT=7083 validator4: logging: *loki-logging @@ -117,6 +123,8 @@ services: build: context: ../.. dockerfile: ./build/Dockerfile.localdev + depends_on: + - db expose: - "7084" # dlv debug - "42069" @@ -131,9 +139,9 @@ services: # Needed for DLV debugging security_opt: - "seccomp:unconfined" - # Uncomment to enable DLV debugging - # environment: - # - DEBUG_PORT=7084 + # Uncomment to enable DLV debugging + environment: + - DEBUG_PORT=7084 servicer1: logging: *loki-logging @@ -151,6 +159,8 @@ services: build: context: ../.. dockerfile: ./build/Dockerfile.localdev + depends_on: + - db expose: - "7085" # dlv debug - "42069" @@ -188,6 +198,8 @@ services: build: context: ../.. dockerfile: ./build/Dockerfile.localdev + depends_on: + - db expose: - "7086" # dlv debug - "42069" From d34715a4bf7b1fd0be1807106773f642ed988d87 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 13:29:21 -0400 Subject: [PATCH 10/27] =?UTF-8?q?=F0=9F=92=B8=20to=20acl=20owner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/config/genesis.json | 4 ++++ build/config/genesis_localhost.json | 4 ++++ charts/pocket/templates/configmap-genesis.yaml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/build/config/genesis.json b/build/config/genesis.json index efa8d4ca5..68dee8f79 100755 --- a/build/config/genesis.json +++ b/build/config/genesis.json @@ -1583,6 +1583,10 @@ { "address": "099044a5282c4089976c6b13ab13e5423dae55ce", "amount": "100000000000000" + }, + { + "address": "da034209758b78eaea06dd99c07909ab54c99b45", + "amount": "100000000000000" } ], "applications": [ diff --git a/build/config/genesis_localhost.json b/build/config/genesis_localhost.json index d53d19766..7b518daf5 100755 --- a/build/config/genesis_localhost.json +++ b/build/config/genesis_localhost.json @@ -27,6 +27,10 @@ { "address": "88a792b7aca673620132ef01f50e62caa58eca83", "amount": "100000000000000" + }, + { + "address": "da034209758b78eaea06dd99c07909ab54c99b45", + "amount": "100000000000000" } ], "pools": [ diff --git a/charts/pocket/templates/configmap-genesis.yaml b/charts/pocket/templates/configmap-genesis.yaml index 4f16bf817..fe5cb4e9c 100644 --- a/charts/pocket/templates/configmap-genesis.yaml +++ b/charts/pocket/templates/configmap-genesis.yaml @@ -1593,6 +1593,10 @@ data: { "address": "099044a5282c4089976c6b13ab13e5423dae55ce", "amount": "100000000000000" + }, + { + "address": "da034209758b78eaea06dd99c07909ab54c99b45", + "amount": "100000000000000" } ], "pools": [ From ff0ea1658ba5e2d80bf3c34fcfce127c31ef5b4f Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 16:26:08 -0400 Subject: [PATCH 11/27] =?UTF-8?q?=F0=9F=93=9D=20persistence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/client/cli/query.go | 2 +- persistence/db.go | 4 ++++ persistence/debug.go | 1 + persistence/gov.go | 22 +++++++++++++++------ persistence/sql/sql.go | 13 ++++++++++++ persistence/trees/trees.go | 23 +++++++++++++++++++++- persistence/types/gov.go | 20 +++++++++++++++++++ rpc/utils.go | 23 ++++++++++++++++++++++ rpc/v1/openapi.yaml | 17 ++++++++++++++++ runtime/manager_test.go | 4 ++++ shared/core/types/proto/upgrade.proto | 17 ++++++++++++++++ shared/modules/persistence_module.go | 6 +++--- utility/unit_of_work/tx_message_handler.go | 7 +++++-- 13 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 shared/core/types/proto/upgrade.proto diff --git a/app/client/cli/query.go b/app/client/cli/query.go index 0552b8c30..78401a20a 100644 --- a/app/client/cli/query.go +++ b/app/client/cli/query.go @@ -379,7 +379,7 @@ func queryHeightCommands() []*cobra.Command { Use: "Upgrade [--height]", Short: "Get the upgrade version", Long: "Queries the node RPC to obtain the upgrade version for the given (or latest if unspecified) height", - Aliases: []string{"param"}, + Aliases: []string{"upgrade"}, Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { client, err := rpc.NewClientWithResponses(flags.RemoteCLIURL) diff --git a/persistence/db.go b/persistence/db.go index 73e64cada..84b5af81e 100644 --- a/persistence/db.go +++ b/persistence/db.go @@ -180,6 +180,10 @@ func initializeGovTables(ctx context.Context, db *pgxpool.Conn) error { return err } + if _, err := db.Exec(ctx, types.UpgradesTableSchema); err != nil { + return err + } + return nil } diff --git a/persistence/debug.go b/persistence/debug.go index eb0577f5e..3ddebe612 100644 --- a/persistence/debug.go +++ b/persistence/debug.go @@ -13,6 +13,7 @@ var nonActorClearFunctions = []func() string{ types.Pool.ClearAllAccounts, types.ClearAllGovParamsQuery, types.ClearAllGovFlagsQuery, + types.ClearAllUpgradesQuery, types.ClearAllBlocksQuery, types.ClearAllIBCStoreQuery, types.ClearAllIBCEventsQuery, diff --git a/persistence/gov.go b/persistence/gov.go index 609a8b6d5..7decb8ba7 100644 --- a/persistence/gov.go +++ b/persistence/gov.go @@ -2,7 +2,6 @@ package persistence import ( "encoding/hex" - "errors" "fmt" "strconv" @@ -12,10 +11,16 @@ import ( "github.com/pokt-network/pocket/shared/modules" ) -// TODO(0xbigboss): Implement this function func (p *PostgresContext) GetVersionAtHeight(height int64) (string, error) { - // This is a placeholder function for the RPC endpoint "v1/query/upgrade" - return "", nil + ctx, tx := p.getCtxAndTx() + var version string + row := tx.QueryRow(ctx, ` + SELECT version FROM upgrades WHERE height <= $1 ORDER BY height DESC LIMIT 1 +`, height) + if err := row.Scan(&version); err != nil { + return "", err + } + return version, nil } // TODO(#882): Implement this function @@ -35,6 +40,7 @@ func (p *PostgresContext) InitGenesisParams(params *genesis.Params) error { return fmt.Errorf("cannot initialize params at height %d", p.Height) } _, err := tx.Exec(ctx, types.InsertParams(params, p.Height)) + p.SetUpgrade(params.AclOwner, "1.0.0", p.Height) return err } @@ -191,6 +197,10 @@ func (p *PostgresContext) getLatestParamsOrFlagsQuery(tableName string) string { return fmt.Sprintf("SELECT DISTINCT ON (name) %s FROM %s ORDER BY name ASC,%s.height DESC", fields, tableName, tableName) } -func (p *PostgresContext) SetUpgrade(version string, height int64) error { - return errors.New("not implemented") +func (p *PostgresContext) SetUpgrade(signer string, version string, height int64) error { + ctx, tx := p.getCtxAndTx() + _, err := tx.Exec(ctx, ` +INSERT INTO upgrades(signer, version, height, created) VALUES ($1, $2, $3, $4) + `, signer, version, height, p.Height) + return err } diff --git a/persistence/sql/sql.go b/persistence/sql/sql.go index 9e99189bb..3a02d7af4 100644 --- a/persistence/sql/sql.go +++ b/persistence/sql/sql.go @@ -154,6 +154,19 @@ func GetParams(pgtx pgx.Tx, height uint64) ([]*coreTypes.Param, error) { return paramSlice, nil } +func GetUpgrade(pgtx pgx.Tx, height uint64) (*coreTypes.Upgrade, error) { + row := pgtx.QueryRow(context.Background(), ` +select signer, version, height, created from upgrades where created = $1 +`, height) + + upgrade := new(coreTypes.Upgrade) + if err := row.Scan(&upgrade.Signer, &upgrade.Version, &upgrade.Height, &upgrade.Created); err != nil { + return nil, err + } + + return upgrade, nil +} + // GetIBCStoreUpdates returns the set of key-value pairs updated at the current height for the IBC store func GetIBCStoreUpdates(pgtx pgx.Tx, height uint64) (keys, values [][]byte, err error) { fields := "key,value" diff --git a/persistence/trees/trees.go b/persistence/trees/trees.go index 8fdc43676..7ca6b79e2 100644 --- a/persistence/trees/trees.go +++ b/persistence/trees/trees.go @@ -46,6 +46,7 @@ const ( TransactionsTreeName = "transactions" ParamsTreeName = "params" FlagsTreeName = "flags" + UpgradesTreeName = "upgrades" IBCTreeName = "ibc" ) @@ -69,7 +70,7 @@ var stateTreeNames = []string{ // Account Trees AccountTreeName, PoolTreeName, // Data Trees - TransactionsTreeName, ParamsTreeName, FlagsTreeName, IBCTreeName, + TransactionsTreeName, ParamsTreeName, FlagsTreeName, UpgradesTreeName, IBCTreeName, } // stateTree is a wrapper around the SMT that contains an identifying @@ -250,6 +251,14 @@ func (t *treeStore) updateMerkleTrees(pgtx pgx.Tx, txi indexer.TxIndexer, height if err := t.updateFlagsTree(flags); err != nil { return "", fmt.Errorf("failed to update flags tree - %w", err) } + case UpgradesTreeName: + upgrade, err := sql.GetUpgrade(pgtx, height) + if err != nil { + return "", fmt.Errorf("failed to get upgrade from transaction: %w", err) + } + if err := t.updateUpgradeTree(upgrade); err != nil { + return "", fmt.Errorf("failed to update upgrade tree - %w", err) + } case IBCTreeName: keys, values, err := sql.GetIBCStoreUpdates(pgtx, height) if err != nil { @@ -477,6 +486,18 @@ func (t *treeStore) updateFlagsTree(flags []*coreTypes.Flag) error { return nil } +func (t *treeStore) updateUpgradeTree(upgrade *coreTypes.Upgrade) error { + upgradeBz, err := codec.GetCodec().Marshal(upgrade) + if err != nil { + return err + } + upgradeKey := crypto.SHA3Hash([]byte(upgrade.Version)) + if err := t.merkleTrees[UpgradesTreeName].tree.Update(upgradeKey, upgradeBz); err != nil { + return err + } + return nil +} + func (t *treeStore) updateIBCTree(keys, values [][]byte) error { if len(keys) != len(values) { return fmt.Errorf("keys and values must be the same length") diff --git a/persistence/types/gov.go b/persistence/types/gov.go index fb393df5b..cf3d8291f 100644 --- a/persistence/types/gov.go +++ b/persistence/types/gov.go @@ -35,6 +35,22 @@ const ( enabled BOOLEAN NOT NULL, PRIMARY KEY(name, height) )` + + UpgradesTableSchema = ` +create table if not exists upgrades +( + signer text not null, + version varchar(10) not null, + height bigint not null unique, + created bigint not null unique, + primary key (version) +); +comment on table upgrades is 'stores the upgrade history of the network'; +comment on column upgrades.signer is 'the address of the signer of the upgrade'; +comment on column upgrades.version is 'the semver 2.0 version of the upgrade'; +comment on column upgrades.height is 'the activation height of the upgrade'; +comment on column upgrades.created is 'the height the upgrade was created'; +` ) var ( @@ -147,3 +163,7 @@ func ClearAllGovParamsQuery() string { func ClearAllGovFlagsQuery() string { return fmt.Sprintf(`DELETE FROM %s`, FlagsTableName) } + +func ClearAllUpgradesQuery() string { + return "DELETE FROM upgrades" +} diff --git a/rpc/utils.go b/rpc/utils.go index 349408bba..5d095356d 100644 --- a/rpc/utils.go +++ b/rpc/utils.go @@ -288,6 +288,25 @@ func (s *rpcServer) txBytesToRPCTxMsg(txBz []byte, messageType string) (*TxMessa ParameterValue: values[1], }, } + case "MessageUpgrade": + m := new(utilTypes.MessageUpgrade) + if err := anypb.UnmarshalTo(m); err != nil { + return nil, err + } + fee, err := s.calculateMessageFeeForActor(m.GetActorType(), messageType) + if err != nil { + return nil, err + } + txMsg.Fee = Fee{ + Amount: fee, + Denom: "upokt", + } + txMsg.Message = MessageUpgrade{ + Signer: hex.EncodeToString(m.GetSigner()), + Version: m.GetVersion(), + Height: m.GetHeight(), + } + // TODO: 0xbigboss MessageCancelUpgrade default: return nil, fmt.Errorf("unknown message type: %s", messageType) } @@ -308,6 +327,10 @@ func (s *rpcServer) calculateMessageFeeForActor(actorType coreTypes.ActorType, m if messageType == "MessageChangeParameter" { return readCtx.GetStringParam(utilTypes.MessageChangeParameterFee, height) } + if messageType == "MessageUpgrade" { + return readCtx.GetStringParam(utilTypes.MessageUpgradeFee, height) + } + // TODO: 0xbigboss MessageCancelUpgrade switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: switch messageType { diff --git a/rpc/v1/openapi.yaml b/rpc/v1/openapi.yaml index c068b4238..90945d565 100644 --- a/rpc/v1/openapi.yaml +++ b/rpc/v1/openapi.yaml @@ -1694,6 +1694,21 @@ components: type: "string" parameter_value: type: "string" + MessageUpgrade: + type: object + required: + - signer + - version + - height + properties: + signer: + type: string + version: + type: string + height: + type: integer + format: int64 + # TODO: 0xbigboss MessageCancelUpgrade PartialSignature: type: object required: @@ -1815,6 +1830,8 @@ components: - $ref: "#/components/schemas/MessageUnstake" - $ref: "#/components/schemas/MessageUnpause" - $ref: "#/components/schemas/MessageChangeParameter" + - $ref: "#/components/schemas/MessageUpgrade" + # TODO: 0xbigboss MessageCancelUpgrade nonce: type: string signature: diff --git a/runtime/manager_test.go b/runtime/manager_test.go index dbd1b009f..d794b4894 100644 --- a/runtime/manager_test.go +++ b/runtime/manager_test.go @@ -1635,6 +1635,10 @@ var expectedGenesis = &genesis.GenesisState{ Address: "099044a5282c4089976c6b13ab13e5423dae55ce", Amount: "100000000000000", }, + { + Address: "da034209758b78eaea06dd99c07909ab54c99b45", + Amount: "100000000000000", + }, }, Applications: []*types.Actor{ { diff --git a/shared/core/types/proto/upgrade.proto b/shared/core/types/proto/upgrade.proto new file mode 100644 index 000000000..d496d9d2c --- /dev/null +++ b/shared/core/types/proto/upgrade.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package core; + +option go_package = "github.com/pokt-network/pocket/shared/core/types"; + +// Upgrade the network to a new version +message Upgrade { + // Address of the account that is initiating the upgrade + string signer = 1; + // Version of the software to upgrade to in semver 2.0 format + string version = 2; + // Height at which the upgrade must be performed + int64 height = 3; + // Height upgrade was created + int64 created = 4; +} diff --git a/shared/modules/persistence_module.go b/shared/modules/persistence_module.go index 39ad6a42c..66a3ef55d 100644 --- a/shared/modules/persistence_module.go +++ b/shared/modules/persistence_module.go @@ -151,7 +151,7 @@ type PersistenceWriteContext interface { SetFlag(paramName string, value any, enabled bool) error // Upgrade Operations - SetUpgrade(version string, height int64) error + SetUpgrade(signer string, version string, height int64) error // IBC Operations // SetIBCStoreEntry sets the key-value pair in the ibc_entries table at the current height the @@ -172,8 +172,8 @@ type PersistenceReadContext interface { Release() // Releases the read context // Version queries - GetVersionAtHeight(height int64) (string, error) // TODO(0xbigboss): Implement this - GetRevisionNumber(height int64) uint64 // TODO(#882): Implement this + GetVersionAtHeight(height int64) (string, error) + GetRevisionNumber(height int64) uint64 // TODO(#882): Implement this // Supported Chains Queries GetSupportedChains(height int64) ([]string, error) // TODO: Implement this diff --git a/utility/unit_of_work/tx_message_handler.go b/utility/unit_of_work/tx_message_handler.go index 9fc4489b9..2d620b971 100644 --- a/utility/unit_of_work/tx_message_handler.go +++ b/utility/unit_of_work/tx_message_handler.go @@ -243,8 +243,11 @@ func (u *baseUtilityUnitOfWork) handlePruneIBCStore(message *ibcTypes.PruneIBCSt } func (u *baseUtilityUnitOfWork) handleMessageUpgrade(message *typesUtil.MessageUpgrade) coreTypes.Error { - u.logger.Info().Str("version", message.Version).Int64("height", message.Height).Msg("setting upgrade") - if err := u.persistenceRWContext.SetUpgrade(message.Version, message.Height); err != nil { + u.logger.Debug().Str("version", message.Version).Int64("height", message.Height).Msg("setting upgrade") + + // validate new upgrade + + if err := u.persistenceRWContext.SetUpgrade(hex.EncodeToString(message.Signer), message.Version, message.Height); err != nil { return coreTypes.ErrSettingUpgrade(err) } return nil From 8ff4565a7398331b0b76b8e6aa2e8b3aaaf22eed Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 17:42:32 -0400 Subject: [PATCH 12/27] fix tests, handle when no upgrades --- persistence/gov.go | 19 +++++++++++++++---- persistence/sql/sql.go | 3 +++ persistence/test/benchmark_state_test.go | 8 ++++++-- persistence/test/state_test.go | 6 +++--- persistence/trees/trees.go | 3 +++ utility/session_test.go | 2 +- 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/persistence/gov.go b/persistence/gov.go index 7decb8ba7..61b0e1385 100644 --- a/persistence/gov.go +++ b/persistence/gov.go @@ -40,7 +40,14 @@ func (p *PostgresContext) InitGenesisParams(params *genesis.Params) error { return fmt.Errorf("cannot initialize params at height %d", p.Height) } _, err := tx.Exec(ctx, types.InsertParams(params, p.Height)) - p.SetUpgrade(params.AclOwner, "1.0.0", p.Height) + if err != nil { + return err + } + _, err = tx.Exec(ctx, ` +INSERT INTO upgrades (signer, version, height, created) VALUES ($1, $2, $3, $4) +ON CONFLICT (version) +DO UPDATE SET signer=EXCLUDED.signer, version=EXCLUDED.version, height=EXCLUDED.height, created=EXCLUDED.created +`, params.AclOwner, "1.0.0", p.Height, p.Height) return err } @@ -197,10 +204,14 @@ func (p *PostgresContext) getLatestParamsOrFlagsQuery(tableName string) string { return fmt.Sprintf("SELECT DISTINCT ON (name) %s FROM %s ORDER BY name ASC,%s.height DESC", fields, tableName, tableName) } -func (p *PostgresContext) SetUpgrade(signer string, version string, height int64) error { +func (p *PostgresContext) SetUpgrade(signer, version string, height int64) error { ctx, tx := p.getCtxAndTx() _, err := tx.Exec(ctx, ` INSERT INTO upgrades(signer, version, height, created) VALUES ($1, $2, $3, $4) - `, signer, version, height, p.Height) - return err +`, signer, version, height, p.Height) + if err != nil { + p.logger.Debug().Err(err).Msg("failed to insert upgrade") + return err + } + return nil } diff --git a/persistence/sql/sql.go b/persistence/sql/sql.go index 3a02d7af4..a83a2703c 100644 --- a/persistence/sql/sql.go +++ b/persistence/sql/sql.go @@ -161,6 +161,9 @@ select signer, version, height, created from upgrades where created = $1 upgrade := new(coreTypes.Upgrade) if err := row.Scan(&upgrade.Signer, &upgrade.Version, &upgrade.Height, &upgrade.Created); err != nil { + if err == pgx.ErrNoRows { + return nil, nil + } return nil, err } diff --git a/persistence/test/benchmark_state_test.go b/persistence/test/benchmark_state_test.go index 6f01efaca..6ba769b51 100644 --- a/persistence/test/benchmark_state_test.go +++ b/persistence/test/benchmark_state_test.go @@ -113,8 +113,12 @@ MethodLoop: arg := method.Type.In(i) switch arg.Kind() { case reflect.String: - // String values in modifier functions are usually amounts - v = reflect.ValueOf(getRandomIntString(maxStringAmount)) + if methodName == "SetUpgrade" { + v = reflect.ValueOf(fmt.Sprintf("%d.0.0", p.Height+1)) + } else { + // String values in modifier functions are usually amounts + v = reflect.ValueOf(getRandomIntString(maxStringAmount)) + } case reflect.Slice: switch arg.Elem().Kind() { case reflect.Uint8: diff --git a/persistence/test/state_test.go b/persistence/test/state_test.go index 9cd767e6f..688728ca4 100644 --- a/persistence/test/state_test.go +++ b/persistence/test/state_test.go @@ -42,9 +42,9 @@ func TestStateHash_DeterministicStateWhenUpdatingAppStake(t *testing.T) { // logic changes, these hashes will need to be updated based on the test output. // TODO: Add an explicit updateSnapshots flag to the test to make this more clear. stateHashes := []string{ - "379cb08579d2ddd78c8f9c8deddf65c77a9d3bae81d670bb8cbd3c2c394e4e51", - "d6a2ad957b2cb1f91095dde9ca052f180c79ec853c242a6b4ea3c798e5e1e20f", - "f8ef2678a97a3e6ea4c2bdec172af03def9c596dec0db708bd414b0e0c49c25a", + "4381dbb013b2003963600ba22492c904e22f3dab48c0b75f4ce55d9e7f030b0b", + "156633eda7aabf49764167a80df4818c2521ad266e3647c97e3e076f910e2658", + "cb9825b7a5b434c04ae735f1f731aa9fa288bf392c7a9afcbca172b472998892", } stakeAmount := initialStakeAmount diff --git a/persistence/trees/trees.go b/persistence/trees/trees.go index 7ca6b79e2..233e31317 100644 --- a/persistence/trees/trees.go +++ b/persistence/trees/trees.go @@ -487,6 +487,9 @@ func (t *treeStore) updateFlagsTree(flags []*coreTypes.Flag) error { } func (t *treeStore) updateUpgradeTree(upgrade *coreTypes.Upgrade) error { + if upgrade == nil { + return nil + } upgradeBz, err := codec.GetCodec().Marshal(upgrade) if err != nil { return err diff --git a/utility/session_test.go b/utility/session_test.go index 0766a09c1..aa8682dcb 100644 --- a/utility/session_test.go +++ b/utility/session_test.go @@ -25,7 +25,7 @@ func TestSession_GetSession_SingleFishermanSingleServicerBaseCase(t *testing.T) numFishermen := 1 numServicers := 1 // needs to be manually updated if business logic changes - expectedSessionId := "b21c41eceba7d8b338e6a51f2519373042b0b23ec1dfe9967c5819d57c60db17" + expectedSessionId := "d64fa91d59e4fdf89130455ebd88dfced45ff166bc4a53323bdf4dd24c02a5f2" runtimeCfg, utilityMod, _ := prepareEnvironment(t, 5, numServicers, 1, numFishermen) From f96a3f1201abc14bae9414dce7ac6c55272f4e79 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 17:43:34 -0400 Subject: [PATCH 13/27] fix tests, handle when no upgrades --- app/client/cli/gov.go | 2 -- utility/unit_of_work/module.go | 4 ---- 2 files changed, 6 deletions(-) diff --git a/app/client/cli/gov.go b/app/client/cli/gov.go index f80c1e3bd..250dc9176 100644 --- a/app/client/cli/gov.go +++ b/app/client/cli/gov.go @@ -136,8 +136,6 @@ func govCommands() []*cobra.Command { return err } - // TODO(0xbigboss): be nice and validate the inputs before submitting, instead of reverting tx. - msg := &types.MessageUpgrade{ Signer: pk.Address(), Version: version, diff --git a/utility/unit_of_work/module.go b/utility/unit_of_work/module.go index af337f349..018fcd4e2 100644 --- a/utility/unit_of_work/module.go +++ b/utility/unit_of_work/module.go @@ -156,10 +156,6 @@ func (uow *baseUtilityUnitOfWork) processProposalBlockTransactions() (err error) return err } - if uow.logger.GetLevel().String() == "debug" { - uow.logger.Debug().Str("tx", txHash).Msgf("processing transaction: %+v", tx) - } - if err := tx.ValidateBasic(); err != nil { return err } From 7a1810773566c569b1ef40cead50202aec1b8c04 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 29 Jul 2023 23:44:24 -0400 Subject: [PATCH 14/27] fix flaky test --- persistence/test/benchmark_state_test.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/persistence/test/benchmark_state_test.go b/persistence/test/benchmark_state_test.go index 6ba769b51..f50fd4fbe 100644 --- a/persistence/test/benchmark_state_test.go +++ b/persistence/test/benchmark_state_test.go @@ -84,6 +84,8 @@ func BenchmarkStateHash(b *testing.B) { } } +var methodCallCount = make(map[string]int) + // Calls a random database modifier function on the given persistence context // //nolint:gosec // G404 - Weak random source is okay in unit tests @@ -100,12 +102,21 @@ MethodLoop: method := t.Method(rand.Intn(numMethods)) methodName := method.Name numArgs := method.Type.NumIn() + var count int + if c, ok := methodCallCount[methodName]; ok { + count = c + } // Preliminary filter to determine which functions we're interested in trying to call if !isModifierRe.MatchString(methodName) { continue } + // IMPROVE: This is a hack to prevent the SetUpgrade function from being called more than once + if methodName == "SetUpgrade" && count > 0 { + continue + } + // Build a random set of arguments to pass to the function being called var callArgs []reflect.Value for i := 1; i < numArgs; i++ { @@ -114,7 +125,8 @@ MethodLoop: switch arg.Kind() { case reflect.String: if methodName == "SetUpgrade" { - v = reflect.ValueOf(fmt.Sprintf("%d.0.0", p.Height+1)) + // SetUpgrade takes a string argument that is not an amount + v = reflect.ValueOf(getRandomIntString(99)) } else { // String values in modifier functions are usually amounts v = reflect.ValueOf(getRandomIntString(maxStringAmount)) @@ -144,6 +156,7 @@ MethodLoop: callArgs = append(callArgs, v) } res := reflect.ValueOf(p).MethodByName(method.Name).Call(callArgs) + methodCallCount[methodName]++ var err error if v := res[0].Interface(); v != nil { if mustSucceed { From 53422aac49f1e7282ed33e86f019243ab02a9821 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sun, 30 Jul 2023 14:27:57 -0400 Subject: [PATCH 15/27] e2e checkpoint --- e2e/tests/steps_init_test.go | 62 +++++++++++++++++ e2e/tests/steps_upgrade_test.go | 110 +++++++++++++++++-------------- e2e/tests/upgrade.feature | 18 +++-- e2e/tests/upgrade_cancel.feature | 28 ++++---- 4 files changed, 147 insertions(+), 71 deletions(-) diff --git a/e2e/tests/steps_init_test.go b/e2e/tests/steps_init_test.go index 1f83171f1..ea581fea8 100644 --- a/e2e/tests/steps_init_test.go +++ b/e2e/tests/steps_init_test.go @@ -47,6 +47,8 @@ type rootSuite struct { clientset *kubernetes.Clientset // node holds command results between runs and reports errors to the test suite node *nodePod + // Pending transaction hashes are stored here. + pendingTxs []string } func (s *rootSuite) Before() { @@ -201,6 +203,66 @@ func (s *rootSuite) ShouldBeAtHeight(pod string, height int64) { require.Equal(s, height, *res.Height) } +// TheNetworkCommitsTheTransactions is a step that triggers the next view and verifies that all pending transactions are committed +func (s *rootSuite) TheNetworkCommitsTheTransactions() { + if len(s.pendingTxs) == 0 { + e2eLogger.Info().Msg("no pending transactions to commit") + require.FailNow(s, "no pending transactions to commit") + } + + // trigger the next view + _, err := s.validator.RunCommand("dui", "TriggerNextView") + require.NoError(s, err) + + // Make a copy of the pendingTxs slice to keep track of the transactions still pending + remainingTxs := make([]string, len(s.pendingTxs)) + copy(remainingTxs, s.pendingTxs) + + // wait up to 10 iterations for all txs to be committed + for i := 0; i < 10; i++ { + // List to hold the transactions that are still pending after this iteration + stillPendingTxs := []string{} + + // Iterate over each remaining transaction + for _, tx := range remainingTxs { + + // check if the tx has been committed + res, err := s.validator.RunCommand("query", "tx", tx) + if err != nil { + e2eLogger.Info().Msgf("failed to query tx %s: %s", tx, err.Error()) + stillPendingTxs = append(stillPendingTxs, tx) + continue + } + if strings.Contains(res.Stdout, "Key not found") { + e2eLogger.Info().Msgf("tx %s not found", tx) + stillPendingTxs = append(stillPendingTxs, tx) + continue + } + if strings.Contains(res.Stdout, "tx failed") { + e2eLogger.Info().Msgf("tx %s failed", tx) + stillPendingTxs = append(stillPendingTxs, tx) + continue + } + if strings.Contains(res.Stdout, "tx succeeded") { + e2eLogger.Info().Msgf("tx %s succeeded", tx) + // No need to add the transaction to stillPendingTxs + } + } + + // Update the remainingTxs slice + remainingTxs = stillPendingTxs + + if len(remainingTxs) == 0 { + break + } + } + + if len(remainingTxs) > 0 { + e2eLogger.Info().Msg("Not all pending transactions committed after 10 attempts") + require.FailNow(s, "Not all pending transactions committed after 10 attempts") + } +} + func (s *rootSuite) TheUserShouldBeAbleToSeeStandardOutputContaining(arg1 string) { require.Contains(s, s.node.result.Stdout, arg1) } diff --git a/e2e/tests/steps_upgrade_test.go b/e2e/tests/steps_upgrade_test.go index 665a01b60..303189957 100644 --- a/e2e/tests/steps_upgrade_test.go +++ b/e2e/tests/steps_upgrade_test.go @@ -2,60 +2,70 @@ package e2e -import "github.com/stretchr/testify/require" - -func (s *rootSuite) UserHasAValidCancelUpgradeCommandWithSignerAndVersion() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) UserHasACancelUpgradeCommandForAPastVersion() { - require.Fail(s, "implement me") +import ( + "fmt" + "strings" + + "github.com/blang/semver/v4" + "github.com/pokt-network/pocket/rpc" + "github.com/pokt-network/pocket/runtime/test_artifacts" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/json" +) + +func (s *rootSuite) TheUserSubmitsAMajorProtocolUpgrade() { + res, err := s.validator.RunCommand("query", "upgrade") + require.NoError(s, err) + + var qur rpc.QueryUpgradeResponse + // TECHDEBT: cli outputs debug logs so scan for our answer + for _, line := range strings.Split(res.Stdout, "\n") { + // parse into QueryUpgradeResponse + err = json.Unmarshal([]byte(line), &qur) + if err == nil && qur.Version != "" { + break + } + } + require.NoError(s, err) + + // submit a major protocol upgrade + newVersion, err := semver.Parse(qur.Version) + require.NoError(s, err) + newVersion.Major++ + res, err = s.validator.RunCommand("gov", "upgrade", test_artifacts.DefaultParams().AclOwner, newVersion.String(), fmt.Sprint(qur.Height+1)) + require.NoError(s, err) + + // TECHBDEBT: cli outputs debug logs last non-blank line is our answer + var lines = strings.Split(res.Stdout, "\n") + var answer string + for i := len(lines) - 1; i >= 0; i-- { + if lines[i] != "" { + answer = lines[i] + break + } + } + // ensure it is a valid sha256 hash + require.Regexp(s, "^([a-f0-9]{64})$", answer, "invalid tx hash") + s.pendingTxs = append(s.pendingTxs, answer) + s.validator.result = res } -func (s *rootSuite) TheSystemShouldCancelTheScheduledUpgrade() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSpecifiedUpgradeIsScheduledAndNotYetActivated() { - require.Fail(s, "implement me") -} +func (s *rootSuite) TheSystemReachesTheUpgradeHeight() { + for { + res, err := s.validator.RunCommand("query", "upgrade") + require.NoError(s, err) -func (s *rootSuite) TheSystemShouldRejectTheCommandAsItCannotCancelAPastUpgrade() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldValidateTheCommand() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldSuccessfullyAcceptTheCommand() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldReturnTheUpdatedProtocolVersion() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldRejectTheCommandDueToInvalidInput() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldRejectTheCommandDueToTooManyVersionsAhead() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldReturnTheSuccessfulCancellationStatus() { - require.Fail(s, "implement me") -} - -func (s *rootSuite) TheSystemShouldApplyTheProtocolUpgradeAtTheSpecifiedActivationHeight() { - require.Fail(s, "implement me") -} + // parse into QueryUpgradeResponse + var qur rpc.QueryUpgradeResponse + err = json.Unmarshal([]byte(res.Stdout), &qur) + require.NoError(s, err) -func (s *rootSuite) TheUserHasAnInvalidUpgradeProtocolCommand() { - require.Fail(s, "implement me") + if qur.Height > 0 { + break + } + } } -func (s *rootSuite) TheUserHasAUpgradeProtocolCommandWithTooManyVersionsJump() { - require.Fail(s, "implement me") +func (s *rootSuite) TheUserShouldBeAbleToSeeTheNewVersion() { + panic("PENDING") } diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature index fcb5c4d4a..06adeba40 100644 --- a/e2e/tests/upgrade.feature +++ b/e2e/tests/upgrade.feature @@ -1,15 +1,19 @@ Feature: Upgrade Protocol - Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI - Given the user is an ACL Owner - When the user runs the command "gov upgrade " - Then the user should be able to see standard output containing "" - When the user runs the command "gov query upgrade" + Scenario: User can query the current protocol version using CLI + Given the user runs the command "query upgrade" Then the user should be able to see standard output containing "" Examples: - | owner | version | height | stdout | - | da034209758b78eaea06dd99c07909ab54c99b45 | 2.0.0 | 100 | 2.0.0 | + | version | + | 1.0.0 | + + Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI + Given the user is an ACL Owner + When the user submits a major protocol upgrade + And the network commits the transactions + When the user runs the command "query upgrade" + Then the user should be able to see the new version Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI Given the user is an ACL Owner diff --git a/e2e/tests/upgrade_cancel.feature b/e2e/tests/upgrade_cancel.feature index c27bb5faf..5fbb80a38 100644 --- a/e2e/tests/upgrade_cancel.feature +++ b/e2e/tests/upgrade_cancel.feature @@ -1,16 +1,16 @@ -Feature: Upgrade Protocol Cancel +# Feature: Upgrade Protocol Cancel - Scenario: User Successfully Cancels a Scheduled Upgrade using CLI - Given the user is an ACL Owner - And the specified upgrade is scheduled and not yet activated - When the user runs the command "gov cancel_upgrade" - Then the system should cancel the scheduled upgrade - When user runs the command "gov query upgrade" - Then the system should return the successful cancellation status +# Scenario: User Successfully Cancels a Scheduled Upgrade using CLI +# Given the user is an ACL Owner +# And the specified upgrade is scheduled and not yet activated +# When the user runs the command "gov cancel_upgrade" +# Then the system should cancel the scheduled upgrade +# When user runs the command "gov query upgrade" +# Then the system should return the successful cancellation status - Scenario: User Attempts to Cancel a Past Upgrade using CLI - Given the user is an ACL Owner - And the user has a cancel upgrade command for a past version - When the user runs the command "gov cancel_upgrade" - Then the system should validate the command - And the system should reject the command as it cannot cancel a past upgrade +# Scenario: User Attempts to Cancel a Past Upgrade using CLI +# Given the user is an ACL Owner +# And the user has a cancel upgrade command for a past version +# When the user runs the command "gov cancel_upgrade" +# Then the system should validate the command +# And the system should reject the command as it cannot cancel a past upgrade From c843e4733e403591c104c3fb1395ad6c9878925a Mon Sep 17 00:00:00 2001 From: BigBoss Date: Mon, 31 Jul 2023 22:44:20 -0400 Subject: [PATCH 16/27] speed up local dev dockerfiles --- build/Dockerfile.client | 11 +---------- build/Dockerfile.localdev | 4 ++-- build/deployments/docker-compose.yaml | 14 +++++++------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/build/Dockerfile.client b/build/Dockerfile.client index 0999c339b..ea776476f 100644 --- a/build/Dockerfile.client +++ b/build/Dockerfile.client @@ -1,4 +1,4 @@ -ARG GOLANG_IMAGE_VERSION=golang:1.20-alpine3.16 +ARG GOLANG_IMAGE_VERSION=golang:1.20-bookworm FROM ${GOLANG_IMAGE_VERSION} AS builder @@ -6,12 +6,3 @@ ENV POCKET_ROOT=/go/src/github.com/pocket-network WORKDIR $POCKET_ROOT -COPY . . - -# Install bash -RUN apk add --no-cache bash - -# Hot reloading -RUN go install github.com/cespare/reflex@latest - -CMD ["/bin/bash"] diff --git a/build/Dockerfile.localdev b/build/Dockerfile.localdev index b337472cd..464a8b3f4 100644 --- a/build/Dockerfile.localdev +++ b/build/Dockerfile.localdev @@ -12,8 +12,6 @@ ENV POCKET_ROOT=/go/src/github.com/pocket-network/ # Source code WORKDIR $POCKET_ROOT -COPY . . - # Hot reloading RUN go install github.com/cespare/reflex@latest @@ -25,3 +23,5 @@ RUN go install github.com/go-delve/delve/cmd/dlv@latest # Needed to make `go install dlv` and `dlv debug` work... RUN apk update && apk add --no-cache gcc musl-dev RUN go get github.com/go-delve/delve/cmd/dlv@latest + +COPY . . diff --git a/build/deployments/docker-compose.yaml b/build/deployments/docker-compose.yaml index 5fbb1abec..20324f598 100755 --- a/build/deployments/docker-compose.yaml +++ b/build/deployments/docker-compose.yaml @@ -23,7 +23,7 @@ services: # Any host that is visible and connected to the cluster can be arbitrarily selected as the RPC host - POCKET_REMOTE_CLI_URL=http://validator1:50832 volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached stdin_open: true tty: true @@ -47,7 +47,7 @@ services: - "${VALIDATOR1_P2P_PORT:-0.0.0.0:42070}:42069" - "${VALIDATOR1_RPC_PORT:-0.0.0.0:50832}:50832" volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached # Needed for DLV debugging security_opt: - "seccomp:unconfined" @@ -79,7 +79,7 @@ services: - "${VALIDATOR2_P2P_PORT:-0.0.0.0:42071}:42069" - "${VALIDATOR2_RPC_PORT:-0.0.0.0:50833}:50832" volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached # Needed for DLV debugging security_opt: - "seccomp:unconfined" @@ -107,7 +107,7 @@ services: - "${VALIDATOR3_P2P_PORT:-0.0.0.0:42072}:42069" - "${VALIDATOR3_RPC_PORT:-0.0.0.0:50834}:50832" volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached # Needed for DLV debugging security_opt: - "seccomp:unconfined" @@ -135,7 +135,7 @@ services: - "${VALIDATOR4_P2P_PORT:-0.0.0.0:42073}:42069" - "${VALIDATOR4_RPC_PORT:-0.0.0.0:50835}:50832" volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached # Needed for DLV debugging security_opt: - "seccomp:unconfined" @@ -171,7 +171,7 @@ services: - "${SERVICER1_P2P_PORT:-0.0.0.0:42074}:42069" - "${SERVICER1_RPC_PORT:-0.0.0.0:50836}:50832" volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached # Needed for DLV debugging security_opt: - "seccomp:unconfined" @@ -210,7 +210,7 @@ services: - "${FISHERMAN1_P2P_PORT:-0.0.0.0:42075}:42069" - "${FISHERMAN1_RPC_PORT:-0.0.0.0:50837}:50832" volumes: - - ${PWD}:/go/src/github.com/pocket-network + - ${PWD}:/go/src/github.com/pocket-network:cached # Needed for DLV debugging security_opt: - "seccomp:unconfined" From e33bc06261a73caaabc65bdc998cdb8fd112f7df Mon Sep 17 00:00:00 2001 From: BigBoss Date: Fri, 4 Aug 2023 18:24:35 -0400 Subject: [PATCH 17/27] wip on fixing e2e --- build/Dockerfile.localdev | 10 ++-------- e2e/tests/steps_gov_test.go | 4 ++-- e2e/tests/steps_init_test.go | 4 ++-- e2e/tests/steps_upgrade_test.go | 8 ++++---- e2e/tests/upgrade.feature | 26 ++++++++++++++++++++++---- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/build/Dockerfile.localdev b/build/Dockerfile.localdev index 464a8b3f4..00b17694a 100644 --- a/build/Dockerfile.localdev +++ b/build/Dockerfile.localdev @@ -12,16 +12,10 @@ ENV POCKET_ROOT=/go/src/github.com/pocket-network/ # Source code WORKDIR $POCKET_ROOT +RUN apk update && apk add --no-cache build-base gcc musl-dev + # Hot reloading RUN go install github.com/cespare/reflex@latest -RUN apk add build-base - # Debugging RUN go install github.com/go-delve/delve/cmd/dlv@latest - -# Needed to make `go install dlv` and `dlv debug` work... -RUN apk update && apk add --no-cache gcc musl-dev -RUN go get github.com/go-delve/delve/cmd/dlv@latest - -COPY . . diff --git a/e2e/tests/steps_gov_test.go b/e2e/tests/steps_gov_test.go index 1be60dbc6..473e54da1 100644 --- a/e2e/tests/steps_gov_test.go +++ b/e2e/tests/steps_gov_test.go @@ -9,13 +9,13 @@ import ( // Ensures that the test artifact DefaultParamsOwner is imported into the CLI keybase. func (s *rootSuite) TheUserIsAnAclOwner() { - res, err := s.validator.RunCommand("keys", + res, err := s.node.RunCommand("keys", "import", test_artifacts.DefaultParamsOwner.String(), ) require.NoError(s, err) require.Contains(s, res.Stdout, "Key imported") - res, err = s.validator.RunCommand("keys", "get", test_artifacts.DefaultParamsOwner.Address().String()) + res, err = s.node.RunCommand("keys", "get", test_artifacts.DefaultParamsOwner.Address().String()) if err != nil { e2eLogger.Error().AnErr("error", err).Str("stdout", res.Stdout).Str("stderr", res.Stderr).Msgf("failed to get acl owner key") require.NoError(s, err) diff --git a/e2e/tests/steps_init_test.go b/e2e/tests/steps_init_test.go index ea581fea8..7818f9ba0 100644 --- a/e2e/tests/steps_init_test.go +++ b/e2e/tests/steps_init_test.go @@ -211,7 +211,7 @@ func (s *rootSuite) TheNetworkCommitsTheTransactions() { } // trigger the next view - _, err := s.validator.RunCommand("dui", "TriggerNextView") + _, err := s.node.RunCommand("Debug", "TriggerView") require.NoError(s, err) // Make a copy of the pendingTxs slice to keep track of the transactions still pending @@ -227,7 +227,7 @@ func (s *rootSuite) TheNetworkCommitsTheTransactions() { for _, tx := range remainingTxs { // check if the tx has been committed - res, err := s.validator.RunCommand("query", "tx", tx) + res, err := s.node.RunCommand("query", "tx", tx) if err != nil { e2eLogger.Info().Msgf("failed to query tx %s: %s", tx, err.Error()) stillPendingTxs = append(stillPendingTxs, tx) diff --git a/e2e/tests/steps_upgrade_test.go b/e2e/tests/steps_upgrade_test.go index 303189957..6a1c96bb2 100644 --- a/e2e/tests/steps_upgrade_test.go +++ b/e2e/tests/steps_upgrade_test.go @@ -14,7 +14,7 @@ import ( ) func (s *rootSuite) TheUserSubmitsAMajorProtocolUpgrade() { - res, err := s.validator.RunCommand("query", "upgrade") + res, err := s.node.RunCommand("query", "upgrade") require.NoError(s, err) var qur rpc.QueryUpgradeResponse @@ -32,7 +32,7 @@ func (s *rootSuite) TheUserSubmitsAMajorProtocolUpgrade() { newVersion, err := semver.Parse(qur.Version) require.NoError(s, err) newVersion.Major++ - res, err = s.validator.RunCommand("gov", "upgrade", test_artifacts.DefaultParams().AclOwner, newVersion.String(), fmt.Sprint(qur.Height+1)) + res, err = s.node.RunCommand("gov", "upgrade", test_artifacts.DefaultParams().AclOwner, newVersion.String(), fmt.Sprint(qur.Height+1)) require.NoError(s, err) // TECHBDEBT: cli outputs debug logs last non-blank line is our answer @@ -47,12 +47,12 @@ func (s *rootSuite) TheUserSubmitsAMajorProtocolUpgrade() { // ensure it is a valid sha256 hash require.Regexp(s, "^([a-f0-9]{64})$", answer, "invalid tx hash") s.pendingTxs = append(s.pendingTxs, answer) - s.validator.result = res + s.node.result = res } func (s *rootSuite) TheSystemReachesTheUpgradeHeight() { for { - res, err := s.validator.RunCommand("query", "upgrade") + res, err := s.node.RunCommand("query", "upgrade") require.NoError(s, err) // parse into QueryUpgradeResponse diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature index 06adeba40..3380de047 100644 --- a/e2e/tests/upgrade.feature +++ b/e2e/tests/upgrade.feature @@ -1,7 +1,10 @@ Feature: Upgrade Protocol Scenario: User can query the current protocol version using CLI - Given the user runs the command "query upgrade" + Given the network is at genesis + And the network has "4" actors of type "Validator" + And "validator-001" should be at height "0" + And the user runs the command "query upgrade" Then the user should be able to see standard output containing "" Examples: @@ -9,22 +12,37 @@ Feature: Upgrade Protocol | 1.0.0 | Scenario: ACL Owner Successfully Submits a Protocol Upgrade Using CLI - Given the user is an ACL Owner + Given the network is at genesis + And the network has "4" actors of type "Validator" + And "validator-001" should be at height "0" + And the user is an ACL Owner When the user submits a major protocol upgrade And the network commits the transactions When the user runs the command "query upgrade" Then the user should be able to see the new version Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI - Given the user is an ACL Owner + Given the network is at genesis + And the network has "4" actors of type "Validator" + And "validator-001" should be at height "0" + And the user is an ACL Owner And the user has an invalid upgrade protocol command When the user runs the command "gov upgrade" Then the system should validate the command And the system should reject the command due to invalid input Scenario: ACL Owner Submits a Protocol Upgrade with Too Many Versions Ahead Using CLI - Given the user is an ACL Owner + Given the network is at genesis + And the network has "4" actors of type "Validator" + And the user is an ACL Owner And the user has a upgrade protocol command with too many versions jump When the user runs the command "gov upgrade" Then the system should validate the command And the system should reject the command due to too many versions ahead + + Scenario: Regular User Submits an Upgrade Using CLI + Given the network is at genesis + And the network has "4" actors of type "Validator" + When the user submits a major protocol upgrade + When the user runs the command "gov upgrade 100.0.0 100000" + Then the user should be able to see standard output containing "invalid upgrade proposal: sender is not authorized to submit upgrade proposals" From 45a0f56556e47a89a44464d341b0b22203503cb4 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 5 Aug 2023 12:19:05 -0400 Subject: [PATCH 18/27] [utility] fix failed to create servicer Adds servicer pk to validator1 docker compose deployment --- build/config/config.validator1.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/config/config.validator1.json b/build/config/config.validator1.json index 6031f1a37..5b7549136 100644 --- a/build/config/config.validator1.json +++ b/build/config/config.validator1.json @@ -56,13 +56,14 @@ }, "servicer": { "enabled": true, - "chains": ["0001"] + "chains": ["0001"], + "private_key": "0ca1a40ddecdab4f5b04fa0bfed1d235beaa2b8082e7554425607516f0862075dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e" }, "ibc": { "enabled": true, "stores_dir": "/var/ibc", "host": { - "private_key": "0ca1a40ddecdab4f5b04fa0bfed1d235beaa2b8082e7554425607516f0862075dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e" + "private_key": "0ca1a40ddecdab4f5b04fa0bfed1d235beaa2b8082e7554425607516f0862075dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e" } } } From b784a7e87170522c7a3de09bd7694ecbdb3a68da Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 5 Aug 2023 16:05:27 -0400 Subject: [PATCH 19/27] fix tests --- e2e/tests/node.go | 4 ++++ persistence/trees/atomic_test.go | 4 ++-- persistence/trees/trees_test.go | 2 +- runtime/manager_test.go | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/e2e/tests/node.go b/e2e/tests/node.go index 422e6e009..d9db0014f 100644 --- a/e2e/tests/node.go +++ b/e2e/tests/node.go @@ -5,6 +5,7 @@ package e2e import ( "fmt" "os/exec" + "strings" "github.com/pokt-network/pocket/runtime" "github.com/pokt-network/pocket/runtime/defaults" @@ -62,6 +63,9 @@ func (n *nodePod) RunCommandOnHost(rpcUrl string, args ...string) (*commandResul "--remote_cli_url=" + rpcUrl, } args = append(base, args...) + + e2eLogger.Debug().Msgf("Running command: kubectl %s", strings.Join(args, " ")) + cmd := exec.Command("kubectl", args...) r := &commandResult{} out, err := cmd.Output() diff --git a/persistence/trees/atomic_test.go b/persistence/trees/atomic_test.go index 06fdbaf8c..c56f6fc9c 100644 --- a/persistence/trees/atomic_test.go +++ b/persistence/trees/atomic_test.go @@ -15,9 +15,9 @@ import ( const ( // the root hash of a tree store where each tree is empty but present and initialized - h0 = "302f2956c084cc3e0e760cf1b8c2da5de79c45fa542f68a660a5fc494b486972" + h0 = "8ba9f76843b2873557dee21b4894e9b308c2717f9c4e69a871ef085a193f842d" // the root hash of a tree store where each tree has has key foo value bar added to it - h1 = "7d5712ea1507915c40e295845fa58773baa405b24b87e9d99761125d826ff915" + h1 = "2096fdc67bdbe59cf3918f08203b6cf49c8c4ccee7a77906a434f9a2272826f4" ) func TestTreeStore_AtomicUpdatesWithSuccessfulRollback(t *testing.T) { diff --git a/persistence/trees/trees_test.go b/persistence/trees/trees_test.go index aa8c41ab4..a42386f85 100644 --- a/persistence/trees/trees_test.go +++ b/persistence/trees/trees_test.go @@ -37,7 +37,7 @@ var ( ) const ( - treesHash1 = "5282ee91a3ec0a6f2b30e4780b369bae78c80ef3ea40587fef6ae263bf41f244" + treesHash1 = "764f122ba41041ff583c02e922abe698f7148ea30ff0d32c78315538e337a3a5" ) func TestTreeStore_Update(t *testing.T) { diff --git a/runtime/manager_test.go b/runtime/manager_test.go index d794b4894..a3a026152 100644 --- a/runtime/manager_test.go +++ b/runtime/manager_test.go @@ -1821,7 +1821,7 @@ func TestNewManagerFromReaders(t *testing.T) { UseCors: false, }, Keybase: defaultCfg.Keybase, - Servicer: &configs.ServicerConfig{Enabled: true}, + Servicer: &configs.ServicerConfig{Enabled: true, PrivateKey: "0ca1a40ddecdab4f5b04fa0bfed1d235beaa2b8082e7554425607516f0862075dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e"}, Validator: &configs.ValidatorConfig{Enabled: true}, Fisherman: defaultCfg.Fisherman, IBC: &configs.IBCConfig{ From 4e6e905834a4d2b65ada90089daf8de4edee902c Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 5 Aug 2023 16:37:09 -0400 Subject: [PATCH 20/27] add missing message_upgrade_fee to localnet --- build/localnet/manifests/configs.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build/localnet/manifests/configs.yaml b/build/localnet/manifests/configs.yaml index da8a091e7..40ef46cab 100644 --- a/build/localnet/manifests/configs.yaml +++ b/build/localnet/manifests/configs.yaml @@ -1587,6 +1587,10 @@ data: { "address": "099044a5282c4089976c6b13ab13e5423dae55ce", "amount": "100000000000000" + }, + { + "address": "da034209758b78eaea06dd99c07909ab54c99b45", + "amount": "100000000000000" } ], "pools": [ @@ -1786,6 +1790,7 @@ data: "message_pause_servicer_fee": "10000", "message_unpause_servicer_fee": "10000", "message_change_parameter_fee": "10000", + "message_upgrade_fee": "10000", "acl_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "blocks_per_session_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_stake_owner": "da034209758b78eaea06dd99c07909ab54c99b45", @@ -1840,7 +1845,8 @@ data: "message_unstake_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_pause_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "message_unpause_servicer_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45" + "message_change_parameter_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45", + "message_upgrade_fee_owner": "da034209758b78eaea06dd99c07909ab54c99b45" }, "genesis_time": { "seconds": 1663610702, From 5c07b9d8d79d1dda59047556f3bf82436726d5c8 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 5 Aug 2023 17:45:43 -0400 Subject: [PATCH 21/27] localnet improvements --- build/Dockerfile.client | 4 ++++ build/localnet/README.md | 5 ++++- build/localnet/Tiltfile | 2 +- e2e/tests/steps_init_test.go | 4 ---- persistence/gov.go | 9 ++++++++- utility/unit_of_work/account.go | 6 ++++++ utility/unit_of_work/transaction.go | 18 ++++++++++++++++++ utility/unit_of_work/uow_leader.go | 9 ++++++++- 8 files changed, 49 insertions(+), 8 deletions(-) diff --git a/build/Dockerfile.client b/build/Dockerfile.client index ea776476f..d1a017cec 100644 --- a/build/Dockerfile.client +++ b/build/Dockerfile.client @@ -6,3 +6,7 @@ ENV POCKET_ROOT=/go/src/github.com/pocket-network WORKDIR $POCKET_ROOT +RUN apt-get update && apt-get install -y procps bash-completion jq +RUN echo "source /etc/bash_completion" >> ~/.bashrc +# tail -n +2 removes the first line of the completion script since the CLI spits out some logs +RUN echo "source <($POCKET_ROOT/bin/p1 completion bash | tail -n +2)" >> ~/.bashrc diff --git a/build/localnet/README.md b/build/localnet/README.md index 02d9a1494..dbfcb84bf 100644 --- a/build/localnet/README.md +++ b/build/localnet/README.md @@ -48,7 +48,7 @@ All necessary dependencies, except Docker and Kubernetes cluster, are installed 3. `Kubernetes cluster`: refer to [Choosing Kubernetes Distribution](#choosing-kubernetes-distribution) section for more details. 4. `kubectl`: CLI is required and should be configured to access the cluster. This should happen automatically if using Docker Desktop, Rancher Desktop, k3s, k3d, minikube, etc. 5. [helm](https://helm.sh/docs/intro/install): required to template the YAML manifests for the dependencies (e.g., Postgres, Grafana). Installation instructions available. -6. [rsync](https://www.hostinger.com/tutorials/how-to-use-rsync): required to for some extensions used with `Tilt`; https://github.com/tilt-dev/tilt-extensions/tree/master/syncback#usage +6. [rsync](https://www.hostinger.com/tutorials/how-to-use-rsync): required to for some extensions used with `Tilt`; ### Choosing Kubernetes Distribution @@ -199,6 +199,9 @@ cat < charts/pocket/pocket-validator-overrides.yaml config: rpc: use_cors: true + logger: + level: debug + format: pretty EOF ``` diff --git a/build/localnet/Tiltfile b/build/localnet/Tiltfile index d4534df35..af0367dd8 100644 --- a/build/localnet/Tiltfile +++ b/build/localnet/Tiltfile @@ -132,7 +132,7 @@ WORKDIR / docker_build_with_restart( "client-image", root_dir, - dockerfile_contents="""FROM debian:bullseye + dockerfile_contents="""FROM debian:bookworm RUN apt-get update && apt-get install -y procps bash-completion jq RUN echo "source /etc/bash_completion" >> ~/.bashrc # tail -n +2 removes the first line of the completion script since the CLI spits out some logs diff --git a/e2e/tests/steps_init_test.go b/e2e/tests/steps_init_test.go index 7818f9ba0..34b190a91 100644 --- a/e2e/tests/steps_init_test.go +++ b/e2e/tests/steps_init_test.go @@ -210,10 +210,6 @@ func (s *rootSuite) TheNetworkCommitsTheTransactions() { require.FailNow(s, "no pending transactions to commit") } - // trigger the next view - _, err := s.node.RunCommand("Debug", "TriggerView") - require.NoError(s, err) - // Make a copy of the pendingTxs slice to keep track of the transactions still pending remainingTxs := make([]string, len(s.pendingTxs)) copy(remainingTxs, s.pendingTxs) diff --git a/persistence/gov.go b/persistence/gov.go index 61b0e1385..94e23b32f 100644 --- a/persistence/gov.go +++ b/persistence/gov.go @@ -39,7 +39,14 @@ func (p *PostgresContext) InitGenesisParams(params *genesis.Params) error { if p.Height != 0 { return fmt.Errorf("cannot initialize params at height %d", p.Height) } - _, err := tx.Exec(ctx, types.InsertParams(params, p.Height)) + + sql := types.InsertParams(params, p.Height) + + if e := p.logger.Trace(); e.Enabled() { + e.Msg("initializing genesis params: " + sql) + } + + _, err := tx.Exec(ctx, sql) if err != nil { return err } diff --git a/utility/unit_of_work/account.go b/utility/unit_of_work/account.go index b0ecf6875..aa135aad6 100644 --- a/utility/unit_of_work/account.go +++ b/utility/unit_of_work/account.go @@ -17,10 +17,16 @@ import ( func (u *baseUtilityUnitOfWork) getAccountAmount(address []byte) (*big.Int, coreTypes.Error) { amountStr, err := u.persistenceReadContext.GetAccountAmount(address, u.height) if err != nil { + if e := u.logger.Trace(); e.Enabled() { + e.Err(err).Msg("failed to get account amount from persistence read context") + } return nil, coreTypes.ErrGetAccountAmount(err) } amount, err := utils.StringToBigInt(amountStr) if err != nil { + if e := u.logger.Trace(); e.Enabled() { + e.Err(err).Msg("failed to convert string to big int amountStr: " + amountStr) + } return nil, coreTypes.ErrStringToBigInt(err) } return amount, nil diff --git a/utility/unit_of_work/transaction.go b/utility/unit_of_work/transaction.go index 6e2d04c87..12ee09538 100644 --- a/utility/unit_of_work/transaction.go +++ b/utility/unit_of_work/transaction.go @@ -16,6 +16,9 @@ import ( func (u *baseUtilityUnitOfWork) HandleTransaction(tx *coreTypes.Transaction, index int) (*coreTypes.IndexedTransaction, coreTypes.Error) { msg, err := u.basicValidateTransaction(tx) if err != nil { + if e := u.logger.Debug(); e.Enabled() { + u.logger.Error().Err(err).Msg("basicValidateTransaction failed") + } return nil, err } msgHandlingResult := u.handleMessage(msg) @@ -28,6 +31,9 @@ func (u *baseUtilityUnitOfWork) basicValidateTransaction(tx *coreTypes.Transacti // Check if the transaction has a valid message msg, err := u.validateTxMessage(tx) if err != nil { + if e := u.logger.Debug(); e.Enabled() { + e.Err(err).Msg("validateTxMessage failed") + } return nil, err } @@ -41,6 +47,9 @@ func (u *baseUtilityUnitOfWork) basicValidateTransaction(tx *coreTypes.Transacti // Validate that the signer has a valid signature address, err = u.validateTxSignature(address, msg) if err != nil { + if e := u.logger.Debug(); e.Enabled() { + e.Err(err).Msg("validateTxSignature failed") + } return nil, err } // Update the address of the message signer based on the validated signature @@ -49,6 +58,9 @@ func (u *baseUtilityUnitOfWork) basicValidateTransaction(tx *coreTypes.Transacti // Validate that the signer has enough funds to pay the fee of the message signed // and deduct the fee from the signer's account if so. if err := u.validateAndDeductTxFees(address, msg); err != nil { + if e := u.logger.Debug(); e.Enabled() { + e.Err(err).Msg("validateAndDeductTxFees failed") + } return nil, err } @@ -90,10 +102,16 @@ func (u *baseUtilityUnitOfWork) validateAndDeductTxFees(address crypto.Address, // Retrieve the amounts and fees fee, err := u.getFee(msg, msg.GetActorType()) if err != nil { + if e := u.logger.Debug(); e.Enabled() { + e.Err(err).Msg("getFee failed for address: " + address.ToString()) + } return err } accountAmount, err := u.getAccountAmount(address) if err != nil { + if e := u.logger.Debug(); e.Enabled() { + e.Err(err).Msg("getAccountAmount failed for address: " + address.ToString()) + } return coreTypes.ErrGetAccountAmount(err) } diff --git a/utility/unit_of_work/uow_leader.go b/utility/unit_of_work/uow_leader.go index cfa2e6707..bbca5c6e3 100644 --- a/utility/unit_of_work/uow_leader.go +++ b/utility/unit_of_work/uow_leader.go @@ -100,9 +100,16 @@ func (uow *leaderUtilityUnitOfWork) reapMempool(txMempool mempool.TXMempool, max break // we've reached our max } + txHash, err := tx.Hash() + + if err != nil { + uow.logger.Err(err).Msg("Error hashing transaction during mempool reaping") + return nil, err + } + idxTx, err := uow.HandleTransaction(tx, txIdx) if err != nil { - uow.logger.Err(err).Msg("Error handling the transaction") + uow.logger.Err(err).Msgf("Error handling transaction during mempool reaping: %s", txHash) // TODO(#327): Properly implement 'unhappy path' for save points if err := uow.revertToLastSavepoint(); err != nil { return nil, err From 2cd8bd82196d7773f62c26498fad4d548db2f36d Mon Sep 17 00:00:00 2001 From: BigBoss Date: Sat, 5 Aug 2023 21:34:20 -0400 Subject: [PATCH 22/27] add upgrade validations, update e2e tests --- e2e/README.md | 2 +- e2e/tests/account.feature | 2 +- e2e/tests/node.go | 17 ++++-- e2e/tests/query.feature | 8 +-- e2e/tests/root.feature | 4 +- e2e/tests/steps_init_test.go | 44 ++++++++++++-- e2e/tests/steps_upgrade_test.go | 71 ---------------------- e2e/tests/upgrade.feature | 54 ++++++++++------ e2e/tests/upgrade_cancel.feature | 4 +- e2e/tests/validator.feature | 2 +- utility/unit_of_work/gov.go | 8 +++ utility/unit_of_work/transaction.go | 4 ++ utility/unit_of_work/tx_message_handler.go | 36 ++++++++--- utility/unit_of_work/tx_message_signers.go | 4 -- 14 files changed, 137 insertions(+), 123 deletions(-) delete mode 100644 e2e/tests/steps_upgrade_test.go diff --git a/e2e/README.md b/e2e/README.md index 5e3ee41c9..5f001ff27 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -38,7 +38,7 @@ Feature: Example Namespace Scenario: User Needs Example Given the user has a node - When the user runs the command "example" + When the user runs the command with no error "example" Then the user should be able to see standard output containing "Example Output" And the pocket client should have exited without error ``` diff --git a/e2e/tests/account.feature b/e2e/tests/account.feature index 8e793dcd9..2b20cc944 100644 --- a/e2e/tests/account.feature +++ b/e2e/tests/account.feature @@ -2,7 +2,7 @@ Feature: Node Namespace Scenario: User Wants Help Using The Node Command Given the user has a node - When the user runs the command "Validator help" + When the user runs the command with no error "Validator help" Then the user should be able to see standard output containing "Available Commands" And the node should have exited without error diff --git a/e2e/tests/node.go b/e2e/tests/node.go index d9db0014f..39dece42e 100644 --- a/e2e/tests/node.go +++ b/e2e/tests/node.go @@ -63,18 +63,23 @@ func (n *nodePod) RunCommandOnHost(rpcUrl string, args ...string) (*commandResul "--remote_cli_url=" + rpcUrl, } args = append(base, args...) - - e2eLogger.Debug().Msgf("Running command: kubectl %s", strings.Join(args, " ")) + cmdStr := strings.Join(args, " ") + e2eLogger.Debug().Msgf("Running command: kubectl %s", cmdStr) cmd := exec.Command("kubectl", args...) r := &commandResult{} out, err := cmd.Output() - if err != nil { - return nil, err - } r.Stdout = string(out) n.result = r // IMPROVE: make targetPodName configurable n.targetPodName = targetDevClientPod - return r, nil + + if err != nil { + // unpack ExitError to get stderr + if exitErr, ok := err.(*exec.ExitError); ok { + r.Stderr = string(exitErr.Stderr) + } + } + e2eLogger.Debug().Str("stderr", r.Stderr).Err(err).Msgf("command result: %s", string(out)) + return r, err } diff --git a/e2e/tests/query.feature b/e2e/tests/query.feature index 74cc60180..15aa5d899 100644 --- a/e2e/tests/query.feature +++ b/e2e/tests/query.feature @@ -3,12 +3,12 @@ Feature: Query Namespace Scenario: User Wants Help Using The Query Command Given the user has a node - When the user runs the command "Query help" + When the user runs the command with no error "Query help" Then the user should be able to see standard output containing "Available Commands" And the node should have exited without error - Scenario: User Wants To See The Block At Current Height + Scenario: User Wants To See The Block At Current Height Given the user has a node - When the user runs the command "Query Block" + When the user runs the command with no error "Query Block" Then the user should be able to see standard output containing "state_hash" - And the node should have exited without error \ No newline at end of file + And the node should have exited without error diff --git a/e2e/tests/root.feature b/e2e/tests/root.feature index b9d6225d4..2d02f6a9e 100644 --- a/e2e/tests/root.feature +++ b/e2e/tests/root.feature @@ -2,6 +2,6 @@ Feature: Root Namespace Scenario: User Needs Help Given the user has a node - When the user runs the command "help" + When the user runs the command with no error "help" Then the user should be able to see standard output containing "Available Commands" - And the node should have exited without error \ No newline at end of file + And the node should have exited without error diff --git a/e2e/tests/steps_init_test.go b/e2e/tests/steps_init_test.go index 34b190a91..522c3557b 100644 --- a/e2e/tests/steps_init_test.go +++ b/e2e/tests/steps_init_test.go @@ -76,7 +76,7 @@ func TestFeatures(t *testing.T) { func (s *rootSuite) TheUserHasANode() { res, err := s.node.RunCommand("help") - require.NoErrorf(s, err, res.Stderr) + require.NoErrorf(s, err, res.Stderr, "failed to run command: 'help' due to error: %s", err) s.node.result = res } @@ -84,13 +84,44 @@ func (s *rootSuite) TheNodeShouldHaveExitedWithoutError() { require.NoError(s, s.node.result.Err) } -func (s *rootSuite) TheUserRunsTheCommand(cmd string) { +func (s *rootSuite) TheUserRunsTheCommandWithNoError(cmd string) { cmds := strings.Split(cmd, " ") res, err := s.node.RunCommand(cmds...) - require.NoError(s, err) + require.NoError(s, err, fmt.Sprintf("failed to run command: '%s' due to error: %s", cmd, err)) + s.node.result = res +} + +func (s *rootSuite) TheUserRunsTheCommandWithError(cmd string) { + cmds := strings.Split(cmd, " ") + res, err := s.node.RunCommand(cmds...) + require.Error(s, err, fmt.Sprintf("expected error running command: '%s'", cmd)) s.node.result = res } +func (s *rootSuite) TheUserSubmitsTheTransaction(cmd string) { + s.TheUserRunsTheCommandWithNoError(cmd) + // TECHBDEBT: cli outputs debug logs last non-blank line is our answer + var lines = strings.Split(s.node.result.Stdout, "\n") + var answer string + for i := len(lines) - 1; i >= 0; i-- { + if lines[i] != "" { + answer = lines[i] + break + } + } + // ensure it is a valid sha256 hash + require.Regexp(s, "^([a-f0-9]{64})$", answer, "invalid tx hash") + s.pendingTxs = append(s.pendingTxs, answer) +} + +func (s *rootSuite) TheUserQueriesTheTransaction(cmd string) { + if len(s.pendingTxs) == 0 { + e2eLogger.Info().Msg("no pending transactions to query") + require.FailNow(s, "no pending transactions to query") + } + s.TheUserRunsTheCommandWithNoError("query tx " + s.pendingTxs[len(s.pendingTxs)-1]) +} + // TheDeveloperRunsTheCommand is similar to TheUserRunsTheCommand but exclusive to `Debug` commands func (s *rootSuite) TheDeveloperRunsTheCommand(cmd string) { cmds := strings.Split(cmd, " ") @@ -199,8 +230,7 @@ func (s *rootSuite) ShouldBeAtHeight(pod string, height int64) { res := getResponseFromStdout[expectedResponse](s, resRaw.Stdout, validate) require.NotNil(s, res) - - require.Equal(s, height, *res.Height) + require.Equal(s, height, *res.Height, "height mismatch") } // TheNetworkCommitsTheTransactions is a step that triggers the next view and verifies that all pending transactions are committed @@ -263,6 +293,10 @@ func (s *rootSuite) TheUserShouldBeAbleToSeeStandardOutputContaining(arg1 string require.Contains(s, s.node.result.Stdout, arg1) } +func (s *rootSuite) TheUserShouldBeAbleToSeeStandardErrorContaining(arg1 string) { + require.Contains(s, s.node.result.Stderr, arg1) +} + func (s *rootSuite) TheUserStakesTheirValidatorWithAmountUpokt(amount int64) { privKey := s.getPrivateKey(validatorA) s.stakeValidator(privKey, fmt.Sprintf("%d", amount)) diff --git a/e2e/tests/steps_upgrade_test.go b/e2e/tests/steps_upgrade_test.go deleted file mode 100644 index 6a1c96bb2..000000000 --- a/e2e/tests/steps_upgrade_test.go +++ /dev/null @@ -1,71 +0,0 @@ -//go:build e2e - -package e2e - -import ( - "fmt" - "strings" - - "github.com/blang/semver/v4" - "github.com/pokt-network/pocket/rpc" - "github.com/pokt-network/pocket/runtime/test_artifacts" - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/util/json" -) - -func (s *rootSuite) TheUserSubmitsAMajorProtocolUpgrade() { - res, err := s.node.RunCommand("query", "upgrade") - require.NoError(s, err) - - var qur rpc.QueryUpgradeResponse - // TECHDEBT: cli outputs debug logs so scan for our answer - for _, line := range strings.Split(res.Stdout, "\n") { - // parse into QueryUpgradeResponse - err = json.Unmarshal([]byte(line), &qur) - if err == nil && qur.Version != "" { - break - } - } - require.NoError(s, err) - - // submit a major protocol upgrade - newVersion, err := semver.Parse(qur.Version) - require.NoError(s, err) - newVersion.Major++ - res, err = s.node.RunCommand("gov", "upgrade", test_artifacts.DefaultParams().AclOwner, newVersion.String(), fmt.Sprint(qur.Height+1)) - require.NoError(s, err) - - // TECHBDEBT: cli outputs debug logs last non-blank line is our answer - var lines = strings.Split(res.Stdout, "\n") - var answer string - for i := len(lines) - 1; i >= 0; i-- { - if lines[i] != "" { - answer = lines[i] - break - } - } - // ensure it is a valid sha256 hash - require.Regexp(s, "^([a-f0-9]{64})$", answer, "invalid tx hash") - s.pendingTxs = append(s.pendingTxs, answer) - s.node.result = res -} - -func (s *rootSuite) TheSystemReachesTheUpgradeHeight() { - for { - res, err := s.node.RunCommand("query", "upgrade") - require.NoError(s, err) - - // parse into QueryUpgradeResponse - var qur rpc.QueryUpgradeResponse - err = json.Unmarshal([]byte(res.Stdout), &qur) - require.NoError(s, err) - - if qur.Height > 0 { - break - } - } -} - -func (s *rootSuite) TheUserShouldBeAbleToSeeTheNewVersion() { - panic("PENDING") -} diff --git a/e2e/tests/upgrade.feature b/e2e/tests/upgrade.feature index 3380de047..df9c8b197 100644 --- a/e2e/tests/upgrade.feature +++ b/e2e/tests/upgrade.feature @@ -4,7 +4,7 @@ Feature: Upgrade Protocol Given the network is at genesis And the network has "4" actors of type "Validator" And "validator-001" should be at height "0" - And the user runs the command "query upgrade" + And the user runs the command with no error "query upgrade" Then the user should be able to see standard output containing "" Examples: @@ -16,33 +16,49 @@ Feature: Upgrade Protocol And the network has "4" actors of type "Validator" And "validator-001" should be at height "0" And the user is an ACL Owner - When the user submits a major protocol upgrade - And the network commits the transactions - When the user runs the command "query upgrade" - Then the user should be able to see the new version + When the user runs the command with no error "gov upgrade da034209758b78eaea06dd99c07909ab54c99b45 2.0.0 1" + And the developer runs the command "TriggerView" + And the developer waits for "1000" milliseconds + And "validator-001" should be at height "1" + And the user runs the command with no error "query upgrade" + Then the user should be able to see standard output containing "2.0.0" - Scenario: ACL Owner Submits an Invalid Protocol Upgrade Using CLI + Scenario: ACL Owner Fails Basic Validation Submitting a Protocol Upgrade Using CLI Given the network is at genesis And the network has "4" actors of type "Validator" And "validator-001" should be at height "0" And the user is an ACL Owner - And the user has an invalid upgrade protocol command - When the user runs the command "gov upgrade" - Then the system should validate the command - And the system should reject the command due to invalid input + When the user runs the command with error "" + Then the user should be able to see standard error containing "" - Scenario: ACL Owner Submits a Protocol Upgrade with Too Many Versions Ahead Using CLI + Examples: + | cmd | error | + | gov upgrade da034209758b78eaea06dd99c07909ab54c99b45 2.0.zxcv 1 | CODE: 149, ERROR: the protocol version is invalid | + | gov upgrade da034209758b78eaea06dd99c07909ab54c99b45 new 1 | CODE: 149, ERROR: the protocol version is invalid | + + Scenario: ACL Owner Fails Consensus Validation Submitting a Protocol Upgrade Using CLI Given the network is at genesis And the network has "4" actors of type "Validator" + And "validator-001" should be at height "0" And the user is an ACL Owner - And the user has a upgrade protocol command with too many versions jump - When the user runs the command "gov upgrade" - Then the system should validate the command - And the system should reject the command due to too many versions ahead + When the user runs the command with no error "" + And the developer runs the command "TriggerView" + And the developer waits for "1000" milliseconds + And "validator-001" should be at height "1" + And the user queries the transaction + Then the user should be able to see standard output containing "" + + Examples: + | cmd | error | + | gov upgrade da034209758b78eaea06dd99c07909ab54c99b45 3.0.0 1 | CODE: 149, ERROR: the protocol version is invalid | + | gov upgrade da034209758b78eaea06dd99c07909ab54c99b45 2.0.0 0 | CODE: 149, ERROR: the protocol version is invalid | - Scenario: Regular User Submits an Upgrade Using CLI + Scenario: Regular User Fails Consensus Validation Submits an Upgrade Using CLI Given the network is at genesis And the network has "4" actors of type "Validator" - When the user submits a major protocol upgrade - When the user runs the command "gov upgrade 100.0.0 100000" - Then the user should be able to see standard output containing "invalid upgrade proposal: sender is not authorized to submit upgrade proposals" + When the user submits the transaction "gov upgrade 00101f2ff54811e84df2d767c661f57a06349b7e 2.0.0 1" + And the developer runs the command "TriggerView" + And the developer waits for "1000" milliseconds + And "validator-001" should be at height "1" + And the user queries the transaction + Then the user should be able to see standard output containing "CODE: 3, ERROR: the signer of the message is not a proper candidate: da034209758b78eaea06dd99c07909ab54c99b45" diff --git a/e2e/tests/upgrade_cancel.feature b/e2e/tests/upgrade_cancel.feature index 5fbb80a38..62aa92d0f 100644 --- a/e2e/tests/upgrade_cancel.feature +++ b/e2e/tests/upgrade_cancel.feature @@ -3,7 +3,7 @@ # Scenario: User Successfully Cancels a Scheduled Upgrade using CLI # Given the user is an ACL Owner # And the specified upgrade is scheduled and not yet activated -# When the user runs the command "gov cancel_upgrade" +# When the user runs the command with no error "gov cancel_upgrade" # Then the system should cancel the scheduled upgrade # When user runs the command "gov query upgrade" # Then the system should return the successful cancellation status @@ -11,6 +11,6 @@ # Scenario: User Attempts to Cancel a Past Upgrade using CLI # Given the user is an ACL Owner # And the user has a cancel upgrade command for a past version -# When the user runs the command "gov cancel_upgrade" +# When the user runs the command with no error "gov cancel_upgrade" # Then the system should validate the command # And the system should reject the command as it cannot cancel a past upgrade diff --git a/e2e/tests/validator.feature b/e2e/tests/validator.feature index e1bd22c4f..6caa38ae7 100644 --- a/e2e/tests/validator.feature +++ b/e2e/tests/validator.feature @@ -2,7 +2,7 @@ Feature: Validator Namespace Scenario: User Wants Help Using The Validator Command Given the user has a node - When the user runs the command "Validator help" + When the user runs the command with no error "Validator help" Then the user should be able to see standard output containing "Available Commands" And the node should have exited without error diff --git a/utility/unit_of_work/gov.go b/utility/unit_of_work/gov.go index 85f646874..a1fb56f36 100644 --- a/utility/unit_of_work/gov.go +++ b/utility/unit_of_work/gov.go @@ -270,3 +270,11 @@ func (u *baseUtilityUnitOfWork) getStringParam(paramName string) (string, coreTy } return value, nil } + +func (u *baseUtilityUnitOfWork) getMessageUpgradeSignerCandidates(_ *typesUtil.MessageUpgrade) ([][]byte, coreTypes.Error) { + owner, err := u.getStringParam(typesUtil.AclOwner) + if err != nil { + return nil, coreTypes.ErrGetParam(typesUtil.AclOwner, err) + } + return [][]byte{[]byte(owner)}, nil +} diff --git a/utility/unit_of_work/transaction.go b/utility/unit_of_work/transaction.go index 12ee09538..53251ee3e 100644 --- a/utility/unit_of_work/transaction.go +++ b/utility/unit_of_work/transaction.go @@ -77,6 +77,10 @@ func (u *baseUtilityUnitOfWork) validateTxMessage(tx *coreTypes.Transaction) (ty if !ok { return nil, coreTypes.ErrDecodeMessage(fmt.Errorf("not a supported message type")) } + // Validate the message the same as the client is expected to + if err := msg.ValidateBasic(); err != nil { + return nil, err + } return msg, nil } diff --git a/utility/unit_of_work/tx_message_handler.go b/utility/unit_of_work/tx_message_handler.go index 2d620b971..e0ff5ef9e 100644 --- a/utility/unit_of_work/tx_message_handler.go +++ b/utility/unit_of_work/tx_message_handler.go @@ -2,8 +2,10 @@ package unit_of_work import ( "encoding/hex" + "errors" "math/big" + "github.com/blang/semver/v4" ibcTypes "github.com/pokt-network/pocket/ibc/types" "github.com/pokt-network/pocket/shared/codec" coreTypes "github.com/pokt-network/pocket/shared/core/types" @@ -242,13 +244,33 @@ func (u *baseUtilityUnitOfWork) handlePruneIBCStore(message *ibcTypes.PruneIBCSt return nil } -func (u *baseUtilityUnitOfWork) handleMessageUpgrade(message *typesUtil.MessageUpgrade) coreTypes.Error { - u.logger.Debug().Str("version", message.Version).Int64("height", message.Height).Msg("setting upgrade") - - // validate new upgrade - - if err := u.persistenceRWContext.SetUpgrade(hex.EncodeToString(message.Signer), message.Version, message.Height); err != nil { - return coreTypes.ErrSettingUpgrade(err) +func (u *baseUtilityUnitOfWork) handleMessageUpgrade(msg *typesUtil.MessageUpgrade) coreTypes.Error { + u.logger.Debug().Str("version", msg.Version).Int64("height", msg.Height).Msg("setting upgrade") + if msg.Height <= u.height { + return coreTypes.ErrSettingUpgrade(errors.New("upgrade height must be greater than current height")) + } + ver, err := semver.Parse(msg.Version) + if err != nil { + return coreTypes.ErrInvalidProtocolVersion(msg.Version) + } + curStr, err := u.persistenceRWContext.GetVersionAtHeight(msg.Height) + if err != nil { + return coreTypes.ErrSettingUpgrade(errors.Join(err, errors.New("getting current version"))) + } + cur, err := semver.Parse(curStr) + if err != nil { + return coreTypes.ErrSettingUpgrade(errors.Join(err, errors.New("parsing current version"))) + } + // ensure version is not too large of a jump + if ver.Major-cur.Major > 1 { + return coreTypes.ErrSettingUpgrade(errors.Join(err, errors.New("major version jump too large"))) + } + // ensure version is greater than current + if ver.LTE(cur) { + return coreTypes.ErrSettingUpgrade(errors.Join(err, errors.New("version must be greater than current"))) + } + if err := u.persistenceRWContext.SetUpgrade(hex.EncodeToString(msg.Signer), msg.Version, msg.Height); err != nil { + return coreTypes.ErrSettingUpgrade(errors.Join(err, errors.New("setting upgrade"))) } return nil } diff --git a/utility/unit_of_work/tx_message_signers.go b/utility/unit_of_work/tx_message_signers.go index 6b81a3d0d..103a3fc0c 100644 --- a/utility/unit_of_work/tx_message_signers.go +++ b/utility/unit_of_work/tx_message_signers.go @@ -89,8 +89,4 @@ func (u *baseUtilityUnitOfWork) getPruneIBCStoreSingerCandidates(msg *ibcTypes.P return [][]byte{msg.Signer}, nil } -func (u *baseUtilityUnitOfWork) getMessageUpgradeSignerCandidates(msg *typesUtil.MessageUpgrade) ([][]byte, coreTypes.Error) { - return [][]byte{msg.Signer}, nil -} - // TODO: 0xbigboss MessageCancelUpgrade From 71b1c51b1bcf25fd5eebc0136050e1d6f826c7c0 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Wed, 9 Aug 2023 10:49:43 -0400 Subject: [PATCH 23/27] clearer var names --- app/client/cli/gov.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/client/cli/gov.go b/app/client/cli/gov.go index 250dc9176..7b468a1e2 100644 --- a/app/client/cli/gov.go +++ b/app/client/cli/gov.go @@ -48,7 +48,7 @@ func govCommands() []*cobra.Command { value := args[2] // TODO(0xbigboss): implement RPC client, route and handler - fmt.Printf("changing parameter %s owned by %s to %s\n", args[1], args[0], args[2]) + fmt.Printf("changing parameter %s owned by %s to %s\n", key, fromAddrHex, value) kb, err := keybaseForCLI() if err != nil { @@ -93,7 +93,7 @@ func govCommands() []*cobra.Command { return fmt.Errorf("HTTP status code: %d\n", resp.StatusCode()) } - fmt.Printf("Successfully sent change parameter %s owned by %s to %s\n", args[1], args[0], args[2]) + fmt.Printf("Successfully sent change parameter %s owned by %s to %s\n", key, fromAddrHex, value) fmt.Printf("HTTP status code: %d\n", resp.StatusCode()) fmt.Println(string(resp.Body)) @@ -112,7 +112,7 @@ func govCommands() []*cobra.Command { version := args[1] heightArg := args[2] - fmt.Printf("submitting upgrade for version %s at height %s.\n", args[0], args[1]) + fmt.Printf("submitting upgrade for version %s at height %s.\n", version, heightArg) kb, err := keybaseForCLI() if err != nil { @@ -162,7 +162,7 @@ func govCommands() []*cobra.Command { return fmt.Errorf("HTTP status code: %d\n", resp.StatusCode()) } - fmt.Printf("Successfully submitted upgrade for version %s at height %s.\n", args[0], args[1]) + fmt.Printf("Successfully submitted upgrade for version %s at height %s.\n", version, heightArg) fmt.Printf("HTTP status code: %d\n", resp.StatusCode()) fmt.Println(string(resp.Body)) From 3357f2ebc491bca6a3ea4107b5d4541a85e2682e Mon Sep 17 00:00:00 2001 From: BigBoss Date: Wed, 9 Aug 2023 11:20:22 -0400 Subject: [PATCH 24/27] formatting --- persistence/sql/sql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence/sql/sql.go b/persistence/sql/sql.go index a83a2703c..87434bd71 100644 --- a/persistence/sql/sql.go +++ b/persistence/sql/sql.go @@ -156,7 +156,7 @@ func GetParams(pgtx pgx.Tx, height uint64) ([]*coreTypes.Param, error) { func GetUpgrade(pgtx pgx.Tx, height uint64) (*coreTypes.Upgrade, error) { row := pgtx.QueryRow(context.Background(), ` -select signer, version, height, created from upgrades where created = $1 +SELECT signer, version, height, created FROM upgrades WHERE created = $1 `, height) upgrade := new(coreTypes.Upgrade) From 580dbfbbe3fb8136d985510a53b917bacb34233f Mon Sep 17 00:00:00 2001 From: BigBoss Date: Wed, 9 Aug 2023 11:32:28 -0400 Subject: [PATCH 25/27] test handle message upgrade --- .../unit_of_work/tx_message_handler_test.go | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 utility/unit_of_work/tx_message_handler_test.go diff --git a/utility/unit_of_work/tx_message_handler_test.go b/utility/unit_of_work/tx_message_handler_test.go new file mode 100644 index 000000000..69aa7ca04 --- /dev/null +++ b/utility/unit_of_work/tx_message_handler_test.go @@ -0,0 +1,76 @@ +package unit_of_work + +import ( + "errors" + "testing" + + "github.com/golang/mock/gomock" + types "github.com/pokt-network/pocket/shared/core/types" + mockModules "github.com/pokt-network/pocket/shared/modules/mocks" + typesUtil "github.com/pokt-network/pocket/utility/types" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" +) + +func TestHandleMessageUpgrade(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockrwcontext := mockModules.NewMockPersistenceRWContext(ctrl) + logger := zerolog.New(nil) + persistenceRWContext := mockrwcontext + + u := &baseUtilityUnitOfWork{ + logger: &logger, + persistenceRWContext: persistenceRWContext, + height: 10, + } + + // Test: upgrade height must be greater than current height + msg := &typesUtil.MessageUpgrade{ + Version: "1.0.0", + Height: 5, + } + err := u.handleMessageUpgrade(msg) + assert.Equal(t, types.ErrSettingUpgrade(errors.New("upgrade height must be greater than current height")), err) + + // Test: invalid protocol version + msg = &typesUtil.MessageUpgrade{ + Version: "invalid-version", + Height: 20, + } + err = u.handleMessageUpgrade(msg) + assert.Equal(t, types.ErrInvalidProtocolVersion("invalid-version"), err) + + // Test: error getting current version + persistenceRWContext.EXPECT().GetVersionAtHeight(gomock.Any()).Return("", errors.New("some error")) + err = u.handleMessageUpgrade(&typesUtil.MessageUpgrade{Version: "2.0.0", Height: 20}) + assert.Error(t, err) + + // Test: error parsing current version + persistenceRWContext.EXPECT().GetVersionAtHeight(gomock.Any()).Return("invalid-version", nil) + err = u.handleMessageUpgrade(&typesUtil.MessageUpgrade{Version: "2.0.0", Height: 20}) + assert.Error(t, err) + + // Test: major version jump too large + persistenceRWContext.EXPECT().GetVersionAtHeight(gomock.Any()).Return("1.0.0", nil) + err = u.handleMessageUpgrade(&typesUtil.MessageUpgrade{Version: "3.0.0", Height: 20}) + assert.Error(t, err) + + // Test: version must be greater than current + persistenceRWContext.EXPECT().GetVersionAtHeight(gomock.Any()).Return("2.0.0", nil) + err = u.handleMessageUpgrade(&typesUtil.MessageUpgrade{Version: "2.0.0", Height: 20}) + assert.Error(t, err) + + // Test: error setting upgrade + persistenceRWContext.EXPECT().GetVersionAtHeight(gomock.Any()).Return("1.0.0", nil) + persistenceRWContext.EXPECT().SetUpgrade(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("some error")) + err = u.handleMessageUpgrade(&typesUtil.MessageUpgrade{Version: "2.0.0", Height: 20}) + assert.Error(t, err) + + // Test: successful upgrade + persistenceRWContext.EXPECT().GetVersionAtHeight(gomock.Any()).Return("1.0.0", nil) + persistenceRWContext.EXPECT().SetUpgrade(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + err = u.handleMessageUpgrade(&typesUtil.MessageUpgrade{Version: "2.0.0", Height: 20}) + assert.NoError(t, err) +} From 02a8e4ce5eb0bbe505bd297e1a6afbb03f5a4af8 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Wed, 9 Aug 2023 10:34:04 -0500 Subject: [PATCH 26/27] Update utility/unit_of_work/uow_leader.go Co-authored-by: Arash <23505281+adshmh@users.noreply.github.com> --- utility/unit_of_work/uow_leader.go | 1 - 1 file changed, 1 deletion(-) diff --git a/utility/unit_of_work/uow_leader.go b/utility/unit_of_work/uow_leader.go index bbca5c6e3..e05bc33bf 100644 --- a/utility/unit_of_work/uow_leader.go +++ b/utility/unit_of_work/uow_leader.go @@ -101,7 +101,6 @@ func (uow *leaderUtilityUnitOfWork) reapMempool(txMempool mempool.TXMempool, max } txHash, err := tx.Hash() - if err != nil { uow.logger.Err(err).Msg("Error hashing transaction during mempool reaping") return nil, err From 08d55bc8b3a011bfcd02b8fb293100e88a5d4f91 Mon Sep 17 00:00:00 2001 From: BigBoss Date: Wed, 9 Aug 2023 11:47:31 -0400 Subject: [PATCH 27/27] format --- persistence/types/gov.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/persistence/types/gov.go b/persistence/types/gov.go index cf3d8291f..7d0e64006 100644 --- a/persistence/types/gov.go +++ b/persistence/types/gov.go @@ -37,19 +37,19 @@ const ( )` UpgradesTableSchema = ` -create table if not exists upgrades +CREATE TABLE IF NOT EXISTS upgrades ( - signer text not null, - version varchar(10) not null, - height bigint not null unique, - created bigint not null unique, - primary key (version) + signer text NOT NULL, + version varchar(10) NOT NULL, + height bigint NOT NULL UNIQUE, + created bigint NOT NULL UNIQUE, + PRIMARY KEY (version) ); -comment on table upgrades is 'stores the upgrade history of the network'; -comment on column upgrades.signer is 'the address of the signer of the upgrade'; -comment on column upgrades.version is 'the semver 2.0 version of the upgrade'; -comment on column upgrades.height is 'the activation height of the upgrade'; -comment on column upgrades.created is 'the height the upgrade was created'; +COMMENT ON TABLE upgrades IS 'stores the upgrade history of the network'; +COMMENT ON COLUMN upgrades.signer IS 'the address of the signer of the upgrade'; +COMMENT ON COLUMN upgrades.version IS 'the semver 2.0 version of the upgrade'; +COMMENT ON COLUMN upgrades.height IS 'the activation height of the upgrade'; +COMMENT ON COLUMN upgrades.created IS 'the height the upgrade was created'; ` )