diff --git a/Makefile b/Makefile index f3bcaf222..a2e98b2ba 100644 --- a/Makefile +++ b/Makefile @@ -518,4 +518,4 @@ check_cross_module_imports: ## Lists cross-module imports .PHONY: send_local_tx send_local_tx: ## A hardcoded send tx to make LocalNet debugging easier - go run app/client/*.go Account Send 00104055c00bed7c983a48aac7dc6335d7c607a7 00204737d2a165ebe4be3a7d5b0af905b0ea91d8 1000 + go run app/client/*.go Account Send --non_interactive 00104055c00bed7c983a48aac7dc6335d7c607a7 00204737d2a165ebe4be3a7d5b0af905b0ea91d8 1000 diff --git a/app/client/cli/actor.go b/app/client/cli/actor.go index a08637fd4..3ac798830 100644 --- a/app/client/cli/actor.go +++ b/app/client/cli/actor.go @@ -129,13 +129,13 @@ If no changes are desired for the parameter, just enter the current param value // removing all invalid characters from rawChains argument rawChains := rawChainCleanupRegex.ReplaceAllString(args[2], "") chains := strings.Split(rawChains, ",") - serviceURI := args[3] + serviceURL := args[3] msg := &typesUtil.MessageStake{ PublicKey: pk.PublicKey().Bytes(), Chains: chains, Amount: amount, - ServiceUrl: serviceURI, + ServiceUrl: serviceURL, OutputAddress: pk.Address(), Signer: pk.Address(), ActorType: cmdDef.ActorType, @@ -201,13 +201,13 @@ func newEditStakeCmd(cmdDef actorCmdDef) *cobra.Command { // removing all invalid characters from rawChains argument rawChains := rawChainCleanupRegex.ReplaceAllString(args[2], "") chains := strings.Split(rawChains, ",") - serviceURI := args[3] + serviceURL := args[3] msg := &typesUtil.MessageEditStake{ Address: fromAddr, Chains: chains, Amount: amount, - ServiceUrl: serviceURI, + ServiceUrl: serviceURL, Signer: pk.Address(), ActorType: cmdDef.ActorType, } diff --git a/app/client/cli/debug.go b/app/client/cli/debug.go index bd9f982d5..e96285edb 100644 --- a/app/client/cli/debug.go +++ b/app/client/cli/debug.go @@ -85,18 +85,18 @@ func NewDebugCommand() *cobra.Command { bus := runtimeMgr.GetBus() modulesRegistry := bus.GetModulesRegistry() - rpcUrl := fmt.Sprintf("http://%s:%s", rpcHost, defaults.DefaultRPCPort) + rpcURL := fmt.Sprintf("http://%s:%s", rpcHost, defaults.DefaultRPCPort) addressBookProvider := rpcABP.NewRPCAddrBookProvider( rpcABP.WithP2PConfig( runtimeMgr.GetConfig().P2P, ), - rpcABP.WithCustomRPCUrl(rpcUrl), + rpcABP.WithCustomRPCURL(rpcURL), ) modulesRegistry.RegisterModule(addressBookProvider) currentHeightProvider := rpcCHP.NewRPCCurrentHeightProvider( - rpcCHP.WithCustomRPCUrl(rpcUrl), + rpcCHP.WithCustomRPCURL(rpcURL), ) modulesRegistry.RegisterModule(currentHeightProvider) diff --git a/app/client/cli/keys.go b/app/client/cli/keys.go index 2901a5471..7c9b89ea5 100644 --- a/app/client/cli/keys.go +++ b/app/client/cli/keys.go @@ -4,15 +4,16 @@ import ( "bytes" "encoding/hex" "fmt" - "github.com/pokt-network/pocket/logger" - "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" - "github.com/pokt-network/pocket/shared/crypto" - utilTypes "github.com/pokt-network/pocket/utility/types" "path/filepath" "strconv" "strings" + "github.com/pokt-network/pocket/logger" + "github.com/pokt-network/pocket/shared/codec" + coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" + "github.com/pokt-network/pocket/app/client/keybase" "github.com/spf13/cobra" ) @@ -363,7 +364,7 @@ func keysExportCommands() []*cobra.Command { logger.Global.Info().Str("output_file", outputFile).Msg("Exporting private key string to file...") - return converters.WriteOutput(exportString, outputFile) + return utils.WriteOutput(exportString, outputFile) }, }, } @@ -384,7 +385,7 @@ func keysImportCommands() []*cobra.Command { if len(args) == 1 { privateKeyString = args[0] } else if inputFile != "" { - privateKeyBz, err := converters.ReadInput(inputFile) + privateKeyBz, err := utils.ReadInput(inputFile) privateKeyString = string(privateKeyBz) if err != nil { return err @@ -578,11 +579,11 @@ func keysSignTxCommands() []*cobra.Command { } // Unmarshal Tx from input file - txBz, err := converters.ReadInput(inputFile) + txBz, err := utils.ReadInput(inputFile) if err != nil { return err } - txProto := new(utilTypes.Transaction) + txProto := new(coreTypes.Transaction) if err := codec.GetCodec().Unmarshal(txBz, txProto); err != nil { return err } @@ -599,7 +600,7 @@ func keysSignTxCommands() []*cobra.Command { } // Add signature to the transaction - sig := new(utilTypes.Signature) + sig := new(coreTypes.Signature) sig.PublicKey = privKey.PublicKey().Bytes() sig.Signature = sigBz txProto.Signature = sig @@ -610,7 +611,7 @@ func keysSignTxCommands() []*cobra.Command { return err } - if err := converters.WriteOutput(txBz, outputFile); err != nil { + if err := utils.WriteOutput(txBz, outputFile); err != nil { return err } @@ -650,11 +651,11 @@ func keysSignTxCommands() []*cobra.Command { } // Unmarshal Tx from input file - txBz, err := converters.ReadInput(inputFile) + txBz, err := utils.ReadInput(inputFile) if err != nil { return err } - txProto := new(utilTypes.Transaction) + txProto := new(coreTypes.Transaction) if err := codec.GetCodec().Unmarshal(txBz, txProto); err != nil { return err } diff --git a/app/client/cli/utils.go b/app/client/cli/utils.go index 1cebb1a7b..cc50fff80 100644 --- a/app/client/cli/utils.go +++ b/app/client/cli/utils.go @@ -14,8 +14,9 @@ import ( "github.com/pokt-network/pocket/logger" "github.com/pokt-network/pocket/rpc" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" + coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" "github.com/spf13/cobra" "golang.org/x/term" @@ -89,7 +90,7 @@ func prepareTxBytes(msg typesUtil.Message, pk crypto.PrivateKey) ([]byte, error) return nil, err } - tx := &typesUtil.Transaction{ + tx := &coreTypes.Transaction{ Msg: anyMsg, Nonce: fmt.Sprintf("%d", crypto.GetNonce()), } @@ -104,7 +105,7 @@ func prepareTxBytes(msg typesUtil.Message, pk crypto.PrivateKey) ([]byte, error) return nil, err } - tx.Signature = &typesUtil.Signature{ + tx.Signature = &coreTypes.Signature{ Signature: signature, PublicKey: pk.PublicKey().Bytes(), } @@ -155,13 +156,13 @@ func readPassphraseMessage(currPwd, prompt string) string { } func validateStakeAmount(amount string) error { - am, err := converters.StringToBigInt(amount) + am, err := utils.StringToBigInt(amount) if err != nil { return err } sr := big.NewInt(stakingRecommendationAmount) - if converters.BigIntLessThan(am, sr) { + if utils.BigIntLessThan(am, sr) { fmt.Printf("The amount you are staking for is below the recommendation of %d POKT, would you still like to continue? y|n\n", sr.Div(sr, oneMillion).Int64()) if !confirmation(pwd) { return fmt.Errorf("aborted") diff --git a/app/client/doc/CHANGELOG.md b/app/client/doc/CHANGELOG.md index 0d956e79e..a2b7ca01d 100644 --- a/app/client/doc/CHANGELOG.md +++ b/app/client/doc/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.19] - 2023-02-28 + +- Renamed the package names for some basic helpers + ## [0.0.0.18] - 2023-02-28 - Implement SLIP-0010 HD child key derivation with the keybase diff --git a/app/client/keybase/debug/keystore.go b/app/client/keybase/debug/keystore.go index 9e8eca0c6..c51efa543 100644 --- a/app/client/keybase/debug/keystore.go +++ b/app/client/keybase/debug/keystore.go @@ -2,7 +2,6 @@ package debug import ( "fmt" - "github.com/pokt-network/pocket/shared/converters" "os" "path/filepath" r "runtime" @@ -12,6 +11,7 @@ import ( "github.com/pokt-network/pocket/runtime" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" pocketk8s "github.com/pokt-network/pocket/shared/k8s" + "github.com/pokt-network/pocket/shared/utils" "gopkg.in/yaml.v2" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -133,7 +133,7 @@ func fetchValidatorPrivateKeysFromFile() (map[string]string, error) { _, current, _, _ := r.Caller(0) //nolint:gocritic // Use path to find private-keys yaml file from being called in any location in the repo yamlFile := filepath.Join(current, privateKeysYamlFile) - if exists, err := converters.FileExists(yamlFile); !exists || err != nil { + if exists, err := utils.FileExists(yamlFile); !exists || err != nil { return nil, fmt.Errorf("unable to find YAML file: %s", yamlFile) } diff --git a/app/client/keybase/keybase_test.go b/app/client/keybase/keybase_test.go index e967acd5d..06c759bb6 100644 --- a/app/client/keybase/keybase_test.go +++ b/app/client/keybase/keybase_test.go @@ -4,7 +4,7 @@ import ( "encoding/hex" "testing" - "github.com/pokt-network/pocket/runtime/test_artifacts/keygenerator" + "github.com/pokt-network/pocket/runtime/test_artifacts/keygen" "github.com/pokt-network/pocket/shared/crypto" "github.com/stretchr/testify/require" ) @@ -441,7 +441,7 @@ func initDB(t *testing.T) Keybase { func createTestKeys(t *testing.T, n int) []crypto.PrivateKey { pks := make([]crypto.PrivateKey, 0) for i := 0; i < n; i++ { - privKeyString, _, _ := keygenerator.GetInstance().Next() + privKeyString, _, _ := keygen.GetInstance().Next() privKey, err := crypto.NewPrivateKey(privKeyString) require.NoError(t, err) pks = append(pks, privKey) diff --git a/app/client/keybase/keystore.go b/app/client/keybase/keystore.go index 1808d9bb7..7dc52b972 100644 --- a/app/client/keybase/keystore.go +++ b/app/client/keybase/keystore.go @@ -4,13 +4,12 @@ import ( "bytes" "encoding/hex" "fmt" - "github.com/pokt-network/pocket/shared/crypto/slip" "strings" - "github.com/pokt-network/pocket/shared/converters" - "github.com/dgraph-io/badger/v3" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/crypto/slip" + "github.com/pokt-network/pocket/shared/utils" ) const ( @@ -32,7 +31,7 @@ type badgerKeybase struct { // NewKeybase creates/Opens the DB at the specified path creating the path if it doesn't exist func NewKeybase(path string) (Keybase, error) { - pathExists, err := converters.DirExists(path) // Creates path if it doesn't exist + pathExists, err := utils.DirExists(path) // Creates path if it doesn't exist if err != nil || !pathExists { return nil, err } diff --git a/build/config/genesis.json b/build/config/genesis.json index 0835757c5..2f02e8fd6 100755 --- a/build/config/genesis.json +++ b/build/config/genesis.json @@ -4040,7 +4040,7 @@ "address": "00104055c00bed7c983a48aac7dc6335d7c607a7", "public_key": "dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e", "chains": null, - "generic_param": "node1.consensus:8080", + "service_url": "node1.consensus:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4051,7 +4051,7 @@ "address": "00204737d2a165ebe4be3a7d5b0af905b0ea91d8", "public_key": "eb2c78364525a210d994a83e02d18b4287ab81f6670cf4510ab6c9f51e296d91", "chains": null, - "generic_param": "node2.consensus:8080", + "service_url": "node2.consensus:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4062,7 +4062,7 @@ "address": "00304d0101847b37fd62e7bebfbdddecdbb7133e", "public_key": "1041a9c76539791fef9bee5b4fcd5bf4a1a489e0790c44cbdfa776b901e13b50", "chains": null, - "generic_param": "node3.consensus:8080", + "service_url": "node3.consensus:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4073,7 +4073,7 @@ "address": "00404a570febd061274f72b50d0a37f611dfe339", "public_key": "d6cea8706f6ee6672c1e013e667ec8c46231e0e7abcf97ba35d89fceb8edae45", "chains": null, - "generic_param": "node4.consensus:8080", + "service_url": "node4.consensus:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4085,10 +4085,7 @@ { "address": "88a792b7aca673620132ef01f50e62caa58eca83", "public_key": "5f78658599943dc3e623539ce0b3c9fe4e192034a1e3fef308bc9f96915754e0", - "chains": [ - "0001" - ], - "generic_param": "1000000", + "chains": ["0001"], "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4100,10 +4097,8 @@ { "address": "43d9ea9d9ad9c58bb96ec41340f83cb2cabb6496", "public_key": "16cd0a304c38d76271f74dd3c90325144425d904ef1b9a6fbab9b201d75a998b", - "chains": [ - "0001" - ], - "generic_param": "node1.consensus:8080", + "chains": ["0001"], + "service_url": "node1.consensus:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4115,10 +4110,8 @@ { "address": "9ba047197ec043665ad3f81278ab1f5d3eaf6b8b", "public_key": "68efd26af01692fcd77dc135ca1de69ede464e8243e6832bd6c37f282db8c9cb", - "chains": [ - "0001" - ], - "generic_param": "node1.consensus:8080", + "chains": ["0001"], + "service_url": "node1.consensus:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4130,7 +4123,7 @@ "blocks_per_session": 4, "app_minimum_stake": "15000000000", "app_max_chains": 15, - "app_baseline_stake_rate": 100, + "app_session_tokens_multiplier": 100, "app_unstaking_blocks": 2016, "app_minimum_pause_blocks": 4, "app_max_pause_blocks": 672, @@ -4184,8 +4177,7 @@ "blocks_per_session_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_stake_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_max_chains_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "app_baseline_stake_rate_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "app_staking_adjustment_owner": "da034209758b78eaea06dd99c07909ab54c99b45", + "app_session_tokens_multiplier_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_unstaking_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_pause_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_max_paused_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", diff --git a/build/docs/CHANGELOG.md b/build/docs/CHANGELOG.md index 4b77a21f7..8e70e2aad 100644 --- a/build/docs/CHANGELOG.md +++ b/build/docs/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.19] - 2023-02-28 + +- Renamed `generic_param` to `service_url` in the config files +- Renamed a few governance parameters to make self explanatory + ## [0.0.0.18] - 2023-02-21 - Rename ServiceNode Actor Type Name to Servicer diff --git a/build/localnet/cluster-manager/main.go b/build/localnet/cluster-manager/main.go index 14214bd6a..25b6a4c4f 100644 --- a/build/localnet/cluster-manager/main.go +++ b/build/localnet/cluster-manager/main.go @@ -22,12 +22,12 @@ import ( const cliPath = "/usr/local/bin/client" var ( - rpcUrl string + rpcURL string logger = pocketLogger.Global.CreateLoggerForModule("cluster-manager") ) func init() { - rpcUrl = fmt.Sprintf("http://%s:%s", runtime.GetEnv("RPC_HOST", "v1-validator001"), defaults.DefaultRPCPort) + rpcURL = fmt.Sprintf("http://%s:%s", runtime.GetEnv("RPC_HOST", "v1-validator001"), defaults.DefaultRPCPort) } func main() { @@ -87,7 +87,7 @@ func stakeValidator(pk crypto.PrivateKey, amount string, chains []string, servic args := []string{ "--non_interactive=true", - "--remote_cli_url=" + rpcUrl, + "--remote_cli_url=" + rpcURL, "Validator", "Stake", pk.Address().String(), @@ -114,7 +114,7 @@ func unstakeValidator(pk crypto.PrivateKey) error { args := []string{ "--non_interactive=true", - "--remote_cli_url=" + rpcUrl, + "--remote_cli_url=" + rpcURL, "Validator", "Unstake", pk.Address().String(), diff --git a/build/localnet/manifests/configs.yaml b/build/localnet/manifests/configs.yaml index 93e949b0f..117ccc5c4 100644 --- a/build/localnet/manifests/configs.yaml +++ b/build/localnet/manifests/configs.yaml @@ -4102,7 +4102,7 @@ data: "address": "00104055c00bed7c983a48aac7dc6335d7c607a7", "public_key": "dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e", "chains": null, - "generic_param": "v1-validator001:8080", + "service_url": "v1-validator001:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4113,7 +4113,7 @@ data: "address": "00204737d2a165ebe4be3a7d5b0af905b0ea91d8", "public_key": "eb2c78364525a210d994a83e02d18b4287ab81f6670cf4510ab6c9f51e296d91", "chains": null, - "generic_param": "v1-validator002:8080", + "service_url": "v1-validator002:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4124,7 +4124,7 @@ data: "address": "00304d0101847b37fd62e7bebfbdddecdbb7133e", "public_key": "1041a9c76539791fef9bee5b4fcd5bf4a1a489e0790c44cbdfa776b901e13b50", "chains": null, - "generic_param": "v1-validator003:8080", + "service_url": "v1-validator003:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4135,7 +4135,7 @@ data: "address": "00404a570febd061274f72b50d0a37f611dfe339", "public_key": "d6cea8706f6ee6672c1e013e667ec8c46231e0e7abcf97ba35d89fceb8edae45", "chains": null, - "generic_param": "v1-validator004:8080", + "service_url": "v1-validator004:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4148,7 +4148,6 @@ data: "address": "88a792b7aca673620132ef01f50e62caa58eca83", "public_key": "5f78658599943dc3e623539ce0b3c9fe4e192034a1e3fef308bc9f96915754e0", "chains": ["0001"], - "generic_param": "1000000", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4161,7 +4160,7 @@ data: "address": "43d9ea9d9ad9c58bb96ec41340f83cb2cabb6496", "public_key": "16cd0a304c38d76271f74dd3c90325144425d904ef1b9a6fbab9b201d75a998b", "chains": ["0001"], - "generic_param": "v1-validator001:8080", + "service_url": "v1-validator001:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4174,7 +4173,7 @@ data: "address": "9ba047197ec043665ad3f81278ab1f5d3eaf6b8b", "public_key": "68efd26af01692fcd77dc135ca1de69ede464e8243e6832bd6c37f282db8c9cb", "chains": ["0001"], - "generic_param": "v1-validator001:8080", + "service_url": "v1-validator001:8080", "staked_amount": "1000000000000", "paused_height": -1, "unstaking_height": -1, @@ -4186,7 +4185,7 @@ data: "blocks_per_session": 4, "app_minimum_stake": "15000000000", "app_max_chains": 15, - "app_baseline_stake_rate": 100, + "app_session_tokens_multiplier": 100, "app_unstaking_blocks": 2016, "app_minimum_pause_blocks": 4, "app_max_pause_blocks": 672, @@ -4240,8 +4239,7 @@ data: "blocks_per_session_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_stake_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_max_chains_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "app_baseline_stake_rate_owner": "da034209758b78eaea06dd99c07909ab54c99b45", - "app_staking_adjustment_owner": "da034209758b78eaea06dd99c07909ab54c99b45", + "app_session_tokens_multiplier_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_unstaking_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_minimum_pause_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", "app_max_paused_blocks_owner": "da034209758b78eaea06dd99c07909ab54c99b45", diff --git a/consensus/doc/CHANGELOG.md b/consensus/doc/CHANGELOG.md index 40d42f642..f77b2e184 100644 --- a/consensus/doc/CHANGELOG.md +++ b/consensus/doc/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.36] - 2023-02-28 + +- Creating a persistence read context when needing to accessing stateless (i.e. block hash) data +- Renamed package names and parameters to reflect changes in the rest of the codebase +- Removed the unused `validator.proto` + ## [0.0.0.35] - 2023-02-28 - Fixed bug in `sendGetMetadataStateSyncMessage` diff --git a/consensus/e2e_tests/pacemaker_test.go b/consensus/e2e_tests/pacemaker_test.go index 9f52937cd..85449447a 100644 --- a/consensus/e2e_tests/pacemaker_test.go +++ b/consensus/e2e_tests/pacemaker_test.go @@ -164,7 +164,6 @@ func TestPacemakerCatchupSameStepDifferentRounds(t *testing.T) { Height: testHeight, StateHash: stateHash, PrevStateHash: "", - NumTxs: 0, ProposerAddress: consensusPK.Address(), QuorumCertificate: nil, } diff --git a/consensus/e2e_tests/utils_test.go b/consensus/e2e_tests/utils_test.go index f99600a9c..d50f61890 100644 --- a/consensus/e2e_tests/utils_test.go +++ b/consensus/e2e_tests/utils_test.go @@ -20,12 +20,12 @@ import ( "github.com/pokt-network/pocket/runtime/test_artifacts" "github.com/pokt-network/pocket/shared" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/messaging" "github.com/pokt-network/pocket/shared/modules" mockModules "github.com/pokt-network/pocket/shared/modules/mocks" + "github.com/pokt-network/pocket/shared/utils" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/anypb" ) @@ -363,13 +363,13 @@ func basePersistenceMock(t *testing.T, _ modules.EventsChannel, bus modules.Bus) blockStoreMock := mocksPer.NewMockKVStore(ctrl) blockStoreMock.EXPECT().Get(gomock.Any()).DoAndReturn(func(height []byte) ([]byte, error) { - heightInt := converters.HeightFromBytes(height) + heightInt := utils.HeightFromBytes(height) if bus.GetConsensusModule().CurrentHeight() < heightInt { return nil, fmt.Errorf("requested height is higher than current height of the node's consensus module") } blockWithHeight := &coreTypes.Block{ BlockHeader: &coreTypes.BlockHeader{ - Height: converters.HeightFromBytes(height), + Height: utils.HeightFromBytes(height), }, } return codec.GetCodec().Marshal(blockWithHeight) @@ -395,7 +395,7 @@ func basePersistenceMock(t *testing.T, _ modules.EventsChannel, bus modules.Bus) // state; hence the `-1` expectation in the call above. persistenceContextMock.EXPECT().Close().Return(nil).AnyTimes() persistenceReadContextMock.EXPECT().GetAllValidators(gomock.Any()).Return(bus.GetRuntimeMgr().GetGenesis().Validators, nil).AnyTimes() - + persistenceReadContextMock.EXPECT().GetBlockHash(gomock.Any()).Return("", nil).AnyTimes() persistenceReadContextMock.EXPECT().Close().Return(nil).AnyTimes() return persistenceMock @@ -463,7 +463,6 @@ func baseUtilityContextMock(t *testing.T, genesisState *genesis.GenesisState) *m utilityContextMock.EXPECT().SetProposalBlock(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() utilityContextMock.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes() utilityContextMock.EXPECT().Release().Return(nil).AnyTimes() - utilityContextMock.EXPECT().GetPersistenceContext().Return(persistenceContextMock).AnyTimes() persistenceContextMock.EXPECT().Release().Return(nil).AnyTimes() diff --git a/consensus/hotstuff_leader.go b/consensus/hotstuff_leader.go index f64663d33..78ee46661 100644 --- a/consensus/hotstuff_leader.go +++ b/consensus/hotstuff_leader.go @@ -392,8 +392,13 @@ func (m *consensusModule) prepareAndApplyBlock(qc *typesCons.QuorumCertificate) return nil, err } - // IMPROVE: This data can be read via an ephemeral read context - no need to use the utility's persistence context - prevBlockHash, err := m.utilityContext.GetPersistenceContext().GetBlockHash(int64(m.height) - 1) + prevHeight := int64(m.height) - 1 + readCtx, err := m.GetBus().GetPersistenceModule().NewReadContext(prevHeight) + if err != nil { + return nil, err + } + + prevBlockHash, err := readCtx.GetBlockHash(prevHeight) if err != nil { return nil, err } @@ -408,7 +413,6 @@ func (m *consensusModule) prepareAndApplyBlock(qc *typesCons.QuorumCertificate) Height: m.height, StateHash: stateHash, PrevStateHash: prevBlockHash, - NumTxs: uint32(len(txs)), ProposerAddress: m.privateKey.Address().Bytes(), QuorumCertificate: qcBytes, } diff --git a/consensus/module.go b/consensus/module.go index 81ab17091..644398d0d 100644 --- a/consensus/module.go +++ b/consensus/module.go @@ -235,7 +235,7 @@ func (*consensusModule) ValidateGenesis(gen *genesis.GenesisState) error { // Sort the validators by their generic param (i.e. service URL) vals := gen.GetValidators() sort.Slice(vals, func(i, j int) bool { - return vals[i].GetGenericParam() < vals[j].GetGenericParam() + return vals[i].GetServiceUrl() < vals[j].GetServiceUrl() }) // Sort the validators by their address diff --git a/consensus/state_sync/server.go b/consensus/state_sync/server.go index fef58e58a..a5016b08e 100644 --- a/consensus/state_sync/server.go +++ b/consensus/state_sync/server.go @@ -5,9 +5,9 @@ import ( typesCons "github.com/pokt-network/pocket/consensus/types" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" ) // This module is responsible for handling requests and business logic that advertises and shares @@ -104,7 +104,7 @@ func (m *stateSync) HandleGetBlockRequest(blockReq *typesCons.GetBlockRequest) e // Get a block from persistence module given block height func (m *stateSync) getBlockAtHeight(blockHeight uint64) (*coreTypes.Block, error) { blockStore := m.GetBus().GetPersistenceModule().GetBlockStore() - heightBytes := converters.HeightToBytes(blockHeight) + heightBytes := utils.HeightToBytes(blockHeight) blockBytes, err := blockStore.Get(heightBytes) if err != nil { diff --git a/consensus/types/actor_mapper_test.go b/consensus/types/actor_mapper_test.go index 44d0b0402..033574e75 100644 --- a/consensus/types/actor_mapper_test.go +++ b/consensus/types/actor_mapper_test.go @@ -13,7 +13,7 @@ func makeTestValidatorWithAddress(address string) *coreTypes.Actor { Address: address, PublicKey: "", Chains: []string{}, - GenericParam: "", + ServiceUrl: "", StakedAmount: "", PausedHeight: 0, UnstakingHeight: 0, diff --git a/consensus/types/proto/validator.proto b/consensus/types/proto/validator.proto deleted file mode 100644 index dfac06ea9..000000000 --- a/consensus/types/proto/validator.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; - -package consensus; - -option go_package = "github.com/pokt-network/pocket/consensus/types"; - -message Validator { - string address = 1; - string public_key = 2; - string staked_amount = 3; - string generic_param = 4; // TODO/DISCUSS re-evaluate naming covention -} diff --git a/logger/docs/CHANGELOG.md b/logger/docs/CHANGELOG.md index 8313b5657..9e2fcfb53 100644 --- a/logger/docs/CHANGELOG.md +++ b/logger/docs/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.9] - 2023-02-28 + +- Removed the unused `bus` from the `logger` struct + ## [0.0.0.8] - 2023-02-24 - Update the logger module interface to use logger pointers instead of values diff --git a/logger/module.go b/logger/module.go index 19e391a1f..091c4d5b5 100644 --- a/logger/module.go +++ b/logger/module.go @@ -18,7 +18,6 @@ type loggerModule struct { base_modules.InterruptableModule zerolog.Logger - bus modules.Bus config *configs.LoggerConfig } diff --git a/p2p/CHANGELOG.md b/p2p/CHANGELOG.md index 5f35a5c2e..1ee783378 100644 --- a/p2p/CHANGELOG.md +++ b/p2p/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.30] - 2023-02-28 + +- Renamed package names and parameters to reflect changes in the rest of the codebase + ## [0.0.0.29] - 2023-02-24 - Update logger value references with pointers @@ -60,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.0.0.19] - 2023-01-19 - Rewrite `interface{}` to `any` + ## [0.0.0.18] - 2023-01-11 - Add a lock to the mempool to avoid parallel messages which has caused the node to crash in the past diff --git a/p2p/README.md b/p2p/README.md index a62937ff6..f9c595f22 100644 --- a/p2p/README.md +++ b/p2p/README.md @@ -14,7 +14,6 @@ This document is meant to be a supplement to the living specification of [1.0 Po - [RainTree testing framework](#raintree-testing-framework) - [Helpers](#helpers) - [Test Generators](#test-generators) - - [Considerations](#considerations) ## Interface @@ -120,9 +119,4 @@ The [rain-tree-simulator](https://github.com/pokt-network/rain-tree-sim/blob/mai You can read the documentation in the [python simulator](https://github.com/pokt-network/rain-tree-sim/blob/main/python) on how it can be used to generate the unit tests found in `module_raintree_test.go`. -#### Considerations - -- **Deterministic Private Key Generation**: Since RainTree is dependant on the lexicographic order of the addresses, the generation of the private keys (and in turn the public keys and addresses) is important and cannot be randomized for the time being. -- **Variable Coupling**:There is an implicit coupling between `validatorId`, `serviceUrl` and `genericParam` that requires understanding of the codebase. Reach out to @olshansk or @andrewnguyen22 for clarity on this. - diff --git a/p2p/bootstrap.go b/p2p/bootstrap.go index ad4dee9aa..d0594fa87 100644 --- a/p2p/bootstrap.go +++ b/p2p/bootstrap.go @@ -62,10 +62,10 @@ func (m *p2pModule) bootstrap() error { rpcABP.WithP2PConfig( m.GetBus().GetRuntimeMgr().GetConfig().P2P, ), - rpcABP.WithCustomRPCUrl(bootstrapNode), + rpcABP.WithCustomRPCURL(bootstrapNode), ) - currentHeightProvider := rpcCHP.NewRPCCurrentHeightProvider(rpcCHP.WithCustomRPCUrl(bootstrapNode)) + currentHeightProvider := rpcCHP.NewRPCCurrentHeightProvider(rpcCHP.WithCustomRPCURL(bootstrapNode)) addrBook, err = addressBookProvider.GetStakedAddrBookAtHeight(currentHeightProvider.CurrentHeight()) if err != nil { diff --git a/p2p/module.go b/p2p/module.go index 4487b6f76..be7e97c53 100644 --- a/p2p/module.go +++ b/p2p/module.go @@ -175,7 +175,7 @@ func (m *p2pModule) Send(addr cryptoPocket.Address, msg *anypb.Any) error { return m.network.NetworkSend(data, addr) } -// TECHDEBT(drewsky): Discuss how to best expose/access `Address` throughout the codebase. +// TECHDEBT: Define what the node identity is throughout the codebase func (m *p2pModule) GetAddress() (cryptoPocket.Address, error) { return m.address, nil } diff --git a/p2p/module_raintree_test.go b/p2p/module_raintree_test.go index 975108936..6c640256d 100644 --- a/p2p/module_raintree_test.go +++ b/p2p/module_raintree_test.go @@ -260,7 +260,7 @@ func testRainTreeCalls(t *testing.T, origNode string, networkSimulationConfig Te err := p2pMod.Start() require.NoError(t, err) for _, peer := range p2pMod.network.GetAddrBook() { - peer.Dialer = connMocks[peer.ServiceUrl] + peer.Dialer = connMocks[peer.ServiceURL] } } diff --git a/p2p/providers/addrbook_provider/addrbook_provider.go b/p2p/providers/addrbook_provider/addrbook_provider.go index b42dcb4a2..1353275be 100644 --- a/p2p/providers/addrbook_provider/addrbook_provider.go +++ b/p2p/providers/addrbook_provider/addrbook_provider.go @@ -40,7 +40,7 @@ func ActorsToAddrBook(abp AddrBookProvider, actors []*coreTypes.Actor) (typesP2P } func ActorToNetworkPeer(abp AddrBookProvider, actor *coreTypes.Actor) (*typesP2P.NetworkPeer, error) { - conn, err := abp.GetConnFactory()(abp.GetP2PConfig(), actor.GetGenericParam()) // generic param is service url + conn, err := abp.GetConnFactory()(abp.GetP2PConfig(), actor.GetServiceUrl()) // generic param is service url if err != nil { return nil, fmt.Errorf("error resolving addr: %v", err) } @@ -54,7 +54,7 @@ func ActorToNetworkPeer(abp AddrBookProvider, actor *coreTypes.Actor) (*typesP2P Dialer: conn, PublicKey: pubKey, Address: pubKey.Address(), - ServiceUrl: actor.GetGenericParam(), // service url + ServiceURL: actor.GetServiceUrl(), // service url } return peer, nil diff --git a/p2p/providers/addrbook_provider/rpc/provider.go b/p2p/providers/addrbook_provider/rpc/provider.go index f715d93af..ae3794f47 100644 --- a/p2p/providers/addrbook_provider/rpc/provider.go +++ b/p2p/providers/addrbook_provider/rpc/provider.go @@ -33,7 +33,7 @@ type rpcAddrBookProvider struct { base_modules.IntegratableModule base_modules.InterruptableModule - rpcUrl string + rpcURL string p2pCfg *configs.P2PConfig rpcClient *rpc.ClientWithResponses @@ -42,7 +42,7 @@ type rpcAddrBookProvider struct { func NewRPCAddrBookProvider(options ...modules.ModuleOption) *rpcAddrBookProvider { rabp := &rpcAddrBookProvider{ - rpcUrl: fmt.Sprintf("http://%s:%s", rpcHost, defaults.DefaultRPCPort), // TODO: Make port configurable + rpcURL: fmt.Sprintf("http://%s:%s", rpcHost, defaults.DefaultRPCPort), // TODO: Make port configurable connFactory: transport.CreateDialer, // default connection factory, overridable with WithConnectionFactory() } @@ -88,10 +88,10 @@ func (rabp *rpcAddrBookProvider) GetStakedAddrBookAtHeight(height uint64) (types var coreActors []*types.Actor for _, rpcActor := range rpcActors { coreActors = append(coreActors, &types.Actor{ - Address: rpcActor.Address, - PublicKey: rpcActor.PublicKey, - GenericParam: rpcActor.ServiceUrl, - ActorType: types.ActorType_ACTOR_TYPE_VAL, + Address: rpcActor.Address, + PublicKey: rpcActor.PublicKey, + ServiceUrl: rpcActor.ServiceUrl, + ActorType: types.ActorType_ACTOR_TYPE_VAL, }) } @@ -114,7 +114,7 @@ func (rabp *rpcAddrBookProvider) SetConnectionFactory(connFactory typesP2P.Conne } func (rabp *rpcAddrBookProvider) initRPCClient() { - rpcClient, err := rpc.NewClientWithResponses(rabp.rpcUrl) + rpcClient, err := rpc.NewClientWithResponses(rabp.rpcURL) if err != nil { log.Fatalf("could not create RPC client: %v", err) } @@ -130,9 +130,9 @@ func WithP2PConfig(p2pCfg *configs.P2PConfig) modules.ModuleOption { } } -// WithCustomRPCUrl allows to specify a custom RPC URL -func WithCustomRPCUrl(rpcUrl string) modules.ModuleOption { +// WithCustomRPCURL allows to specify a custom RPC URL +func WithCustomRPCURL(rpcURL string) modules.ModuleOption { return func(rabp modules.InitializableModule) { - rabp.(*rpcAddrBookProvider).rpcUrl = rpcUrl + rabp.(*rpcAddrBookProvider).rpcURL = rpcURL } } diff --git a/p2p/providers/current_height_provider/rpc/provider.go b/p2p/providers/current_height_provider/rpc/provider.go index 3624d8361..97470d52b 100644 --- a/p2p/providers/current_height_provider/rpc/provider.go +++ b/p2p/providers/current_height_provider/rpc/provider.go @@ -28,7 +28,7 @@ type rpcCurrentHeightProvider struct { base_modules.IntegratableModule base_modules.InterruptableModule - rpcUrl string + rpcURL string rpcClient *rpc.ClientWithResponses } @@ -65,7 +65,7 @@ func (rchp *rpcCurrentHeightProvider) CurrentHeight() uint64 { func NewRPCCurrentHeightProvider(options ...modules.ModuleOption) *rpcCurrentHeightProvider { rchp := &rpcCurrentHeightProvider{ - rpcUrl: fmt.Sprintf("http://%s:%s", rpcHost, defaults.DefaultRPCPort), // TODO: Make port configurable + rpcURL: fmt.Sprintf("http://%s:%s", rpcHost, defaults.DefaultRPCPort), // TODO: Make port configurable } for _, o := range options { @@ -78,7 +78,7 @@ func NewRPCCurrentHeightProvider(options ...modules.ModuleOption) *rpcCurrentHei } func (rchp *rpcCurrentHeightProvider) initRPCClient() { - rpcClient, err := rpc.NewClientWithResponses(rchp.rpcUrl) + rpcClient, err := rpc.NewClientWithResponses(rchp.rpcURL) if err != nil { log.Fatalf("could not create RPC client: %v", err) } @@ -87,9 +87,9 @@ func (rchp *rpcCurrentHeightProvider) initRPCClient() { // options -// WithCustomRPCUrl allows to specify a custom RPC URL -func WithCustomRPCUrl(rpcUrl string) modules.ModuleOption { +// WithCustomRPCURL allows to specify a custom RPC URL +func WithCustomRPCURL(rpcURL string) modules.ModuleOption { return func(rabp modules.InitializableModule) { - rabp.(*rpcCurrentHeightProvider).rpcUrl = rpcUrl + rabp.(*rpcCurrentHeightProvider).rpcURL = rpcURL } } diff --git a/p2p/raintree/addrbook_utils.go b/p2p/raintree/addrbook_utils.go index bfe14c439..3c9fbc660 100644 --- a/p2p/raintree/addrbook_utils.go +++ b/p2p/raintree/addrbook_utils.go @@ -53,7 +53,7 @@ func (n *rainTreeNetwork) getTarget(targetPercentage float64, addrBookLen int, l peersManagerStateView := n.peersManager.getNetworkView() target := target{ - serviceUrl: peersManagerStateView.addrBookMap[peersManagerStateView.addrList[i]].ServiceUrl, + serviceURL: peersManagerStateView.addrBookMap[peersManagerStateView.addrList[i]].ServiceURL, percentage: targetPercentage, level: level, addrBookLengthAtHeight: addrBookLen, diff --git a/p2p/raintree/peers_manager_test.go b/p2p/raintree/peers_manager_test.go index 864a4cccc..dbdacf7ec 100644 --- a/p2p/raintree/peers_manager_test.go +++ b/p2p/raintree/peers_manager_test.go @@ -15,7 +15,7 @@ import ( ) const ( - serviceUrlFormat = "val_%d" + serviceURLFormat = "val_%d" ) type ExpectedRainTreeNetworkConfig struct { @@ -244,7 +244,7 @@ func getAlphabetAddrBook(n int) (addrBook types.AddrBook) { return } addrBook = append(addrBook, &types.NetworkPeer{ - ServiceUrl: fmt.Sprintf(serviceUrlFormat, i), + ServiceURL: fmt.Sprintf(serviceURLFormat, i), Address: []byte{byte(ch)}, }) } diff --git a/p2p/raintree/target.go b/p2p/raintree/target.go index fb29589fc..f44e40722 100644 --- a/p2p/raintree/target.go +++ b/p2p/raintree/target.go @@ -9,7 +9,7 @@ import ( type target struct { address cryptoPocket.Address - serviceUrl string + serviceURL string level uint32 // the level of the node in the RainTree tree (inverse of height in traditional computer science) percentage float64 // the target percentage within the peer list used to select this as a target @@ -25,16 +25,16 @@ func (t target) DebugString(n *rainTreeNetwork) string { selfAddr := n.selfAddr.String() for i := 0; i < t.addrBookLengthAtHeight; i++ { addr := peersManagerStateView.addrList[i] - serviceUrl := peersManagerStateView.addrBookMap[addr].ServiceUrl + serviceURL := peersManagerStateView.addrBookMap[addr].ServiceURL switch { case i == t.index && t.isSelf: - fmt.Fprintf(&s, " (**%s**) ", serviceUrl) + fmt.Fprintf(&s, " (**%s**) ", serviceURL) case i == t.index: - fmt.Fprintf(&s, " **%s** ", serviceUrl) + fmt.Fprintf(&s, " **%s** ", serviceURL) case addr == selfAddr: - fmt.Fprintf(&s, " (%s) ", serviceUrl) + fmt.Fprintf(&s, " (%s) ", serviceURL) default: - fmt.Fprintf(&s, " %s ", serviceUrl) + fmt.Fprintf(&s, " %s ", serviceURL) } } diff --git a/p2p/raintree/types/proto/raintree.proto b/p2p/raintree/types/proto/raintree.proto index 12b77c4a9..88fc07473 100644 --- a/p2p/raintree/types/proto/raintree.proto +++ b/p2p/raintree/types/proto/raintree.proto @@ -6,7 +6,5 @@ option go_package = "github.com/pokt-network/pocket/p2p/types"; message RainTreeMessage { uint32 level = 1; bytes data = 2; - - uint64 nonce = 3; - // DISCUSS(drewsky): discuss if we should have entropy at the RainTree level. + uint64 nonce = 3; // DISCUSS: Does RainTree even need entropy at this level? } \ No newline at end of file diff --git a/p2p/types/network_peer.go b/p2p/types/network_peer.go index 5ee7a4ee2..5ae95580d 100644 --- a/p2p/types/network_peer.go +++ b/p2p/types/network_peer.go @@ -10,5 +10,5 @@ type NetworkPeer struct { Address cryptoPocket.Address // This is only included because it's a more human-friendly differentiator between peers - ServiceUrl string + ServiceURL string } diff --git a/p2p/utils_test.go b/p2p/utils_test.go index 205142842..6859cada2 100644 --- a/p2p/utils_test.go +++ b/p2p/utils_test.go @@ -17,6 +17,7 @@ import ( "github.com/pokt-network/pocket/runtime/configs" types "github.com/pokt-network/pocket/runtime/configs/types" "github.com/pokt-network/pocket/runtime/genesis" + "github.com/pokt-network/pocket/runtime/test_artifacts" coreTypes "github.com/pokt-network/pocket/shared/core/types" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/modules" @@ -28,7 +29,7 @@ import ( // ~~~~~~ RainTree Unit Test Configurations ~~~~~~ const ( - serviceUrlFormat = "node%d.consensus:8080" + serviceURLFormat = "node%d.consensus:8080" eventsChannelSize = 10000 // Since we simulate up to a 27 node network, we will pre-generate a n >= 27 number of keys to avoid generation // every time. The genesis config seed start is set for deterministic key generation and 42 was chosen arbitrarily. @@ -70,7 +71,7 @@ type TestNetworkSimulationConfig map[string]struct { // CLEANUP: This could (should?) be a codebase-wide shared test helper func validatorId(i int) string { - return fmt.Sprintf(serviceUrlFormat, i) + return fmt.Sprintf(serviceURLFormat, i) } func waitForNetworkSimulationCompletion(t *testing.T, wg *sync.WaitGroup) { @@ -165,8 +166,8 @@ func createMockGenesisState(valKeys []cryptoPocket.PrivateKey) *genesis.GenesisS ActorType: coreTypes.ActorType_ACTOR_TYPE_VAL, Address: addr, PublicKey: valKey.PublicKey().String(), - GenericParam: validatorId(i + 1), - StakedAmount: "1000000000000000", + ServiceUrl: validatorId(i + 1), + StakedAmount: test_artifacts.DefaultStakeAmountString, PausedHeight: int64(0), UnstakingHeight: int64(0), Output: addr, diff --git a/persistence/account_shared_sql.go b/persistence/account_shared_sql.go index 37b3cb557..a3583e0e7 100644 --- a/persistence/account_shared_sql.go +++ b/persistence/account_shared_sql.go @@ -5,8 +5,8 @@ import ( "github.com/jackc/pgx/v5" "github.com/pokt-network/pocket/persistence/types" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/utils" ) const ( @@ -37,18 +37,18 @@ func (p *PostgresContext) operationAccountAmount( if err != nil { return err } - originalAmountBig, err := converters.StringToBigInt(originalAmount) + originalAmountBig, err := utils.StringToBigInt(originalAmount) if err != nil { return err } - amountBig, err := converters.StringToBigInt(amount) + amountBig, err := utils.StringToBigInt(amount) if err != nil { return err } if err := op(originalAmountBig, amountBig); err != nil { return err } - if _, err = tx.Exec(ctx, accountSchema.InsertAccountQuery(identifier, converters.BigIntToString(originalAmountBig), height)); err != nil { + if _, err = tx.Exec(ctx, accountSchema.InsertAccountQuery(identifier, utils.BigIntToString(originalAmountBig), height)); err != nil { return err } return nil diff --git a/persistence/actor_shared_sql.go b/persistence/actor_shared_sql.go index e22bcc372..8058838d3 100644 --- a/persistence/actor_shared_sql.go +++ b/persistence/actor_shared_sql.go @@ -11,27 +11,6 @@ import ( moduleTypes "github.com/pokt-network/pocket/shared/modules/types" ) -// IMPROVE(team): Move this into a proto enum. We are not using `iota` for the time being -// for the purpose of being explicit: https://github.com/pokt-network/pocket/pull/140#discussion_r939731342 -// TODO: Consolidate with proto enum in the utility module -const ( - UndefinedStakingStatus = int32(0) - UnstakingStatus = int32(1) - StakedStatus = int32(2) - UnstakedStatus = int32(3) -) - -func UnstakingHeightToStatus(unstakingHeight int64) int32 { - switch unstakingHeight { - case -1: - return StakedStatus - case 0: - return UnstakedStatus - default: - return UnstakingStatus - } -} - func (p *PostgresContext) GetExists(actorSchema types.ProtocolActorSchema, address []byte, height int64) (exists bool, err error) { ctx, tx := p.getCtxAndTx() @@ -94,7 +73,7 @@ func (p *PostgresContext) getActorFromRow(actorType coreTypes.ActorType, row pgx &actor.Address, &actor.PublicKey, &actor.StakedAmount, - &actor.GenericParam, + &actor.ServiceUrl, &actor.Output, &actor.PausedHeight, &actor.UnstakingHeight, @@ -143,7 +122,7 @@ func (p *PostgresContext) InsertActor(actorSchema types.ProtocolActorSchema, act } _, err = tx.Exec(ctx, actorSchema.InsertQuery( - actor.Address, actor.PublicKey, actor.StakedAmount, actor.GenericParam, + actor.Address, actor.PublicKey, actor.StakedAmount, actor.ServiceUrl, actor.Output, actor.PausedHeight, actor.UnstakingHeight, actor.Chains, height)) return err @@ -157,7 +136,7 @@ func (p *PostgresContext) UpdateActor(actorSchema types.ProtocolActorSchema, act return err } - if _, err = tx.Exec(ctx, actorSchema.UpdateQuery(actor.Address, actor.StakedAmount, actor.GenericParam, height)); err != nil { + if _, err = tx.Exec(ctx, actorSchema.UpdateQuery(actor.Address, actor.StakedAmount, actor.ServiceUrl, height)); err != nil { return err } @@ -198,16 +177,16 @@ func (p *PostgresContext) GetActorStatus(actorSchema types.ProtocolActorSchema, ctx, tx := p.getCtxAndTx() if err := tx.QueryRow(ctx, actorSchema.GetUnstakingHeightQuery(hex.EncodeToString(address), height)).Scan(&unstakingHeight); err != nil { - return UndefinedStakingStatus, err + return int32(coreTypes.StakeStatus_UnknownStatus), err } switch { case unstakingHeight == -1: - return StakedStatus, nil + return int32(coreTypes.StakeStatus_Staked), nil case unstakingHeight > height: - return UnstakingStatus, nil + return int32(coreTypes.StakeStatus_Unstaking), nil default: - return UnstakedStatus, nil + return int32(coreTypes.StakeStatus_Unstaked), nil } } diff --git a/persistence/application.go b/persistence/application.go index 97608da85..c6082d369 100644 --- a/persistence/application.go +++ b/persistence/application.go @@ -13,7 +13,7 @@ func (p *PostgresContext) GetAppExists(address []byte, height int64) (exists boo } //nolint:gocritic // tooManyResultsChecker This function needs to return many values -func (p *PostgresContext) GetApp(address []byte, height int64) (operator, publicKey, stakedTokens, maxRelays, outputAddress string, pauseHeight, unstakingHeight int64, chains []string, err error) { +func (p *PostgresContext) GetApp(address []byte, height int64) (operator, publicKey, stakedTokens, outputAddress string, pauseHeight, unstakingHeight int64, chains []string, err error) { actor, err := p.getActor(types.ApplicationActor, address, height) if err != nil { return @@ -21,7 +21,6 @@ func (p *PostgresContext) GetApp(address []byte, height int64) (operator, public operator = actor.Address publicKey = actor.PublicKey stakedTokens = actor.StakedAmount - maxRelays = actor.GenericParam outputAddress = actor.Output pauseHeight = actor.PausedHeight unstakingHeight = actor.UnstakingHeight @@ -29,13 +28,12 @@ func (p *PostgresContext) GetApp(address []byte, height int64) (operator, public return } -func (p *PostgresContext) InsertApp(address, publicKey, output []byte, _ bool, _ int32, maxRelays, stakedTokens string, chains []string, pausedHeight, unstakingHeight int64) error { +func (p *PostgresContext) InsertApp(address, publicKey, output []byte, _ bool, _ int32, stakedTokens string, chains []string, pausedHeight, unstakingHeight int64) error { return p.InsertActor(types.ApplicationActor, &coreTypes.Actor{ ActorType: coreTypes.ActorType_ACTOR_TYPE_APP, Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), Chains: chains, - GenericParam: maxRelays, StakedAmount: stakedTokens, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, @@ -43,12 +41,11 @@ func (p *PostgresContext) InsertApp(address, publicKey, output []byte, _ bool, _ }) } -func (p *PostgresContext) UpdateApp(address []byte, maxRelays, stakedAmount string, chains []string) error { +func (p *PostgresContext) UpdateApp(address []byte, stakedAmount string, chains []string) error { return p.UpdateActor(types.ApplicationActor, &coreTypes.Actor{ ActorType: coreTypes.ActorType_ACTOR_TYPE_APP, Address: hex.EncodeToString(address), Chains: chains, - GenericParam: maxRelays, StakedAmount: stakedAmount, }) } diff --git a/persistence/block.go b/persistence/block.go index 88bd3aff8..02b0d48e0 100644 --- a/persistence/block.go +++ b/persistence/block.go @@ -8,8 +8,8 @@ import ( "github.com/pokt-network/pocket/persistence/kvstore" "github.com/pokt-network/pocket/persistence/types" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/utils" ) func (p *persistenceModule) TransactionExists(transactionHash string) (bool, error) { @@ -67,18 +67,12 @@ func (p *PostgresContext) prepareBlock(proposerAddr, quorumCert []byte) (*coreTy } } - txsHash, err := p.getTxsHash() - if err != nil { - return nil, err - } - blockHeader := &coreTypes.BlockHeader{ Height: uint64(p.Height), StateHash: p.stateHash, PrevStateHash: prevBlockHash, ProposerAddress: proposerAddr, QuorumCertificate: quorumCert, - TransactionsHash: txsHash, } block := &coreTypes.Block{ BlockHeader: blockHeader, @@ -107,5 +101,5 @@ func (p *PostgresContext) storeBlock(block *coreTypes.Block) error { return err } log.Printf("Storing block %d in block store.\n", block.BlockHeader.Height) - return p.blockStore.Set(converters.HeightToBytes(uint64(p.Height)), blockBz) + return p.blockStore.Set(utils.HeightToBytes(uint64(p.Height)), blockBz) } diff --git a/persistence/debug.go b/persistence/debug.go index 1c75da797..39e44a4f2 100644 --- a/persistence/debug.go +++ b/persistence/debug.go @@ -7,9 +7,9 @@ import ( "github.com/celestiaorg/smt" "github.com/pokt-network/pocket/persistence/types" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/messaging" + "github.com/pokt-network/pocket/shared/utils" ) // A list of functions to clear data from the DB not associated with protocol actors @@ -46,7 +46,7 @@ func (m *persistenceModule) HandleDebugMessage(debugMessage *messaging.DebugMess func (m *persistenceModule) showLatestBlockInStore(_ *messaging.DebugMessage) { // TODO: Add an iterator to the `kvstore` and use that instead height := m.GetBus().GetConsensusModule().CurrentHeight() - 1 - blockBytes, err := m.GetBlockStore().Get(converters.HeightToBytes(height)) + blockBytes, err := m.GetBlockStore().Get(utils.HeightToBytes(height)) if err != nil { m.logger.Error().Err(err).Uint64("height", height).Msg("Error getting block from block store") return diff --git a/persistence/docs/CHANGELOG.md b/persistence/docs/CHANGELOG.md index 4ead54401..125284a7f 100644 --- a/persistence/docs/CHANGELOG.md +++ b/persistence/docs/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.39] - 2023-02-28 + +- Renamed package names and parameters to reflect changes in the rest of the codebase +- Removed the `StakeStatus` constants to use the global proto enum types +- Removed the whole concept of `maxRelays` as we're introducing a new rate limiting approach +- Added documentation to make certain things clearer +- Renamed `GenericParam` to `ServiceURL` +- Removed `txsOrderInBlockHashDescending` since we don't need a hash specific to txs - it's part of the state hash + ## [0.0.0.38] - 2023-02-24 - Update logger value references with pointers diff --git a/persistence/fisherman.go b/persistence/fisherman.go index 9664d4694..f80128ee7 100644 --- a/persistence/fisherman.go +++ b/persistence/fisherman.go @@ -18,7 +18,7 @@ func (p *PostgresContext) GetFisherman(address []byte, height int64) (operator, operator = actor.Address publicKey = actor.PublicKey stakedTokens = actor.StakedAmount - serviceURL = actor.GenericParam + serviceURL = actor.ServiceUrl outputAddress = actor.Output pausedHeight = actor.PausedHeight unstakingHeight = actor.UnstakingHeight @@ -32,7 +32,7 @@ func (p *PostgresContext) InsertFisherman(address, publicKey, output []byte, _ b Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), Chains: chains, - GenericParam: serviceURL, + ServiceUrl: serviceURL, StakedAmount: stakedTokens, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, @@ -45,7 +45,7 @@ func (p *PostgresContext) UpdateFisherman(address []byte, serviceURL, stakedAmou ActorType: coreTypes.ActorType_ACTOR_TYPE_FISH, Address: hex.EncodeToString(address), StakedAmount: stakedAmount, - GenericParam: serviceURL, + ServiceUrl: serviceURL, Chains: chains, }) } diff --git a/persistence/genesis.go b/persistence/genesis.go index 11369f52d..cd4e2d588 100644 --- a/persistence/genesis.go +++ b/persistence/genesis.go @@ -7,8 +7,8 @@ import ( "github.com/pokt-network/pocket/persistence/types" "github.com/pokt-network/pocket/runtime/genesis" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/utils" ) // CONSIDERATION: Should this return an error and let the caller decide if it should log a fatal error? @@ -17,7 +17,7 @@ func (m *persistenceModule) populateGenesisState(state *genesis.GenesisState) { // and we need to add proper unit tests for it.` poolValues := make(map[string]*big.Int, 0) addValueToPool := func(poolName string, valueToAdd string) error { - value, err := converters.StringToBigInt(valueToAdd) + value, err := utils.StringToBigInt(valueToAdd) if err != nil { return err } @@ -57,10 +57,12 @@ func (m *persistenceModule) populateGenesisState(state *genesis.GenesisState) { Pool coreTypes.Pools }{ { - Name: "app", - Getter: state.GetApplications, - InsertFn: rwContext.InsertApp, - Pool: coreTypes.Pools_POOLS_APP_STAKE, + Name: "app", + Getter: state.GetApplications, + InsertFn: func(address, publicKey, output []byte, paused bool, status int32, serviceURL, stakedTokens string, chains []string, pausedHeight, unstakingHeight int64) error { + return rwContext.InsertApp(address, publicKey, output, paused, status, stakedTokens, chains, pausedHeight, unstakingHeight) + }, + Pool: coreTypes.Pools_POOLS_APP_STAKE, }, { Name: "servicer", @@ -98,7 +100,7 @@ func (m *persistenceModule) populateGenesisState(state *genesis.GenesisState) { if err != nil { log.Fatalf("an error occurred converting output to bytes %s", act.GetOutput()) } - err = saic.InsertFn(addrBz, pubKeyBz, outputBz, false, StakedStatus, act.GetGenericParam(), act.GetStakedAmount(), act.GetChains(), act.GetPausedHeight(), act.GetUnstakingHeight()) + err = saic.InsertFn(addrBz, pubKeyBz, outputBz, false, int32(coreTypes.StakeStatus_Staked), act.GetServiceUrl(), act.GetStakedAmount(), act.GetChains(), act.GetPausedHeight(), act.GetUnstakingHeight()) if err != nil { log.Fatalf("an error occurred inserting an %s in the genesis state: %s", saic.Name, err.Error()) } diff --git a/persistence/indexer/proto/transaction_indexer.proto b/persistence/indexer/proto/transaction_indexer.proto index 960857e49..6b99465ba 100644 --- a/persistence/indexer/proto/transaction_indexer.proto +++ b/persistence/indexer/proto/transaction_indexer.proto @@ -7,8 +7,8 @@ message TxRes { bytes tx = 1; // The bytes of the indexed transaction int64 height = 2; // The block height at which the transaction was included int32 index = 3; // The order (i.e. position within a block) where the proposer included the transaction - int32 result_code = 4; // INVESTIGATE(andrew): look into having a `utility.Code` enum for this - string error = 5; // INVESTIGATE(andrew): look into having a `utility.Error` enum for this + int32 result_code = 4; // CONSIDERATION: look into having a `utility.Code` enum for this + string error = 5; // CONSIDERATION: look into having a `utility.Error` enum for this string signer_addr = 6; string recipient_addr = 7; string message_type = 8; // CONSOLIDATE(M4): Once the message types are well defined and stable, consolidate them into an enum diff --git a/persistence/module.go b/persistence/module.go index 9596b94f5..75e096fd7 100644 --- a/persistence/module.go +++ b/persistence/module.go @@ -26,17 +26,25 @@ var ( type persistenceModule struct { base_modules.IntegratableModule + logger *modules.Logger + config *configs.PersistenceConfig genesisState *genesis.GenesisState + // A key-value store mapping heights to blocks. Needed for block synchronization. blockStore kvstore.KVStore - txIndexer indexer.TxIndexer - stateTrees *stateTrees - logger *modules.Logger + // A tx indexer (i.e. key-value store) mapping transaction hashes to transactions. Needed for + // avoiding tx replays attacks, and is also used as the backing database for the transaction + // tx merkle tree. + txIndexer indexer.TxIndexer + + // A list of all the merkle trees maintained by the persistence module that roll up into the state commitment. + stateTrees *stateTrees // TECHDEBT: Need to implement context pooling (for writes), timeouts (for read & writes), etc... - writeContext *PostgresContext // only one write context is allowed at a time + // only one write context is allowed at a time + writeContext *PostgresContext } func Create(bus modules.Bus, options ...modules.ModuleOption) (modules.Module, error) { @@ -137,7 +145,7 @@ func (m *persistenceModule) NewRWContext(height int64) (modules.PersistenceRWCon tx, err := conn.BeginTx(context.TODO(), pgx.TxOptions{ IsoLevel: pgx.ReadUncommitted, AccessMode: pgx.ReadWrite, - DeferrableMode: pgx.Deferrable, // TODO(andrew): Research if this should be `Deferrable` + DeferrableMode: pgx.Deferrable, // INVESTIGATE: Research if this should be `Deferrable` }) if err != nil { return nil, err @@ -168,7 +176,7 @@ func (m *persistenceModule) NewReadContext(height int64) (modules.PersistenceRea tx, err := conn.BeginTx(context.TODO(), pgx.TxOptions{ IsoLevel: pgx.ReadCommitted, AccessMode: pgx.ReadOnly, - DeferrableMode: pgx.NotDeferrable, // TODO(andrew): Research if this should be `Deferrable` + DeferrableMode: pgx.NotDeferrable, // INVESTIGATE: Research if this should be `Deferrable` }) if err != nil { return nil, err diff --git a/persistence/servicer.go b/persistence/servicer.go index 680d8e230..d61e39323 100644 --- a/persistence/servicer.go +++ b/persistence/servicer.go @@ -18,7 +18,7 @@ func (p *PostgresContext) GetServicer(address []byte, height int64) (operator, p operator = actor.Address publicKey = actor.PublicKey stakedTokens = actor.StakedAmount - serviceURL = actor.GenericParam + serviceURL = actor.ServiceUrl outputAddress = actor.Output pausedHeight = actor.PausedHeight unstakingHeight = actor.UnstakingHeight @@ -32,7 +32,7 @@ func (p *PostgresContext) InsertServicer(address, publicKey, output []byte, _ bo Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), StakedAmount: stakedTokens, - GenericParam: serviceURL, + ServiceUrl: serviceURL, Output: hex.EncodeToString(output), PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, @@ -45,7 +45,7 @@ func (p *PostgresContext) UpdateServicer(address []byte, serviceURL, stakedAmoun ActorType: coreTypes.ActorType_ACTOR_TYPE_SERVICER, Address: hex.EncodeToString(address), StakedAmount: stakedAmount, - GenericParam: serviceURL, + ServiceUrl: serviceURL, Chains: chains, }) } diff --git a/persistence/state.go b/persistence/state.go index 7058f3a50..0575301f1 100644 --- a/persistence/state.go +++ b/persistence/state.go @@ -50,12 +50,6 @@ const ( numMerkleTrees ) -const ( - // IMPORTANT: The order, ascending, is critical since it defines the integrity of `transactionsHash`. - // If this changes, the `transactionsHash`` in the block will differ, rendering it invalid. - txsOrderInBlockHashDescending = false -) - var merkleTreeToString = map[merkleTree]string{ appMerkleTree: "app", valMerkleTree: "val", @@ -196,27 +190,6 @@ func (p *PostgresContext) getStateHash() string { return hex.EncodeToString(stateHash[:]) } -// Transactions Hash Helpers - -// Returns a digest (a single hash) of all the transactions included in the block. -// This allows separating the integrity of the transactions from their storage. -func (p *PostgresContext) getTxsHash() (txs []byte, err error) { - txResults, err := p.txIndexer.GetByHeight(p.Height, txsOrderInBlockHashDescending) - if err != nil { - return nil, err - } - - for _, txResult := range txResults { - txHash, err := txResult.Hash() - if err != nil { - return nil, err - } - txs = append(txs, txHash...) - } - - return crypto.SHA3Hash(txs), nil -} - // Actor Tree Helpers func (p *PostgresContext) updateActorsTree(actorType coreTypes.ActorType) error { @@ -266,7 +239,7 @@ func (p *PostgresContext) getActorsUpdatedAtHeight(actorType coreTypes.ActorType Address: schemaActor.Address, PublicKey: schemaActor.PublicKey, Chains: schemaActor.Chains, - GenericParam: schemaActor.GenericParam, + ServiceUrl: schemaActor.ServiceUrl, StakedAmount: schemaActor.StakedAmount, PausedHeight: schemaActor.PausedHeight, UnstakingHeight: schemaActor.UnstakingHeight, diff --git a/persistence/test/account_test.go b/persistence/test/account_test.go index 9404ffb16..0847daf3f 100644 --- a/persistence/test/account_test.go +++ b/persistence/test/account_test.go @@ -9,14 +9,12 @@ import ( "testing" "github.com/pokt-network/pocket/persistence" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" "github.com/stretchr/testify/require" ) -// TODO(andrew): Find all places where we import twice and update the imports appropriately. - func FuzzAccountAmount(f *testing.F) { db := NewTestPostgresContext(f, 0) operations := []string{ @@ -45,14 +43,14 @@ func FuzzAccountAmount(f *testing.F) { f.Fuzz(func(t *testing.T, op string) { delta := big.NewInt(int64(rand.Intn(1000))) //nolint:gosec // G404 - Weak random source is okay in unit tests - deltaString := converters.BigIntToString(delta) + deltaString := utils.BigIntToString(delta) switch op { case "AddAmount": originalAmountBig, err := db.GetAccountAmount(addrBz, db.Height) require.NoError(t, err) - originalAmount, err := converters.StringToBigInt(originalAmountBig) + originalAmount, err := utils.StringToBigInt(originalAmountBig) require.NoError(t, err) err = db.AddAccountAmount(addrBz, deltaString) @@ -63,7 +61,7 @@ func FuzzAccountAmount(f *testing.F) { originalAmountBig, err := db.GetAccountAmount(addrBz, db.Height) require.NoError(t, err) - originalAmount, err := converters.StringToBigInt(originalAmountBig) + originalAmount, err := utils.StringToBigInt(originalAmountBig) require.NoError(t, err) err = db.SubtractAccountAmount(addrBz, deltaString) @@ -83,7 +81,7 @@ func FuzzAccountAmount(f *testing.F) { currentAmount, err := db.GetAccountAmount(addrBz, db.Height) require.NoError(t, err) - require.Equal(t, converters.BigIntToString(expectedAmount), currentAmount, fmt.Sprintf("unexpected amount after %s", op)) + require.Equal(t, utils.BigIntToString(expectedAmount), currentAmount, fmt.Sprintf("unexpected amount after %s", op)) }) } @@ -128,14 +126,14 @@ func TestAddAccountAmount(t *testing.T) { require.NoError(t, err) amountToAddBig := big.NewInt(100) - err = db.AddAccountAmount(addrBz, converters.BigIntToString(amountToAddBig)) + err = db.AddAccountAmount(addrBz, utils.BigIntToString(amountToAddBig)) require.NoError(t, err) accountAmount, err := db.GetAccountAmount(addrBz, db.Height) require.NoError(t, err) accountAmountBig := (&big.Int{}).Add(DefaultStakeBig, amountToAddBig) - expectedAccountAmount := converters.BigIntToString(accountAmountBig) + expectedAccountAmount := utils.BigIntToString(accountAmountBig) require.Equal(t, expectedAccountAmount, accountAmount, "unexpected amount after add") } @@ -199,14 +197,14 @@ func TestSubAccountAmount(t *testing.T) { require.NoError(t, err) amountToSubBig := big.NewInt(100) - err = db.SubtractAccountAmount(addrBz, converters.BigIntToString(amountToSubBig)) + err = db.SubtractAccountAmount(addrBz, utils.BigIntToString(amountToSubBig)) require.NoError(t, err) accountAmount, err := db.GetAccountAmount(addrBz, db.Height) require.NoError(t, err) accountAmountBig := (&big.Int{}).Sub(DefaultStakeBig, amountToSubBig) - expectedAccountAmount := converters.BigIntToString(accountAmountBig) + expectedAccountAmount := utils.BigIntToString(accountAmountBig) require.Equal(t, expectedAccountAmount, accountAmount, "unexpected amount after sub") } @@ -233,14 +231,14 @@ func FuzzPoolAmount(f *testing.F) { f.Fuzz(func(t *testing.T, op string) { delta := big.NewInt(int64(rand.Intn(1000))) //nolint:gosec // G404 - Weak random source is okay in unit tests - deltaString := converters.BigIntToString(delta) + deltaString := utils.BigIntToString(delta) switch op { case "AddAmount": originalAmountBig, err := db.GetPoolAmount(pool.Address, db.Height) require.NoError(t, err) - originalAmount, err := converters.StringToBigInt(originalAmountBig) + originalAmount, err := utils.StringToBigInt(originalAmountBig) require.NoError(t, err) err = db.AddPoolAmount(pool.Address, deltaString) @@ -251,7 +249,7 @@ func FuzzPoolAmount(f *testing.F) { originalAmountBig, err := db.GetPoolAmount(pool.Address, db.Height) require.NoError(t, err) - originalAmount, err := converters.StringToBigInt(originalAmountBig) + originalAmount, err := utils.StringToBigInt(originalAmountBig) require.NoError(t, err) err = db.SubtractPoolAmount(pool.Address, deltaString) @@ -271,7 +269,7 @@ func FuzzPoolAmount(f *testing.F) { currentAmount, err := db.GetPoolAmount(pool.Address, db.Height) require.NoError(t, err) - require.Equal(t, converters.BigIntToString(expectedAmount), currentAmount, fmt.Sprintf("unexpected amount after %s", op)) + require.Equal(t, utils.BigIntToString(expectedAmount), currentAmount, fmt.Sprintf("unexpected amount after %s", op)) }) } @@ -310,14 +308,14 @@ func TestAddPoolAmount(t *testing.T) { require.NoError(t, err) amountToAddBig := big.NewInt(100) - err = db.AddPoolAmount(pool.Address, converters.BigIntToString(amountToAddBig)) + err = db.AddPoolAmount(pool.Address, utils.BigIntToString(amountToAddBig)) require.NoError(t, err) poolAmount, err := db.GetPoolAmount(pool.Address, db.Height) require.NoError(t, err) poolAmountBig := (&big.Int{}).Add(DefaultStakeBig, amountToAddBig) - expectedPoolAmount := converters.BigIntToString(poolAmountBig) + expectedPoolAmount := utils.BigIntToString(poolAmountBig) require.Equal(t, expectedPoolAmount, poolAmount, "unexpected amount after add") } @@ -329,14 +327,14 @@ func TestSubPoolAmount(t *testing.T) { require.NoError(t, err) amountToSubBig := big.NewInt(100) - err = db.SubtractPoolAmount(pool.Address, converters.BigIntToString(amountToSubBig)) + err = db.SubtractPoolAmount(pool.Address, utils.BigIntToString(amountToSubBig)) require.NoError(t, err) poolAmount, err := db.GetPoolAmount(pool.Address, db.Height) require.NoError(t, err) poolAmountBig := (&big.Int{}).Sub(DefaultStakeBig, amountToSubBig) - expectedPoolAmount := converters.BigIntToString(poolAmountBig) + expectedPoolAmount := utils.BigIntToString(poolAmountBig) require.Equal(t, expectedPoolAmount, poolAmount, "unexpected amount after sub") } diff --git a/persistence/test/application_test.go b/persistence/test/application_test.go index 38fa56841..01b377b86 100644 --- a/persistence/test/application_test.go +++ b/persistence/test/application_test.go @@ -66,7 +66,7 @@ func TestUpdateApp(t *testing.T) { addrBz, err := hex.DecodeString(app.Address) require.NoError(t, err) - _, _, stakedTokens, _, _, _, _, chains, err := db.GetApp(addrBz, 0) + _, _, stakedTokens, _, _, _, chains, err := db.GetApp(addrBz, 0) require.NoError(t, err) require.Equal(t, DefaultChains, chains, "default chains incorrect for current height") require.Equal(t, DefaultStake, stakedTokens, "default stake incorrect for current height") @@ -75,15 +75,15 @@ func TestUpdateApp(t *testing.T) { require.NotEqual(t, DefaultStake, StakeToUpdate) // sanity check to make sure the tests are correct require.NotEqual(t, DefaultChains, ChainsToUpdate) // sanity check to make sure the tests are correct - err = db.UpdateApp(addrBz, app.GenericParam, StakeToUpdate, ChainsToUpdate) + err = db.UpdateApp(addrBz, StakeToUpdate, ChainsToUpdate) require.NoError(t, err) - _, _, stakedTokens, _, _, _, _, chains, err = db.GetApp(addrBz, 0) + _, _, stakedTokens, _, _, _, chains, err = db.GetApp(addrBz, 0) require.NoError(t, err) require.Equal(t, DefaultChains, chains, "default chains incorrect for previous height") require.Equal(t, DefaultStake, stakedTokens, "default stake incorrect for previous height") - _, _, stakedTokens, _, _, _, _, chains, err = db.GetApp(addrBz, 1) + _, _, stakedTokens, _, _, _, chains, err = db.GetApp(addrBz, 1) require.NoError(t, err) require.Equal(t, ChainsToUpdate, chains, "chains not updated for current height") require.Equal(t, StakeToUpdate, stakedTokens, "stake not updated for current height") @@ -109,23 +109,23 @@ func TestGetAppsReadyToUnstake(t *testing.T) { require.NoError(t, err) // Unstake app at height 0 - err = db.SetAppUnstakingHeightAndStatus(addrBz, 0, persistence.UnstakingStatus) + err = db.SetAppUnstakingHeightAndStatus(addrBz, 0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Unstake app2 and app3 at height 1 - err = db.SetAppUnstakingHeightAndStatus(addrBz2, 1, persistence.UnstakingStatus) + err = db.SetAppUnstakingHeightAndStatus(addrBz2, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) - err = db.SetAppUnstakingHeightAndStatus(addrBz3, 1, persistence.UnstakingStatus) + err = db.SetAppUnstakingHeightAndStatus(addrBz3, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Check unstaking apps at height 0 - unstakingApps, err := db.GetAppsReadyToUnstake(0, persistence.UnstakingStatus) + unstakingApps, err := db.GetAppsReadyToUnstake(0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 1, len(unstakingApps), "wrong number of actors ready to unstake at height 0") require.Equal(t, app.Address, unstakingApps[0].GetAddress(), "unexpected application actor returned") // Check unstaking apps at height 1 - unstakingApps, err = db.GetAppsReadyToUnstake(1, persistence.UnstakingStatus) + unstakingApps, err = db.GetAppsReadyToUnstake(1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 2, len(unstakingApps), "wrong number of actors ready to unstake at height 1") require.ElementsMatch(t, []string{app2.Address, app3.Address}, []string{unstakingApps[0].Address, unstakingApps[1].Address}) @@ -142,7 +142,7 @@ func TestGetAppStatus(t *testing.T) { // Check status before the app exists status, err := db.GetAppStatus(addrBz, 0) require.Error(t, err) - require.Equal(t, persistence.UndefinedStakingStatus, status, "unexpected status") + require.Equal(t, int32(coreTypes.StakeStatus_UnknownStatus), status, "unexpected status") // Check status after the app exists status, err = db.GetAppStatus(addrBz, 1) @@ -183,14 +183,14 @@ func TestSetAppPauseHeightAndUnstakeLater(t *testing.T) { err = db.SetAppPauseHeight(addrBz, pauseHeight) require.NoError(t, err) - _, _, _, _, _, appPausedHeight, _, _, err := db.GetApp(addrBz, db.Height) + _, _, _, _, appPausedHeight, _, _, err := db.GetApp(addrBz, db.Height) require.NoError(t, err) require.Equal(t, pauseHeight, appPausedHeight, "pause height not updated") err = db.SetAppStatusAndUnstakingHeightIfPausedBefore(pauseHeight+1, unstakingHeight, -1 /*unused*/) require.NoError(t, err) - _, _, _, _, _, _, appUnstakingHeight, _, err := db.GetApp(addrBz, db.Height) + _, _, _, _, _, appUnstakingHeight, _, err := db.GetApp(addrBz, db.Height) require.NoError(t, err) require.Equal(t, unstakingHeight, appUnstakingHeight, "unstaking height was not set correctly") } @@ -222,7 +222,6 @@ func newTestApp() (*coreTypes.Actor, error) { Address: hex.EncodeToString(operatorKey.Address()), PublicKey: hex.EncodeToString(operatorKey.Bytes()), Chains: DefaultChains, - GenericParam: DefaultMaxRelays, StakedAmount: DefaultStake, PausedHeight: DefaultPauseHeight, UnstakingHeight: DefaultUnstakingHeight, @@ -278,7 +277,6 @@ func createAndInsertDefaultTestApp(db *persistence.PostgresContext) (*coreTypes. outputBz, false, DefaultStakeStatus, - DefaultMaxRelays, DefaultStake, DefaultChains, DefaultPauseHeight, @@ -286,7 +284,7 @@ func createAndInsertDefaultTestApp(db *persistence.PostgresContext) (*coreTypes. } func getTestApp(db *persistence.PostgresContext, address []byte) (*coreTypes.Actor, error) { - operator, publicKey, stakedTokens, maxRelays, outputAddress, pauseHeight, unstakingHeight, chains, err := db.GetApp(address, db.Height) + operator, publicKey, stakedTokens, outputAddress, pauseHeight, unstakingHeight, chains, err := db.GetApp(address, db.Height) if err != nil { return nil, err } @@ -295,7 +293,6 @@ func getTestApp(db *persistence.PostgresContext, address []byte) (*coreTypes.Act Address: operator, PublicKey: publicKey, Chains: chains, - GenericParam: maxRelays, StakedAmount: stakedTokens, PausedHeight: pauseHeight, UnstakingHeight: unstakingHeight, diff --git a/persistence/test/fisherman_test.go b/persistence/test/fisherman_test.go index 0f513ac30..b671012f0 100644 --- a/persistence/test/fisherman_test.go +++ b/persistence/test/fisherman_test.go @@ -13,8 +13,6 @@ import ( "github.com/stretchr/testify/require" ) -// TODO(andrew): Rename `addrBz` to `fishAddrBz` so tests are easier to read and understand. Ditto in all other locations. - func FuzzFisherman(f *testing.F) { fuzzSingleProtocolActor(f, newTestGenericActor(types.FishermanActor, newTestFisherman), @@ -83,7 +81,7 @@ func TestUpdateFisherman(t *testing.T) { require.NotEqual(t, DefaultStake, StakeToUpdate) // sanity check to make sure the tests are correct require.NotEqual(t, DefaultChains, ChainsToUpdate) // sanity check to make sure the tests are correct - err = db.UpdateFisherman(addrBz, fisherman.GenericParam, StakeToUpdate, ChainsToUpdate) + err = db.UpdateFisherman(addrBz, fisherman.ServiceUrl, StakeToUpdate, ChainsToUpdate) require.NoError(t, err) _, _, stakedTokens, _, _, _, _, chains, err = db.GetFisherman(addrBz, 0) @@ -117,23 +115,23 @@ func TestGetFishermenReadyToUnstake(t *testing.T) { require.NoError(t, err) // Unstake fisherman at height 0 - err = db.SetFishermanUnstakingHeightAndStatus(addrBz, 0, persistence.UnstakingStatus) + err = db.SetFishermanUnstakingHeightAndStatus(addrBz, 0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Unstake fisherman2 and fisherman3 at height 1 - err = db.SetFishermanUnstakingHeightAndStatus(addrBz2, 1, persistence.UnstakingStatus) + err = db.SetFishermanUnstakingHeightAndStatus(addrBz2, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) - err = db.SetFishermanUnstakingHeightAndStatus(addrBz3, 1, persistence.UnstakingStatus) + err = db.SetFishermanUnstakingHeightAndStatus(addrBz3, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Check unstaking fishermans at height 0 - unstakingFishermen, err := db.GetFishermenReadyToUnstake(0, persistence.UnstakingStatus) + unstakingFishermen, err := db.GetFishermenReadyToUnstake(0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 1, len(unstakingFishermen), "wrong number of actors ready to unstake at height 0") require.Equal(t, fisherman.Address, unstakingFishermen[0].GetAddress(), "unexpected fishermanlication actor returned") // Check unstaking fishermans at height 1 - unstakingFishermen, err = db.GetFishermenReadyToUnstake(1, persistence.UnstakingStatus) + unstakingFishermen, err = db.GetFishermenReadyToUnstake(1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 2, len(unstakingFishermen), "wrong number of actors ready to unstake at height 1") require.ElementsMatch(t, []string{fisherman2.Address, fisherman3.Address}, []string{unstakingFishermen[0].Address, unstakingFishermen[1].Address}) @@ -151,7 +149,7 @@ func TestGetFishermanStatus(t *testing.T) { // Check status before the fisherman exists status, err := db.GetFishermanStatus(addrBz, 0) require.Error(t, err) - require.Equal(t, persistence.UndefinedStakingStatus, status, "unexpected status") + require.Equal(t, int32(coreTypes.StakeStatus_UnknownStatus), status, "unexpected status") // Check status after the fisherman exists status, err = db.GetFishermanStatus(addrBz, 1) @@ -235,7 +233,7 @@ func newTestFisherman() (*coreTypes.Actor, error) { Address: hex.EncodeToString(operatorKey.Address()), PublicKey: hex.EncodeToString(operatorKey.Bytes()), Chains: DefaultChains, - GenericParam: DefaultServiceUrl, + ServiceUrl: DefaultServiceURL, StakedAmount: DefaultStake, PausedHeight: DefaultPauseHeight, UnstakingHeight: DefaultUnstakingHeight, @@ -266,7 +264,7 @@ func createAndInsertDefaultTestFisherman(db *persistence.PostgresContext) (*core outputBz, false, DefaultStakeStatus, - DefaultServiceUrl, + DefaultServiceURL, DefaultStake, DefaultChains, DefaultPauseHeight, @@ -298,7 +296,7 @@ func getTestFisherman(db *persistence.PostgresContext, address []byte) (*coreTyp Address: hex.EncodeToString(operatorAddr), PublicKey: hex.EncodeToString(operatorPubKey), Chains: chains, - GenericParam: serviceURL, + ServiceUrl: serviceURL, StakedAmount: stakedTokens, PausedHeight: pauseHeight, UnstakingHeight: unstakingHeight, diff --git a/persistence/test/generic_test.go b/persistence/test/generic_test.go index e48ad12a9..09f9e0f55 100644 --- a/persistence/test/generic_test.go +++ b/persistence/test/generic_test.go @@ -12,8 +12,6 @@ import ( "github.com/stretchr/testify/require" ) -// TODO(andrew): Be consistent with `GenericParam` and `ActorSpecificParam` throughout the codebase; preferably the latter. - func getGenericActor[T any]( protocolActorSchema types.ProtocolActorSchema, getActor func(*persistence.PostgresContext, []byte) (T, error), @@ -214,7 +212,7 @@ func getActorValues(_ types.ProtocolActorSchema, actorValue reflect.Value) *core Address: actorValue.FieldByName("Address").String(), PublicKey: actorValue.FieldByName("PublicKey").String(), StakedAmount: actorValue.FieldByName("StakedAmount").String(), - GenericParam: actorValue.FieldByName("GenericParam").String(), + ServiceUrl: actorValue.FieldByName("ServiceUrl").String(), Output: actorValue.FieldByName("Output").String(), PausedHeight: actorValue.FieldByName("PausedHeight").Int(), UnstakingHeight: actorValue.FieldByName("UnstakingHeight").Int(), diff --git a/persistence/test/servicer_test.go b/persistence/test/servicer_test.go index 807314fa6..91ae929b2 100644 --- a/persistence/test/servicer_test.go +++ b/persistence/test/servicer_test.go @@ -81,7 +81,7 @@ func TestUpdateServicer(t *testing.T) { require.NotEqual(t, DefaultStake, StakeToUpdate) // sanity check to make sure the tests are correct require.NotEqual(t, DefaultChains, ChainsToUpdate) // sanity check to make sure the tests are correct - err = db.UpdateServicer(addrBz, servicer.GenericParam, StakeToUpdate, ChainsToUpdate) + err = db.UpdateServicer(addrBz, servicer.ServiceUrl, StakeToUpdate, ChainsToUpdate) require.NoError(t, err) _, _, stakedTokens, _, _, _, _, chains, err = db.GetServicer(addrBz, 0) @@ -117,23 +117,23 @@ func TestGetServicersReadyToUnstake(t *testing.T) { require.NoError(t, err) // Unstake servicer at height 0 - err = db.SetServicerUnstakingHeightAndStatus(addrBz, 0, persistence.UnstakingStatus) + err = db.SetServicerUnstakingHeightAndStatus(addrBz, 0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Unstake servicer2 and servicer3 at height 1 - err = db.SetServicerUnstakingHeightAndStatus(addrBz2, 1, persistence.UnstakingStatus) + err = db.SetServicerUnstakingHeightAndStatus(addrBz2, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) - err = db.SetServicerUnstakingHeightAndStatus(addrBz3, 1, persistence.UnstakingStatus) + err = db.SetServicerUnstakingHeightAndStatus(addrBz3, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Check unstaking servicers at height 0 - unstakingServicers, err := db.GetServicersReadyToUnstake(0, persistence.UnstakingStatus) + unstakingServicers, err := db.GetServicersReadyToUnstake(0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 1, len(unstakingServicers), "wrong number of actors ready to unstake at height 0") require.Equal(t, servicer.Address, unstakingServicers[0].Address, "unexpected servicerlication actor returned") // Check unstaking servicers at height 1 - unstakingServicers, err = db.GetServicersReadyToUnstake(1, persistence.UnstakingStatus) + unstakingServicers, err = db.GetServicersReadyToUnstake(1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 2, len(unstakingServicers), "wrong number of actors ready to unstake at height 1") require.ElementsMatch(t, []string{servicer2.Address, servicer3.Address}, []string{unstakingServicers[0].Address, unstakingServicers[1].Address}) @@ -151,7 +151,7 @@ func TestGetServicerStatus(t *testing.T) { // Check status before the servicer exists status, err := db.GetServicerStatus(addrBz, 0) require.Error(t, err) - require.Equal(t, persistence.UndefinedStakingStatus, status, "unexpected status") + require.Equal(t, int32(coreTypes.StakeStatus_UnknownStatus), status, "unexpected status") // Check status after the servicer exists status, err = db.GetServicerStatus(addrBz, 1) @@ -235,7 +235,7 @@ func newTestServicer() (*coreTypes.Actor, error) { Address: hex.EncodeToString(operatorKey.Address()), PublicKey: hex.EncodeToString(operatorKey.Bytes()), Chains: DefaultChains, - GenericParam: DefaultServiceUrl, + ServiceUrl: DefaultServiceURL, StakedAmount: DefaultStake, PausedHeight: DefaultPauseHeight, UnstakingHeight: DefaultUnstakingHeight, @@ -266,7 +266,7 @@ func createAndInsertDefaultTestServicer(db *persistence.PostgresContext) (*coreT outputBz, false, DefaultStakeStatus, - DefaultServiceUrl, + DefaultServiceURL, DefaultStake, DefaultChains, DefaultPauseHeight, @@ -298,7 +298,7 @@ func getTestServicer(db *persistence.PostgresContext, address []byte) (*coreType Address: hex.EncodeToString(operatorAddr), PublicKey: hex.EncodeToString(operatorPubKey), Chains: chains, - GenericParam: serviceURL, + ServiceUrl: serviceURL, StakedAmount: stakedTokens, PausedHeight: pauseHeight, UnstakingHeight: unstakingHeight, diff --git a/persistence/test/setup_test.go b/persistence/test/setup_test.go index d347402a0..9ced31cb2 100644 --- a/persistence/test/setup_test.go +++ b/persistence/test/setup_test.go @@ -16,12 +16,12 @@ import ( "github.com/pokt-network/pocket/runtime" "github.com/pokt-network/pocket/runtime/configs" "github.com/pokt-network/pocket/runtime/test_artifacts" - "github.com/pokt-network/pocket/runtime/test_artifacts/keygenerator" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/runtime/test_artifacts/keygen" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/messaging" "github.com/pokt-network/pocket/shared/modules" moduleTypes "github.com/pokt-network/pocket/shared/modules/types" + "github.com/pokt-network/pocket/shared/utils" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" ) @@ -29,20 +29,18 @@ import ( var ( DefaultChains = []string{"0001"} ChainsToUpdate = []string{"0002"} - DefaultServiceUrl = "https://foo.bar" + DefaultServiceURL = "https://foo.bar" DefaultPoolName = "TESTING_POOL" - DefaultDeltaBig = big.NewInt(100) - DefaultAccountBig = big.NewInt(1000000) - DefaultStakeBig = big.NewInt(1000000000000000) - DefaultMaxRelaysBig = big.NewInt(1000000) + DefaultDeltaBig = big.NewInt(100) + DefaultAccountBig = big.NewInt(1000000) + DefaultStakeBig = big.NewInt(1000000000000000) - DefaultAccountAmount = converters.BigIntToString(DefaultAccountBig) - DefaultStake = converters.BigIntToString(DefaultStakeBig) - DefaultMaxRelays = converters.BigIntToString(DefaultMaxRelaysBig) - StakeToUpdate = converters.BigIntToString((&big.Int{}).Add(DefaultStakeBig, DefaultDeltaBig)) + DefaultAccountAmount = utils.BigIntToString(DefaultAccountBig) + DefaultStake = utils.BigIntToString(DefaultStakeBig) + StakeToUpdate = utils.BigIntToString((&big.Int{}).Add(DefaultStakeBig, DefaultDeltaBig)) - DefaultStakeStatus = int32(persistence.StakedStatus) + DefaultStakeStatus = int32(coreTypes.StakeStatus_Staked) DefaultPauseHeight = int64(-1) // pauseHeight=-1 means not paused DefaultUnstakingHeight = int64(-1) // pauseHeight=-1 means not unstaking @@ -92,7 +90,7 @@ func NewTestPostgresContext(t testing.TB, height int64) *persistence.PostgresCon // TODO(olshansky): Take in `t testing.T` as a parameter and error if there's an issue func newTestPersistenceModule(databaseUrl string) modules.PersistenceModule { - teardownDeterministicKeygen := keygenerator.GetInstance().SetSeed(42) + teardownDeterministicKeygen := keygen.GetInstance().SetSeed(42) defer teardownDeterministicKeygen() cfg := &configs.Config{ @@ -184,7 +182,7 @@ func fuzzSingleProtocolActor( numParamUpdatesSupported := 3 newStakedTokens := originalActor.StakedAmount newChains := originalActor.Chains - newActorSpecificParam := originalActor.GenericParam + serviceUrl := originalActor.ServiceUrl iterations := rand.Intn(2) for i := 0; i < iterations; i++ { @@ -194,9 +192,9 @@ func fuzzSingleProtocolActor( case 1: switch protocolActorSchema.GetActorSpecificColName() { case types.ServiceURLCol: - newActorSpecificParam = getRandomServiceURL() - case types.MaxRelaysCol: - newActorSpecificParam = getRandomBigIntString() + serviceUrl = getRandomServiceURL() + case types.UnusedCol: + serviceUrl = "" default: t.Error("Unexpected actor specific column name") } @@ -210,7 +208,7 @@ func fuzzSingleProtocolActor( Address: originalActor.Address, PublicKey: originalActor.PublicKey, StakedAmount: newStakedTokens, - GenericParam: newActorSpecificParam, + ServiceUrl: serviceUrl, Output: originalActor.Output, PausedHeight: originalActor.PausedHeight, UnstakingHeight: originalActor.UnstakingHeight, @@ -229,7 +227,7 @@ func fuzzSingleProtocolActor( log.Println("") } require.Equal(t, newStakedTokens, newActor.StakedAmount, "staked tokens not updated") - require.Equal(t, newActorSpecificParam, newActor.GenericParam, "actor specific param not updated") + require.Equal(t, serviceUrl, newActor.ServiceUrl, "actor specific param not updated") case "GetActorsReadyToUnstake": unstakingActors, err := db.GetActorsReadyToUnstake(protocolActorSchema, db.Height) require.NoError(t, err) @@ -248,11 +246,11 @@ func fuzzSingleProtocolActor( switch { case originalActor.UnstakingHeight == DefaultUnstakingHeight: - require.Equal(t, persistence.StakedStatus, status, "actor status should be staked") + require.Equal(t, int32(coreTypes.StakeStatus_Staked), status, "actor status should be staked") case originalActor.UnstakingHeight > db.Height: - require.Equal(t, persistence.UnstakingStatus, status, "actor status should be unstaking") + require.Equal(t, int32(coreTypes.StakeStatus_Unstaking), status, "actor status should be unstaking") default: - require.Equal(t, persistence.UnstakedStatus, status, "actor status should be unstaked") + require.Equal(t, int32(coreTypes.StakeStatus_Unstaked), status, "actor status should be unstaked") } case "GetActorPauseHeight": pauseHeight, err := db.GetActorPauseHeightIfExists(protocolActorSchema, addr, db.Height) @@ -342,7 +340,7 @@ func getRandomServiceURL() string { } func getRandomBigIntString() string { - return converters.BigIntToString(big.NewInt(rand.Int63())) //nolint:gosec // G404 - Weak random source is okay in unit tests + return utils.BigIntToString(big.NewInt(rand.Int63())) //nolint:gosec // G404 - Weak random source is okay in unit tests } func setRandomSeed() { diff --git a/persistence/test/state_test.go b/persistence/test/state_test.go index 53bc0d415..4cb77f4c3 100644 --- a/persistence/test/state_test.go +++ b/persistence/test/state_test.go @@ -9,9 +9,9 @@ import ( "github.com/pokt-network/pocket/persistence/indexer" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/modules" + "github.com/pokt-network/pocket/shared/utils" "github.com/stretchr/testify/require" ) @@ -46,16 +46,16 @@ 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{ - "4e781020ad767db9bedc9d64bb30c69a5f1d94a57049c74a6f6e26d8ff3046bc", - "01786ad7ebd82641b5fa040798edf9eaebc07ac34bdcbd7e089c75ef09f730ee", - "fa3682d967de200686d0567ff2ab3568372decd91a7a94112d0c1ce493eee2c0", + "3c2ed817d9311d95f083ae8422ead660cf2dd56505cfd332bb0b56449791d3dc", + "b8d57c4c41eb37862673f6203a6fe87dd17d4036f5d87b8f34dca921f8a05e9a", + "4e6cee965c48678acc30ac714c317bac5f1ce8f876a97dc32d7673b7ccf105f0", } stakeAmount := initialStakeAmount for i := 0; i < len(stateHashes); i++ { // Get the context at the new height and retrieve one of the apps height := int64(i + 1) - heightBz := converters.HeightToBytes(uint64(height)) + heightBz := utils.HeightToBytes(uint64(height)) expectedStateHash := stateHashes[i] db := NewTestPostgresContext(t, height) diff --git a/persistence/test/validator_test.go b/persistence/test/validator_test.go index d5df1f97a..9afd49d8e 100644 --- a/persistence/test/validator_test.go +++ b/persistence/test/validator_test.go @@ -80,7 +80,7 @@ func TestUpdateValidator(t *testing.T) { db.Height = 1 require.NotEqual(t, DefaultStake, StakeToUpdate) // sanity check to make sure the tests are correct - err = db.UpdateValidator(addrBz, validator.GenericParam, StakeToUpdate) + err = db.UpdateValidator(addrBz, validator.ServiceUrl, StakeToUpdate) require.NoError(t, err) _, _, stakedTokens, _, _, _, _, err = db.GetValidator(addrBz, 0) @@ -114,24 +114,24 @@ func TestGetValidatorsReadyToUnstake(t *testing.T) { require.NoError(t, err) // Unstake validator at height 0 - err = db.SetValidatorUnstakingHeightAndStatus(addrBz, 0, persistence.UnstakingStatus) + err = db.SetValidatorUnstakingHeightAndStatus(addrBz, 0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Unstake validator2 and validator3 at height 1 - err = db.SetValidatorUnstakingHeightAndStatus(addrBz2, 1, persistence.UnstakingStatus) + err = db.SetValidatorUnstakingHeightAndStatus(addrBz2, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) - err = db.SetValidatorUnstakingHeightAndStatus(addrBz3, 1, persistence.UnstakingStatus) + err = db.SetValidatorUnstakingHeightAndStatus(addrBz3, 1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) // Check unstaking validators at height 0 - unstakingValidators, err := db.GetValidatorsReadyToUnstake(0, persistence.UnstakingStatus) + unstakingValidators, err := db.GetValidatorsReadyToUnstake(0, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 1, len(unstakingValidators), "wrong number of actors ready to unstake at height 0") require.Equal(t, validator.Address, unstakingValidators[0].GetAddress(), "unexpected unstaking validator returned") // Check unstaking validators at height 1 - unstakingValidators, err = db.GetValidatorsReadyToUnstake(1, persistence.UnstakingStatus) + unstakingValidators, err = db.GetValidatorsReadyToUnstake(1, int32(coreTypes.StakeStatus_Unstaking)) require.NoError(t, err) require.Equal(t, 2, len(unstakingValidators), "wrong number of actors ready to unstake at height 1") require.ElementsMatch(t, []string{validator2.Address, validator3.Address}, []string{unstakingValidators[0].Address, unstakingValidators[1].Address}) @@ -149,7 +149,7 @@ func TestGetValidatorStatus(t *testing.T) { // Check status before the validator exists status, err := db.GetValidatorStatus(addrBz, 0) require.Error(t, err) - require.Equal(t, persistence.UndefinedStakingStatus, status, "unexpected status") + require.Equal(t, int32(coreTypes.StakeStatus_UnknownStatus), status, "unexpected status") // Check status after the validator exists status, err = db.GetValidatorStatus(addrBz, 1) @@ -163,7 +163,6 @@ func TestGetValidatorPauseHeightIfExists(t *testing.T) { validator, err := createAndInsertDefaultTestValidator(db) require.NoError(t, err) - // TODO(andrew): In order to make the tests clearer (here and elsewhere), use `validatorAddrBz` instead of `addrBz` addrBz, err := hex.DecodeString(validator.Address) require.NoError(t, err) @@ -233,7 +232,7 @@ func newTestValidator() (*coreTypes.Actor, error) { return &coreTypes.Actor{ Address: hex.EncodeToString(operatorKey.Address()), PublicKey: hex.EncodeToString(operatorKey.Bytes()), - GenericParam: DefaultServiceUrl, + ServiceUrl: DefaultServiceURL, StakedAmount: DefaultStake, PausedHeight: DefaultPauseHeight, UnstakingHeight: DefaultUnstakingHeight, @@ -264,7 +263,7 @@ func createAndInsertDefaultTestValidator(db *persistence.PostgresContext) (*core outputBz, false, DefaultStakeStatus, - DefaultServiceUrl, + DefaultServiceURL, DefaultStake, DefaultPauseHeight, DefaultUnstakingHeight) @@ -294,7 +293,7 @@ func getTestValidator(db *persistence.PostgresContext, address []byte) (*coreTyp return &coreTypes.Actor{ Address: hex.EncodeToString(operatorAddr), PublicKey: hex.EncodeToString(operatorPubKey), - GenericParam: serviceURL, + ServiceUrl: serviceURL, StakedAmount: stakedTokens, PausedHeight: pauseHeight, UnstakingHeight: unstakingHeight, diff --git a/persistence/types/actor_shared_sql.go b/persistence/types/actor_shared_sql.go index 958051179..074ab1aa0 100644 --- a/persistence/types/actor_shared_sql.go +++ b/persistence/types/actor_shared_sql.go @@ -1,6 +1,7 @@ package types // CLEANUP: Move SQL specific business logic into a `sql` package under `persistence` +// TECHDEBT: Be consistent with `ServiceUrl` and `ActorSpecificParam` throughout the codebase; preferably the latter. import ( "bytes" @@ -26,11 +27,11 @@ const ( NameCol = "name" StakedTokensCol = "staked_tokens" ServiceURLCol = "service_url" + UnusedCol = "unused" // TECHDEBT: Unused column name from legacy behaviour OutputAddressCol = "output_address" UnstakingHeightCol = "unstaking_height" PausedHeightCol = "paused_height" ChainIDCol = "chain_id" - MaxRelaysCol = "max_relays" HeightCol = "height" ) diff --git a/persistence/types/application.go b/persistence/types/application.go index a6881f9b7..df8140994 100644 --- a/persistence/types/application.go +++ b/persistence/types/application.go @@ -2,6 +2,10 @@ package types import coreTypes "github.com/pokt-network/pocket/shared/core/types" +// TECHDEBT: s/ApplicationSchema/applicationSchema +// TECHDEBT: s/ApplicationActor/ApplicationActorSchema +// TECHDEBT: Ditto for all other actor types +// TECHDEBT: Should we use an ORM? var _ ProtocolActorSchema = &ApplicationSchema{} type ApplicationSchema struct { @@ -22,7 +26,7 @@ var ApplicationActor ProtocolActorSchema = &ApplicationSchema{ tableName: AppTableName, chainsTableName: AppChainsTableName, - actorSpecificColName: MaxRelaysCol, + actorSpecificColName: UnusedCol, heightConstraintName: AppHeightConstraintName, chainsHeightConstraintName: AppChainsConstraintName, diff --git a/persistence/types/base_actor.go b/persistence/types/base_actor.go index f291556e2..01bbb6096 100644 --- a/persistence/types/base_actor.go +++ b/persistence/types/base_actor.go @@ -20,7 +20,9 @@ type BaseProtocolActorSchema struct { chainsTableName string // SQL Columns - actorSpecificColName string // CONSIDERATION: If actor specific behaviour expands, this will need to be refactored to be a list. + // TECHDEBT: This is currently used to store the ServiceURL for each actor, but may need to be + // extended to lists of different types in the future. + actorSpecificColName string // SQL Constraints heightConstraintName string diff --git a/persistence/types/gov_test.go b/persistence/types/gov_test.go index 6b2b68fe7..c8d8f4919 100644 --- a/persistence/types/gov_test.go +++ b/persistence/types/gov_test.go @@ -26,8 +26,7 @@ func TestInsertParams(t *testing.T) { want: "INSERT INTO params VALUES ('blocks_per_session', -1, 'BIGINT', 4)," + "('app_minimum_stake', -1, 'STRING', '15000000000')," + "('app_max_chains', -1, 'SMALLINT', 15)," + - "('app_baseline_stake_rate', -1, 'BIGINT', 100)," + - "('app_staking_adjustment', -1, 'BIGINT', 0)," + + "('app_session_tokens_multiplier', -1, 'BIGINT', 100)," + "('app_unstaking_blocks', -1, 'BIGINT', 2016)," + "('app_minimum_pause_blocks', -1, 'SMALLINT', 4)," + "('app_max_pause_blocks', -1, 'BIGINT', 672)," + @@ -81,8 +80,7 @@ func TestInsertParams(t *testing.T) { "('blocks_per_session_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('app_minimum_stake_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('app_max_chains_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + - "('app_baseline_stake_rate_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + - "('app_staking_adjustment_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + + "('app_session_tokens_multiplier_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('app_unstaking_blocks_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('app_minimum_pause_blocks_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + "('app_max_paused_blocks_owner', -1, 'STRING', 'da034209758b78eaea06dd99c07909ab54c99b45')," + diff --git a/persistence/types/protocol_actor.go b/persistence/types/protocol_actor.go index 7b16a1def..f8069eb21 100644 --- a/persistence/types/protocol_actor.go +++ b/persistence/types/protocol_actor.go @@ -32,7 +32,6 @@ type ProtocolActorSchema interface { // Returns a query to retrieve data associated with all the apps ready to unstake. GetReadyToUnstakeQuery(unstakingHeight int64) string // Returns a query to retrieve the output address of an Actor given its operator address. - // DISCUSS(drewsky): Why/how we even need this. What is an output & operator for an app? GetOutputAddressQuery(operatorAddress string, height int64) string // Returns a query to retrieve the stake amount of an actor GetStakeAmountQuery(address string, height int64) string @@ -47,11 +46,11 @@ type ProtocolActorSchema interface { /*** Create/Insert Queries ***/ // Returns a query to create a new Actor with all of the necessary data. - InsertQuery(address, publicKey, stakedTokens, maxRelays, outputAddress string, pausedHeight, unstakingHeight int64, chains []string, height int64) string + InsertQuery(address, publicKey, stakedTokens, serviceURL, outputAddress string, pausedHeight, unstakingHeight int64, chains []string, height int64) string /*** Update Queries ***/ // Returns a query to update an Actor's stake and/or max relays. - UpdateQuery(address, stakedTokens, maxRelays string, height int64) string + UpdateQuery(address, stakedTokens, serviceURL string, height int64) string // Returns a query to update the chains an Actor is staked for. UpdateChainsQuery(address string, chains []string, height int64) string // Returns a query to update the height at which an Actor is unstaking. diff --git a/persistence/types/validator.go b/persistence/types/validator.go index 6cded8004..962fb2e43 100644 --- a/persistence/types/validator.go +++ b/persistence/types/validator.go @@ -29,16 +29,17 @@ var ValidatorActor ProtocolActorSchema = &ValidatorSchema{ }, } -func (actor *ValidatorSchema) InsertQuery(address, publicKey, stakedTokens, maxRelays, outputAddress string, pausedHeight, unstakingHeight int64, _ []string, height int64) string { +func (actor *ValidatorSchema) InsertQuery(address, publicKey, stakedTokens, serviceURL, outputAddress string, pausedHeight, unstakingHeight int64, _ []string, height int64) string { return Insert(&coreTypes.Actor{ Address: address, PublicKey: publicKey, + ServiceUrl: serviceURL, StakedAmount: stakedTokens, Output: outputAddress, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, }, - actor.actorSpecificColName, maxRelays, + actor.actorSpecificColName, serviceURL, actor.heightConstraintName, NullString, actor.tableName, NullString, height) diff --git a/persistence/validator.go b/persistence/validator.go index 356659872..3f9672b15 100644 --- a/persistence/validator.go +++ b/persistence/validator.go @@ -18,7 +18,7 @@ func (p *PostgresContext) GetValidator(address []byte, height int64) (operator, operator = actor.Address publicKey = actor.PublicKey stakedTokens = actor.StakedAmount - serviceURL = actor.GenericParam + serviceURL = actor.ServiceUrl outputAddress = actor.Output pausedHeight = actor.PausedHeight unstakingHeight = actor.UnstakingHeight @@ -31,7 +31,7 @@ func (p *PostgresContext) InsertValidator(address, publicKey, output []byte, _ b Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), StakedAmount: stakedTokens, - GenericParam: serviceURL, + ServiceUrl: serviceURL, Output: hex.EncodeToString(output), PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, @@ -43,7 +43,7 @@ func (p *PostgresContext) UpdateValidator(address []byte, serviceURL, stakedAmou ActorType: coreTypes.ActorType_ACTOR_TYPE_VAL, Address: hex.EncodeToString(address), StakedAmount: stakedAmount, - GenericParam: serviceURL, + ServiceUrl: serviceURL, }) } @@ -83,11 +83,6 @@ func (p *PostgresContext) GetValidatorOutputAddress(operator []byte, height int6 return p.GetActorOutputAddress(types.ValidatorActor, operator, height) } -// TODO: implement missed blocks -func (p *PostgresContext) SetValidatorPauseHeightAndMissedBlocks(address []byte, pausedHeight int64, missedBlocks int) error { - return nil -} - // TODO: implement missed blocks func (p *PostgresContext) SetValidatorMissedBlocks(address []byte, missedBlocks int) error { return nil diff --git a/rpc/doc/CHANGELOG.md b/rpc/doc/CHANGELOG.md index e0785a8a5..2ead6c808 100644 --- a/rpc/doc/CHANGELOG.md +++ b/rpc/doc/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.15] - 2023-02-28 + +- Rename `CheckTransaction` to `HandleTransaction` + ## [0.0.0.14] - 2023-02-24 - Update logger value references with pointers diff --git a/rpc/handlers.go b/rpc/handlers.go index 041fb4865..0d816ed3e 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -6,10 +6,9 @@ import ( "github.com/labstack/echo/v4" "github.com/pokt-network/pocket/app" - "github.com/pokt-network/pocket/shared/codec" - typesCore "github.com/pokt-network/pocket/shared/core/types" + coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/modules" - typesUtil "github.com/pokt-network/pocket/utility/types" + "github.com/pokt-network/pocket/utility" ) func (s *rpcServer) GetV1Health(ctx echo.Context) error { @@ -31,7 +30,7 @@ func (s *rpcServer) PostV1ClientBroadcastTxSync(ctx echo.Context) error { return ctx.String(http.StatusBadRequest, "cannot decode tx bytes") } - if err = s.GetBus().GetUtilityModule().CheckTransaction(txBz); err != nil { + if err = s.GetBus().GetUtilityModule().HandleTransaction(txBz); err != nil { return ctx.String(http.StatusInternalServerError, err.Error()) } @@ -53,20 +52,17 @@ func (s *rpcServer) GetV1ConsensusState(ctx echo.Context) error { // Broadcast to the entire validator set func (s *rpcServer) broadcastMessage(msgBz []byte) error { - utilMsg := &typesUtil.TransactionGossipMessage{ - Tx: msgBz, - } - - anyUtilityMessage, err := codec.GetCodec().ToAny(utilMsg) + utilityMsg, err := utility.PrepareTxGossipMessage(msgBz) if err != nil { - s.logger.Error().Err(err).Msg("Failed to create Any proto from transaction gossip") + s.logger.Error().Err(err).Msg("Failed to prepare transaction gossip message") return err } - if err := s.GetBus().GetP2PModule().Broadcast(anyUtilityMessage); err != nil { + if err := s.GetBus().GetP2PModule().Broadcast(utilityMsg); err != nil { s.logger.Error().Err(err).Msg("Failed to broadcast utility message") return err } + return nil } @@ -98,7 +94,7 @@ func (s *rpcServer) GetV1P2pStakedActorsAddressBook(ctx echo.Context, params Get Address: protocolActor.Address, Type: protocolActorToRPCActorTypeEnum(protocolActor.ActorType), PublicKey: protocolActor.PublicKey, - ServiceUrl: protocolActor.GenericParam, + ServiceUrl: protocolActor.ServiceUrl, }) } @@ -111,15 +107,15 @@ func (s *rpcServer) GetV1P2pStakedActorsAddressBook(ctx echo.Context, params Get } // protocolActorToRPCActorTypeEnum converts a protocol actor type to the rpc actor type enum -func protocolActorToRPCActorTypeEnum(protocolActorType typesCore.ActorType) ActorTypesEnum { +func protocolActorToRPCActorTypeEnum(protocolActorType coreTypes.ActorType) ActorTypesEnum { switch protocolActorType { - case typesCore.ActorType_ACTOR_TYPE_APP: + case coreTypes.ActorType_ACTOR_TYPE_APP: return Application - case typesCore.ActorType_ACTOR_TYPE_FISH: + case coreTypes.ActorType_ACTOR_TYPE_FISH: return Fisherman - case typesCore.ActorType_ACTOR_TYPE_SERVICER: + case coreTypes.ActorType_ACTOR_TYPE_SERVICER: return Servicer - case typesCore.ActorType_ACTOR_TYPE_VAL: + case coreTypes.ActorType_ACTOR_TYPE_VAL: return Validator default: panic("invalid actor type") @@ -127,8 +123,8 @@ func protocolActorToRPCActorTypeEnum(protocolActorType typesCore.ActorType) Acto } // getProtocolActorGetter returns the correct protocol actor getter function based on the actor type parameter -func getProtocolActorGetter(persistenceContext modules.PersistenceReadContext, params GetV1P2pStakedActorsAddressBookParams) func(height int64) ([]*typesCore.Actor, error) { - var protocolActorGetter func(height int64) ([]*typesCore.Actor, error) = persistenceContext.GetAllStakedActors +func getProtocolActorGetter(persistenceContext modules.PersistenceReadContext, params GetV1P2pStakedActorsAddressBookParams) func(height int64) ([]*coreTypes.Actor, error) { + var protocolActorGetter func(height int64) ([]*coreTypes.Actor, error) = persistenceContext.GetAllStakedActors if params.ActorType == nil { return persistenceContext.GetAllStakedActors } diff --git a/runtime/configs/config.go b/runtime/configs/config.go index 44af2c544..b7cd5a51b 100644 --- a/runtime/configs/config.go +++ b/runtime/configs/config.go @@ -32,7 +32,7 @@ func NewDefaultConfig(options ...func(*Config)) *Config { MaxMempoolTransactions: defaults.DefaultUtilityMaxMempoolTransactions, }, Persistence: &PersistenceConfig{ - PostgresUrl: defaults.DefaultPersistencePostgresUrl, + PostgresUrl: defaults.DefaultPersistencePostgresURL, BlockStorePath: defaults.DefaultPersistenceBlockStorePath, }, P2P: &P2PConfig{ diff --git a/runtime/defaults/defaults.go b/runtime/defaults/defaults.go index b074bddfc..a17bb03c8 100644 --- a/runtime/defaults/defaults.go +++ b/runtime/defaults/defaults.go @@ -29,7 +29,7 @@ var ( DefaultUtilityMaxMempoolTransactionBytes = uint64(1024 ^ 3) // 1GB V0 defaults DefaultUtilityMaxMempoolTransactions = uint32(9000) // persistence - DefaultPersistencePostgresUrl = "postgres://postgres:postgres@pocket-db:5432/postgres" + DefaultPersistencePostgresURL = "postgres://postgres:postgres@pocket-db:5432/postgres" DefaultPersistenceBlockStorePath = "/var/blockstore" // p2p DefaultP2PConsensusPort = uint32(8080) diff --git a/runtime/docs/CHANGELOG.md b/runtime/docs/CHANGELOG.md index 033fbbf8d..88408fae3 100644 --- a/runtime/docs/CHANGELOG.md +++ b/runtime/docs/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.24] - 2023-02-28 + +- Rename `app_staking_adjustment` to `app_session_tokens_multiplier` +- Remove `app_baseline_stake_rate` +- Rename `keygenerator` to `keygen` + ## [0.0.0.23] - 2023-02-21 - Rename ServiceNode Actor Type Name to Servicer diff --git a/runtime/genesis/proto/genesis.proto b/runtime/genesis/proto/genesis.proto index 4c760c49c..0245fc2fa 100644 --- a/runtime/genesis/proto/genesis.proto +++ b/runtime/genesis/proto/genesis.proto @@ -21,7 +21,8 @@ message GenesisState { Params params = 10; } -// DISCUSS(drewskey): Explore a more general purpose "feature flag" like approach for this. +// TECHDEBT: Explore a more general purpose "feature flag" approach that makes it easy to add/remove +// parametesr and add activation heights for them as well. message Params { //@gotags: pokt:"val_type=BIGINT" int32 blocks_per_session = 1; @@ -30,220 +31,216 @@ message Params { //@gotags: pokt:"val_type=SMALLINT" int32 app_max_chains = 3; //@gotags: pokt:"val_type=BIGINT" - int32 app_baseline_stake_rate = 4; + int32 app_session_tokens_multiplier = 4; //@gotags: pokt:"val_type=BIGINT" - int32 app_staking_adjustment = 5; - //@gotags: pokt:"val_type=BIGINT" - int32 app_unstaking_blocks = 6; + int32 app_unstaking_blocks = 5; //@gotags: pokt:"val_type=SMALLINT" - int32 app_minimum_pause_blocks = 7; + int32 app_minimum_pause_blocks = 6; //@gotags: pokt:"val_type=BIGINT" - int32 app_max_pause_blocks = 8; + int32 app_max_pause_blocks = 7; //@gotags: pokt:"val_type=STRING" - string servicer_minimum_stake = 9; + string servicer_minimum_stake = 8; //@gotags: pokt:"val_type=SMALLINT" - int32 servicer_max_chains = 10; + int32 servicer_max_chains = 9; //@gotags: pokt:"val_type=BIGINT" - int32 servicer_unstaking_blocks = 11; + int32 servicer_unstaking_blocks = 10; //@gotags: pokt:"val_type=SMALLINT" - int32 servicer_minimum_pause_blocks = 12; + int32 servicer_minimum_pause_blocks = 11; //@gotags: pokt:"val_type=BIGINT" - int32 servicer_max_pause_blocks = 13; + int32 servicer_max_pause_blocks = 12; //@gotags: pokt:"val_type=SMALLINT" - int32 servicers_per_session = 14; + int32 servicers_per_session = 13; //@gotags: pokt:"val_type=STRING" - string fisherman_minimum_stake = 15; + string fisherman_minimum_stake = 14; //@gotags: pokt:"val_type=SMALLINT" - int32 fisherman_max_chains = 16; + int32 fisherman_max_chains = 15; //@gotags: pokt:"val_type=BIGINT" - int32 fisherman_unstaking_blocks = 17; + int32 fisherman_unstaking_blocks = 16; //@gotags: pokt:"val_type=SMALLINT" - int32 fisherman_minimum_pause_blocks = 18; + int32 fisherman_minimum_pause_blocks = 17; //@gotags: pokt:"val_type=SMALLINT" - int32 fisherman_max_pause_blocks = 19; + int32 fisherman_max_pause_blocks = 18; //@gotags: pokt:"val_type=STRING" - string validator_minimum_stake = 20; + string validator_minimum_stake = 19; //@gotags: pokt:"val_type=BIGINT" - int32 validator_unstaking_blocks = 21; + int32 validator_unstaking_blocks = 20; //@gotags: pokt:"val_type=SMALLINT" - int32 validator_minimum_pause_blocks = 22; + int32 validator_minimum_pause_blocks = 21; //@gotags: pokt:"val_type=SMALLINT" - int32 validator_max_pause_blocks = 23; + int32 validator_max_pause_blocks = 22; //@gotags: pokt:"val_type=SMALLINT" - int32 validator_maximum_missed_blocks = 24; + int32 validator_maximum_missed_blocks = 23; //@gotags: pokt:"val_type=SMALLINT" - int32 validator_max_evidence_age_in_blocks = 25; + int32 validator_max_evidence_age_in_blocks = 24; //@gotags: pokt:"val_type=SMALLINT" - int32 proposer_percentage_of_fees = 26; + int32 proposer_percentage_of_fees = 25; //@gotags: pokt:"val_type=SMALLINT" - int32 missed_blocks_burn_percentage = 27; + int32 missed_blocks_burn_percentage = 26; //@gotags: pokt:"val_type=SMALLINT" - int32 double_sign_burn_percentage = 28; + int32 double_sign_burn_percentage = 27; //@gotags: pokt:"val_type=STRING" - string message_double_sign_fee = 29; + string message_double_sign_fee = 28; //@gotags: pokt:"val_type=STRING" - string message_send_fee = 30; + string message_send_fee = 29; //@gotags: pokt:"val_type=STRING" - string message_stake_fisherman_fee = 31; + string message_stake_fisherman_fee = 30; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_fisherman_fee = 32; + string message_edit_stake_fisherman_fee = 31; //@gotags: pokt:"val_type=STRING" - string message_unstake_fisherman_fee = 33; + string message_unstake_fisherman_fee = 32; //@gotags: pokt:"val_type=STRING" - string message_pause_fisherman_fee = 34; + string message_pause_fisherman_fee = 33; //@gotags: pokt:"val_type=STRING" - string message_unpause_fisherman_fee = 35; + string message_unpause_fisherman_fee = 34; //@gotags: pokt:"val_type=STRING" - string message_fisherman_pause_servicer_fee = 36; + string message_fisherman_pause_servicer_fee = 35; //@gotags: pokt:"val_type=STRING" - string message_test_score_fee = 37; + string message_test_score_fee = 36; //@gotags: pokt:"val_type=STRING" - string message_prove_test_score_fee = 38; + string message_prove_test_score_fee = 37; //@gotags: pokt:"val_type=STRING" - string message_stake_app_fee = 39; + string message_stake_app_fee = 38; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_app_fee = 40; + string message_edit_stake_app_fee = 39; //@gotags: pokt:"val_type=STRING" - string message_unstake_app_fee = 41; + string message_unstake_app_fee = 40; //@gotags: pokt:"val_type=STRING" - string message_pause_app_fee = 42; + string message_pause_app_fee = 41; //@gotags: pokt:"val_type=STRING" - string message_unpause_app_fee = 43; + string message_unpause_app_fee = 42; //@gotags: pokt:"val_type=STRING" - string message_stake_validator_fee = 44; + string message_stake_validator_fee = 43; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_validator_fee = 45; + string message_edit_stake_validator_fee = 44; //@gotags: pokt:"val_type=STRING" - string message_unstake_validator_fee = 46; + string message_unstake_validator_fee = 45; //@gotags: pokt:"val_type=STRING" - string message_pause_validator_fee = 47; + string message_pause_validator_fee = 46; //@gotags: pokt:"val_type=STRING" - string message_unpause_validator_fee = 48; + string message_unpause_validator_fee = 47; //@gotags: pokt:"val_type=STRING" - string message_stake_servicer_fee = 49; + string message_stake_servicer_fee = 48; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_servicer_fee = 50; + string message_edit_stake_servicer_fee = 49; //@gotags: pokt:"val_type=STRING" - string message_unstake_servicer_fee = 51; + string message_unstake_servicer_fee = 50; //@gotags: pokt:"val_type=STRING" - string message_pause_servicer_fee = 52; + string message_pause_servicer_fee = 51; //@gotags: pokt:"val_type=STRING" - string message_unpause_servicer_fee = 53; + string message_unpause_servicer_fee = 52; //@gotags: pokt:"val_type=STRING" - string message_change_parameter_fee = 54; + string message_change_parameter_fee = 53; //@gotags: pokt:"val_type=STRING" - string acl_owner = 55; - //@gotags: pokt:"val_type=STRING" - string blocks_per_session_owner = 56; + string acl_owner = 54; //@gotags: pokt:"val_type=STRING" - string app_minimum_stake_owner = 57; + string blocks_per_session_owner = 55; //@gotags: pokt:"val_type=STRING" - string app_max_chains_owner = 58; + string app_minimum_stake_owner = 56; //@gotags: pokt:"val_type=STRING" - string app_baseline_stake_rate_owner = 59; + string app_max_chains_owner = 57; //@gotags: pokt:"val_type=STRING" - string app_staking_adjustment_owner = 60; + string app_session_tokens_multiplier_owner = 58; //@gotags: pokt:"val_type=STRING" - string app_unstaking_blocks_owner = 61; + string app_unstaking_blocks_owner = 59; //@gotags: pokt:"val_type=STRING" - string app_minimum_pause_blocks_owner = 62; + string app_minimum_pause_blocks_owner = 60; //@gotags: pokt:"val_type=STRING" - string app_max_paused_blocks_owner = 63; + string app_max_paused_blocks_owner = 61; //@gotags: pokt:"val_type=STRING" - string servicer_minimum_stake_owner = 64; + string servicer_minimum_stake_owner = 62; //@gotags: pokt:"val_type=STRING" - string servicer_max_chains_owner = 65; + string servicer_max_chains_owner = 63; //@gotags: pokt:"val_type=STRING" - string servicer_unstaking_blocks_owner = 66; + string servicer_unstaking_blocks_owner = 64; //@gotags: pokt:"val_type=STRING" - string servicer_minimum_pause_blocks_owner = 67; + string servicer_minimum_pause_blocks_owner = 65; //@gotags: pokt:"val_type=STRING" - string servicer_max_paused_blocks_owner = 68; + string servicer_max_paused_blocks_owner = 66; //@gotags: pokt:"val_type=STRING" - string servicers_per_session_owner = 69; + string servicers_per_session_owner = 67; //@gotags: pokt:"val_type=STRING" - string fisherman_minimum_stake_owner = 70; + string fisherman_minimum_stake_owner = 68; //@gotags: pokt:"val_type=STRING" - string fisherman_max_chains_owner = 71; + string fisherman_max_chains_owner = 69; //@gotags: pokt:"val_type=STRING" - string fisherman_unstaking_blocks_owner = 72; + string fisherman_unstaking_blocks_owner = 70; //@gotags: pokt:"val_type=STRING" - string fisherman_minimum_pause_blocks_owner = 73; + string fisherman_minimum_pause_blocks_owner = 71; //@gotags: pokt:"val_type=STRING" - string fisherman_max_paused_blocks_owner = 74; + string fisherman_max_paused_blocks_owner = 72; //@gotags: pokt:"val_type=STRING" - string validator_minimum_stake_owner = 75; + string validator_minimum_stake_owner = 73; //@gotags: pokt:"val_type=STRING" - string validator_unstaking_blocks_owner = 76; + string validator_unstaking_blocks_owner = 74; //@gotags: pokt:"val_type=STRING" - string validator_minimum_pause_blocks_owner = 77; + string validator_minimum_pause_blocks_owner = 75; //@gotags: pokt:"val_type=STRING" - string validator_max_paused_blocks_owner = 78; + string validator_max_paused_blocks_owner = 76; //@gotags: pokt:"val_type=STRING" - string validator_maximum_missed_blocks_owner = 79; + string validator_maximum_missed_blocks_owner = 77; //@gotags: pokt:"val_type=STRING" - string validator_max_evidence_age_in_blocks_owner = 80; + string validator_max_evidence_age_in_blocks_owner = 78; //@gotags: pokt:"val_type=STRING" - string proposer_percentage_of_fees_owner = 81; + string proposer_percentage_of_fees_owner = 79; //@gotags: pokt:"val_type=STRING" - string missed_blocks_burn_percentage_owner = 82; + string missed_blocks_burn_percentage_owner = 80; //@gotags: pokt:"val_type=STRING" - string double_sign_burn_percentage_owner = 83; + string double_sign_burn_percentage_owner = 81; //@gotags: pokt:"val_type=STRING" - string message_double_sign_fee_owner = 84; + string message_double_sign_fee_owner = 82; //@gotags: pokt:"val_type=STRING" - string message_send_fee_owner = 85; + string message_send_fee_owner = 83; //@gotags: pokt:"val_type=STRING" - string message_stake_fisherman_fee_owner = 86; + string message_stake_fisherman_fee_owner = 84; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_fisherman_fee_owner = 87; + string message_edit_stake_fisherman_fee_owner = 85; //@gotags: pokt:"val_type=STRING" - string message_unstake_fisherman_fee_owner = 88; + string message_unstake_fisherman_fee_owner = 86; //@gotags: pokt:"val_type=STRING" - string message_pause_fisherman_fee_owner = 89; + string message_pause_fisherman_fee_owner = 87; //@gotags: pokt:"val_type=STRING" - string message_unpause_fisherman_fee_owner = 90; + string message_unpause_fisherman_fee_owner = 88; //@gotags: pokt:"val_type=STRING" - string message_fisherman_pause_servicer_fee_owner = 91; + string message_fisherman_pause_servicer_fee_owner = 89; //@gotags: pokt:"val_type=STRING" - string message_test_score_fee_owner = 92; + string message_test_score_fee_owner = 90; //@gotags: pokt:"val_type=STRING" - string message_prove_test_score_fee_owner = 93; + string message_prove_test_score_fee_owner = 91; //@gotags: pokt:"val_type=STRING" - string message_stake_app_fee_owner = 94; + string message_stake_app_fee_owner = 92; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_app_fee_owner = 95; + string message_edit_stake_app_fee_owner = 93; //@gotags: pokt:"val_type=STRING" - string message_unstake_app_fee_owner = 96; + string message_unstake_app_fee_owner = 94; //@gotags: pokt:"val_type=STRING" - string message_pause_app_fee_owner = 97; + string message_pause_app_fee_owner = 95; //@gotags: pokt:"val_type=STRING" - string message_unpause_app_fee_owner = 98; + string message_unpause_app_fee_owner = 96; //@gotags: pokt:"val_type=STRING" - string message_stake_validator_fee_owner = 99; + string message_stake_validator_fee_owner = 97; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_validator_fee_owner = 100; + string message_edit_stake_validator_fee_owner = 98; //@gotags: pokt:"val_type=STRING" - string message_unstake_validator_fee_owner = 101; + string message_unstake_validator_fee_owner = 99; //@gotags: pokt:"val_type=STRING" - string message_pause_validator_fee_owner = 102; + string message_pause_validator_fee_owner = 100; //@gotags: pokt:"val_type=STRING" - string message_unpause_validator_fee_owner = 103; + string message_unpause_validator_fee_owner = 101; //@gotags: pokt:"val_type=STRING" - string message_stake_servicer_fee_owner = 104; + string message_stake_servicer_fee_owner = 102; //@gotags: pokt:"val_type=STRING" - string message_edit_stake_servicer_fee_owner = 105; + string message_edit_stake_servicer_fee_owner = 103; //@gotags: pokt:"val_type=STRING" - string message_unstake_servicer_fee_owner = 106; + string message_unstake_servicer_fee_owner = 104; //@gotags: pokt:"val_type=STRING" - string message_pause_servicer_fee_owner = 107; + string message_pause_servicer_fee_owner = 105; //@gotags: pokt:"val_type=STRING" - string message_unpause_servicer_fee_owner = 108; + string message_unpause_servicer_fee_owner = 106; //@gotags: pokt:"val_type=STRING" - string message_change_parameter_fee_owner = 109; + string message_change_parameter_fee_owner = 107; } diff --git a/runtime/manager_test.go b/runtime/manager_test.go index 3073fc287..98d9b705f 100644 --- a/runtime/manager_test.go +++ b/runtime/manager_test.go @@ -4066,7 +4066,6 @@ var expectedGenesis = &genesis.GenesisState{ Address: "88a792b7aca673620132ef01f50e62caa58eca83", PublicKey: "5f78658599943dc3e623539ce0b3c9fe4e192034a1e3fef308bc9f96915754e0", Chains: []string{"0001"}, - GenericParam: "1000000", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, @@ -4079,7 +4078,7 @@ var expectedGenesis = &genesis.GenesisState{ Address: "00104055c00bed7c983a48aac7dc6335d7c607a7", PublicKey: "dfe357de55649e6d2ce889acf15eb77e94ab3c5756fe46d3c7538d37f27f115e", Chains: nil, - GenericParam: "node1.consensus:8080", + ServiceUrl: "node1.consensus:8080", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, @@ -4090,7 +4089,7 @@ var expectedGenesis = &genesis.GenesisState{ Address: "00204737d2a165ebe4be3a7d5b0af905b0ea91d8", PublicKey: "eb2c78364525a210d994a83e02d18b4287ab81f6670cf4510ab6c9f51e296d91", Chains: nil, - GenericParam: "node2.consensus:8080", + ServiceUrl: "node2.consensus:8080", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, @@ -4101,7 +4100,7 @@ var expectedGenesis = &genesis.GenesisState{ Address: "00304d0101847b37fd62e7bebfbdddecdbb7133e", PublicKey: "1041a9c76539791fef9bee5b4fcd5bf4a1a489e0790c44cbdfa776b901e13b50", Chains: nil, - GenericParam: "node3.consensus:8080", + ServiceUrl: "node3.consensus:8080", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, @@ -4112,7 +4111,7 @@ var expectedGenesis = &genesis.GenesisState{ Address: "00404a570febd061274f72b50d0a37f611dfe339", PublicKey: "d6cea8706f6ee6672c1e013e667ec8c46231e0e7abcf97ba35d89fceb8edae45", Chains: nil, - GenericParam: "node4.consensus:8080", + ServiceUrl: "node4.consensus:8080", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, @@ -4125,7 +4124,7 @@ var expectedGenesis = &genesis.GenesisState{ Address: "43d9ea9d9ad9c58bb96ec41340f83cb2cabb6496", PublicKey: "16cd0a304c38d76271f74dd3c90325144425d904ef1b9a6fbab9b201d75a998b", Chains: []string{"0001"}, - GenericParam: "node1.consensus:8080", + ServiceUrl: "node1.consensus:8080", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, @@ -4138,7 +4137,7 @@ var expectedGenesis = &genesis.GenesisState{ Address: "9ba047197ec043665ad3f81278ab1f5d3eaf6b8b", PublicKey: "68efd26af01692fcd77dc135ca1de69ede464e8243e6832bd6c37f282db8c9cb", Chains: []string{"0001"}, - GenericParam: "node1.consensus:8080", + ServiceUrl: "node1.consensus:8080", StakedAmount: "1000000000000", PausedHeight: -1, UnstakingHeight: -1, diff --git a/runtime/test_artifacts/defaults.go b/runtime/test_artifacts/defaults.go index 4419a29d6..6f64e25f3 100644 --- a/runtime/test_artifacts/defaults.go +++ b/runtime/test_artifacts/defaults.go @@ -3,21 +3,19 @@ package test_artifacts import ( "math/big" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/shared/utils" ) var ( DefaultChains = []string{"0001"} DefaultServiceURL = "" DefaultStakeAmount = big.NewInt(1000000000000) - DefaultStakeAmountString = converters.BigIntToString(DefaultStakeAmount) - DefaultMaxRelays = big.NewInt(1000000) - DefaultMaxRelaysString = converters.BigIntToString(DefaultMaxRelays) + DefaultStakeAmountString = utils.BigIntToString(DefaultStakeAmount) DefaultAccountAmount = big.NewInt(100000000000000) - DefaultAccountAmountString = converters.BigIntToString(DefaultAccountAmount) + DefaultAccountAmountString = utils.BigIntToString(DefaultAccountAmount) DefaultPauseHeight = int64(-1) DefaultUnstakingHeight = int64(-1) DefaultChainID = "testnet" - ServiceUrlFormat = "node%d.consensus:8080" + ServiceURLFormat = "node%d.consensus:8080" DefaultMaxBlockBytes = uint64(4000000) ) diff --git a/runtime/test_artifacts/generator.go b/runtime/test_artifacts/generator.go index 5ca9b6cbe..3542a6618 100644 --- a/runtime/test_artifacts/generator.go +++ b/runtime/test_artifacts/generator.go @@ -7,7 +7,7 @@ import ( "github.com/pokt-network/pocket/runtime/configs" "github.com/pokt-network/pocket/runtime/genesis" - "github.com/pokt-network/pocket/runtime/test_artifacts/keygenerator" + "github.com/pokt-network/pocket/runtime/test_artifacts/keygen" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" "google.golang.org/protobuf/types/known/timestamppb" @@ -67,7 +67,7 @@ func NewPools() (pools []*coreTypes.Account) { func NewAccounts(n int, privateKeys ...string) (accounts []*coreTypes.Account) { for i := 0; i < n; i++ { - _, _, addr := keygenerator.GetInstance().Next() + _, _, addr := keygen.GetInstance().Next() if privateKeys != nil { pk, _ := crypto.NewPrivateKey(privateKeys[i]) addr = pk.Address().String() @@ -85,11 +85,8 @@ func NewAccounts(n int, privateKeys ...string) (accounts []*coreTypes.Account) { // types of actors which needs to be fixed. func NewActors(actorType coreTypes.ActorType, n int) (actors []*coreTypes.Actor, privateKeys []string) { for i := 0; i < n; i++ { - genericParam := getServiceUrl(i + 1) - if int32(actorType) == int32(coreTypes.ActorType_ACTOR_TYPE_APP) { - genericParam = DefaultMaxRelaysString - } - actor, pk := NewDefaultActor(int32(actorType), genericParam) + serviceURL := getServiceURL(i + 1) + actor, pk := NewDefaultActor(int32(actorType), serviceURL) actors = append(actors, actor) privateKeys = append(privateKeys, pk) } @@ -97,23 +94,21 @@ func NewActors(actorType coreTypes.ActorType, n int) (actors []*coreTypes.Actor, return } -func getServiceUrl(n int) string { - return fmt.Sprintf(ServiceUrlFormat, n) +func getServiceURL(n int) string { + return fmt.Sprintf(ServiceURLFormat, n) } -func NewDefaultActor(actorType int32, genericParam string) (actor *coreTypes.Actor, privateKey string) { - privKey, pubKey, addr := keygenerator.GetInstance().Next() +func NewDefaultActor(actorType int32, serviceURL string) (actor *coreTypes.Actor, privateKey string) { + privKey, pubKey, addr := keygen.GetInstance().Next() chains := DefaultChains if actorType == int32(coreTypes.ActorType_ACTOR_TYPE_VAL) { chains = nil - } else if actorType == int32(coreTypes.ActorType_ACTOR_TYPE_APP) { - genericParam = DefaultMaxRelaysString } return &coreTypes.Actor{ Address: addr, PublicKey: pubKey, Chains: chains, - GenericParam: genericParam, + ServiceUrl: serviceURL, StakedAmount: DefaultStakeAmountString, PausedHeight: DefaultPauseHeight, UnstakingHeight: DefaultUnstakingHeight, diff --git a/runtime/test_artifacts/gov.go b/runtime/test_artifacts/gov.go index d4159d56e..1f836bbbb 100644 --- a/runtime/test_artifacts/gov.go +++ b/runtime/test_artifacts/gov.go @@ -5,8 +5,8 @@ import ( "github.com/pokt-network/pocket/runtime/genesis" - "github.com/pokt-network/pocket/shared/converters" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" ) // TODO (Team) this entire file should be re-scoped. DefaultParameters are only a testing thing because prod defers to the genesis file @@ -16,25 +16,24 @@ var DefaultParamsOwner, _ = crypto.NewPrivateKey("ff538589deb7f28bbce1ba68b37d2e func DefaultParams() *genesis.Params { return &genesis.Params{ BlocksPerSession: 4, - AppMinimumStake: converters.BigIntToString(big.NewInt(15000000000)), + AppMinimumStake: utils.BigIntToString(big.NewInt(15000000000)), AppMaxChains: 15, - AppBaselineStakeRate: 100, - AppStakingAdjustment: 0, + AppSessionTokensMultiplier: 100, AppUnstakingBlocks: 2016, AppMinimumPauseBlocks: 4, AppMaxPauseBlocks: 672, - ServicerMinimumStake: converters.BigIntToString(big.NewInt(15000000000)), + ServicerMinimumStake: utils.BigIntToString(big.NewInt(15000000000)), ServicerMaxChains: 15, ServicerUnstakingBlocks: 2016, ServicerMinimumPauseBlocks: 4, ServicerMaxPauseBlocks: 672, ServicersPerSession: 24, - FishermanMinimumStake: converters.BigIntToString(big.NewInt(15000000000)), + FishermanMinimumStake: utils.BigIntToString(big.NewInt(15000000000)), FishermanMaxChains: 15, FishermanUnstakingBlocks: 2016, FishermanMinimumPauseBlocks: 4, FishermanMaxPauseBlocks: 672, - ValidatorMinimumStake: converters.BigIntToString(big.NewInt(15000000000)), + ValidatorMinimumStake: utils.BigIntToString(big.NewInt(15000000000)), ValidatorUnstakingBlocks: 2016, ValidatorMinimumPauseBlocks: 4, ValidatorMaxPauseBlocks: 672, @@ -43,38 +42,37 @@ func DefaultParams() *genesis.Params { ProposerPercentageOfFees: 10, MissedBlocksBurnPercentage: 1, DoubleSignBurnPercentage: 5, - MessageDoubleSignFee: converters.BigIntToString(big.NewInt(10000)), - MessageSendFee: converters.BigIntToString(big.NewInt(10000)), - MessageStakeFishermanFee: converters.BigIntToString(big.NewInt(10000)), - MessageEditStakeFishermanFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnstakeFishermanFee: converters.BigIntToString(big.NewInt(10000)), - MessagePauseFishermanFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnpauseFishermanFee: converters.BigIntToString(big.NewInt(10000)), - MessageFishermanPauseServicerFee: converters.BigIntToString(big.NewInt(10000)), - MessageTestScoreFee: converters.BigIntToString(big.NewInt(10000)), - MessageProveTestScoreFee: converters.BigIntToString(big.NewInt(10000)), - MessageStakeAppFee: converters.BigIntToString(big.NewInt(10000)), - MessageEditStakeAppFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnstakeAppFee: converters.BigIntToString(big.NewInt(10000)), - MessagePauseAppFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnpauseAppFee: converters.BigIntToString(big.NewInt(10000)), - MessageStakeValidatorFee: converters.BigIntToString(big.NewInt(10000)), - MessageEditStakeValidatorFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnstakeValidatorFee: converters.BigIntToString(big.NewInt(10000)), - MessagePauseValidatorFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnpauseValidatorFee: converters.BigIntToString(big.NewInt(10000)), - MessageStakeServicerFee: converters.BigIntToString(big.NewInt(10000)), - MessageEditStakeServicerFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnstakeServicerFee: converters.BigIntToString(big.NewInt(10000)), - MessagePauseServicerFee: converters.BigIntToString(big.NewInt(10000)), - MessageUnpauseServicerFee: converters.BigIntToString(big.NewInt(10000)), - MessageChangeParameterFee: converters.BigIntToString(big.NewInt(10000)), + MessageDoubleSignFee: utils.BigIntToString(big.NewInt(10000)), + MessageSendFee: utils.BigIntToString(big.NewInt(10000)), + MessageStakeFishermanFee: utils.BigIntToString(big.NewInt(10000)), + MessageEditStakeFishermanFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnstakeFishermanFee: utils.BigIntToString(big.NewInt(10000)), + MessagePauseFishermanFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnpauseFishermanFee: utils.BigIntToString(big.NewInt(10000)), + MessageFishermanPauseServicerFee: utils.BigIntToString(big.NewInt(10000)), + MessageTestScoreFee: utils.BigIntToString(big.NewInt(10000)), + MessageProveTestScoreFee: utils.BigIntToString(big.NewInt(10000)), + MessageStakeAppFee: utils.BigIntToString(big.NewInt(10000)), + MessageEditStakeAppFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnstakeAppFee: utils.BigIntToString(big.NewInt(10000)), + MessagePauseAppFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnpauseAppFee: utils.BigIntToString(big.NewInt(10000)), + MessageStakeValidatorFee: utils.BigIntToString(big.NewInt(10000)), + MessageEditStakeValidatorFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnstakeValidatorFee: utils.BigIntToString(big.NewInt(10000)), + MessagePauseValidatorFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnpauseValidatorFee: utils.BigIntToString(big.NewInt(10000)), + MessageStakeServicerFee: utils.BigIntToString(big.NewInt(10000)), + MessageEditStakeServicerFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnstakeServicerFee: utils.BigIntToString(big.NewInt(10000)), + MessagePauseServicerFee: utils.BigIntToString(big.NewInt(10000)), + MessageUnpauseServicerFee: utils.BigIntToString(big.NewInt(10000)), + MessageChangeParameterFee: utils.BigIntToString(big.NewInt(10000)), AclOwner: DefaultParamsOwner.Address().String(), BlocksPerSessionOwner: DefaultParamsOwner.Address().String(), AppMinimumStakeOwner: DefaultParamsOwner.Address().String(), AppMaxChainsOwner: DefaultParamsOwner.Address().String(), - AppBaselineStakeRateOwner: DefaultParamsOwner.Address().String(), - AppStakingAdjustmentOwner: DefaultParamsOwner.Address().String(), + AppSessionTokensMultiplierOwner: DefaultParamsOwner.Address().String(), AppUnstakingBlocksOwner: DefaultParamsOwner.Address().String(), AppMinimumPauseBlocksOwner: DefaultParamsOwner.Address().String(), AppMaxPausedBlocksOwner: DefaultParamsOwner.Address().String(), diff --git a/runtime/test_artifacts/keygenerator/keygen.go b/runtime/test_artifacts/keygen/keygen.go similarity index 98% rename from runtime/test_artifacts/keygenerator/keygen.go rename to runtime/test_artifacts/keygen/keygen.go index c55377051..de8fead11 100644 --- a/runtime/test_artifacts/keygenerator/keygen.go +++ b/runtime/test_artifacts/keygen/keygen.go @@ -1,4 +1,4 @@ -package keygenerator +package keygen import ( "bytes" diff --git a/runtime/test_artifacts/util.go b/runtime/test_artifacts/util.go index f1c46669f..94e7097a6 100644 --- a/runtime/test_artifacts/util.go +++ b/runtime/test_artifacts/util.go @@ -50,9 +50,9 @@ func SetupPostgresDocker() (*dockertest.Pool, *dockertest.Resource, string) { log.Fatalf("***Make sure your docker daemon is running!!*** Could not start resource: %s\n", err.Error()) } hostAndPort := resource.GetHostPort("5432/tcp") - databaseUrl := fmt.Sprintf(connStringFormat, user, password, hostAndPort, db) + databaseURL := fmt.Sprintf(connStringFormat, user, password, hostAndPort, db) - log.Println("Connecting to database on url: ", databaseUrl) + log.Println("Connecting to database on url: ", databaseURL) c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) @@ -71,7 +71,7 @@ func SetupPostgresDocker() (*dockertest.Pool, *dockertest.Resource, string) { poolRetryChan := make(chan struct{}, 1) retryConnectFn := func() error { - _, err := pgx.Connect(context.Background(), databaseUrl) + _, err := pgx.Connect(context.Background(), databaseURL) if err != nil { return fmt.Errorf("unable to connect to database: %v", err) } @@ -86,10 +86,10 @@ func SetupPostgresDocker() (*dockertest.Pool, *dockertest.Resource, string) { // Wait for a successful DB connection <-poolRetryChan - return pool, resource, databaseUrl + return pool, resource, databaseURL } -// TODO(drewsky): Currently exposed only for testing purposes. +// TECHDEBT: Only exposed for test purposes because the utility module is dependant on the implementation of the persistence module func CleanupPostgresDocker(_ *testing.M, pool *dockertest.Pool, resource *dockertest.Resource) { // You can't defer this because `os.Exit`` doesn't care for defer if err := pool.Purge(resource); err != nil { diff --git a/shared/CHANGELOG.md b/shared/CHANGELOG.md index 56839c35a..4ccfe6ecd 100644 --- a/shared/CHANGELOG.md +++ b/shared/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.36] - 2023-02-28 + +- Move `StakeStatus` into `actor.proto` +- Rename `generic_param` into `service_url` +- Remove unused params from `BlockHeader` +- Document `transaction.proto` and move it from the `utility` module to `shared` +- Moved `signature.go` from the `utility` module to `shared` +- Added documentation to important functions in the `Persistence` and `Utility` shared modules +- Added documentation on how/why `UnstakingActor` should be removed + ## [0.0.0.35] - 2023-02-28 - Implement SLIP-0010 specification for HD child key derivation @@ -26,7 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.0.0.31] - 2023-02-22 -- Export consensus module's ConsensusDebugModule interface. +- Export consensus module's ConsensusDebugModule interface. ## [0.0.0.30] - 2023-02-21 diff --git a/shared/core/types/actor.go b/shared/core/types/actor.go index 79fa21999..9fabc6176 100644 --- a/shared/core/types/actor.go +++ b/shared/core/types/actor.go @@ -1,7 +1,5 @@ package types -// REFACTOR: Evaluate a way to define an interface for the actors which would enable to easily -// remove all the `switch actorType` statements in the codebase. func (a ActorType) GetName() string { return ActorType_name[int32(a)] } diff --git a/shared/core/types/proto/actor.proto b/shared/core/types/proto/actor.proto index 275e6e75d..e6d0bbdee 100644 --- a/shared/core/types/proto/actor.proto +++ b/shared/core/types/proto/actor.proto @@ -12,12 +12,22 @@ enum ActorType { ACTOR_TYPE_VAL = 4; } +enum StakeStatus { + UnknownStatus = 0; + Unstaking = 1; + Staked = 2; + Unstaked = 3; +} + +// TODO(#555): Investigate ways of having actor specific params that are not part of the shared struct. message Actor { ActorType actor_type = 1; string address = 2; string public_key = 3; - repeated string chains = 4; - string generic_param = 5; // TODO(#313): Generalize `GenericParam` to a different name + repeated string chains = 4; // Not applicable to `Validator` actors + // proto-gen-c does not support `go_name` at the time of writing resulting + // in the output go field being snakeCase: ServiceUrl (https://github.com/golang/protobuf/issues/555) + string service_url = 5; // Not applicable to `Application` actors string staked_amount = 6; int64 paused_height = 7; int64 unstaking_height = 8; diff --git a/shared/core/types/proto/block.proto b/shared/core/types/proto/block.proto index b8b92e943..c4ee88cdf 100644 --- a/shared/core/types/proto/block.proto +++ b/shared/core/types/proto/block.proto @@ -9,19 +9,11 @@ import "google/protobuf/timestamp.proto"; message BlockHeader { uint64 height = 1; string networkId = 2; // used to differentiate what network the chain is on (Tendermint legacy) - string stateHash = 3; - string prevStateHash = 4; // The stateHash of the block at height-1 - bytes proposerAddress = 5; // The proposer of this block; TODO: Change this to an string - bytes quorumCertificate = 6; // The quorum certificate containing signature from 2/3+ validators at height - - // INVESTIGATE(#361): Decide if we need `transactionsHash` given that it is captured in the `transactionsTree`. - bytes transactionsHash = 7; // The hash of all the transactions in the block - - // TECHDEBT: Re-evaluate whether we want/need these fields (copied over from Tendermint's structures) - // at all. They were added earlier on in the implementation but might not be needed at all. - google.protobuf.Timestamp time = 8; - uint32 numTxs = 9; // Num txs in this block (Tendermint legacy) - int64 totalTxs = 10; // Total in the entire chain Num (Tendermint legacy) + string stateHash = 3; // the state committment at this blocks height + string prevStateHash = 4; // the state committment at this block height-1 + bytes proposerAddress = 5; // the address of the proposer of this block; TECHDEBT: Change this to an string + bytes quorumCertificate = 6; // the quorum certificate containing signature from 2/3+ validators at this height + google.protobuf.Timestamp timestampt = 7; // CONSIDERATION: Is this needed? } message Block { diff --git a/shared/core/types/proto/transaction.proto b/shared/core/types/proto/transaction.proto new file mode 100644 index 000000000..35b748ea9 --- /dev/null +++ b/shared/core/types/proto/transaction.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package core; + +option go_package = "github.com/pokt-network/pocket/shared/core/types"; + +import "google/protobuf/any.proto"; + +// Transaction is the fundamental building block of any signed state transitions (i.e. messages) +// `Transaction` is used to name the type for clarity & verbosity, but `tx` is used method signatures +// and variable names to be concise. https://github.com/pokt-network/pocket/pull/503 +message Transaction { + + // The message to be signed is intentionally an `Any` type, since it is up to the module to + // define the exact message type, its contents and validation protocol. + google.protobuf.Any msg = 1; + + // A one-time nonce to avoid replay previous transaction. + string nonce = 2; + + // The signature must sign the `Transaction` protobuf containing both the `msg` and `nonce` with + // a nil signature. + Signature signature = 3; // The signature +} + +// CONSOLIDATE: Consolidate with other signature types throughout the codebase (e.g. consensus) +message Signature { + bytes public_key = 1; + bytes signature = 2; +} \ No newline at end of file diff --git a/shared/core/types/signature.go b/shared/core/types/signature.go new file mode 100644 index 000000000..b7f07d8f9 --- /dev/null +++ b/shared/core/types/signature.go @@ -0,0 +1,13 @@ +package types + +import "fmt" + +func (s *Signature) ValidateBasic() error { + if s.Signature == nil { + return fmt.Errorf("signature cannot be empty") + } + if s.PublicKey == nil { + return fmt.Errorf("public key cannot be empty") + } + return nil +} diff --git a/utility/types/transaction.go b/shared/core/types/transaction.go similarity index 57% rename from utility/types/transaction.go rename to shared/core/types/transaction.go index f80601043..3bc233f4a 100644 --- a/utility/types/transaction.go +++ b/shared/core/types/transaction.go @@ -2,48 +2,50 @@ package types import ( "bytes" + "fmt" "github.com/pokt-network/pocket/shared/codec" "github.com/pokt-network/pocket/shared/crypto" + "google.golang.org/protobuf/proto" ) -func TxFromBytes(txProtoBytes []byte) (*Transaction, Error) { +var _ ITransaction = &Transaction{} + +// TxFromBytes unmarshals a proto serialized Transaction to a Transaction protobuf +func TxFromBytes(txProtoBz []byte) (*Transaction, error) { tx := &Transaction{} - if err := codec.GetCodec().Unmarshal(txProtoBytes, tx); err != nil { - return nil, ErrUnmarshalTransaction(err) + if err := codec.GetCodec().Unmarshal(txProtoBz, tx); err != nil { + return nil, err } return tx, nil } -func TxHash(txProtoBytes []byte) string { - return crypto.GetHashStringFromBytes(txProtoBytes) +// TxHash returns the hash of the proto marshaled transaction +func TxHash(txProtoBz []byte) string { + return crypto.GetHashStringFromBytes(txProtoBz) } -var ( - _ Validatable = &Transaction{} - _ ITransaction = &Transaction{} -) - // `ITransaction` is an interface that helps capture the functions added to the `Transaction` data structure. // It is unlikely for there to be multiple implementations of this interface in prod. type ITransaction interface { - GetMessage() (Message, Error) - Sign(privateKey crypto.PrivateKey) Error - Hash() (string, Error) + GetMessage() (proto.Message, error) + Sign(privateKey crypto.PrivateKey) error + Hash() (string, error) SignableBytes() ([]byte, error) Bytes() ([]byte, error) Equals(tx2 ITransaction) bool } -func (tx *Transaction) ValidateBasic() Error { +// TODO(#556): Update this function to return pocket specific error codes. +func (tx *Transaction) ValidateBasic() error { // Nonce cannot be empty to avoid transaction replays if tx.Nonce == "" { - return ErrEmptyNonce() + return fmt.Errorf("nonce cannot be empty") // ErrEmptyNonce } // Is there a signature we can verify? if tx.Signature == nil { - return ErrEmptySignature() + return fmt.Errorf("signature cannot be empty") // ErrEmptySignature } if err := tx.Signature.ValidateBasic(); err != nil { return err @@ -52,45 +54,42 @@ func (tx *Transaction) ValidateBasic() Error { // Does the transaction have a valid key? publicKey, err := crypto.NewPublicKeyFromBytes(tx.Signature.PublicKey) if err != nil { - return ErrNewPublicKeyFromBytes(err) + return err // ErrEmptyPublicKey or ErrNewPublicKeyFromBytes } // Is there a valid msg that can be decoded? if _, err := tx.GetMessage(); err != nil { - return err + return err // ? ErrBadMessage } signBytes, err := tx.SignableBytes() if err != nil { - return ErrProtoMarshal(err) + return err // ? ErrBadSignature } + if ok := publicKey.Verify(signBytes, tx.Signature.Signature); !ok { - return ErrSignatureVerificationFailed() + return fmt.Errorf("signature verification failed") // ErrSignatureVerificationFailed } return nil } -func (tx *Transaction) GetMessage() (Message, Error) { - msg, err := codec.GetCodec().FromAny(tx.Msg) +func (tx *Transaction) GetMessage() (proto.Message, error) { + anyMsg, err := codec.GetCodec().FromAny(tx.Msg) if err != nil { - return nil, ErrProtoFromAny(err) - } - message, ok := msg.(Message) - if !ok { - return nil, ErrDecodeMessage() + return nil, err } - return message, nil + return anyMsg, nil } -func (tx *Transaction) Sign(privateKey crypto.PrivateKey) Error { +func (tx *Transaction) Sign(privateKey crypto.PrivateKey) error { txSignableBz, err := tx.SignableBytes() if err != nil { - return ErrProtoMarshal(err) + return err } signature, er := privateKey.Sign(txSignableBz) if er != nil { - return ErrTransactionSign(er) + return err } tx.Signature = &Signature{ PublicKey: privateKey.PublicKey().Bytes(), @@ -99,18 +98,18 @@ func (tx *Transaction) Sign(privateKey crypto.PrivateKey) Error { return nil } -func (tx *Transaction) Hash() (string, Error) { +func (tx *Transaction) Hash() (string, error) { txProtoBz, err := tx.Bytes() if err != nil { - return "", ErrProtoMarshal(err) + return "", err } return TxHash(txProtoBz), nil } // The bytes of the transaction that should have been signed. func (tx *Transaction) SignableBytes() ([]byte, error) { - // This is not simply `tx.Message().GetCanonicalBytes()` because the txCopy also contains - // other metadata such as the nonce which has to be part signed as well. + // All the contents of the transaction (including the nonce), with the exception of the signature + // need to be signed by the signer. txCopy := codec.GetCodec().Clone(tx).(*Transaction) txCopy.Signature = nil return codec.GetCodec().Marshal(txCopy) diff --git a/utility/types/transaction_test.go b/shared/core/types/transaction_test.go similarity index 54% rename from utility/types/transaction_test.go rename to shared/core/types/transaction_test.go index 6f5c9ec0b..73a4bbdf7 100644 --- a/utility/types/transaction_test.go +++ b/shared/core/types/transaction_test.go @@ -13,8 +13,6 @@ import ( var ( testingSenderPrivateKey, _ = crypto.GeneratePrivateKey() testingSenderPublicKey = testingSenderPrivateKey.PublicKey() - testingSenderAddr = testingSenderPublicKey.Address() - testingToAddr, _ = crypto.GenerateAddress() ) func TestTransaction_BytesAndFromBytes(t *testing.T) { @@ -35,30 +33,14 @@ func TestTransaction_BytesAndFromBytes(t *testing.T) { require.Equal(t, proto.Clone(&tx), proto.Clone(tx2), "transaction mismatch") } -func TestTransaction_GetMessage(t *testing.T) { - tx := newUnsignedTestingTransaction(t) - msg, err := tx.GetMessage() - require.NoError(t, err) - - expected := newTestingMsgSend(t) - require.NotEqual(t, expected, msg) - require.Equal(t, msg.ProtoReflect().Type(), expected.ProtoReflect().Type()) - - messageSend := msg.(*MessageSend) - expectedMessageSend := expected.(*MessageSend) - require.Equal(t, messageSend.Amount, expectedMessageSend.Amount, "unequal messages") - require.Equal(t, messageSend.FromAddress, expectedMessageSend.FromAddress, "unequal messages") - require.Equal(t, messageSend.ToAddress, expectedMessageSend.ToAddress, "unequal messages") -} - func TestTransaction_Sign(t *testing.T) { tx := newUnsignedTestingTransaction(t) err := tx.Sign(testingSenderPrivateKey) require.NoError(t, err) - msg, er := tx.SignableBytes() - require.NoError(t, er) + msg, err := tx.SignableBytes() + require.NoError(t, err) verified := testingSenderPublicKey.Verify(msg, tx.Signature.Signature) require.True(t, verified, "signature should be verified") @@ -69,53 +51,44 @@ func TestTransaction_ValidateBasic(t *testing.T) { err := tx.Sign(testingSenderPrivateKey) require.NoError(t, err) - er := tx.ValidateBasic() - require.NoError(t, er) + err = tx.ValidateBasic() + require.NoError(t, err) txNoNonce := proto.Clone(&tx).(*Transaction) txNoNonce.Nonce = "" - er = txNoNonce.ValidateBasic() - require.Equal(t, ErrEmptyNonce().Code(), er.Code()) + err = txNoNonce.ValidateBasic() + require.Error(t, err) txInvalidMessageAny := proto.Clone(&tx).(*Transaction) txInvalidMessageAny.Msg = nil - er = txInvalidMessageAny.ValidateBasic() - require.Equal(t, ErrProtoFromAny(er).Code(), er.Code()) + err = txInvalidMessageAny.ValidateBasic() + require.Error(t, err) txEmptySig := proto.Clone(&tx).(*Transaction) txEmptySig.Signature = nil - er = txEmptySig.ValidateBasic() - require.Equal(t, ErrEmptySignature().Code(), er.Code()) + err = txEmptySig.ValidateBasic() + require.Error(t, err) txEmptyPublicKey := proto.Clone(&tx).(*Transaction) txEmptyPublicKey.Signature.PublicKey = nil - er = txEmptyPublicKey.ValidateBasic() - require.Equal(t, ErrEmptyPublicKey().Code(), er.Code()) + err = txEmptyPublicKey.ValidateBasic() + require.Error(t, err) txInvalidPublicKey := proto.Clone(&tx).(*Transaction) txInvalidPublicKey.Signature.PublicKey = []byte("publickey") err = txInvalidPublicKey.ValidateBasic() - require.Equal(t, ErrNewPublicKeyFromBytes(err).Code(), err.Code()) + require.Error(t, err) txInvalidSignature := proto.Clone(&tx).(*Transaction) tx.Signature.PublicKey = testingSenderPublicKey.Bytes() - txInvalidSignature.Signature.Signature = []byte("signature") - er = txInvalidSignature.ValidateBasic() - require.Equal(t, ErrSignatureVerificationFailed().Code(), er.Code()) -} - -func newTestingMsgSend(_ *testing.T) Message { - return &MessageSend{ - FromAddress: testingSenderAddr, - ToAddress: testingToAddr, - Amount: defaultAmount, - } + txInvalidSignature.Signature.Signature = []byte("signature2") + err = txInvalidSignature.ValidateBasic() + require.Error(t, err) } func newUnsignedTestingTransaction(t *testing.T) Transaction { - msg := newTestingMsgSend(t) - - anyMsg, err := codec.GetCodec().ToAny(msg) + txMsg := &Transaction{} + anyMsg, err := codec.GetCodec().ToAny(txMsg) require.NoError(t, err) return Transaction{ diff --git a/shared/crypto/ed25519.go b/shared/crypto/ed25519.go index 9d1cd66a0..4f9007ca1 100644 --- a/shared/crypto/ed25519.go +++ b/shared/crypto/ed25519.go @@ -149,7 +149,7 @@ func NewPublicKey(hexString string) (PublicKey, error) { func NewPublicKeyFromBytes(bz []byte) (PublicKey, error) { bzLen := len(bz) if bzLen != ed25519.PublicKeySize { - return nil, ErrInvalidPublicKeyLen(bzLen) + return nil, ErrInvalidPublicKeyLen(bzLen) } return Ed25519PublicKey(bz), nil } diff --git a/shared/messaging/events.go b/shared/messaging/events.go index ecaf6c0d1..cbb9c2c48 100644 --- a/shared/messaging/events.go +++ b/shared/messaging/events.go @@ -1,7 +1,11 @@ package messaging const ( + // Node NodeStartedEventType = "pocket.NodeStartedEvent" ConsensusNewHeightEventType = "pocket.ConsensusNewHeightEvent" StateMachineTransitionEventType = "pocket.StateMachineTransitionEvent" + + // Utility + TxGossipMessageContentType = "utility.TxGossipMessage" ) diff --git a/shared/messaging/messages_test.go b/shared/messaging/messages_test.go index 9e6b12254..d80c650eb 100644 --- a/shared/messaging/messages_test.go +++ b/shared/messaging/messages_test.go @@ -7,7 +7,6 @@ import ( "github.com/pokt-network/pocket/consensus" typesCons "github.com/pokt-network/pocket/consensus/types" "github.com/pokt-network/pocket/shared/messaging" - "github.com/pokt-network/pocket/utility" typesUtil "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -31,8 +30,8 @@ func TestPocketEnvelope_GetContentType(t *testing.T) { wantContentType: consensus.HotstuffMessageContentType, }, { - msg: &typesUtil.TransactionGossipMessage{}, - wantContentType: utility.TransactionGossipMessageContentType, + msg: &typesUtil.TxGossipMessage{}, + wantContentType: messaging.TxGossipMessageContentType, }, } diff --git a/shared/modules/persistence_module.go b/shared/modules/persistence_module.go index f31cbd43b..1da8ad40c 100644 --- a/shared/modules/persistence_module.go +++ b/shared/modules/persistence_module.go @@ -47,11 +47,15 @@ type PersistenceRWContext interface { // REFACTOR: Simplify the interface // - Add general purpose methods such as `ActorOperation(enum_actor_type, ...)` which can be use like so: `Insert(FISHERMAN, ...)` -// - Use general purpose parameter methods such as `Set(enum_gov_type, ...)` such as `Set(STAKING_ADJUSTMENT, ...)` +// - Use general purpose parameter methods such as `Set(enum_gov_type, ...)` such as `Set(STAKING_, ...)` // - Reference: https://dave.cheney.net/practical-go/presentations/gophercon-israel.html#_prefer_single_method_interfaces -// TECHDEBT: convert address and public key to string from bytes -// NOTE: There's not really a use case for a write only interface, but it abstracts and contrasts nicely against the read only context +// TECHDEBT: +// - Decouple functions that can be split into two or more independent behaviours (e.g. `SetAppStatusAndUnstakingHeightIfPausedBefore`) +// - Rename `Unstaking` to `Unbonding` where appropriate +// - convert address and public key to string from bytes + +// PersistenceWriteContext has no use-case independent of `PersistenceRWContext`, but is a useful abstraction type PersistenceWriteContext interface { // Context Operations NewSavePoint([]byte) error @@ -63,9 +67,13 @@ type PersistenceWriteContext interface { // Indexer Operations - // Block Operations - ComputeStateHash() (string, error) // Update the merkle trees, computes the new state hash, and returns it - IndexTransaction(txResult TxResult) error // TODO(#361): Look into an approach to remove `TxResult` from shared interfaces + // ComputeStateHash updates the merkle trees, computes the new state hash (i.e. state commitment) + // if the context is committed. + ComputeStateHash() (string, error) + + // Indexes the transaction using several different keys (for lookup purposes) in the key-value store + // that backs the transaction merkle tree. + IndexTransaction(txResult TxResult) error // Pool Operations AddPoolAmount(name string, amount string) error @@ -79,8 +87,8 @@ type PersistenceWriteContext interface { SetAccountAmount(address []byte, amount string) error // NOTE: same as (insert) // App Operations - InsertApp(address []byte, publicKey []byte, output []byte, paused bool, status int32, maxRelays string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error - UpdateApp(address []byte, maxRelaysToAdd string, amount string, chainsToUpdate []string) error + InsertApp(address []byte, publicKey []byte, output []byte, paused bool, status int32, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error + UpdateApp(address []byte, amount string, chainsToUpdate []string) error SetAppStakeAmount(address []byte, stakeAmount string) error SetAppUnstakingHeightAndStatus(address []byte, unstakingHeight int64, status int32) error SetAppStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight int64, status int32) error @@ -106,11 +114,9 @@ type PersistenceWriteContext interface { InsertValidator(address []byte, publicKey []byte, output []byte, paused bool, status int32, serviceURL string, stakedTokens string, pausedHeight int64, unstakingHeight int64) error UpdateValidator(address []byte, serviceURL string, amount string) error SetValidatorStakeAmount(address []byte, stakeAmount string) error - // IMPROVE: Decouple and/or rename these functions SetValidatorUnstakingHeightAndStatus(address []byte, unstakingHeight int64, status int32) error SetValidatorsStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight int64, status int32) error SetValidatorPauseHeight(address []byte, height int64) error - SetValidatorPauseHeightAndMissedBlocks(address []byte, pauseHeight int64, missedBlocks int) error SetValidatorMissedBlocks(address []byte, missedBlocks int) error // Param Operations diff --git a/shared/modules/tx_result.go b/shared/modules/tx_result.go new file mode 100644 index 000000000..476a31779 --- /dev/null +++ b/shared/modules/tx_result.go @@ -0,0 +1,25 @@ +package modules + +// TxResult is a hydrated/blown-up version of a `Transaction` proto`. +// +// It is the result of a transaction on which basic validation has been applied, and from which the +// embedded Message, and its contents, were deserialized and extracted. +// +// `TxResult` is not a `coreTypes` since it does not directly affect the state hash, but is used for +// cross-module (i.e. shared) communication. It can be seen as a convenience struct that avoids the +// needs to query the BlockStore or deserialize Transaction protos every time a single piece of metadata +// of an applied transaction is needed. +type TxResult interface { + GetTx() []byte // a serialized `Transaction` proto + GetHeight() int64 // the block height at which the transaction was included + GetIndex() int32 // the transaction's index within the block (i.e. ordered by when the proposer received it in the mempool) + GetResultCode() int32 // 0 is no error, otherwise corresponds to error object code; // IMPROVE: Consider using enums for the result codes + GetError() string // description of the error if the result code is non-zero; IMPROVE: Add a specific type fot he error code + GetSignerAddr() string // the address of the signer (e.g. sender) of the transaction + GetRecipientAddr() string // Optional: the address of the recipient of the transaction (if applicable) + GetMessageType() string // the message type contained in the transaction; must correspond to a proto that the node can can process (e.g. Stake, Unstake, Send, etc...) // IMPROVE: How do we document all the types? + Bytes() ([]byte, error) // returns the serialized `TxResult` + FromBytes([]byte) (TxResult, error) // returns the deserialized `TxResult` + Hash() ([]byte, error) // the hash of the TxResult bytes + HashFromBytes([]byte) ([]byte, error) // same operation as `Hash`, but avoid re-serializing the tx +} diff --git a/shared/modules/types.go b/shared/modules/types.go deleted file mode 100644 index 9b4c984f5..000000000 --- a/shared/modules/types.go +++ /dev/null @@ -1,18 +0,0 @@ -package modules - -// The result of executing a transaction against the blockchain state so that it is included in the block - -type TxResult interface { - GetTx() []byte // the transaction object primitive - GetHeight() int64 // the height at which the tx was applied - GetIndex() int32 // the transaction's index within the block (i.e. ordered by when the proposer received it in the mempool) - GetResultCode() int32 // 0 is no error, otherwise corresponds to error object code; // IMPROVE: Add a specific type fot he result code - GetError() string // can be empty; IMPROVE: Add a specific type fot he error code - GetSignerAddr() string // get the address of who signed (i.e. sent) the transaction - GetRecipientAddr() string // get the address of who received the transaction; may be empty - GetMessageType() string // corresponds to type of message (validator-stake, app-unjail, node-stake, etc) // IMPROVE: Add an enum for message types - Hash() ([]byte, error) // the hash of the tx bytes - HashFromBytes([]byte) ([]byte, error) // same operation as `Hash`, but avoid re-serializing the tx - Bytes() ([]byte, error) // returns the serialized transaction bytes - FromBytes([]byte) (TxResult, error) // returns the deserialized transaction result -} diff --git a/shared/modules/types/proto/unstaking_actor.proto b/shared/modules/types/proto/unstaking_actor.proto index 33f2b95f2..e387d204b 100644 --- a/shared/modules/types/proto/unstaking_actor.proto +++ b/shared/modules/types/proto/unstaking_actor.proto @@ -4,8 +4,10 @@ package modules; option go_package = "github.com/pokt-network/pocket/shared/modules/types"; -// TECHDEBT: Identify if the codebase can be simplified by removing this protobuf altogether in -// exchange for using actor.proto. If not, move it into coreTypes. +// TECHDEBT: Remove this interface from `shared/modules` and use the `Actor` protobuf type instead +// There will need to be some documentation or indicator that the Actor struct returned may not be +// fully hydrated. Alternatively, we could eat the performance cost and just hydrate the entire struct +// which may be simpler and clearer. message UnstakingActor { string address = 1; string stake_amount = 2; diff --git a/shared/modules/utility_module.go b/shared/modules/utility_module.go index 464fbb4cc..b3843c2a8 100644 --- a/shared/modules/utility_module.go +++ b/shared/modules/utility_module.go @@ -7,22 +7,28 @@ import ( "google.golang.org/protobuf/types/known/anypb" ) -const UtilityModuleName = "utility" +const ( + UtilityModuleName = "utility" +) + +// TECHDEBT: Replace []byte with semantic type (addresses, transactions, etc...) type UtilityModule interface { Module - // General purpose handler of utility specific messages that are not externalized in shared directories - HandleMessage(*anypb.Any) error - - // Creates a `utilityContext` with an underlying read-write `persistenceContext`; only 1 of which can exist at a time + // NewContext creates a `utilityContext` with an underlying read-write `persistenceContext` (only 1 of which can exist at a time) NewContext(height int64) (UtilityContext, error) - // Basic Transaction validation. - // SIDE EFFECT: Transaction is added to the utility's module mempool if valid to be repeated in the future; not obvious from the functional name. - CheckTransaction(tx []byte) error + // HandleTransaction does basic `Transaction` validation & adds it to the utility's module mempool if valid + HandleTransaction(tx []byte) error + // GetMempool returns the utility module's mempool of transactions gossiped throughout the network GetMempool() mempool.TXMempool + + // HandleUtilityMessage is a general purpose handler of utility-specific messages used for utility-specific business logic. + // It is useful for handling messages from the utility module's of other nodes that do not directly affect the state. + // IMPROVE: Find opportunities to break this apart as the module matures. + HandleUtilityMessage(*anypb.Any) error } // TECHDEBT: `CreateAndApplyProposalBlock` and `ApplyBlock` should be be refactored into a @@ -30,33 +36,32 @@ type UtilityModule interface { // The context within which the node can operate with the utility layer. type UtilityContext interface { - // Block operations - - // This function is intended to be called by any type of node during state transitions. - // For example, both block proposers and replicas/verifiers will use it to create a - // context (before finalizing it) during consensus, and all verifiers will call it during state sync. - // TODO: Replace []byte with semantic type + // SetProposalBlock updates the utility context with the proposed state transition. + // It does not apply, validate or commit the changes. + // For example, it can be use during state sync to set a proposed state transition before validation. + // TODO: Investigate a way to potentially simplify the interface by removing this function. SetProposalBlock(blockHash string, proposerAddr []byte, txs [][]byte) error - // Reaps the mempool for transactions to be proposed in a new block, and applies them to this - // context. + + // CreateAndApplyProposalBlock reaps the mempool for txs to be proposed in a new block, and + // applies them to this context after validation. // Only intended to be used by the block proposer. - // TODO: Replace []byte with semantic type CreateAndApplyProposalBlock(proposer []byte, maxTxBytes int) (stateHash string, txs [][]byte, err error) - // Applies the proposed local state (i.e. the transactions in the current context). + + // ApplyBlock applies the context's in-memory proposed state (i.e. the txs in this context). // Only intended to be used by the block verifiers (i.e. replicas). ApplyBlock() (stateHash string, err error) - // Context operations - - // Releases the utility context and any underlying contexts it references + // Release releases this utility context and any underlying contexts it references Release() error - // Commit the current utility context (along with its underlying persistence context) to disk + + // Commit commits this utility context along with any underlying contexts (e.g. persistenceContext) it references Commit(quorumCert []byte) error - // Returns the read-write persistence context initialized by this utility context - GetPersistenceContext() PersistenceRWContext } -// TECHDEBT: Remove this interface from `shared/modules` +// TECHDEBT: Remove this interface from `shared/modules` and use the `Actor` protobuf type instead +// There will need to be some documentation or indicator that the Actor struct returned may not be +// fully hydrated. Alternatively, we could eat the performance cost and just hydrate the entire struct +// which may be simpler and clearer. type UnstakingActor interface { GetAddress() []byte GetOutputAddress() []byte diff --git a/shared/node.go b/shared/node.go index 971a6ecf0..66c533aeb 100644 --- a/shared/node.go +++ b/shared/node.go @@ -126,6 +126,8 @@ func (m *Node) GetBus() modules.Bus { return m.bus } +// TECHDEBT: The `shared` package has dependencies on types in the individual modules. +// TODO: Move all message types this is dependant on to the `messaging` package func (node *Node) handleEvent(message *messaging.PocketEnvelope) error { contentType := message.GetContentType() switch contentType { @@ -138,8 +140,8 @@ func (node *Node) handleEvent(message *messaging.PocketEnvelope) error { return node.GetBus().GetConsensusModule().HandleMessage(message.Content) case consensus.StateSyncMessageContentType: return node.GetBus().GetConsensusModule().HandleStateSyncMessage(message.Content) - case utility.TransactionGossipMessageContentType: - return node.GetBus().GetUtilityModule().HandleMessage(message.Content) + case messaging.TxGossipMessageContentType: + return node.GetBus().GetUtilityModule().HandleUtilityMessage(message.Content) case messaging.DebugMessageEventType: return node.handleDebugMessage(message) case messaging.ConsensusNewHeightEventType, messaging.StateMachineTransitionEventType: diff --git a/shared/converters/file_utils.go b/shared/utils/file_utils.go similarity index 98% rename from shared/converters/file_utils.go rename to shared/utils/file_utils.go index bfc0f9d1d..ad373b08f 100644 --- a/shared/converters/file_utils.go +++ b/shared/utils/file_utils.go @@ -1,4 +1,4 @@ -package converters +package utils import ( "errors" diff --git a/shared/converters/util.go b/shared/utils/num_utils.go similarity index 66% rename from shared/converters/util.go rename to shared/utils/num_utils.go index 666595316..caecf73fb 100644 --- a/shared/converters/util.go +++ b/shared/utils/num_utils.go @@ -1,4 +1,4 @@ -package converters +package utils import ( "encoding/binary" @@ -7,20 +7,29 @@ import ( ) const ( - defaultDenomination = 10 + numericBase = 10 ) func StringToBigInt(s string) (*big.Int, error) { b := big.Int{} - i, ok := b.SetString(s, defaultDenomination) + i, ok := b.SetString(s, numericBase) if !ok { return nil, fmt.Errorf("unable to SetString() with base 10") } return i, nil } +func StringToBigFloat(s string) (*big.Float, error) { + b := big.Float{} + f, ok := b.SetString(s) + if !ok { + return nil, fmt.Errorf("unable to SetString() on float") + } + return f, nil +} + func BigIntToString(b *big.Int) string { - return b.Text(defaultDenomination) + return b.Text(numericBase) } func BigIntLessThan(a, b *big.Int) bool { diff --git a/shared/converters/num_utils_test.go b/shared/utils/num_utils_test.go similarity index 94% rename from shared/converters/num_utils_test.go rename to shared/utils/num_utils_test.go index 9f8ea4851..655974bc0 100644 --- a/shared/converters/num_utils_test.go +++ b/shared/utils/num_utils_test.go @@ -1,4 +1,4 @@ -package converters +package utils import ( "math/big" diff --git a/utility/account.go b/utility/account.go index 50ba875d4..19988904f 100644 --- a/utility/account.go +++ b/utility/account.go @@ -1,25 +1,26 @@ package utility +// Internal business logic for `Accounts` & `Pools` (i.e. autonomous accounts owned by the protocol) +// +// Accounts are utility module structures that resemble currency holding vehicles; e.g. a bank account. +// Pools are autonomous accounts owned by the protocol; e.g. an account for a fee pool that gets distributed + import ( "math/big" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/shared/utils" "github.com/pokt-network/pocket/utility/types" typesUtil "github.com/pokt-network/pocket/utility/types" ) -// 'Accounts' are utility module structures that resemble currency holding vehicles; e.g. a bank account. +// Accounts specific functionality func (u *utilityContext) getAccountAmount(address []byte) (*big.Int, types.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } - amountStr, err := store.GetAccountAmount(address, height) + amountStr, err := u.store.GetAccountAmount(address, u.height) if err != nil { return nil, typesUtil.ErrGetAccountAmount(err) } - amount, err := converters.StringToBigInt(amountStr) + amount, err := utils.StringToBigInt(amountStr) if err != nil { return nil, typesUtil.ErrStringToBigInt(err) } @@ -27,45 +28,43 @@ func (u *utilityContext) getAccountAmount(address []byte) (*big.Int, types.Error } func (u *utilityContext) addAccountAmount(address []byte, amountToAdd *big.Int) types.Error { - if err := u.Store().AddAccountAmount(address, converters.BigIntToString(amountToAdd)); err != nil { + if err := u.store.AddAccountAmount(address, utils.BigIntToString(amountToAdd)); err != nil { return types.ErrAddAccountAmount(err) } return nil } func (u *utilityContext) subtractAccountAmount(address []byte, amountToSubtract *big.Int) types.Error { - if err := u.Store().SubtractAccountAmount(address, converters.BigIntToString(amountToSubtract)); err != nil { + if err := u.store.SubtractAccountAmount(address, utils.BigIntToString(amountToSubtract)); err != nil { return types.ErrSetAccountAmount(err) } return nil } func (u *utilityContext) setAccountAmount(address []byte, amount *big.Int) types.Error { - if err := u.Store().SetAccountAmount(address, converters.BigIntToString(amount)); err != nil { + if err := u.store.SetAccountAmount(address, utils.BigIntToString(amount)); err != nil { return types.ErrSetAccountAmount(err) } return nil } -// 'Pools' are autonomous accounts owned by the protocol; e.g. an account for a fee pool that gets distributed +// Pools specific functionality + +// IMPROVE: Pool function should accept the actual pool types rather than the `FriendlyName` string func (u *utilityContext) insertPool(name string, amount *big.Int) types.Error { - if err := u.Store().InsertPool(name, converters.BigIntToString(amount)); err != nil { + if err := u.store.InsertPool(name, utils.BigIntToString(amount)); err != nil { return types.ErrSetPool(name, err) } return nil } func (u *utilityContext) getPoolAmount(name string) (*big.Int, types.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } - amountStr, err := store.GetPoolAmount(name, height) + amountStr, err := u.store.GetPoolAmount(name, u.height) if err != nil { return nil, types.ErrGetPoolAmount(name, err) } - amount, err := converters.StringToBigInt(amountStr) + amount, err := utils.StringToBigInt(amountStr) if err != nil { return nil, types.ErrStringToBigInt(err) } @@ -73,21 +72,21 @@ func (u *utilityContext) getPoolAmount(name string) (*big.Int, types.Error) { } func (u *utilityContext) addPoolAmount(name string, amountToAdd *big.Int) types.Error { - if err := u.Store().AddPoolAmount(name, converters.BigIntToString(amountToAdd)); err != nil { + if err := u.store.AddPoolAmount(name, utils.BigIntToString(amountToAdd)); err != nil { return types.ErrAddPoolAmount(name, err) } return nil } func (u *utilityContext) subPoolAmount(name string, amountToSub *big.Int) types.Error { - if err := u.Store().SubtractPoolAmount(name, converters.BigIntToString(amountToSub)); err != nil { + if err := u.store.SubtractPoolAmount(name, utils.BigIntToString(amountToSub)); err != nil { return types.ErrSubPoolAmount(name, err) } return nil } func (u *utilityContext) setPoolAmount(name string, amount *big.Int) types.Error { - if err := u.Store().SetPoolAmount(name, converters.BigIntToString(amount)); err != nil { + if err := u.store.SetPoolAmount(name, utils.BigIntToString(amount)); err != nil { return types.ErrSetPoolAmount(name, err) } return nil diff --git a/utility/account_test.go b/utility/account_test.go index 6a06edc91..ab17d394a 100644 --- a/utility/account_test.go +++ b/utility/account_test.go @@ -6,9 +6,9 @@ import ( "sort" "testing" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" "github.com/stretchr/testify/require" ) @@ -16,7 +16,7 @@ func TestUtilityContext_AddAccountAmount(t *testing.T) { ctx := newTestingUtilityContext(t, 0) acc := getFirstTestingAccount(t, ctx) - initialAmount, err := converters.StringToBigInt(acc.GetAmount()) + initialAmount, err := utils.StringToBigInt(acc.GetAmount()) require.NoError(t, err) addAmount := big.NewInt(1) @@ -35,7 +35,7 @@ func TestUtilityContext_SubtractAccountAmount(t *testing.T) { ctx := newTestingUtilityContext(t, 0) acc := getFirstTestingAccount(t, ctx) - beforeAmount, err := converters.StringToBigInt(acc.GetAmount()) + beforeAmount, err := utils.StringToBigInt(acc.GetAmount()) require.NoError(t, err) subAmount := big.NewInt(100) @@ -69,7 +69,7 @@ func TestUtilityContext_AddPoolAmount(t *testing.T) { ctx := newTestingUtilityContext(t, 0) pool := getFirstTestingPool(t, ctx) - initialAmount, err := converters.StringToBigInt(pool.GetAmount()) + initialAmount, err := utils.StringToBigInt(pool.GetAmount()) require.NoError(t, err) addAmount := big.NewInt(1) @@ -99,7 +99,7 @@ func TestUtilityContext_SetPoolAmount(t *testing.T) { ctx := newTestingUtilityContext(t, 0) pool := getFirstTestingPool(t, ctx) - beforeAmount, err := converters.StringToBigInt(pool.GetAmount()) + beforeAmount, err := utils.StringToBigInt(pool.GetAmount()) require.NoError(t, err) expectedAfterAmount := big.NewInt(100) @@ -130,7 +130,7 @@ func TestUtilityContext_SubPoolAmount(t *testing.T) { } func getAllTestingAccounts(t *testing.T, ctx *utilityContext) []*coreTypes.Account { - accs, err := (ctx.persistenceContext).GetAllAccounts(0) + accs, err := ctx.store.GetAllAccounts(0) require.NoError(t, err) sort.Slice(accs, func(i, j int) bool { @@ -144,7 +144,7 @@ func getFirstTestingAccount(t *testing.T, ctx *utilityContext) *coreTypes.Accoun } func getAllTestingPools(t *testing.T, ctx *utilityContext) []*coreTypes.Account { - pools, err := (ctx.persistenceContext).GetAllPools(0) + pools, err := ctx.store.GetAllPools(0) require.NoError(t, err) sort.Slice(pools, func(i, j int) bool { diff --git a/utility/actor.go b/utility/actor.go index e163787e1..9147bd576 100644 --- a/utility/actor.go +++ b/utility/actor.go @@ -1,29 +1,33 @@ package utility +// Internal business logic for functionality shared across all `Actors`. +// +// An Actor is any protocol level actor that likely has something-at-stake and interacts with the +// protocol through some sort of on-chain state transitions. + import ( "math/big" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" ) -// `Actor` is the consolidated term for common functionality among the following network actors: application, fisherman, servicer, validator, etc. +// Actor setters func (u *utilityContext) setActorStakeAmount(actorType coreTypes.ActorType, addr []byte, amount *big.Int) typesUtil.Error { - store := u.Store() - amountStr := converters.BigIntToString(amount) + amountStr := utils.BigIntToString(amount) var err error switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - err = store.SetAppStakeAmount(addr, amountStr) + err = u.store.SetAppStakeAmount(addr, amountStr) case coreTypes.ActorType_ACTOR_TYPE_FISH: - err = store.SetFishermanStakeAmount(addr, amountStr) + err = u.store.SetFishermanStakeAmount(addr, amountStr) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - err = store.SetServicerStakeAmount(addr, amountStr) + err = u.store.SetServicerStakeAmount(addr, amountStr) case coreTypes.ActorType_ACTOR_TYPE_VAL: - err = store.SetValidatorStakeAmount(addr, amountStr) + err = u.store.SetValidatorStakeAmount(addr, amountStr) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } @@ -34,20 +38,17 @@ func (u *utilityContext) setActorStakeAmount(actorType coreTypes.ActorType, addr return nil } -func (u *utilityContext) setActorUnstakingHeight(actorType coreTypes.ActorType, addr []byte, height int64) typesUtil.Error { - store := u.Store() - unstakingStatus := int32(typesUtil.StakeStatus_Unstaking) - +func (u *utilityContext) setActorUnbondingHeight(actorType coreTypes.ActorType, addr []byte, height int64) typesUtil.Error { var err error switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - err = store.SetAppUnstakingHeightAndStatus(addr, height, unstakingStatus) + err = u.store.SetAppUnstakingHeightAndStatus(addr, height, int32(coreTypes.StakeStatus_Unstaking)) case coreTypes.ActorType_ACTOR_TYPE_FISH: - err = store.SetFishermanUnstakingHeightAndStatus(addr, height, unstakingStatus) + err = u.store.SetFishermanUnstakingHeightAndStatus(addr, height, int32(coreTypes.StakeStatus_Unstaking)) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - err = store.SetServicerUnstakingHeightAndStatus(addr, height, unstakingStatus) + err = u.store.SetServicerUnstakingHeightAndStatus(addr, height, int32(coreTypes.StakeStatus_Unstaking)) case coreTypes.ActorType_ACTOR_TYPE_VAL: - err = store.SetValidatorUnstakingHeightAndStatus(addr, height, unstakingStatus) + err = u.store.SetValidatorUnstakingHeightAndStatus(addr, height, int32(coreTypes.StakeStatus_Unstaking)) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } @@ -59,18 +60,16 @@ func (u *utilityContext) setActorUnstakingHeight(actorType coreTypes.ActorType, } func (u *utilityContext) setActorPausedHeight(actorType coreTypes.ActorType, addr []byte, height int64) typesUtil.Error { - store := u.Store() - var err error switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - err = store.SetAppPauseHeight(addr, height) + err = u.store.SetAppPauseHeight(addr, height) case coreTypes.ActorType_ACTOR_TYPE_FISH: - err = store.SetFishermanPauseHeight(addr, height) + err = u.store.SetFishermanPauseHeight(addr, height) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - err = store.SetServicerPauseHeight(addr, height) + err = u.store.SetServicerPauseHeight(addr, height) case coreTypes.ActorType_ACTOR_TYPE_VAL: - err = store.SetValidatorPauseHeight(addr, height) + err = u.store.SetValidatorPauseHeight(addr, height) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } @@ -81,22 +80,21 @@ func (u *utilityContext) setActorPausedHeight(actorType coreTypes.ActorType, add return nil } -func (u *utilityContext) getActorStakeAmount(actorType coreTypes.ActorType, addr []byte) (*big.Int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } +// Actor getters +func (u *utilityContext) getActorStakeAmount(actorType coreTypes.ActorType, addr []byte) (*big.Int, typesUtil.Error) { var stakeAmount string + var err error + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - stakeAmount, err = store.GetAppStakeAmount(height, addr) + stakeAmount, err = u.store.GetAppStakeAmount(u.height, addr) case coreTypes.ActorType_ACTOR_TYPE_FISH: - stakeAmount, err = store.GetFishermanStakeAmount(height, addr) + stakeAmount, err = u.store.GetFishermanStakeAmount(u.height, addr) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - stakeAmount, err = store.GetServicerStakeAmount(height, addr) + stakeAmount, err = u.store.GetServicerStakeAmount(u.height, addr) case coreTypes.ActorType_ACTOR_TYPE_VAL: - stakeAmount, err = store.GetValidatorStakeAmount(height, addr) + stakeAmount, err = u.store.GetValidatorStakeAmount(u.height, addr) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } @@ -105,7 +103,7 @@ func (u *utilityContext) getActorStakeAmount(actorType coreTypes.ActorType, addr return nil, typesUtil.ErrGetStakeAmount(err) } - amount, err := converters.StringToBigInt(stakeAmount) + amount, err := utils.StringToBigInt(stakeAmount) if err != nil { return nil, typesUtil.ErrStringToBigInt(err) } @@ -114,11 +112,6 @@ func (u *utilityContext) getActorStakeAmount(actorType coreTypes.ActorType, addr } func (u *utilityContext) getMaxAllowedPausedBlocks(actorType coreTypes.ActorType) (int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - var paramName string switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: @@ -133,20 +126,15 @@ func (u *utilityContext) getMaxAllowedPausedBlocks(actorType coreTypes.ActorType return 0, typesUtil.ErrUnknownActorType(actorType.String()) } - maxPausedBlocks, err := store.GetIntParam(paramName, height) + maxPausedBlocks, err := u.store.GetIntParam(paramName, u.height) if err != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetParam(paramName, err) + return 0, typesUtil.ErrGetParam(paramName, err) } return maxPausedBlocks, nil } func (u *utilityContext) getMinRequiredPausedBlocks(actorType coreTypes.ActorType) (int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - var paramName string switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: @@ -161,78 +149,68 @@ func (u *utilityContext) getMinRequiredPausedBlocks(actorType coreTypes.ActorTyp return 0, typesUtil.ErrUnknownActorType(actorType.String()) } - minPausedBlocks, er := store.GetIntParam(paramName, height) + minPausedBlocks, er := u.store.GetIntParam(paramName, u.height) if er != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetParam(paramName, er) + return 0, typesUtil.ErrGetParam(paramName, er) } return minPausedBlocks, nil } func (u *utilityContext) getPausedHeightIfExists(actorType coreTypes.ActorType, addr []byte) (int64, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - var pauseHeight int64 + var err error + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - pauseHeight, err = store.GetAppPauseHeightIfExists(addr, height) + pauseHeight, err = u.store.GetAppPauseHeightIfExists(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_FISH: - pauseHeight, err = store.GetFishermanPauseHeightIfExists(addr, height) + pauseHeight, err = u.store.GetFishermanPauseHeightIfExists(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - pauseHeight, err = store.GetServicerPauseHeightIfExists(addr, height) + pauseHeight, err = u.store.GetServicerPauseHeightIfExists(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_VAL: - pauseHeight, err = store.GetValidatorPauseHeightIfExists(addr, height) + pauseHeight, err = u.store.GetValidatorPauseHeightIfExists(addr, u.height) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } if err != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetPauseHeight(err) + return 0, typesUtil.ErrGetPauseHeight(err) } return pauseHeight, nil } -func (u *utilityContext) getActorStatus(actorType coreTypes.ActorType, addr []byte) (typesUtil.StakeStatus, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - +func (u *utilityContext) getActorStatus(actorType coreTypes.ActorType, addr []byte) (coreTypes.StakeStatus, typesUtil.Error) { var status int32 + var err error + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - status, err = store.GetAppStatus(addr, height) + status, err = u.store.GetAppStatus(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_FISH: - status, err = store.GetFishermanStatus(addr, height) + status, err = u.store.GetFishermanStatus(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - status, err = store.GetServicerStatus(addr, height) + status, err = u.store.GetServicerStatus(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_VAL: - status, err = store.GetValidatorStatus(addr, height) + status, err = u.store.GetValidatorStatus(addr, u.height) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } if err != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetStatus(err) + return coreTypes.StakeStatus_UnknownStatus, typesUtil.ErrGetStatus(err) } - if _, ok := typesUtil.StakeStatus_name[status]; !ok { - return typesUtil.ZeroInt, typesUtil.ErrUnknownStatus(status) + if _, ok := coreTypes.StakeStatus_name[status]; !ok { + return coreTypes.StakeStatus_UnknownStatus, typesUtil.ErrUnknownStatus(status) } - return typesUtil.StakeStatus(status), nil + return coreTypes.StakeStatus(status), nil } func (u *utilityContext) getMinRequiredStakeAmount(actorType coreTypes.ActorType) (*big.Int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } - var paramName string + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: paramName = typesUtil.AppMinimumStakeParamName @@ -246,12 +224,12 @@ func (u *utilityContext) getMinRequiredStakeAmount(actorType coreTypes.ActorType return nil, typesUtil.ErrUnknownActorType(actorType.String()) } - minStake, er := store.GetStringParam(paramName, height) + minStake, er := u.store.GetStringParam(paramName, u.height) if er != nil { return nil, typesUtil.ErrGetParam(paramName, er) } - amount, err := converters.StringToBigInt(minStake) + amount, err := utils.StringToBigInt(minStake) if err != nil { return nil, typesUtil.ErrStringToBigInt(err) } @@ -259,13 +237,8 @@ func (u *utilityContext) getMinRequiredStakeAmount(actorType coreTypes.ActorType } func (u *utilityContext) getUnbondingHeight(actorType coreTypes.ActorType) (int64, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - var paramName string - var unstakingBlocksPeriod int + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: paramName = typesUtil.AppUnstakingBlocksParamName @@ -279,20 +252,15 @@ func (u *utilityContext) getUnbondingHeight(actorType coreTypes.ActorType) (int6 return 0, typesUtil.ErrUnknownActorType(actorType.String()) } - unstakingBlocksPeriod, err = store.GetIntParam(paramName, height) + unstakingBlocksPeriod, err := u.store.GetIntParam(paramName, u.height) if err != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetParam(paramName, err) + return 0, typesUtil.ErrGetParam(paramName, err) } return u.height + int64(unstakingBlocksPeriod), nil } func (u *utilityContext) getMaxAllowedChains(actorType coreTypes.ActorType) (int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - var paramName string switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: @@ -305,7 +273,7 @@ func (u *utilityContext) getMaxAllowedChains(actorType coreTypes.ActorType) (int return 0, typesUtil.ErrUnknownActorType(actorType.String()) } - maxChains, err := store.GetIntParam(paramName, height) + maxChains, err := u.store.GetIntParam(paramName, u.height) if err != nil { return 0, typesUtil.ErrGetParam(paramName, err) } @@ -314,21 +282,18 @@ func (u *utilityContext) getMaxAllowedChains(actorType coreTypes.ActorType) (int } func (u *utilityContext) getActorExists(actorType coreTypes.ActorType, addr []byte) (bool, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return false, typesUtil.ErrGetHeight(err) - } - var exists bool + var err error + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - exists, err = store.GetAppExists(addr, height) + exists, err = u.store.GetAppExists(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_FISH: - exists, err = store.GetFishermanExists(addr, height) + exists, err = u.store.GetFishermanExists(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - exists, err = store.GetServicerExists(addr, height) + exists, err = u.store.GetServicerExists(addr, u.height) case coreTypes.ActorType_ACTOR_TYPE_VAL: - exists, err = store.GetValidatorExists(addr, height) + exists, err = u.store.GetValidatorExists(addr, u.height) default: return false, typesUtil.ErrUnknownActorType(actorType.String()) } @@ -343,21 +308,18 @@ func (u *utilityContext) getActorExists(actorType coreTypes.ActorType, addr []by // IMPROVE: Need to re-evaluate the design of `Output Address` to support things like "rev-share" // and multiple output addresses. func (u *utilityContext) getActorOutputAddress(actorType coreTypes.ActorType, operator []byte) ([]byte, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } - var outputAddr []byte + var err error + switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - outputAddr, err = store.GetAppOutputAddress(operator, height) + outputAddr, err = u.store.GetAppOutputAddress(operator, u.height) case coreTypes.ActorType_ACTOR_TYPE_FISH: - outputAddr, err = store.GetFishermanOutputAddress(operator, height) + outputAddr, err = u.store.GetFishermanOutputAddress(operator, u.height) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - outputAddr, err = store.GetServicerOutputAddress(operator, height) + outputAddr, err = u.store.GetServicerOutputAddress(operator, u.height) case coreTypes.ActorType_ACTOR_TYPE_VAL: - outputAddr, err = store.GetValidatorOutputAddress(operator, height) + outputAddr, err = u.store.GetValidatorOutputAddress(operator, u.height) default: err = typesUtil.ErrUnknownActorType(actorType.String()) } diff --git a/utility/actor_test.go b/utility/actor_test.go index 3fc5209da..1501bf9c4 100644 --- a/utility/actor_test.go +++ b/utility/actor_test.go @@ -9,9 +9,9 @@ import ( "github.com/pokt-network/pocket/runtime/test_artifacts" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" @@ -100,7 +100,7 @@ func TestUtilityContext_HandleMessageEditStake(t *testing.T) { // Edit the staked amount amountEdited := test_artifacts.DefaultAccountAmount.Add(test_artifacts.DefaultAccountAmount, big.NewInt(1)) - amountEditedString := converters.BigIntToString(amountEdited) + amountEditedString := utils.BigIntToString(amountEdited) msgAmountEdited := codec.GetCodec().Clone(msg).(*typesUtil.MessageEditStake) msgAmountEdited.Amount = amountEditedString @@ -142,7 +142,7 @@ func TestUtilityContext_HandleMessageUnstake(t *testing.T) { default: t.Fatalf("unexpected actor type %s", actorType.String()) } - err := ctx.persistenceContext.SetParam(paramName, numUnstakingBlocks) + err := ctx.store.SetParam(paramName, numUnstakingBlocks) require.NoError(t, err, "error setting minimum pause blocks") actor := getFirstActor(t, ctx, actorType) @@ -193,7 +193,7 @@ func TestUtilityContext_HandleMessageUnpause(t *testing.T) { default: t.Fatalf("unexpected actor type %s", actorType.String()) } - err := ctx.persistenceContext.SetParam(paramName, minPauseBlocksNumber) + err := ctx.store.SetParam(paramName, minPauseBlocksNumber) require.NoError(t, err, "error setting minimum pause blocks") actor := getFirstActor(t, ctx, actorType) @@ -308,7 +308,7 @@ func TestUtilityContext_BeginUnstakingMaxPausedActors(t *testing.T) { default: t.Fatalf("unexpected actor type %s", actorType.String()) } - err := ctx.persistenceContext.SetParam(paramName, maxPausedBlocks) + err := ctx.store.SetParam(paramName, maxPausedBlocks) require.NoError(t, err) actor := getFirstActor(t, ctx, actorType) @@ -327,7 +327,7 @@ func TestUtilityContext_BeginUnstakingMaxPausedActors(t *testing.T) { // Verify that the actor is still staked status, err := ctx.getActorStatus(actorType, addrBz) require.NoError(t, err) - require.Equal(t, typesUtil.StakeStatus_Staked, status, "actor should be staked") + require.Equal(t, coreTypes.StakeStatus_Staked, status, "actor should be staked") // Start a new context when the actor still shouldn't be unstaked require.NoError(t, ctx.Commit([]byte("empty qc"))) @@ -341,7 +341,7 @@ func TestUtilityContext_BeginUnstakingMaxPausedActors(t *testing.T) { // Verify that the actor is still staked status, err = ctx.getActorStatus(actorType, addrBz) require.NoError(t, err) - require.Equal(t, typesUtil.StakeStatus_Staked, status, "actor should be staked") + require.Equal(t, coreTypes.StakeStatus_Staked, status, "actor should be staked") // Start a new context when the actor should be unstaked require.NoError(t, ctx.Release()) @@ -354,7 +354,7 @@ func TestUtilityContext_BeginUnstakingMaxPausedActors(t *testing.T) { // Verify that the actor is still staked status, err = ctx.getActorStatus(actorType, addrBz) require.NoError(t, err) - require.Equal(t, typesUtil.StakeStatus_Unstaking, status, "actor should be staked") + require.Equal(t, coreTypes.StakeStatus_Unstaking, status, "actor should be staked") }) } } @@ -400,9 +400,9 @@ func TestUtilityContext_BeginUnstakingActorsPausedBefore_UnbondUnstakingActors(t t.Fatalf("unexpected actor type %s", actorType.String()) } - er := ctx.persistenceContext.SetParam(paramName1, maxPausedBlocks) + er := ctx.store.SetParam(paramName1, maxPausedBlocks) require.NoError(t, er, "error setting max paused blocks") - er = ctx.persistenceContext.SetParam(paramName2, unstakingBlocks) + er = ctx.store.SetParam(paramName2, unstakingBlocks) require.NoError(t, er, "error setting max paused blocks") er = ctx.setPoolAmount(poolName, poolInitAMount) require.NoError(t, er) @@ -439,7 +439,7 @@ func TestUtilityContext_BeginUnstakingActorsPausedBefore_UnbondUnstakingActors(t status, err := ctx.getActorStatus(actorType, addrBz) require.NoError(t, err) - require.Equal(t, typesUtil.StakeStatus_Unstaking, status, "actor should be unstaking") + require.Equal(t, coreTypes.StakeStatus_Unstaking, status, "actor should be unstaking") // Commit the context and start a new one while the actor is still unstaking require.NoError(t, ctx.Commit([]byte("empty QC"))) @@ -447,7 +447,7 @@ func TestUtilityContext_BeginUnstakingActorsPausedBefore_UnbondUnstakingActors(t status, err = ctx.getActorStatus(actorType, addrBz) require.NoError(t, err) - require.Equal(t, typesUtil.StakeStatus_Unstaking, status, "actor should be unstaking") + require.Equal(t, coreTypes.StakeStatus_Unstaking, status, "actor should be unstaking") // Release the context since there's nothing to commit and start a new one where the actors can be unbound require.NoError(t, ctx.Release()) @@ -465,7 +465,7 @@ func TestUtilityContext_BeginUnstakingActorsPausedBefore_UnbondUnstakingActors(t amount, err = ctx.getPoolAmount(poolName) require.NoError(t, err) - stakedAmount, err := converters.StringToBigInt(actor.StakedAmount) + stakedAmount, err := utils.StringToBigInt(actor.StakedAmount) require.NoError(t, err) expectedAmount := big.NewInt(0).Sub(poolInitAMount, stakedAmount) require.Equalf(t, expectedAmount, amount, "pool amount should be unchanged for %s", poolName) @@ -473,12 +473,12 @@ func TestUtilityContext_BeginUnstakingActorsPausedBefore_UnbondUnstakingActors(t // Status should be changed from Unstaking to Unstaked status, err = ctx.getActorStatus(actorType, addrBz) require.NoError(t, err) - require.Equal(t, typesUtil.StakeStatus_Unstaked, status, "actor should be unstaking") + require.Equal(t, coreTypes.StakeStatus_Unstaked, status, "actor should be unstaking") }) } } -func TestUtilityContext_GetExists(t *testing.T) { +func TestUtilityContext_GetActorExists(t *testing.T) { for actorTypeNum := range coreTypes.ActorType_name { if actorTypeNum == 0 { // ACTOR_TYPE_UNSPECIFIED continue @@ -686,13 +686,13 @@ func getActorByAddr(t *testing.T, ctx *utilityContext, actorType coreTypes.Actor } func getAllTestingApps(t *testing.T, ctx *utilityContext) []*coreTypes.Actor { - actors, err := (ctx.persistenceContext).GetAllApps(ctx.height) + actors, err := ctx.store.GetAllApps(ctx.height) require.NoError(t, err) return actors } func getAllTestingValidators(t *testing.T, ctx *utilityContext) []*coreTypes.Actor { - actors, err := (ctx.persistenceContext).GetAllValidators(ctx.height) + actors, err := ctx.store.GetAllValidators(ctx.height) require.NoError(t, err) sort.Slice(actors, func(i, j int) bool { return actors[i].GetAddress() < actors[j].GetAddress() @@ -701,13 +701,13 @@ func getAllTestingValidators(t *testing.T, ctx *utilityContext) []*coreTypes.Act } func getAllTestingFish(t *testing.T, ctx *utilityContext) []*coreTypes.Actor { - actors, err := (ctx.persistenceContext).GetAllFishermen(ctx.height) + actors, err := ctx.store.GetAllFishermen(ctx.height) require.NoError(t, err) return actors } func getAllTestingServicers(t *testing.T, ctx *utilityContext) []*coreTypes.Actor { - actors, err := (ctx.persistenceContext).GetAllServicers(ctx.height) + actors, err := ctx.store.GetAllServicers(ctx.height) require.NoError(t, err) return actors } diff --git a/utility/application.go b/utility/application.go index 0b3d8330e..9fa253dcd 100644 --- a/utility/application.go +++ b/utility/application.go @@ -1,61 +1,32 @@ package utility +// Internal business logic for the `Application` protocol actor. +// +// An Application stakes POKT in exchange for tokens to access Web3 access provided by the servicers. + import ( - "math" "math/big" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" ) -var ( - // TECHDEBT: Re-evalute the denomination of tokens used throughout the codebase. `MillionInt` is - // currently used to convert POKT to uPOKT but this is not clear throughout the codebase. - MillionInt = big.NewFloat(1e6) -) - -// TODO(M3): Re-evaluate the implementation in this function when implementing the Application Protocol -// and rate limiting -func (u *utilityContext) calculateMaxAppRelays(appStakeStr string) (string, typesUtil.Error) { - appStakeBigInt, er := converters.StringToBigInt(appStakeStr) +// TODO(M3): This is not actively being used in any real business logic yet. +// +// calculateAppSessionTokens determines the number of "session tokens" an application gets at the beginning +// of every session. For example, 1 session token could equate to a quota of 1 relay. +func (u *utilityContext) calculateAppSessionTokens(appStakeStr string) (string, typesUtil.Error) { + appStake, er := utils.StringToBigInt(appStakeStr) if er != nil { return typesUtil.EmptyString, typesUtil.ErrStringToBigInt(er) } - stabilityAdjustment, err := u.getStabilityAdjustment() - if err != nil { - return typesUtil.EmptyString, err - } - - // INVESTIGATE: Need to understand what `baseline adjustment` is - baseRate, err := u.getBaselineAppStakeRate() + stakeToSessionTokensMultiplier, err := u.getAppSessionTokensMultiplier() if err != nil { return typesUtil.EmptyString, err } - // convert amount to float64 - appStake := big.NewFloat(float64(appStakeBigInt.Int64())) - - // get the percentage of the baseline stake rate; can be over 100% - basePercentage := big.NewFloat(float64(baseRate) / float64(100)) - - // multiply the two - baselineThroughput := basePercentage.Mul(basePercentage, appStake) - - // Convert POKT to uPOKT - baselineThroughput.Quo(baselineThroughput, MillionInt) - - // add staking adjustment; can be -ve - adjusted := baselineThroughput.Add(baselineThroughput, big.NewFloat(float64(stabilityAdjustment))) - - // truncate the integer - result, _ := adjusted.Int(nil) - - // bounding Max Amount of relays to maxint64 - max := big.NewInt(math.MaxInt64) - if i := result.Cmp(max); i < -1 { - result = max - } - - return converters.BigIntToString(result), nil + stakeToSessionTokens := big.NewInt(int64(stakeToSessionTokensMultiplier)) + sessionTokens := appStake.Mul(appStake, stakeToSessionTokens) + return sessionTokens.String(), nil } diff --git a/utility/application_test.go b/utility/application_test.go index 7cbb926d5..fd5e988cd 100644 --- a/utility/application_test.go +++ b/utility/application_test.go @@ -7,10 +7,16 @@ import ( "github.com/stretchr/testify/require" ) +const ( + DefaultAppSessionTokens = "100000000000000" +) + func TestUtilityContext_CalculateMaxAppRelays(t *testing.T) { ctx := newTestingUtilityContext(t, 1) actor := getFirstActor(t, ctx, coreTypes.ActorType_ACTOR_TYPE_APP) - newMaxRelays, err := ctx.calculateMaxAppRelays(actor.GetStakedAmount()) + appSessionTokens, err := ctx.calculateAppSessionTokens(actor.StakedAmount) require.NoError(t, err) - require.Equal(t, actor.GetGenericParam(), newMaxRelays) + // TODO: These are hardcoded values based on params from the genesis file. Expand on tests + // when implementing the Application protocol. + require.Equal(t, DefaultAppSessionTokens, appSessionTokens) } diff --git a/utility/block.go b/utility/block.go index 0f587a702..fb72f9ac4 100644 --- a/utility/block.go +++ b/utility/block.go @@ -1,95 +1,95 @@ package utility +// Internal business logic containing the lifecycle of Block-related operations + import ( "encoding/hex" - "fmt" "math/big" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" moduleTypes "github.com/pokt-network/pocket/shared/modules/types" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" ) -// This 'block' file contains all the lifecycle block operations. - -// The ApplyBlock function is the 'main' operation that executes a 'block' object against the state. - -// Pocket Network adopt a Tendermint-like lifecycle of BeginBlock -> DeliverTx -> EndBlock in that -// order. Like the name suggests, BeginBlock is an autonomous state operation that executes at the -// beginning of every block DeliverTx individually applies each transaction against the state and -// rolls it back (not yet implemented) if fails. Like BeginBlock, EndBlock is an autonomous state -// operation that executes at the end of every block. - -// TODO: Make sure to call `utility.CheckTransaction`, which calls `persistence.TransactionExists` +// CreateAndApplyProposalBlock implements the exposed functionality of the shared UtilityContext interface. func (u *utilityContext) CreateAndApplyProposalBlock(proposer []byte, maxTransactionBytes int) (stateHash string, txs [][]byte, err error) { - lastBlockByzantineVals, err := u.getLastBlockByzantineValidators() + prevBlockByzantineVals, err := u.prevBlockByzantineValidators() if err != nil { return "", nil, err } + // begin block lifecycle phase - if err := u.beginBlock(lastBlockByzantineVals); err != nil { + if err := u.beginBlock(prevBlockByzantineVals); err != nil { return "", nil, err } txs = make([][]byte, 0) - totalTxsSizeInBytes := 0 - txIndex := 0 + txsTotalBz := 0 + txIdx := 0 - mempool := u.getBus().GetUtilityModule().GetMempool() + mempool := u.GetBus().GetUtilityModule().GetMempool() for !mempool.IsEmpty() { - txBytes, err := mempool.PopTx() + // NB: In order for transactions to have entered the mempool, `HandleTransaction` must have + // been called which handles basic checks & validation. + txBz, err := mempool.PopTx() if err != nil { return "", nil, err } - tx, err := typesUtil.TxFromBytes(txBytes) + + tx, err := coreTypes.TxFromBytes(txBz) if err != nil { return "", nil, err } - txTxsSizeInBytes := len(txBytes) - totalTxsSizeInBytes += txTxsSizeInBytes - if totalTxsSizeInBytes >= maxTransactionBytes { + + txBzSize := len(txBz) + txsTotalBz += txBzSize + + // Exceeding maximum transaction bytes to be added in this block + if txsTotalBz >= maxTransactionBytes { // Add back popped tx to be applied in a future block - err := mempool.AddTx(txBytes) - if err != nil { + if err := mempool.AddTx(txBz); err != nil { return "", nil, err } break // we've reached our max } - txResult, err := u.applyTx(txIndex, tx) + + txResult, err := u.hydrateTxResult(tx, txIdx) if err != nil { u.logger.Err(err).Msg("Error in ApplyTransaction") // TODO(#327): Properly implement 'unhappy path' for save points if err := u.revertLastSavePoint(); err != nil { return "", nil, err } - totalTxsSizeInBytes -= txTxsSizeInBytes + txsTotalBz -= txBzSize continue } - if err := u.persistenceContext.IndexTransaction(txResult); err != nil { - u.logger.Fatal().Err(err).Msgf("TODO(#327): We can apply the transaction but not index it. Crash the process for now: %v\n", err) + + // Index the transaction + if err := u.store.IndexTransaction(txResult); err != nil { + u.logger.Fatal().Err(err).Msgf("TODO(#327): The transaction can by hydrated but not indexed. Crash the process for now: %v\n", err) } - txs = append(txs, txBytes) - txIndex++ + txs = append(txs, txBz) + txIdx++ } if err := u.endBlock(proposer); err != nil { return "", nil, err } - // return the app hash (consensus module will get the validator set directly) - stateHash, err = u.persistenceContext.ComputeStateHash() + + // Compute & return the new state hash + stateHash, err = u.store.ComputeStateHash() if err != nil { u.logger.Fatal().Err(err).Msg("Updating the app hash failed. TODO: Look into roll-backing the entire commit...") } - u.logger.Info().Msgf("CreateAndApplyProposalBlock - computed state hash: %s", stateHash) + u.logger.Info().Str("state_hash", stateHash).Msgf("CreateAndApplyProposalBlock finished successfully") return stateHash, txs, err } -// TODO: Make sure to call `utility.CheckTransaction`, which calls `persistence.TransactionExists` // CLEANUP: code re-use ApplyBlock() for CreateAndApplyBlock() func (u *utilityContext) ApplyBlock() (string, error) { - lastByzantineValidators, err := u.getLastBlockByzantineValidators() + lastByzantineValidators, err := u.prevBlockByzantineValidators() if err != nil { return "", err } @@ -99,9 +99,11 @@ func (u *utilityContext) ApplyBlock() (string, error) { return "", err } + mempool := u.GetBus().GetUtilityModule().GetMempool() + // deliver txs lifecycle phase for index, txProtoBytes := range u.proposalBlockTxs { - tx, err := typesUtil.TxFromBytes(txProtoBytes) + tx, err := coreTypes.TxFromBytes(txProtoBytes) if err != nil { return "", err } @@ -113,20 +115,29 @@ func (u *utilityContext) ApplyBlock() (string, error) { // Or wait until the entire lifecycle is over to evaluate an 'invalid' block // Validate and apply the transaction to the Postgres database - txResult, err := u.applyTx(index, tx) + txResult, err := u.hydrateTxResult(tx, index) if err != nil { return "", err } - if err := u.persistenceContext.IndexTransaction(txResult); err != nil { - u.logger.Fatal().Err(err).Msgf("TODO(#327): We can apply the transaction but not index it. Crash the process for now: %v\n", err) + txHash, err := tx.Hash() + if err != nil { + return "", err + } + + // TODO: Need to properly add transactions back on rollbacks + if mempool.Contains(txHash) { + if err := mempool.RemoveTx(txProtoBytes); err != nil { + return "", err + } + u.logger.Info().Str("tx_hash", txHash).Msg("Applying tx that WAS in the local mempool") + } else { + u.logger.Info().Str("tx_hash", txHash).Msg("Applying tx that WAS NOT in the local mempool") } - // TODO: if found, remove transaction from mempool. - // DISCUSS: What if the context is rolled back or cancelled. Do we add it back to the mempool? - // if err := u.Mempool.RemoveTx(tx); err != nil { - // return nil, err - // } + if err := u.store.IndexTransaction(txResult); err != nil { + u.logger.Fatal().Err(err).Msgf("TODO(#327): We can apply the transaction but not index it. Crash the process for now: %v\n", err) + } } // end block lifecycle phase @@ -134,7 +145,7 @@ func (u *utilityContext) ApplyBlock() (string, error) { return "", err } // return the app hash (consensus module will get the validator set directly) - stateHash, err := u.persistenceContext.ComputeStateHash() + stateHash, err := u.store.ComputeStateHash() if err != nil { u.logger.Fatal().Err(err).Msg("Updating the app hash failed. TODO: Look into roll-backing the entire commit...") return "", typesUtil.ErrAppHash(err) @@ -149,6 +160,7 @@ func (u *utilityContext) beginBlock(previousBlockByzantineValidators [][]byte) t if err := u.handleByzantineValidators(previousBlockByzantineValidators); err != nil { return err } + // INCOMPLETE: Identify what else needs to be done in the begin block lifecycle phase return nil } @@ -157,74 +169,81 @@ func (u *utilityContext) endBlock(proposer []byte) typesUtil.Error { if err := u.handleProposerRewards(proposer); err != nil { return err } + // unstake actors that have been 'unstaking' for the UnstakingBlocks if err := u.unbondUnstakingActors(); err != nil { return err } + // begin unstaking the actors who have been paused for MaxPauseBlocks if err := u.beginUnstakingMaxPausedActors(); err != nil { return err } + + // INCOMPLETE: Identify what else needs to be done in the begin block lifecycle phase return nil } -// handleByzantineValidators handles the validators who either didn't sign at all or disagreed with the 2/3+ majority -func (u *utilityContext) handleByzantineValidators(lastBlockByzantineValidators [][]byte) typesUtil.Error { - maxMissedBlocks, err := u.getValidatorMaxMissedBlocks() +func (u *utilityContext) handleProposerRewards(proposer []byte) typesUtil.Error { + feePoolName := coreTypes.Pools_POOLS_FEE_COLLECTOR.FriendlyName() + feesAndRewardsCollected, err := u.getPoolAmount(feePoolName) if err != nil { return err } - for _, address := range lastBlockByzantineValidators { - numberOfMissedBlocks, err := u.getValidatorMissedBlocks(address) - if err != nil { - return err - } - // increment missed blocks - numberOfMissedBlocks++ - // handle if over the threshold - if numberOfMissedBlocks >= maxMissedBlocks { - // pause the validator and reset missed blocks - if err := u.pauseValidatorAndSetMissedBlocks(address, u.height, int(typesUtil.HeightNotUsed)); err != nil { - return err - } - // burn validator for missing blocks - burnPercentage, err := u.getMissedBlocksBurnPercentage() - if err != nil { - return err - } - if err := u.burnValidator(burnPercentage, address); err != nil { - return err - } - } else if err := u.setValidatorMissedBlocks(address, numberOfMissedBlocks); err != nil { - return err - } + + // Nullify the rewards pool + if err := u.setPoolAmount(feePoolName, big.NewInt(0)); err != nil { + return err + } + + // + proposerCutPercentage, err := u.getProposerPercentageOfFees() + if err != nil { + return err + } + + daoCutPercentage := 100 - proposerCutPercentage + if daoCutPercentage < 0 || daoCutPercentage > 100 { + return typesUtil.ErrInvalidProposerCutPercentage() + } + + amountToProposerFloat := new(big.Float).SetInt(feesAndRewardsCollected) + amountToProposerFloat.Mul(amountToProposerFloat, big.NewFloat(float64(proposerCutPercentage))) + amountToProposerFloat.Quo(amountToProposerFloat, big.NewFloat(100)) + amountToProposer, _ := amountToProposerFloat.Int(nil) + amountToDAO := feesAndRewardsCollected.Sub(feesAndRewardsCollected, amountToProposer) + if err := u.addAccountAmount(proposer, amountToProposer); err != nil { + return err + } + if err := u.addPoolAmount(coreTypes.Pools_POOLS_DAO.FriendlyName(), amountToDAO); err != nil { + return err } return nil } func (u *utilityContext) unbondUnstakingActors() (err typesUtil.Error) { - var er error - store := u.Store() for actorTypeNum := range coreTypes.ActorType_name { if actorTypeNum == 0 { // ACTOR_TYPE_UNSPECIFIED continue } actorType := coreTypes.ActorType(actorTypeNum) - var readyToUnstake []*moduleTypes.UnstakingActor + var readyToUnbond []*moduleTypes.UnstakingActor var poolName string + + var er error switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - readyToUnstake, er = store.GetAppsReadyToUnstake(u.height, int32(typesUtil.StakeStatus_Unstaking)) + readyToUnbond, er = u.store.GetAppsReadyToUnstake(u.height, int32(coreTypes.StakeStatus_Unstaking)) poolName = coreTypes.Pools_POOLS_APP_STAKE.FriendlyName() case coreTypes.ActorType_ACTOR_TYPE_FISH: - readyToUnstake, er = store.GetFishermenReadyToUnstake(u.height, int32(typesUtil.StakeStatus_Unstaking)) + readyToUnbond, er = u.store.GetFishermenReadyToUnstake(u.height, int32(coreTypes.StakeStatus_Unstaking)) poolName = coreTypes.Pools_POOLS_FISHERMAN_STAKE.FriendlyName() case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - readyToUnstake, er = store.GetServicersReadyToUnstake(u.height, int32(typesUtil.StakeStatus_Unstaking)) + readyToUnbond, er = u.store.GetServicersReadyToUnstake(u.height, int32(coreTypes.StakeStatus_Unstaking)) poolName = coreTypes.Pools_POOLS_SERVICER_STAKE.FriendlyName() case coreTypes.ActorType_ACTOR_TYPE_VAL: - readyToUnstake, er = store.GetValidatorsReadyToUnstake(u.height, int32(typesUtil.StakeStatus_Unstaking)) + readyToUnbond, er = u.store.GetValidatorsReadyToUnstake(u.height, int32(coreTypes.StakeStatus_Unstaking)) poolName = coreTypes.Pools_POOLS_VALIDATOR_STAKE.FriendlyName() case coreTypes.ActorType_ACTOR_TYPE_UNSPECIFIED: continue @@ -232,17 +251,18 @@ func (u *utilityContext) unbondUnstakingActors() (err typesUtil.Error) { if er != nil { return typesUtil.ErrGetReadyToUnstake(er) } - for _, actor := range readyToUnstake { - if poolName == coreTypes.Pools_POOLS_VALIDATOR_STAKE.FriendlyName() { - fmt.Println("unstaking validator", actor.StakeAmount) - } - stakeAmount, er := converters.StringToBigInt(actor.StakeAmount) - if er != nil { - return typesUtil.ErrStringToBigInt(er) + + // Loop through all unstaking actors and unbond those that have reached the waiting period, + // move their stake from the pool back to the corresponding account. + for _, actor := range readyToUnbond { + stakeAmount, err := utils.StringToBigInt(actor.StakeAmount) + if err != nil { + return typesUtil.ErrStringToBigInt(err) } - outputAddrBz, er := hex.DecodeString(actor.OutputAddress) - if er != nil { - return typesUtil.ErrHexDecodeFromString(er) + + outputAddrBz, err := hex.DecodeString(actor.OutputAddress) + if err != nil { + return typesUtil.ErrHexDecodeFromString(err) } if err := u.subPoolAmount(poolName, stakeAmount); err != nil { @@ -253,6 +273,7 @@ func (u *utilityContext) unbondUnstakingActors() (err typesUtil.Error) { } } } + return nil } @@ -282,21 +303,21 @@ func (u *utilityContext) beginUnstakingMaxPausedActors() (err typesUtil.Error) { } func (u *utilityContext) beginUnstakingActorsPausedBefore(pausedBeforeHeight int64, actorType coreTypes.ActorType) (err typesUtil.Error) { - var er error - store := u.Store() unbondingHeight, err := u.getUnbondingHeight(actorType) if err != nil { return err } + + var er error switch actorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - er = store.SetAppStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(typesUtil.StakeStatus_Unstaking)) + er = u.store.SetAppStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(coreTypes.StakeStatus_Unstaking)) case coreTypes.ActorType_ACTOR_TYPE_FISH: - er = store.SetFishermanStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(typesUtil.StakeStatus_Unstaking)) + er = u.store.SetFishermanStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(coreTypes.StakeStatus_Unstaking)) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - er = store.SetServicerStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(typesUtil.StakeStatus_Unstaking)) + er = u.store.SetServicerStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(coreTypes.StakeStatus_Unstaking)) case coreTypes.ActorType_ACTOR_TYPE_VAL: - er = store.SetValidatorsStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(typesUtil.StakeStatus_Unstaking)) + er = u.store.SetValidatorsStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unbondingHeight, int32(coreTypes.StakeStatus_Unstaking)) } if er != nil { return typesUtil.ErrSetStatusPausedBefore(er, pausedBeforeHeight) @@ -304,70 +325,7 @@ func (u *utilityContext) beginUnstakingActorsPausedBefore(pausedBeforeHeight int return nil } -func (u *utilityContext) handleProposerRewards(proposer []byte) typesUtil.Error { - feePoolName := coreTypes.Pools_POOLS_FEE_COLLECTOR.FriendlyName() - feesAndRewardsCollected, err := u.getPoolAmount(feePoolName) - if err != nil { - return err - } - if err := u.setPoolAmount(feePoolName, big.NewInt(0)); err != nil { - return err - } - proposerCutPercentage, err := u.getProposerPercentageOfFees() - if err != nil { - return err - } - daoCutPercentage := 100 - proposerCutPercentage - if daoCutPercentage < 0 || daoCutPercentage > 100 { - return typesUtil.ErrInvalidProposerCutPercentage() - } - amountToProposerFloat := new(big.Float).SetInt(feesAndRewardsCollected) - amountToProposerFloat.Mul(amountToProposerFloat, big.NewFloat(float64(proposerCutPercentage))) - amountToProposerFloat.Quo(amountToProposerFloat, big.NewFloat(100)) - amountToProposer, _ := amountToProposerFloat.Int(nil) - amountToDAO := feesAndRewardsCollected.Sub(feesAndRewardsCollected, amountToProposer) - if err := u.addAccountAmount(proposer, amountToProposer); err != nil { - return err - } - if err := u.addPoolAmount(coreTypes.Pools_POOLS_DAO.FriendlyName(), amountToDAO); err != nil { - return err - } - return nil -} - -// TODO: Need to design & document this business logic. -func (u *utilityContext) getValidatorMissedBlocks(address []byte) (int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - missedBlocks, er := store.GetValidatorMissedBlocks(address, height) - if er != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetMissedBlocks(er) - } - return missedBlocks, nil -} - -// TODO: Need to design & document this business logic. -func (u *utilityContext) pauseValidatorAndSetMissedBlocks(address []byte, pauseHeight int64, missedBlocks int) typesUtil.Error { - store := u.Store() - if err := store.SetValidatorPauseHeightAndMissedBlocks(address, pauseHeight, missedBlocks); err != nil { - return typesUtil.ErrSetPauseHeight(err) - } - return nil -} - -// TODO: Need to design & document this business logic. -func (u *utilityContext) setValidatorMissedBlocks(address []byte, missedBlocks int) typesUtil.Error { - store := u.Store() - er := store.SetValidatorMissedBlocks(address, missedBlocks) - if er != nil { - return typesUtil.ErrSetMissedBlocks(er) - } - return nil -} - // TODO: Need to design & document this business logic. -func (u *utilityContext) getLastBlockByzantineValidators() ([][]byte, error) { +func (u *utilityContext) prevBlockByzantineValidators() ([][]byte, error) { return nil, nil } diff --git a/utility/context.go b/utility/context.go index 7ebdcc26d..11df37706 100644 --- a/utility/context.go +++ b/utility/context.go @@ -4,93 +4,85 @@ import ( "encoding/hex" "github.com/pokt-network/pocket/shared/modules" + "github.com/pokt-network/pocket/shared/modules/base_modules" typesUtil "github.com/pokt-network/pocket/utility/types" ) -type utilityContext struct { - bus modules.Bus - height int64 +var ( + _ modules.IntegratableModule = &utilityContext{} + _ modules.UtilityContext = &utilityContext{} +) - persistenceContext modules.PersistenceRWContext - savePointsSet map[string]struct{} - savePointsList [][]byte +type utilityContext struct { + base_modules.IntegratableModule logger *modules.Logger + height int64 + + store modules.PersistenceRWContext + savePointsSet map[string]struct{} + savePointsList [][]byte // TECHDEBT: Consolidate all these types with the shared Protobuf struct and create a `proposalBlock` - proposalProposerAddr []byte proposalStateHash string + proposalProposerAddr []byte proposalBlockTxs [][]byte } func (u *utilityModule) NewContext(height int64) (modules.UtilityContext, error) { - ctx, err := u.GetBus().GetPersistenceModule().NewRWContext(height) + persistenceCtx, err := u.GetBus().GetPersistenceModule().NewRWContext(height) if err != nil { return nil, typesUtil.ErrNewPersistenceContext(err) } - return &utilityContext{ - bus: u.GetBus(), - height: height, - logger: u.logger, - persistenceContext: ctx, - savePointsList: make([][]byte, 0), - savePointsSet: make(map[string]struct{}), - }, nil + ctx := &utilityContext{ + logger: u.logger, + height: height, + + // No save points on start + store: persistenceCtx, + savePointsList: make([][]byte, 0), + savePointsSet: make(map[string]struct{}), + } + ctx.IntegratableModule.SetBus(u.GetBus()) + return ctx, nil } func (p *utilityContext) SetProposalBlock(blockHash string, proposerAddr []byte, txs [][]byte) error { - p.proposalProposerAddr = proposerAddr p.proposalStateHash = blockHash + p.proposalProposerAddr = proposerAddr p.proposalBlockTxs = txs return nil } -func (u *utilityContext) Store() modules.PersistenceRWContext { - return u.persistenceContext -} - -func (u *utilityContext) GetPersistenceContext() modules.PersistenceRWContext { - return u.persistenceContext -} - func (u *utilityContext) Commit(quorumCert []byte) error { - if err := u.persistenceContext.Commit(u.proposalProposerAddr, quorumCert); err != nil { + if err := u.store.Commit(u.proposalProposerAddr, quorumCert); err != nil { return err } - u.persistenceContext = nil + u.store = nil return nil } func (u *utilityContext) Release() error { - if u.persistenceContext == nil { + if u.store == nil { return nil } - if err := u.persistenceContext.Release(); err != nil { + if err := u.store.Release(); err != nil { return err } - u.persistenceContext = nil + u.store = nil return nil } -// TECHDEBT: We should be using the height of the context and shouldn't need to be retrieving -// -// the height from the store either for "current height" operations. -func (u *utilityContext) getStoreAndHeight() (modules.PersistenceRWContext, int64, error) { - store := u.Store() - height, err := store.GetHeight() - return store, height, err -} - // TODO: This has not been tested or investigated in detail func (u *utilityContext) revertLastSavePoint() typesUtil.Error { - if len(u.savePointsSet) == typesUtil.ZeroInt { + if len(u.savePointsSet) == 0 { return typesUtil.ErrEmptySavePoints() } var key []byte popIndex := len(u.savePointsList) - 1 key, u.savePointsList = u.savePointsList[popIndex], u.savePointsList[:popIndex] delete(u.savePointsSet, hex.EncodeToString(key)) - if err := u.persistenceContext.RollbackToSavePoint(key); err != nil { + if err := u.store.RollbackToSavePoint(key); err != nil { return typesUtil.ErrRollbackSavePoint(err) } return nil @@ -98,7 +90,7 @@ func (u *utilityContext) revertLastSavePoint() typesUtil.Error { //nolint:unused // TODO: This has not been tested or investigated in detail func (u *utilityContext) newSavePoint(txHashBz []byte) typesUtil.Error { - if err := u.persistenceContext.NewSavePoint(txHashBz); err != nil { + if err := u.store.NewSavePoint(txHashBz); err != nil { return typesUtil.ErrNewSavePoint(err) } txHash := hex.EncodeToString(txHashBz) @@ -109,19 +101,3 @@ func (u *utilityContext) newSavePoint(txHashBz []byte) typesUtil.Error { u.savePointsSet[txHash] = struct{}{} return nil } - -func (u *utilityContext) getBus() modules.Bus { - return u.bus -} - -func (u *utilityContext) setBus(bus modules.Bus) *utilityContext { - u.bus = bus - return u -} - -func (c *utilityContext) Reset() typesUtil.Error { - if err := c.persistenceContext.Release(); err != nil { - return typesUtil.ErrResetContext(err) - } - return nil -} diff --git a/utility/doc/CHANGELOG.md b/utility/doc/CHANGELOG.md index 062ed4c62..511bb340e 100644 --- a/utility/doc/CHANGELOG.md +++ b/utility/doc/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.0.31] - 2023-02-28 + +- Fixed bug where we were not removing txs from the mempool of replicas +- Added thorough documentation in different parts of the codebase +- Replace the `Store()` function with a `.store` accessor +- Removed the unnecessary `getStoreAndHeight()` function +- Simplified `calculateMaxAppRelays` to a temporary `calculateAppSessionTokens` implementation +- Improved the readability of the `Block` lifecycle and `Message` validation +- Simplified the testing utilities used +- Updated the `session` interface +- Renamed `applyTx` to `hydrateTx` and added documentation on its functionality +- Removed `DefaultTxResult` and added documentation to `TxResult` result + ## [0.0.0.30] - 2023-02-24 - Update logger value references with pointers diff --git a/utility/doc/PROTOCOL_RELAY.md b/utility/doc/PROTOCOL_RELAY.md index 43cf8c8c5..5fa9070a5 100644 --- a/utility/doc/PROTOCOL_RELAY.md +++ b/utility/doc/PROTOCOL_RELAY.md @@ -140,7 +140,7 @@ _See the [Session Protocol](https://github.com/pokt-network/pocket/blob/main/uti ### Report volume metric applicable relays to `Fisherman` 1. All volume applicable relays need to be sent to the assigned trusted `Fisherman` (selected by the [Session Protocol](https://github.com/pokt-network/pocket/blob/main/utility/doc/PROTOCOLS.md)) for a proper verification of the volume completed. -2. Send `volumeRelays` to `fishermanServiceURL` through http. +2. Send `volumeRelays` to `fishermanServiceUrl` through http. ```mermaid graph TD diff --git a/utility/doc/README.md b/utility/doc/README.md index 927d67f84..b86a835e1 100644 --- a/utility/doc/README.md +++ b/utility/doc/README.md @@ -149,7 +149,7 @@ Added governance params: And minimally satisfy the following interface: ```go -CheckTransaction(tx []byte) error +HandleTransaction(tx []byte) error GetProposalTransactions(proposer []byte, maxTransactionBytes int, lastBlockByzantineValidators [][]byte) (txs [][]byte, err error) ApplyBlock(Height int64, proposer []byte, txs [][]byte, lastBlockByzantineValidators [][]byte) (appHash []byte, err error) ``` diff --git a/utility/gov.go b/utility/gov.go index 7a6afb765..e267c4f91 100644 --- a/utility/gov.go +++ b/utility/gov.go @@ -3,27 +3,26 @@ package utility import ( "math/big" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" "google.golang.org/protobuf/types/known/wrapperspb" ) func (u *utilityContext) updateParam(paramName string, value any) typesUtil.Error { - store := u.Store() switch t := value.(type) { case *wrapperspb.Int32Value: - if err := store.SetParam(paramName, (int(t.Value))); err != nil { + if err := u.store.SetParam(paramName, (int(t.Value))); err != nil { return typesUtil.ErrUpdateParam(err) } return nil case *wrapperspb.StringValue: - if err := store.SetParam(paramName, t.Value); err != nil { + if err := u.store.SetParam(paramName, t.Value); err != nil { return typesUtil.ErrUpdateParam(err) } return nil case *wrapperspb.BytesValue: - if err := store.SetParam(paramName, t.Value); err != nil { + if err := u.store.SetParam(paramName, t.Value); err != nil { return typesUtil.ErrUpdateParam(err) } return nil @@ -34,8 +33,8 @@ func (u *utilityContext) updateParam(paramName string, value any) typesUtil.Erro return typesUtil.ErrUnknownParam(paramName) } -func (u *utilityContext) getParameter(paramName string, height int64) (any, error) { - return u.Store().GetParameter(paramName, height) +func (u *utilityContext) getParameter(paramName string) (any, error) { + return u.store.GetParameter(paramName, u.height) } func (u *utilityContext) getAppMinimumStake() (*big.Int, typesUtil.Error) { @@ -46,12 +45,8 @@ func (u *utilityContext) getAppMaxChains() (int, typesUtil.Error) { return u.getIntParam(typesUtil.AppMaxChainsParamName) } -func (u *utilityContext) getBaselineAppStakeRate() (int, typesUtil.Error) { - return u.getIntParam(typesUtil.AppBaselineStakeRateParamName) -} - -func (u *utilityContext) getStabilityAdjustment() (int, typesUtil.Error) { - return u.getIntParam(typesUtil.AppStakingAdjustmentParamName) +func (u *utilityContext) getAppSessionTokensMultiplier() (int, typesUtil.Error) { + return u.getIntParam(typesUtil.AppSessionTokensMultiplierParamName) } func (u *utilityContext) getAppUnstakingBlocks() (int64, typesUtil.Error) { @@ -254,227 +249,219 @@ func (u *utilityContext) getParamOwner(paramName string) ([]byte, error) { // DISCUSS (@deblasis): here we could potentially leverage the struct tags in gov.proto by specifying an `owner` key // eg: `app_minimum_stake` could have `pokt:"owner=app_minimum_stake_owner"` // in here we would use that map to point to the owner, removing this switch, centralizing the logic and making it declarative - store, height, er := u.getStoreAndHeight() - if er != nil { - return nil, er - } switch paramName { case typesUtil.AclOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.BlocksPerSessionParamName: - return store.GetBytesParam(typesUtil.BlocksPerSessionOwner, height) + return u.store.GetBytesParam(typesUtil.BlocksPerSessionOwner, u.height) case typesUtil.AppMaxChainsParamName: - return store.GetBytesParam(typesUtil.AppMaxChainsOwner, height) + return u.store.GetBytesParam(typesUtil.AppMaxChainsOwner, u.height) case typesUtil.AppMinimumStakeParamName: - return store.GetBytesParam(typesUtil.AppMinimumStakeOwner, height) - case typesUtil.AppBaselineStakeRateParamName: - return store.GetBytesParam(typesUtil.AppBaselineStakeRateOwner, height) - case typesUtil.AppStakingAdjustmentParamName: - return store.GetBytesParam(typesUtil.AppStakingAdjustmentOwner, height) + return u.store.GetBytesParam(typesUtil.AppMinimumStakeOwner, u.height) + case typesUtil.AppSessionTokensMultiplierParamName: + return u.store.GetBytesParam(typesUtil.AppSessionTokensMultiplierOwner, u.height) case typesUtil.AppUnstakingBlocksParamName: - return store.GetBytesParam(typesUtil.AppUnstakingBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.AppUnstakingBlocksOwner, u.height) case typesUtil.AppMinimumPauseBlocksParamName: - return store.GetBytesParam(typesUtil.AppMinimumPauseBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.AppMinimumPauseBlocksOwner, u.height) case typesUtil.AppMaxPauseBlocksParamName: - return store.GetBytesParam(typesUtil.AppMaxPausedBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.AppMaxPausedBlocksOwner, u.height) case typesUtil.ServicersPerSessionParamName: - return store.GetBytesParam(typesUtil.ServicersPerSessionOwner, height) + return u.store.GetBytesParam(typesUtil.ServicersPerSessionOwner, u.height) case typesUtil.ServicerMinimumStakeParamName: - return store.GetBytesParam(typesUtil.ServicerMinimumStakeOwner, height) + return u.store.GetBytesParam(typesUtil.ServicerMinimumStakeOwner, u.height) case typesUtil.ServicerMaxChainsParamName: - return store.GetBytesParam(typesUtil.ServicerMaxChainsOwner, height) + return u.store.GetBytesParam(typesUtil.ServicerMaxChainsOwner, u.height) case typesUtil.ServicerUnstakingBlocksParamName: - return store.GetBytesParam(typesUtil.ServicerUnstakingBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ServicerUnstakingBlocksOwner, u.height) case typesUtil.ServicerMinimumPauseBlocksParamName: - return store.GetBytesParam(typesUtil.ServicerMinimumPauseBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ServicerMinimumPauseBlocksOwner, u.height) case typesUtil.ServicerMaxPauseBlocksParamName: - return store.GetBytesParam(typesUtil.ServicerMaxPausedBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ServicerMaxPausedBlocksOwner, u.height) case typesUtil.FishermanMinimumStakeParamName: - return store.GetBytesParam(typesUtil.FishermanMinimumStakeOwner, height) + return u.store.GetBytesParam(typesUtil.FishermanMinimumStakeOwner, u.height) case typesUtil.FishermanMaxChainsParamName: - return store.GetBytesParam(typesUtil.FishermanMaxChainsOwner, height) + return u.store.GetBytesParam(typesUtil.FishermanMaxChainsOwner, u.height) case typesUtil.FishermanUnstakingBlocksParamName: - return store.GetBytesParam(typesUtil.FishermanUnstakingBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.FishermanUnstakingBlocksOwner, u.height) case typesUtil.FishermanMinimumPauseBlocksParamName: - return store.GetBytesParam(typesUtil.FishermanMinimumPauseBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.FishermanMinimumPauseBlocksOwner, u.height) case typesUtil.FishermanMaxPauseBlocksParamName: - return store.GetBytesParam(typesUtil.FishermanMaxPausedBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.FishermanMaxPausedBlocksOwner, u.height) case typesUtil.ValidatorMinimumStakeParamName: - return store.GetBytesParam(typesUtil.ValidatorMinimumStakeOwner, height) + return u.store.GetBytesParam(typesUtil.ValidatorMinimumStakeOwner, u.height) case typesUtil.ValidatorUnstakingBlocksParamName: - return store.GetBytesParam(typesUtil.ValidatorUnstakingBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ValidatorUnstakingBlocksOwner, u.height) case typesUtil.ValidatorMinimumPauseBlocksParamName: - return store.GetBytesParam(typesUtil.ValidatorMinimumPauseBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ValidatorMinimumPauseBlocksOwner, u.height) case typesUtil.ValidatorMaxPausedBlocksParamName: - return store.GetBytesParam(typesUtil.ValidatorMaxPausedBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ValidatorMaxPausedBlocksOwner, u.height) case typesUtil.ValidatorMaximumMissedBlocksParamName: - return store.GetBytesParam(typesUtil.ValidatorMaximumMissedBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ValidatorMaximumMissedBlocksOwner, u.height) case typesUtil.ProposerPercentageOfFeesParamName: - return store.GetBytesParam(typesUtil.ProposerPercentageOfFeesOwner, height) + return u.store.GetBytesParam(typesUtil.ProposerPercentageOfFeesOwner, u.height) case typesUtil.ValidatorMaxEvidenceAgeInBlocksParamName: - return store.GetBytesParam(typesUtil.ValidatorMaxEvidenceAgeInBlocksOwner, height) + return u.store.GetBytesParam(typesUtil.ValidatorMaxEvidenceAgeInBlocksOwner, u.height) case typesUtil.MissedBlocksBurnPercentageParamName: - return store.GetBytesParam(typesUtil.MissedBlocksBurnPercentageOwner, height) + return u.store.GetBytesParam(typesUtil.MissedBlocksBurnPercentageOwner, u.height) case typesUtil.DoubleSignBurnPercentageParamName: - return store.GetBytesParam(typesUtil.DoubleSignBurnPercentageOwner, height) + return u.store.GetBytesParam(typesUtil.DoubleSignBurnPercentageOwner, u.height) case typesUtil.MessageDoubleSignFee: - return store.GetBytesParam(typesUtil.MessageDoubleSignFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageDoubleSignFeeOwner, u.height) case typesUtil.MessageSendFee: - return store.GetBytesParam(typesUtil.MessageSendFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageSendFeeOwner, u.height) case typesUtil.MessageStakeFishermanFee: - return store.GetBytesParam(typesUtil.MessageStakeFishermanFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageStakeFishermanFeeOwner, u.height) case typesUtil.MessageEditStakeFishermanFee: - return store.GetBytesParam(typesUtil.MessageEditStakeFishermanFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageEditStakeFishermanFeeOwner, u.height) case typesUtil.MessageUnstakeFishermanFee: - return store.GetBytesParam(typesUtil.MessageUnstakeFishermanFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnstakeFishermanFeeOwner, u.height) case typesUtil.MessagePauseFishermanFee: - return store.GetBytesParam(typesUtil.MessagePauseFishermanFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessagePauseFishermanFeeOwner, u.height) case typesUtil.MessageUnpauseFishermanFee: - return store.GetBytesParam(typesUtil.MessageUnpauseFishermanFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnpauseFishermanFeeOwner, u.height) case typesUtil.MessageFishermanPauseServicerFee: - return store.GetBytesParam(typesUtil.MessageFishermanPauseServicerFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageFishermanPauseServicerFeeOwner, u.height) case typesUtil.MessageTestScoreFee: - return store.GetBytesParam(typesUtil.MessageTestScoreFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageTestScoreFeeOwner, u.height) case typesUtil.MessageProveTestScoreFee: - return store.GetBytesParam(typesUtil.MessageProveTestScoreFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageProveTestScoreFeeOwner, u.height) case typesUtil.MessageStakeAppFee: - return store.GetBytesParam(typesUtil.MessageStakeAppFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageStakeAppFeeOwner, u.height) case typesUtil.MessageEditStakeAppFee: - return store.GetBytesParam(typesUtil.MessageEditStakeAppFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageEditStakeAppFeeOwner, u.height) case typesUtil.MessageUnstakeAppFee: - return store.GetBytesParam(typesUtil.MessageUnstakeAppFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnstakeAppFeeOwner, u.height) case typesUtil.MessagePauseAppFee: - return store.GetBytesParam(typesUtil.MessagePauseAppFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessagePauseAppFeeOwner, u.height) case typesUtil.MessageUnpauseAppFee: - return store.GetBytesParam(typesUtil.MessageUnpauseAppFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnpauseAppFeeOwner, u.height) case typesUtil.MessageStakeValidatorFee: - return store.GetBytesParam(typesUtil.MessageStakeValidatorFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageStakeValidatorFeeOwner, u.height) case typesUtil.MessageEditStakeValidatorFee: - return store.GetBytesParam(typesUtil.MessageEditStakeValidatorFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageEditStakeValidatorFeeOwner, u.height) case typesUtil.MessageUnstakeValidatorFee: - return store.GetBytesParam(typesUtil.MessageUnstakeValidatorFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnstakeValidatorFeeOwner, u.height) case typesUtil.MessagePauseValidatorFee: - return store.GetBytesParam(typesUtil.MessagePauseValidatorFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessagePauseValidatorFeeOwner, u.height) case typesUtil.MessageUnpauseValidatorFee: - return store.GetBytesParam(typesUtil.MessageUnpauseValidatorFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnpauseValidatorFeeOwner, u.height) case typesUtil.MessageStakeServicerFee: - return store.GetBytesParam(typesUtil.MessageStakeServicerFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageStakeServicerFeeOwner, u.height) case typesUtil.MessageEditStakeServicerFee: - return store.GetBytesParam(typesUtil.MessageEditStakeServicerFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageEditStakeServicerFeeOwner, u.height) case typesUtil.MessageUnstakeServicerFee: - return store.GetBytesParam(typesUtil.MessageUnstakeServicerFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnstakeServicerFeeOwner, u.height) case typesUtil.MessagePauseServicerFee: - return store.GetBytesParam(typesUtil.MessagePauseServicerFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessagePauseServicerFeeOwner, u.height) case typesUtil.MessageUnpauseServicerFee: - return store.GetBytesParam(typesUtil.MessageUnpauseServicerFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageUnpauseServicerFeeOwner, u.height) case typesUtil.MessageChangeParameterFee: - return store.GetBytesParam(typesUtil.MessageChangeParameterFeeOwner, height) + return u.store.GetBytesParam(typesUtil.MessageChangeParameterFeeOwner, u.height) case typesUtil.BlocksPerSessionOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.AppMaxChainsOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.AppMinimumStakeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) - case typesUtil.AppBaselineStakeRateOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) - case typesUtil.AppStakingAdjustmentOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) + case typesUtil.AppSessionTokensMultiplierOwner: + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.AppUnstakingBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.AppMinimumPauseBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.AppMaxPausedBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ServicerMinimumStakeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ServicerMaxChainsOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ServicerUnstakingBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ServicerMinimumPauseBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ServicerMaxPausedBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ServicersPerSessionOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.FishermanMinimumStakeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.FishermanMaxChainsOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.FishermanUnstakingBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.FishermanMinimumPauseBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.FishermanMaxPausedBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ValidatorMinimumStakeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ValidatorUnstakingBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ValidatorMinimumPauseBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ValidatorMaxPausedBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ValidatorMaximumMissedBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ProposerPercentageOfFeesOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.ValidatorMaxEvidenceAgeInBlocksOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MissedBlocksBurnPercentageOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.DoubleSignBurnPercentageOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageSendFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageStakeFishermanFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageEditStakeFishermanFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnstakeFishermanFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessagePauseFishermanFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnpauseFishermanFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageFishermanPauseServicerFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageTestScoreFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageProveTestScoreFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageStakeAppFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageEditStakeAppFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnstakeAppFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessagePauseAppFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnpauseAppFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageStakeValidatorFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageEditStakeValidatorFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnstakeValidatorFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessagePauseValidatorFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnpauseValidatorFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageStakeServicerFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageEditStakeServicerFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnstakeServicerFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessagePauseServicerFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageUnpauseServicerFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) case typesUtil.MessageChangeParameterFeeOwner: - return store.GetBytesParam(typesUtil.AclOwner, height) + return u.store.GetBytesParam(typesUtil.AclOwner, u.height) default: return nil, typesUtil.ErrUnknownParam(paramName) } @@ -552,16 +539,12 @@ func (u *utilityContext) getMessageChangeParameterSignerCandidates(msg *typesUti } func (u *utilityContext) getBigIntParam(paramName string) (*big.Int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } - value, err := store.GetStringParam(paramName, height) + value, err := u.store.GetStringParam(paramName, u.height) if err != nil { u.logger.Err(err) return nil, typesUtil.ErrGetParam(paramName, err) } - amount, err := converters.StringToBigInt(value) + amount, err := utils.StringToBigInt(value) if err != nil { return nil, typesUtil.ErrStringToBigInt(err) } @@ -569,35 +552,23 @@ func (u *utilityContext) getBigIntParam(paramName string) (*big.Int, typesUtil.E } func (u *utilityContext) getIntParam(paramName string) (int, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() + value, err := u.store.GetIntParam(paramName, u.height) if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - value, err := store.GetIntParam(paramName, height) - if err != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetParam(paramName, err) + return 0, typesUtil.ErrGetParam(paramName, err) } return value, nil } func (u *utilityContext) getInt64Param(paramName string) (int64, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return 0, typesUtil.ErrGetHeight(err) - } - value, err := store.GetIntParam(paramName, height) + value, err := u.store.GetIntParam(paramName, u.height) if err != nil { - return typesUtil.ZeroInt, typesUtil.ErrGetParam(paramName, err) + return 0, typesUtil.ErrGetParam(paramName, err) } return int64(value), nil } func (u *utilityContext) getByteArrayParam(paramName string) ([]byte, typesUtil.Error) { - store, height, err := u.getStoreAndHeight() - if err != nil { - return nil, typesUtil.ErrGetHeight(err) - } - value, err := store.GetBytesParam(paramName, height) + value, err := u.store.GetBytesParam(paramName, u.height) if err != nil { return nil, typesUtil.ErrGetParam(paramName, err) } diff --git a/utility/gov_test.go b/utility/gov_test.go index 07ecd44fa..1be3a8a89 100644 --- a/utility/gov_test.go +++ b/utility/gov_test.go @@ -7,7 +7,7 @@ import ( "github.com/pokt-network/pocket/runtime/genesis" "github.com/pokt-network/pocket/runtime/test_artifacts" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/wrapperspb" @@ -43,7 +43,6 @@ func TestUtilityContext_GetAppMinimumPauseBlocks(t *testing.T) { gotParam, err := ctx.getAppMinimumPauseBlocks() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetAppMinimumStake(t *testing.T) { @@ -52,8 +51,7 @@ func TestUtilityContext_GetAppMinimumStake(t *testing.T) { defaultParam := defaultParams.GetAppMinimumStake() gotParam, err := ctx.getAppMinimumStake() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetAppUnstakingBlocks(t *testing.T) { @@ -63,27 +61,15 @@ func TestUtilityContext_GetAppUnstakingBlocks(t *testing.T) { gotParam, err := ctx.getAppUnstakingBlocks() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - -} - -func TestUtilityContext_GetBaselineAppStakeRate(t *testing.T) { - ctx := newTestingUtilityContext(t, 0) - defaultParams := DefaultTestingParams(t) - defaultParam := int(defaultParams.GetAppBaselineStakeRate()) - gotParam, err := ctx.getBaselineAppStakeRate() - require.NoError(t, err) - require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetBlocksPerSession(t *testing.T) { ctx := newTestingUtilityContext(t, 0) defaultParams := DefaultTestingParams(t) defaultParam := int(defaultParams.GetBlocksPerSession()) - gotParam, err := ctx.getParameter(typesUtil.BlocksPerSessionParamName, 0) + gotParam, err := ctx.getParameter(typesUtil.BlocksPerSessionParamName) require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetDoubleSignBurnPercentage(t *testing.T) { @@ -93,7 +79,6 @@ func TestUtilityContext_GetDoubleSignBurnPercentage(t *testing.T) { gotParam, err := ctx.getDoubleSignBurnPercentage() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetDoubleSignFeeOwner(t *testing.T) { @@ -107,7 +92,6 @@ func TestUtilityContext_GetDoubleSignFeeOwner(t *testing.T) { require.NoError(t, er) require.Equal(t, defaultParamTx, gotParam) - } func TestUtilityContext_GetFishermanMaxChains(t *testing.T) { @@ -117,7 +101,6 @@ func TestUtilityContext_GetFishermanMaxChains(t *testing.T) { gotParam, err := ctx.getFishermanMaxChains() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetFishermanMaxPausedBlocks(t *testing.T) { @@ -127,7 +110,6 @@ func TestUtilityContext_GetFishermanMaxPausedBlocks(t *testing.T) { gotParam, err := ctx.getFishermanMaxPausedBlocks() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetFishermanMinimumPauseBlocks(t *testing.T) { @@ -137,7 +119,6 @@ func TestUtilityContext_GetFishermanMinimumPauseBlocks(t *testing.T) { gotParam, err := ctx.getFishermanMinimumPauseBlocks() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetFishermanMinimumStake(t *testing.T) { @@ -146,8 +127,7 @@ func TestUtilityContext_GetFishermanMinimumStake(t *testing.T) { defaultParam := defaultParams.GetFishermanMinimumStake() gotParam, err := ctx.getFishermanMinimumStake() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetFishermanUnstakingBlocks(t *testing.T) { @@ -157,7 +137,6 @@ func TestUtilityContext_GetFishermanUnstakingBlocks(t *testing.T) { gotParam, err := ctx.getFishermanUnstakingBlocks() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetMaxEvidenceAgeInBlocks(t *testing.T) { @@ -167,7 +146,6 @@ func TestUtilityContext_GetMaxEvidenceAgeInBlocks(t *testing.T) { gotParam, err := ctx.getMaxEvidenceAgeInBlocks() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) - } func TestUtilityContext_GetMessageChangeParameterFee(t *testing.T) { @@ -176,8 +154,7 @@ func TestUtilityContext_GetMessageChangeParameterFee(t *testing.T) { defaultParam := defaultParams.GetMessageChangeParameterFee() gotParam, err := ctx.getMessageChangeParameterFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageDoubleSignFee(t *testing.T) { @@ -186,8 +163,7 @@ func TestUtilityContext_GetMessageDoubleSignFee(t *testing.T) { defaultParam := defaultParams.GetMessageDoubleSignFee() gotParam, err := ctx.getMessageDoubleSignFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageEditStakeAppFee(t *testing.T) { @@ -196,7 +172,7 @@ func TestUtilityContext_GetMessageEditStakeAppFee(t *testing.T) { defaultParam := defaultParams.GetMessageEditStakeAppFee() gotParam, err := ctx.getMessageEditStakeAppFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageEditStakeFishermanFee(t *testing.T) { @@ -205,7 +181,7 @@ func TestUtilityContext_GetMessageEditStakeFishermanFee(t *testing.T) { defaultParam := defaultParams.GetMessageEditStakeFishermanFee() gotParam, err := ctx.getMessageEditStakeFishermanFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageEditStakeServicerFee(t *testing.T) { @@ -214,7 +190,7 @@ func TestUtilityContext_GetMessageEditStakeServicerFee(t *testing.T) { defaultParam := defaultParams.GetMessageEditStakeServicerFee() gotParam, err := ctx.getMessageEditStakeServicerFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageEditStakeValidatorFee(t *testing.T) { @@ -223,7 +199,7 @@ func TestUtilityContext_GetMessageEditStakeValidatorFee(t *testing.T) { defaultParam := defaultParams.GetMessageEditStakeValidatorFee() gotParam, err := ctx.getMessageEditStakeValidatorFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageFishermanPauseServicerFee(t *testing.T) { @@ -232,7 +208,7 @@ func TestUtilityContext_GetMessageFishermanPauseServicerFee(t *testing.T) { defaultParam := defaultParams.GetMessageFishermanPauseServicerFee() gotParam, err := ctx.getMessageFishermanPauseServicerFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessagePauseAppFee(t *testing.T) { @@ -241,7 +217,7 @@ func TestUtilityContext_GetMessagePauseAppFee(t *testing.T) { defaultParam := defaultParams.GetMessagePauseAppFee() gotParam, err := ctx.getMessagePauseAppFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessagePauseFishermanFee(t *testing.T) { @@ -250,7 +226,7 @@ func TestUtilityContext_GetMessagePauseFishermanFee(t *testing.T) { defaultParam := defaultParams.GetMessagePauseFishermanFee() gotParam, err := ctx.getMessagePauseFishermanFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessagePauseServicerFee(t *testing.T) { @@ -259,7 +235,7 @@ func TestUtilityContext_GetMessagePauseServicerFee(t *testing.T) { defaultParam := defaultParams.GetMessagePauseServicerFee() gotParam, err := ctx.getMessagePauseServicerFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessagePauseValidatorFee(t *testing.T) { @@ -268,7 +244,7 @@ func TestUtilityContext_GetMessagePauseValidatorFee(t *testing.T) { defaultParam := defaultParams.GetMessagePauseValidatorFee() gotParam, err := ctx.getMessagePauseValidatorFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageProveTestScoreFee(t *testing.T) { @@ -277,8 +253,7 @@ func TestUtilityContext_GetMessageProveTestScoreFee(t *testing.T) { defaultParam := defaultParams.GetMessageProveTestScoreFee() gotParam, err := ctx.getMessageProveTestScoreFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageSendFee(t *testing.T) { @@ -287,7 +262,7 @@ func TestUtilityContext_GetMessageSendFee(t *testing.T) { defaultParam := defaultParams.GetMessageSendFee() gotParam, err := ctx.getMessageSendFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageStakeAppFee(t *testing.T) { @@ -296,7 +271,7 @@ func TestUtilityContext_GetMessageStakeAppFee(t *testing.T) { defaultParam := defaultParams.GetMessageStakeAppFee() gotParam, err := ctx.getMessageStakeAppFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageStakeFishermanFee(t *testing.T) { @@ -305,8 +280,7 @@ func TestUtilityContext_GetMessageStakeFishermanFee(t *testing.T) { defaultParam := defaultParams.GetMessageStakeFishermanFee() gotParam, err := ctx.getMessageStakeFishermanFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageStakeServicerFee(t *testing.T) { @@ -315,7 +289,7 @@ func TestUtilityContext_GetMessageStakeServicerFee(t *testing.T) { defaultParam := defaultParams.GetMessageStakeServicerFee() gotParam, err := ctx.getMessageStakeServicerFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageStakeValidatorFee(t *testing.T) { @@ -324,7 +298,7 @@ func TestUtilityContext_GetMessageStakeValidatorFee(t *testing.T) { defaultParam := defaultParams.GetMessageStakeValidatorFee() gotParam, err := ctx.getMessageStakeValidatorFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageTestScoreFee(t *testing.T) { @@ -333,7 +307,7 @@ func TestUtilityContext_GetMessageTestScoreFee(t *testing.T) { defaultParam := defaultParams.GetMessageTestScoreFee() gotParam, err := ctx.getMessageTestScoreFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnpauseAppFee(t *testing.T) { @@ -342,7 +316,7 @@ func TestUtilityContext_GetMessageUnpauseAppFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnpauseAppFee() gotParam, err := ctx.getMessageUnpauseAppFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnpauseFishermanFee(t *testing.T) { @@ -351,7 +325,7 @@ func TestUtilityContext_GetMessageUnpauseFishermanFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnpauseFishermanFee() gotParam, err := ctx.getMessageUnpauseFishermanFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnpauseServicerFee(t *testing.T) { @@ -360,7 +334,7 @@ func TestUtilityContext_GetMessageUnpauseServicerFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnpauseServicerFee() gotParam, err := ctx.getMessageUnpauseServicerFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnpauseValidatorFee(t *testing.T) { @@ -369,8 +343,7 @@ func TestUtilityContext_GetMessageUnpauseValidatorFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnpauseValidatorFee() gotParam, err := ctx.getMessageUnpauseValidatorFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnstakeAppFee(t *testing.T) { @@ -379,8 +352,7 @@ func TestUtilityContext_GetMessageUnstakeAppFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnstakeAppFee() gotParam, err := ctx.getMessageUnstakeAppFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) - + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnstakeFishermanFee(t *testing.T) { @@ -389,7 +361,7 @@ func TestUtilityContext_GetMessageUnstakeFishermanFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnstakeFishermanFee() gotParam, err := ctx.getMessageUnstakeFishermanFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnstakeServicerFee(t *testing.T) { @@ -398,7 +370,7 @@ func TestUtilityContext_GetMessageUnstakeServicerFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnstakeServicerFee() gotParam, err := ctx.getMessageUnstakeServicerFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMessageUnstakeValidatorFee(t *testing.T) { @@ -407,7 +379,7 @@ func TestUtilityContext_GetMessageUnstakeValidatorFee(t *testing.T) { defaultParam := defaultParams.GetMessageUnstakeValidatorFee() gotParam, err := ctx.getMessageUnstakeValidatorFee() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetMissedBlocksBurnPercentage(t *testing.T) { @@ -461,7 +433,7 @@ func TestUtilityContext_GetServicerMinimumStake(t *testing.T) { defaultParam := defaultParams.GetServicerMinimumStake() gotParam, err := ctx.getServicerMinimumStake() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetServicerUnstakingBlocks(t *testing.T) { @@ -473,11 +445,11 @@ func TestUtilityContext_GetServicerUnstakingBlocks(t *testing.T) { require.Equal(t, defaultParam, gotParam) } -func TestUtilityContext_GetStakingAdjustment(t *testing.T) { +func TestUtilityContext_GetSessionTokensMultiplier(t *testing.T) { ctx := newTestingUtilityContext(t, 0) defaultParams := DefaultTestingParams(t) - defaultParam := int(defaultParams.GetAppStakingAdjustment()) - gotParam, err := ctx.getStabilityAdjustment() + defaultParam := int(defaultParams.GetAppSessionTokensMultiplier()) + gotParam, err := ctx.getAppSessionTokensMultiplier() require.NoError(t, err) require.Equal(t, defaultParam, gotParam) } @@ -515,7 +487,7 @@ func TestUtilityContext_GetValidatorMinimumStake(t *testing.T) { defaultParam := defaultParams.GetValidatorMinimumStake() gotParam, err := ctx.getValidatorMinimumStake() require.NoError(t, err) - require.Equal(t, defaultParam, converters.BigIntToString(gotParam)) + require.Equal(t, defaultParam, utils.BigIntToString(gotParam)) } func TestUtilityContext_GetValidatorUnstakingBlocks(t *testing.T) { @@ -550,7 +522,6 @@ func TestUtilityContext_HandleMessageChangeParameter(t *testing.T) { gotParam, err = ctx.getMissedBlocksBurnPercentage() require.NoError(t, err) require.Equal(t, int(newParamValue), gotParam) - } func TestUtilityContext_GetParamOwner(t *testing.T) { @@ -572,12 +543,8 @@ func TestUtilityContext_GetParamOwner(t *testing.T) { gotParam, err = ctx.getParamOwner(typesUtil.AppMinimumStakeParamName) require.NoError(t, err) require.Equal(t, defaultParam, hex.EncodeToString(gotParam)) - defaultParam = defaultParams.GetAppBaselineStakeRateOwner() - gotParam, err = ctx.getParamOwner(typesUtil.AppBaselineStakeRateParamName) - require.NoError(t, err) - require.Equal(t, defaultParam, hex.EncodeToString(gotParam)) - defaultParam = defaultParams.GetAppStakingAdjustmentOwner() - gotParam, err = ctx.getParamOwner(typesUtil.AppStakingAdjustmentOwner) + defaultParam = defaultParams.GetAppSessionTokensMultiplierOwner() + gotParam, err = ctx.getParamOwner(typesUtil.AppSessionTokensMultiplierOwner) require.NoError(t, err) require.Equal(t, defaultParam, hex.EncodeToString(gotParam)) defaultParam = defaultParams.GetAppUnstakingBlocksOwner() @@ -790,11 +757,10 @@ func TestUtilityContext_GetParamOwner(t *testing.T) { require.NoError(t, err) require.Equal(t, defaultParam, hex.EncodeToString(gotParam)) defaultParam = defaultParams.GetAclOwner() - gotParam, err = ctx.getParamOwner(typesUtil.AppBaselineStakeRateOwner) require.NoError(t, err) require.Equal(t, defaultParam, hex.EncodeToString(gotParam)) defaultParam = defaultParams.GetAclOwner() - gotParam, err = ctx.getParamOwner(typesUtil.AppStakingAdjustmentOwner) + gotParam, err = ctx.getParamOwner(typesUtil.AppSessionTokensMultiplierOwner) require.NoError(t, err) require.Equal(t, defaultParam, hex.EncodeToString(gotParam)) defaultParam = defaultParams.GetAclOwner() diff --git a/utility/message_test.go b/utility/message_test.go index 358942426..e74f72b09 100644 --- a/utility/message_test.go +++ b/utility/message_test.go @@ -5,7 +5,7 @@ import ( "math/big" "testing" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/shared/utils" "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" ) @@ -15,11 +15,11 @@ func TestUtilityContext_HandleMessageSend(t *testing.T) { accs := getAllTestingAccounts(t, ctx) sendAmount := big.NewInt(1000000) - sendAmountString := converters.BigIntToString(sendAmount) - senderBalanceBefore, err := converters.StringToBigInt(accs[0].GetAmount()) + sendAmountString := utils.BigIntToString(sendAmount) + senderBalanceBefore, err := utils.StringToBigInt(accs[0].GetAmount()) require.NoError(t, err) - recipientBalanceBefore, err := converters.StringToBigInt(accs[1].GetAmount()) + recipientBalanceBefore, err := utils.StringToBigInt(accs[1].GetAmount()) require.NoError(t, err) addrBz, er := hex.DecodeString(accs[0].GetAddress()) @@ -33,10 +33,10 @@ func TestUtilityContext_HandleMessageSend(t *testing.T) { require.NoError(t, err, "handle message send") accs = getAllTestingAccounts(t, ctx) - senderBalanceAfter, err := converters.StringToBigInt(accs[0].GetAmount()) + senderBalanceAfter, err := utils.StringToBigInt(accs[0].GetAmount()) require.NoError(t, err) - recipientBalanceAfter, err := converters.StringToBigInt(accs[1].GetAmount()) + recipientBalanceAfter, err := utils.StringToBigInt(accs[1].GetAmount()) require.NoError(t, err) require.Equal(t, sendAmount, big.NewInt(0).Sub(senderBalanceBefore, senderBalanceAfter)) require.Equal(t, sendAmount, big.NewInt(0).Sub(recipientBalanceAfter, recipientBalanceBefore)) @@ -47,7 +47,7 @@ func TestUtilityContext_GetMessageSendSignerCandidates(t *testing.T) { accs := getAllTestingAccounts(t, ctx) sendAmount := big.NewInt(1000000) - sendAmountString := converters.BigIntToString(sendAmount) + sendAmountString := utils.BigIntToString(sendAmount) addrBz, er := hex.DecodeString(accs[0].GetAddress()) require.NoError(t, er) diff --git a/utility/module_test.go b/utility/module_test.go index b6cd69980..5bc10ff1e 100644 --- a/utility/module_test.go +++ b/utility/module_test.go @@ -5,7 +5,6 @@ import ( "os" "testing" - "github.com/golang/mock/gomock" "github.com/pokt-network/pocket/logger" "github.com/pokt-network/pocket/persistence" "github.com/pokt-network/pocket/runtime" @@ -14,7 +13,6 @@ import ( "github.com/pokt-network/pocket/shared/mempool" "github.com/pokt-network/pocket/shared/messaging" "github.com/pokt-network/pocket/shared/modules" - mockModules "github.com/pokt-network/pocket/shared/modules/mocks" utilTypes "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" ) @@ -30,9 +28,10 @@ const ( ) var ( - // Initialized in TestMain + testUtilityMod modules.UtilityModule + + // TODO(#261): Utility module tests should have no dependencies on the persistence module (which instantiates a postgres container) testPersistenceMod modules.PersistenceModule - testUtilityMod modules.UtilityModule ) func NewTestingMempool(_ *testing.T) mempool.TXMempool { @@ -40,10 +39,9 @@ func NewTestingMempool(_ *testing.T) mempool.TXMempool { } func TestMain(m *testing.M) { - // TODO(#261): Utility module tests should have no dependencies on a postgres container - pool, resource, dbUrl := test_artifacts.SetupPostgresDocker() + pool, resource, dbURL := test_artifacts.SetupPostgresDocker() - runtimeCfg := newTestRuntimeConfig(dbUrl) + runtimeCfg := newTestRuntimeConfig(dbURL) bus, err := runtime.CreateBus(runtimeCfg) if err != nil { log.Fatalf("Error creating bus: %s", err) @@ -73,35 +71,52 @@ func newTestingUtilityContext(t *testing.T, height int64) *utilityContext { testUtilityMod.GetMempool().Clear() }) - uc := &utilityContext{ - logger: logger.Global.CreateLoggerForModule(modules.UtilityModuleName), - height: height, - persistenceContext: persistenceContext, - savePointsSet: make(map[string]struct{}), - savePointsList: make([][]byte, 0), + ctx := &utilityContext{ + logger: logger.Global.CreateLoggerForModule(modules.UtilityModuleName), + height: height, + store: persistenceContext, + savePointsSet: make(map[string]struct{}), + savePointsList: make([][]byte, 0), + } + ctx.SetBus(testUtilityMod.GetBus()) + + return ctx +} + +func newTestUtilityModule(bus modules.Bus) modules.UtilityModule { + utilityMod, err := Create(bus) + if err != nil { + log.Fatalf("Error creating persistence module: %s", err) } + return utilityMod.(modules.UtilityModule) +} - return uc.setBus(testUtilityMod.GetBus()) +func newTestPersistenceModule(bus modules.Bus) modules.PersistenceModule { + persistenceMod, err := persistence.Create(bus) + if err != nil { + log.Fatalf("Error creating persistence module: %s", err) + } + return persistenceMod.(modules.PersistenceModule) } -func newTestRuntimeConfig(databaseUrl string) *runtime.Manager { +func newTestRuntimeConfig(databaseURL string) *runtime.Manager { cfg := &configs.Config{ + Utility: &configs.UtilityConfig{ + MaxMempoolTransactionBytes: 1000000, + MaxMempoolTransactions: 1000, + }, Persistence: &configs.PersistenceConfig{ - PostgresUrl: databaseUrl, + PostgresUrl: databaseURL, NodeSchema: testSchema, - BlockStorePath: "", - TxIndexerPath: "", - TreesStoreDir: "", + BlockStorePath: "", // in memory + TxIndexerPath: "", // in memory + TreesStoreDir: "", // in memory MaxConnsCount: 4, MinConnsCount: 0, MaxConnLifetime: "1h", MaxConnIdleTime: "30m", HealthCheckPeriod: "5m", }, - Utility: &configs.UtilityConfig{ - MaxMempoolTransactionBytes: 1000000, - MaxMempoolTransactions: 1000, - }, } genesisState, _ := test_artifacts.NewGenesisState( testingValidatorCount, @@ -112,39 +127,3 @@ func newTestRuntimeConfig(databaseUrl string) *runtime.Manager { runtimeCfg := runtime.NewManager(cfg, genesisState) return runtimeCfg } - -func newTestUtilityModule(bus modules.Bus) modules.UtilityModule { - utilityMod, err := Create(bus) - if err != nil { - log.Fatalf("Error creating persistence module: %s", err) - } - return utilityMod.(modules.UtilityModule) -} - -// TODO(#261): Utility module tests should have no dependencies on the persistence module -func newTestPersistenceModule(bus modules.Bus) modules.PersistenceModule { - persistenceMod, err := persistence.Create(bus) - if err != nil { - log.Fatalf("Error creating persistence module: %s", err) - } - return persistenceMod.(modules.PersistenceModule) -} - -// IMPROVE: Not part of `TestMain` because a mock requires `testing.T` to be initialized. -// We are trying to only initialize one `testPersistenceModule` in all the tests, so when the -// utility module tests are no longer dependant on the persistence module explicitly, this -// can be improved. -func mockBusInTestModules(t *testing.T) { - ctrl := gomock.NewController(t) - - busMock := mockModules.NewMockBus(ctrl) - busMock.EXPECT().GetPersistenceModule().Return(testPersistenceMod).AnyTimes() - busMock.EXPECT().GetUtilityModule().Return(testUtilityMod).AnyTimes() - - testPersistenceMod.SetBus(busMock) - testUtilityMod.SetBus(busMock) - - t.Cleanup(func() { - testPersistenceMod.SetBus(nil) - }) -} diff --git a/utility/session.go b/utility/session.go index 4c3a0f1a5..1260248d1 100644 --- a/utility/session.go +++ b/utility/session.go @@ -5,102 +5,137 @@ package utility import ( "encoding/binary" - "encoding/hex" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/utility/types" ) -type RelayChain Identifier -type GeoZone Identifier +// TODO: When implementing please review if block height tolerance (+,-1) is included in the session protocol: pokt-network/pocket-core#1464 CC @Olshansk -type Identifier interface { - Name() string - ID() string - Bytes() []byte -} +// REFACTOR: Move these into `utility/types` and consider creating an enum +type RelayChain string +type GeoZone string type Session interface { - NewSession(sessionHeight int64, blockHash string, geoZone GeoZone, relayChain RelayChain, application *coreTypes.Actor) (Session, types.Error) + NewSession(sessionHeight int64, relayChain RelayChain, geoZone GeoZone, application *coreTypes.Actor) (Session, types.Error) + GetSessionID() []byte // the identifier of the dispatched session + GetSessionHeight() int64 // the block height when the session started + GetRelayChain() RelayChain // the web3 chain identifier + GetGeoZone() GeoZone // the geo-location zone where the application is intending to operate during the session + GetApplication() *coreTypes.Actor // the Application consuming the web3 access GetServicers() []*coreTypes.Actor // the Servicers providing Web3 to the application GetFishermen() []*coreTypes.Actor // the Fishermen monitoring the servicers - GetApplication() *coreTypes.Actor // the Application consuming the web3 access - GetRelayChain() RelayChain // the chain identifier of the web3 - GetGeoZone() GeoZone // the geo-location zone where all are registered - GetSessionHeight() int64 // the block height when the session started } var _ Session = &session{} type session struct { - servicers []*coreTypes.Actor - fishermen []*coreTypes.Actor - application *coreTypes.Actor - relayChain RelayChain - geoZone GeoZone - blockHash string - key []byte - sessionHeight int64 + sessionId []byte + height int64 + relayChain RelayChain + geoZone GeoZone + application *coreTypes.Actor + servicers []*coreTypes.Actor + fishermen []*coreTypes.Actor } -func (s *session) NewSession(sessionHeight int64, blockHash string, geoZone GeoZone, relayChain RelayChain, application *coreTypes.Actor) (session Session, err types.Error) { - s.sessionHeight = sessionHeight - s.blockHash = blockHash - s.geoZone = geoZone - s.relayChain = relayChain - s.application = application - s.key, err = s.sessionKey() - if err != nil { - return +func (*session) NewSession( + sessionHeight int64, + relayChain RelayChain, + geoZone GeoZone, + application *coreTypes.Actor, +) (Session, types.Error) { + s := &session{ + height: sessionHeight, + relayChain: relayChain, + geoZone: geoZone, + application: application, + } + + // TODO: make these configurable or based on governance params + numServicers := 1 + numFisherman := 1 + + var err types.Error + if s.servicers, err = s.selectSessionServicers(numServicers); err != nil { + return nil, err + } + if s.fishermen, err = s.selectSessionFishermen(numFisherman); err != nil { + return nil, err + } + if s.sessionId, err = s.getSessionId(); err != nil { + return nil, err } - s.servicers = s.findClosestXServicers() - s.fishermen = s.findClosestYFishermen() return s, nil } +func (s *session) GetSessionID() []byte { + return s.sessionId +} + +func (s *session) GetSessionHeight() int64 { + return s.height +} + +func (s *session) GetRelayChain() RelayChain { + return s.relayChain +} + +func (s *session) GetGeoZone() GeoZone { + return s.geoZone +} + +func (s *session) GetApplication() *coreTypes.Actor { + return s.application +} + +func (s *session) GetFishermen() []*coreTypes.Actor { + return s.fishermen +} + +func (s *session) GetServicers() []*coreTypes.Actor { + return s.servicers +} + // use the seed information to determine a SHA3Hash that is used to find the closest N actors based // by comparing the sessionKey with the actors' public key -func (s *session) sessionKey() ([]byte, types.Error) { - sessionHeightBytes := make([]byte, 8) - binary.LittleEndian.PutUint64(sessionHeightBytes, uint64(s.sessionHeight)) - blockHashBz, err := hex.DecodeString(s.blockHash) - if err != nil { - return nil, types.ErrHexDecodeFromString(err) - } +func (s *session) getSessionId() ([]byte, types.Error) { + sessionHeightBz := make([]byte, 8) + binary.LittleEndian.PutUint64(sessionHeightBz, uint64(s.height)) + + blockHashBz := []byte("get block hash bytes at s.sessionHeight from persistence module") + appPubKey, err := crypto.NewPublicKey(s.application.GetPublicKey()) if err != nil { return nil, types.ErrNewPublicKeyFromBytes(err) } - return concat(sessionHeightBytes, blockHashBz, s.geoZone.Bytes(), s.relayChain.Bytes(), appPubKey.Bytes()), nil + + return concat(sessionHeightBz, blockHashBz, []byte(s.geoZone), []byte(s.relayChain), appPubKey.Bytes()), nil } // uses the current 'world state' to determine the servicers in the session // 1) get an ordered list of the public keys of servicers who are: // - actively staked -// - staked within geo-zone +// - staked within geo-zone (or closest geo-zones) // - staked for relay-chain // // 2) calls `pseudoRandomSelection(servicers, numberOfNodesPerSession)` -func (s *session) findClosestXServicers() []*coreTypes.Actor { - // IMPORTANT: - // THIS IS A DEMONSTRABLE FUNCTION THAT WILL NOT BE IMPLEMENTED AS SUCH - // IT EXISTS IN THIS COMMIT PURELY TO COMMUNICATE THE EXPECTED BEHAVIOR - return nil +func (s *session) selectSessionServicers(numServicers int) ([]*coreTypes.Actor, types.Error) { + // IMPORTANT: This function is for behaviour illustrative purposes only and implementation may differ. + return nil, nil } // uses the current 'world state' to determine the fishermen in the session // 1) get an ordered list of the public keys of fishermen who are: // - actively staked -// - staked within geo-zone +// - staked within geo-zone (or closest geo-zones) // - staked for relay-chain // // 2) calls `pseudoRandomSelection(fishermen, numberOfFishPerSession)` -func (s *session) findClosestYFishermen() []*coreTypes.Actor { - // IMPORTANT: - // THIS IS A DEMONSTRABLE FUNCTION THAT WILL NOT BE IMPLEMENTED AS SUCH - // IT EXISTS IN THIS COMMIT PURELY TO COMMUNICATE THE EXPECTED BEHAVIOR - return nil +func (s *session) selectSessionFishermen(numFishermen int) ([]*coreTypes.Actor, types.Error) { + // IMPORTANT: This function is for behaviour illustrative purposes only and implementation may differ. + return nil, nil } // 1) passed an ordered list of the public keys of actors and number of nodes @@ -114,37 +149,11 @@ func (s *session) findClosestYFishermen() []*coreTypes.Actor { // or it would be subject to lexicographical proximity bias attacks // //nolint:unused // This is a demonstratable function -func (s *session) pseudoRandomSelection(orderedListOfPublicKeys []string, numberOfActorsInSession int) []*coreTypes.Actor { - // IMPORTANT: - // THIS IS A DEMONSTRABLE FUNCTION THAT WILL NOT BE IMPLEMENTED AS SUCH - // IT EXISTS IN THIS COMMIT PURELY TO COMMUNICATE THE EXPECTED BEHAVIOR +func (s *session) pseudoRandomSelection(orderedListOfPublicKeys []string, numActorsToSelect int) []*coreTypes.Actor { + // IMPORTANT: This function is for behaviour illustrative purposes only and implementation may differ. return nil } -func (s *session) GetServicers() []*coreTypes.Actor { - return s.servicers -} - -func (s *session) GetFishermen() []*coreTypes.Actor { - return s.fishermen -} - -func (s *session) GetApplication() *coreTypes.Actor { - return s.application -} - -func (s *session) GetRelayChain() RelayChain { - return s.relayChain -} - -func (s *session) GetGeoZone() GeoZone { - return s.geoZone -} - -func (s *session) GetSessionHeight() int64 { - return s.sessionHeight -} - func concat(b ...[]byte) (result []byte) { for _, bz := range b { result = append(result, bz...) diff --git a/utility/transaction.go b/utility/transaction.go index eaabf9879..b553fe6c5 100644 --- a/utility/transaction.go +++ b/utility/transaction.go @@ -2,7 +2,7 @@ package utility import ( "bytes" - "encoding/hex" + "fmt" "github.com/pokt-network/pocket/shared/codec" coreTypes "github.com/pokt-network/pocket/shared/core/types" @@ -11,9 +11,11 @@ import ( typesUtil "github.com/pokt-network/pocket/utility/types" ) -func (u *utilityModule) CheckTransaction(txProtoBytes []byte) error { +// HandleTransaction implements the exposed functionality of the shared utilityModule interface. +func (u *utilityModule) HandleTransaction(txProtoBytes []byte) error { + txHash := coreTypes.TxHash(txProtoBytes) + // Is the tx already in the mempool (in memory)? - txHash := typesUtil.TxHash(txProtoBytes) if u.mempool.Contains(txHash) { return typesUtil.ErrDuplicateTransaction() } @@ -26,7 +28,7 @@ func (u *utilityModule) CheckTransaction(txProtoBytes []byte) error { } // Can the tx be decoded? - tx := &typesUtil.Transaction{} + tx := &coreTypes.Transaction{} if err := codec.GetCodec().Unmarshal(txProtoBytes, tx); err != nil { return typesUtil.ErrProtoUnmarshal(err) } @@ -40,57 +42,81 @@ func (u *utilityModule) CheckTransaction(txProtoBytes []byte) error { return u.mempool.AddTx(txProtoBytes) } -func (u *utilityContext) applyTx(index int, tx *typesUtil.Transaction) (modules.TxResult, typesUtil.Error) { - msg, signer, err := u.anteHandleMessage(tx) +// hydrateTxResult converts a `Transaction` proto into a `TxResult` struct` after doing basic validation +// and extracting the relevant data from the embedded signed Message. `index` is the intended location +// of its index (i.e. the transaction number) in the block where it is included. +// +// IMPROVE: hydration should accept and return the same type (i.e. TxResult) so there may be opportunity +// to refactor this in the future. +func (u *utilityContext) hydrateTxResult(tx *coreTypes.Transaction, index int) (modules.TxResult, typesUtil.Error) { + msg, err := u.anteHandleMessage(tx) if err != nil { return nil, err } - return tx.ToTxResult(u.height, index, signer, msg.GetMessageRecipient(), msg.GetMessageName(), u.handleMessage(msg)) + msgHandlingResult := u.handleMessage(msg) + return typesUtil.TxToTxResult(tx, u.height, index, msg, msgHandlingResult) } -func (u *utilityContext) anteHandleMessage(tx *typesUtil.Transaction) (msg typesUtil.Message, signer string, err typesUtil.Error) { - msg, err = tx.GetMessage() - if err != nil { - return nil, "", err +// anteHandleMessage handles basic validation of the message in the Transaction before it is processed +// REFACTOR: Splitting this into a `feeValidation`, `signerValidation`, and `messageValidation` etc +// would make it more modular and readable. +func (u *utilityContext) anteHandleMessage(tx *coreTypes.Transaction) (typesUtil.Message, typesUtil.Error) { + // Check if the transaction has a valid message + anyMsg, er := tx.GetMessage() + if er != nil { + return nil, typesUtil.ErrDecodeMessage(er) } - fee, err := u.getFee(msg, msg.GetActorType()) - if err != nil { - return nil, "", err + msg, ok := anyMsg.(typesUtil.Message) + if !ok { + return nil, typesUtil.ErrDecodeMessage(fmt.Errorf("not a supported message type")) } + + // Get the address of the transaction signer pubKey, er := crypto.NewPublicKeyFromBytes(tx.Signature.PublicKey) if er != nil { - return nil, "", typesUtil.ErrNewPublicKeyFromBytes(er) + return nil, typesUtil.ErrNewPublicKeyFromBytes(er) } address := pubKey.Address() + addressHex := address.ToString() + + // Validate that the signer has enough funds to pay the fee of the message signed + fee, err := u.getFee(msg, msg.GetActorType()) + if err != nil { + return nil, err + } accountAmount, err := u.getAccountAmount(address) if err != nil { - return nil, "", typesUtil.ErrGetAccountAmount(err) + return nil, typesUtil.ErrGetAccountAmount(err) } accountAmount.Sub(accountAmount, fee) if accountAmount.Sign() == -1 { - return nil, "", typesUtil.ErrInsufficientAmount(address.String()) + return nil, typesUtil.ErrInsufficientAmount(addressHex) } + + // Validate that the signer has a valid signature + var isValidSigner bool signerCandidates, err := u.getSignerCandidates(msg) if err != nil { - return nil, "", err + return nil, err } - var isValidSigner bool for _, candidate := range signerCandidates { if bytes.Equal(candidate, address) { isValidSigner = true - signer = hex.EncodeToString(candidate) + msg.SetSigner(address) break } } if !isValidSigner { - return nil, signer, typesUtil.ErrInvalidSigner() + return nil, typesUtil.ErrInvalidSigner(addressHex) } + + // Remove the fee from the signer's account and add it to the fee collector pool if err := u.setAccountAmount(address, accountAmount); err != nil { - return nil, signer, err + return nil, err } if err := u.addPoolAmount(coreTypes.Pools_POOLS_FEE_COLLECTOR.FriendlyName(), fee); err != nil { - return nil, "", err + return nil, err } - msg.SetSigner(address) - return msg, signer, nil + + return msg, nil } diff --git a/utility/transaction_test.go b/utility/transaction_test.go index 15130f40f..4c7cc9244 100644 --- a/utility/transaction_test.go +++ b/utility/transaction_test.go @@ -7,9 +7,10 @@ import ( "github.com/pokt-network/pocket/runtime/test_artifacts" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" + "github.com/pokt-network/pocket/shared/core/types" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" ) @@ -22,9 +23,9 @@ func TestUtilityContext_AnteHandleMessage(t *testing.T) { ctx := newTestingUtilityContext(t, 0) tx, startingBalance, _, signer := newTestingTransaction(t, ctx) - _, signerString, err := ctx.anteHandleMessage(tx) + msg, err := ctx.anteHandleMessage(tx) require.NoError(t, err) - require.Equal(t, signer.Address().String(), signerString) + require.Equal(t, signer.Address().Bytes(), msg.GetSigner()) feeBig, err := ctx.getMessageSendFee() require.NoError(t, err) @@ -38,7 +39,7 @@ func TestUtilityContext_ApplyTransaction(t *testing.T) { ctx := newTestingUtilityContext(t, 0) tx, startingBalance, amount, signer := newTestingTransaction(t, ctx) - txResult, err := ctx.applyTx(0, tx) + txResult, err := ctx.hydrateTxResult(tx, 0) require.NoError(t, err) require.Equal(t, int32(0), txResult.GetResultCode()) require.Equal(t, "", txResult.GetError()) @@ -52,20 +53,18 @@ func TestUtilityContext_ApplyTransaction(t *testing.T) { require.Equal(t, expectedAfterBalance, amount, "unexpected after balance") } -func TestUtilityContext_CheckTransaction(t *testing.T) { - mockBusInTestModules(t) - +func TestUtilityContext_HandleTransaction(t *testing.T) { ctx := newTestingUtilityContext(t, 0) tx, _, _, _ := newTestingTransaction(t, ctx) txBz, err := tx.Bytes() require.NoError(t, err) - require.NoError(t, testUtilityMod.CheckTransaction(txBz)) + require.NoError(t, testUtilityMod.HandleTransaction(txBz)) hash, err := tx.Hash() require.NoError(t, err) require.True(t, testUtilityMod.GetMempool().Contains(hash)) - require.Equal(t, testUtilityMod.CheckTransaction(txBz).Error(), typesUtil.ErrDuplicateTransaction().Error()) + require.Equal(t, testUtilityMod.HandleTransaction(txBz).Error(), typesUtil.ErrDuplicateTransaction().Error()) } func TestUtilityContext_GetSignerCandidates(t *testing.T) { @@ -73,7 +72,7 @@ func TestUtilityContext_GetSignerCandidates(t *testing.T) { accs := getAllTestingAccounts(t, ctx) sendAmount := big.NewInt(1000000) - sendAmountString := converters.BigIntToString(sendAmount) + sendAmountString := utils.BigIntToString(sendAmount) addrBz, er := hex.DecodeString(accs[0].GetAddress()) require.NoError(t, er) addrBz2, er := hex.DecodeString(accs[1].GetAddress()) @@ -87,15 +86,13 @@ func TestUtilityContext_GetSignerCandidates(t *testing.T) { } func TestUtilityContext_CreateAndApplyBlock(t *testing.T) { - mockBusInTestModules(t) - ctx := newTestingUtilityContext(t, 0) tx, _, _, _ := newTestingTransaction(t, ctx) - proposer := getFirstActor(t, ctx, coreTypes.ActorType_ACTOR_TYPE_VAL) + proposer := getFirstActor(t, ctx, types.ActorType_ACTOR_TYPE_VAL) txBz, err := tx.Bytes() require.NoError(t, err) - require.NoError(t, testUtilityMod.CheckTransaction(txBz)) + require.NoError(t, testUtilityMod.HandleTransaction(txBz)) appHash, txs, er := ctx.CreateAndApplyProposalBlock([]byte(proposer.GetAddress()), 10000) require.NoError(t, er) @@ -109,11 +106,11 @@ func TestUtilityContext_HandleMessage(t *testing.T) { accs := getAllTestingAccounts(t, ctx) sendAmount := big.NewInt(1000000) - sendAmountString := converters.BigIntToString(sendAmount) - senderBalanceBefore, err := converters.StringToBigInt(accs[0].GetAmount()) + sendAmountString := utils.BigIntToString(sendAmount) + senderBalanceBefore, err := utils.StringToBigInt(accs[0].GetAmount()) require.NoError(t, err) - recipientBalanceBefore, err := converters.StringToBigInt(accs[1].GetAmount()) + recipientBalanceBefore, err := utils.StringToBigInt(accs[1].GetAmount()) require.NoError(t, err) addrBz, er := hex.DecodeString(accs[0].GetAddress()) require.NoError(t, er) @@ -122,17 +119,17 @@ func TestUtilityContext_HandleMessage(t *testing.T) { msg := NewTestingSendMessage(t, addrBz, addrBz2, sendAmountString) require.NoError(t, ctx.handleMessageSend(&msg)) accs = getAllTestingAccounts(t, ctx) - senderBalanceAfter, err := converters.StringToBigInt(accs[0].GetAmount()) + senderBalanceAfter, err := utils.StringToBigInt(accs[0].GetAmount()) require.NoError(t, err) - recipientBalanceAfter, err := converters.StringToBigInt(accs[1].GetAmount()) + recipientBalanceAfter, err := utils.StringToBigInt(accs[1].GetAmount()) require.NoError(t, err) require.Equal(t, sendAmount, big.NewInt(0).Sub(senderBalanceBefore, senderBalanceAfter), "unexpected sender balance") require.Equal(t, sendAmount, big.NewInt(0).Sub(recipientBalanceAfter, recipientBalanceBefore), "unexpected recipient balance") } -func newTestingTransaction(t *testing.T, ctx *utilityContext) (tx *typesUtil.Transaction, startingBalance, amountSent *big.Int, signer crypto.PrivateKey) { +func newTestingTransaction(t *testing.T, ctx *utilityContext) (tx *coreTypes.Transaction, startingBalance, amountSent *big.Int, signer crypto.PrivateKey) { amountSent = new(big.Int).Set(defaultSendAmount) startingBalance = new(big.Int).Set(test_artifacts.DefaultAccountAmount) @@ -145,11 +142,11 @@ func newTestingTransaction(t *testing.T, ctx *utilityContext) (tx *typesUtil.Tra signerAddr := signer.Address() require.NoError(t, ctx.setAccountAmount(signerAddr, startingBalance)) - msg := NewTestingSendMessage(t, signerAddr, recipientAddr.Bytes(), converters.BigIntToString(amountSent)) + msg := NewTestingSendMessage(t, signerAddr, recipientAddr.Bytes(), utils.BigIntToString(amountSent)) any, err := codec.GetCodec().ToAny(&msg) require.NoError(t, err) - tx = &typesUtil.Transaction{ + tx = &coreTypes.Transaction{ Msg: any, Nonce: testNonce, } diff --git a/utility/message_handler.go b/utility/tx_message_handler.go similarity index 76% rename from utility/message_handler.go rename to utility/tx_message_handler.go index 8992511a8..cbcb03c10 100644 --- a/utility/message_handler.go +++ b/utility/tx_message_handler.go @@ -2,43 +2,15 @@ package utility import ( "encoding/hex" - "fmt" "math/big" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/utility/types" + "github.com/pokt-network/pocket/shared/utils" typesUtil "github.com/pokt-network/pocket/utility/types" - "google.golang.org/protobuf/types/known/anypb" ) -const ( - TransactionGossipMessageContentType = "utility.TransactionGossipMessage" -) - -func (u *utilityModule) HandleMessage(message *anypb.Any) error { - switch message.MessageName() { - case TransactionGossipMessageContentType: - msg, err := codec.GetCodec().FromAny(message) - if err != nil { - return err - } - - if txGossipMsg, ok := msg.(*types.TransactionGossipMessage); !ok { - return fmt.Errorf("failed to cast message to UtilityMessage") - } else if err := u.CheckTransaction(txGossipMsg.Tx); err != nil { - return err - } - u.logger.Info().Str("source", "MEMPOOL").Msg("Successfully added a new message to the mempool!") - default: - return types.ErrUnknownMessageType(message.MessageName()) - } - - return nil -} - func (u *utilityContext) handleMessage(msg typesUtil.Message) (err typesUtil.Error) { switch x := msg.(type) { case *typesUtil.MessageSend: @@ -60,7 +32,7 @@ func (u *utilityContext) handleMessage(msg typesUtil.Message) (err typesUtil.Err func (u *utilityContext) handleMessageSend(message *typesUtil.MessageSend) typesUtil.Error { // convert the amount to big.Int - amount, er := converters.StringToBigInt(message.Amount) + amount, er := utils.StringToBigInt(message.Amount) if er != nil { return typesUtil.ErrStringToBigInt(er) } @@ -127,21 +99,16 @@ func (u *utilityContext) handleStakeMessage(message *typesUtil.MessageStake) typ return err } - store := u.Store() // insert actor switch message.ActorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - maxRelays, err := u.calculateMaxAppRelays(message.Amount) - if err != nil { - return err - } - er = store.InsertApp(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(typesUtil.StakeStatus_Staked), maxRelays, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + er = u.store.InsertApp(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(coreTypes.StakeStatus_Staked), message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) case coreTypes.ActorType_ACTOR_TYPE_FISH: - er = store.InsertFisherman(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(typesUtil.StakeStatus_Staked), message.ServiceUrl, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + er = u.store.InsertFisherman(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(coreTypes.StakeStatus_Staked), message.ServiceUrl, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - er = store.InsertServicer(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(typesUtil.StakeStatus_Staked), message.ServiceUrl, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + er = u.store.InsertServicer(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(coreTypes.StakeStatus_Staked), message.ServiceUrl, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) case coreTypes.ActorType_ACTOR_TYPE_VAL: - er = store.InsertValidator(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(typesUtil.StakeStatus_Staked), message.ServiceUrl, message.Amount, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + er = u.store.InsertValidator(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, int32(coreTypes.StakeStatus_Staked), message.ServiceUrl, message.Amount, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) } if er != nil { return typesUtil.ErrInsert(er) @@ -161,7 +128,7 @@ func (u *utilityContext) handleEditStakeMessage(message *typesUtil.MessageEditSt if err != nil { return err } - amount, er := converters.StringToBigInt(message.Amount) + amount, er := utils.StringToBigInt(message.Amount) if er != nil { return typesUtil.ErrStringToBigInt(err) } @@ -190,20 +157,15 @@ func (u *utilityContext) handleEditStakeMessage(message *typesUtil.MessageEditSt if err := u.addPoolAmount(coreTypes.Pools_POOLS_APP_STAKE.FriendlyName(), amount); err != nil { return err } - store := u.Store() switch message.ActorType { case coreTypes.ActorType_ACTOR_TYPE_APP: - maxRelays, err := u.calculateMaxAppRelays(message.Amount) - if err != nil { - return err - } - er = store.UpdateApp(message.Address, maxRelays, message.Amount, message.Chains) + er = u.store.UpdateApp(message.Address, message.Amount, message.Chains) case coreTypes.ActorType_ACTOR_TYPE_FISH: - er = store.UpdateFisherman(message.Address, message.ServiceUrl, message.Amount, message.Chains) + er = u.store.UpdateFisherman(message.Address, message.ServiceUrl, message.Amount, message.Chains) case coreTypes.ActorType_ACTOR_TYPE_SERVICER: - er = store.UpdateServicer(message.Address, message.ServiceUrl, message.Amount, message.Chains) + er = u.store.UpdateServicer(message.Address, message.ServiceUrl, message.Amount, message.Chains) case coreTypes.ActorType_ACTOR_TYPE_VAL: - er = store.UpdateValidator(message.Address, message.ServiceUrl, message.Amount) + er = u.store.UpdateValidator(message.Address, message.ServiceUrl, message.Amount) } if er != nil { return typesUtil.ErrInsert(er) @@ -212,9 +174,9 @@ func (u *utilityContext) handleEditStakeMessage(message *typesUtil.MessageEditSt } func (u *utilityContext) handleUnstakeMessage(message *typesUtil.MessageUnstake) typesUtil.Error { - if status, err := u.getActorStatus(message.ActorType, message.Address); err != nil || status != typesUtil.StakeStatus_Staked { - if status != typesUtil.StakeStatus_Staked { - return typesUtil.ErrInvalidStatus(status, typesUtil.StakeStatus_Staked) + if status, err := u.getActorStatus(message.ActorType, message.Address); err != nil || status != coreTypes.StakeStatus_Staked { + if status != coreTypes.StakeStatus_Staked { + return typesUtil.ErrInvalidStatus(status, coreTypes.StakeStatus_Staked) } return err } @@ -222,7 +184,7 @@ func (u *utilityContext) handleUnstakeMessage(message *typesUtil.MessageUnstake) if err != nil { return err } - if err := u.setActorUnstakingHeight(message.ActorType, message.Address, unbondingHeight); err != nil { + if err := u.setActorUnbondingHeight(message.ActorType, message.Address, unbondingHeight); err != nil { return err } return nil @@ -340,11 +302,11 @@ func (u *utilityContext) checkAboveMinStake(actorType coreTypes.ActorType, amoun if err != nil { return nil, err } - amount, er := converters.StringToBigInt(amountStr) + amount, er := utils.StringToBigInt(amountStr) if er != nil { return nil, typesUtil.ErrStringToBigInt(err) } - if converters.BigIntLessThan(amount, minStake) { + if utils.BigIntLessThan(amount, minStake) { return nil, typesUtil.ErrMinimumStake() } return amount, nil diff --git a/utility/types/constants.go b/utility/types/constants.go index bfa459503..84cc42e45 100644 --- a/utility/types/constants.go +++ b/utility/types/constants.go @@ -1,9 +1,9 @@ package types -// CLEANUP: Consider moving these into a shared location or eliminating altogether +// CLEANUP: Consider moving these into a shared location or seeing if they can be eliminated altogether const ( - ZeroInt = 0 - // IMPROVE: -1 is returned when retrieving the paused height of an unpaused actor. Consider a more user friendly and semantic way of managing this. + EmptyString = "" + // IMPROVE: -1 is used for defining unused heights (e.g. unpaused actor has pausedHeight=-1). + // Consider a more user friendly and semantic way of managing this. HeightNotUsed = int64(-1) - EmptyString = "" ) diff --git a/utility/types/error.go b/utility/types/error.go index b28b29cb0..6ede51b32 100644 --- a/utility/types/error.go +++ b/utility/types/error.go @@ -8,9 +8,11 @@ import ( "errors" "fmt" + coreTypes "github.com/pokt-network/pocket/shared/core/types" cryptoPocket "github.com/pokt-network/pocket/shared/crypto" ) +// TODO(#556): Move this to a shared package so it can be used throughout the entire codebase type Error interface { Code() Code error @@ -38,7 +40,8 @@ func NewError(code Code, msg string) Error { } } -type Code float64 +// NextCode: 133 +type Code float64 // CONSIDERATION: Should these be a proto enum or a golang iota? //nolint:gosec // G101 - Not hard-coded credentials const ( @@ -79,6 +82,7 @@ const ( CodeInterfaceConversionError Code = 38 CodeGetAccountAmountError Code = 39 CodeStringToBigIntError Code = 40 + CodeStringToBigFloatError Code = 132 CodeInsufficientAmountError Code = 41 CodeAddAccountAmountError Code = 42 CodeSetAccountError Code = 43 @@ -108,7 +112,7 @@ const ( CodeNotPausedError Code = 67 CodeNotReadyToUnpauseError Code = 68 CodeSetStatusPausedBeforeError Code = 69 - CodeInvalidServiceUrlError Code = 70 + CodeInvalidServiceURLError Code = 70 CodeNotExistsError Code = 71 CodeGetMissedBlocksError Code = 72 CodeEmptyHashError Code = 73 @@ -182,7 +186,7 @@ const ( GetMissedBlocksError = "an error occurred getting the missed blocks field" DecodeMessageError = "unable to decode the message" NotExistsError = "the actor does not exist in the state" - InvalidServiceUrlError = "the service url is not valid" + InvalidServiceURLError = "the service url is not valid" NotReadyToUnpauseError = "the actor isn't ready to unpause as the minimum number of blocks hasn't passed since pausing" NotPausedError = "the actor is not paused" SetPauseHeightError = "an error occurred setting the pause height" @@ -268,6 +272,7 @@ const ( SocketIOStartFailedError = "socket error: failed to start socket reading/writing (io)" EmptyTransactionError = "the transaction is empty" StringToBigIntError = "error converting string to big int" + StringToBigFloatError = "error converting string to big float" GetAllValidatorsError = "an error occurred getting all validators from the state" InvalidAmountError = "the amount field is invalid; cannot be converted to big.Int" InvalidAddressLenError = "the length of the address is not valid" @@ -325,8 +330,8 @@ func ErrUnequalRounds() Error { return NewError(CodeUnequalRoundsError, UnequalRoundsError) } -func ErrInvalidServiceUrl(reason string) Error { - return NewError(CodeInvalidServiceUrlError, fmt.Sprintf("%s: %s", InvalidServiceUrlError, reason)) +func ErrInvalidServiceURL(reason string) Error { + return NewError(CodeInvalidServiceURLError, fmt.Sprintf("%s: %s", InvalidServiceURLError, reason)) } func ErrSetPauseHeight(err error) Error { @@ -425,8 +430,8 @@ func ErrUnauthorizedParamChange(owner []byte) Error { return NewError(CodeUnauthorizedParamChangeError, fmt.Sprintf("%s: %s", UnauthorizedParamChangeError, hex.EncodeToString(owner))) } -func ErrInvalidSigner() Error { - return NewError(CodeInvalidSignerError, InvalidSignerError) +func ErrInvalidSigner(address string) Error { + return NewError(CodeInvalidSignerError, fmt.Sprintf("%s: %s", InvalidSignerError, address)) } func ErrMaxChains(maxChains int) Error { @@ -449,7 +454,7 @@ func ErrUnknownStatus(status int32) Error { return NewError(CodeInvalidStatusError, fmt.Sprintf("%s: unknown status %d", InvalidStatusError, status)) } -func ErrInvalidStatus(got, expected StakeStatus) Error { +func ErrInvalidStatus(got, expected coreTypes.StakeStatus) Error { return NewError(CodeInvalidStatusError, fmt.Sprintf("%s: %d expected %d", InvalidStatusError, got, expected)) } @@ -589,8 +594,8 @@ func ErrSignatureVerificationFailed() Error { return NewError(CodeSignatureVerificationFailedError, SignatureVerificationFailedError) } -func ErrDecodeMessage() Error { - return NewError(CodeDecodeMessageError, DecodeMessageError) +func ErrDecodeMessage(err error) Error { + return NewError(CodeDecodeMessageError, fmt.Sprintf("%s: %s", DecodeMessageError, err.Error())) } func ErrProtoFromAny(err error) Error { @@ -686,6 +691,10 @@ func ErrStringToBigInt(err error) Error { return NewError(CodeStringToBigIntError, fmt.Sprintf("%s: %s", StringToBigIntError, err.Error())) } +func ErrStringToBigFloat(err error) Error { + return NewError(CodeStringToBigFloatError, fmt.Sprintf("%s: %s", StringToBigFloatError, err.Error())) +} + func ErrInsufficientAmount(address string) Error { return NewError(CodeInsufficientAmountError, fmt.Sprintf("%s: with address %s", InsufficientAmountError, address)) } diff --git a/utility/types/gov.go b/utility/types/gov.go index 9e43284e4..33cce6aff 100644 --- a/utility/types/gov.go +++ b/utility/types/gov.go @@ -10,15 +10,14 @@ const ( // Application actor gov params AppMinimumStakeParamName = "app_minimum_stake" AppMaxChainsParamName = "app_max_chains" - AppBaselineStakeRateParamName = "app_baseline_stake_rate" AppUnstakingBlocksParamName = "app_unstaking_blocks" AppMinimumPauseBlocksParamName = "app_minimum_pause_blocks" AppMaxPauseBlocksParamName = "app_max_pause_blocks" - // The constant integer adjustment that the DAO may use to move the stake. The DAO may manually - // adjust an application's MaxRelays at the time of staking to correct for short-term fluctuations - // in the price of POKT, which may not be reflected in ParticipationRate - // When this parameter is set to 0, no adjustment is being made. - AppStakingAdjustmentParamName = "app_staking_adjustment" // IMPROVE: Document & explain the purpose of this parameter in more detail. + // The Application's usage tokens during each session is determined by its stake. The session + // is rate limited using the "Token Bucket" algorithm, where the number of tokens in the beginning + // of each session is determined by this parameter. + //nolint:gosec // G101 - Not a hardcoded credential + AppSessionTokensMultiplierParamName = "app_session_tokens_multiplier" // Servicer actor gov params ServicerMinimumStakeParamName = "servicer_minimum_stake" @@ -94,13 +93,13 @@ const ( BlocksPerSessionOwner = "blocks_per_session_owner" - AppMinimumStakeOwner = "app_minimum_stake_owner" - AppMaxChainsOwner = "app_max_chains_owner" - AppBaselineStakeRateOwner = "app_baseline_stake_rate_owner" - AppStakingAdjustmentOwner = "app_staking_adjustment_owner" - AppUnstakingBlocksOwner = "app_unstaking_blocks_owner" - AppMinimumPauseBlocksOwner = "app_minimum_pause_blocks_owner" - AppMaxPausedBlocksOwner = "app_max_paused_blocks_owner" + AppMinimumStakeOwner = "app_minimum_stake_owner" + AppMaxChainsOwner = "app_max_chains_owner" + //nolint:gosec // G101 - Not a hardcoded credential + AppSessionTokensMultiplierOwner = "app_session_tokens_multiplier_owner" + AppUnstakingBlocksOwner = "app_unstaking_blocks_owner" + AppMinimumPauseBlocksOwner = "app_minimum_pause_blocks_owner" + AppMaxPausedBlocksOwner = "app_max_paused_blocks_owner" ServicerMinimumStakeOwner = "servicer_minimum_stake_owner" ServicerMaxChainsOwner = "servicer_max_chains_owner" diff --git a/utility/types/message.go b/utility/types/message.go index f9f9ad648..688f1d53f 100644 --- a/utility/types/message.go +++ b/utility/types/message.go @@ -15,11 +15,14 @@ import ( type Message interface { proto.Message // TECHDEBT: Still making direct `proto` reference even with a central `codec` package - Validatable + + ValidateBasic() Error + + SetSigner(signerAddr []byte) // TECHDEBT: Convert to string or `crypto.Address` type GetMessageName() string GetMessageRecipient() string - SetSigner(signer []byte) + GetSigner() []byte // TECHDEBT: Convert to string or `crypto.Address` type GetActorType() coreTypes.ActorType GetCanonicalBytes() []byte } @@ -79,6 +82,13 @@ func (msg *MessageChangeParameter) ValidateBasic() Error { return nil } +func (msg *MessageSend) SetSigner(signer []byte) { /* no-op */ } +func (msg *MessageStake) SetSigner(signer []byte) { msg.Signer = signer } +func (msg *MessageEditStake) SetSigner(signer []byte) { msg.Signer = signer } +func (msg *MessageUnstake) SetSigner(signer []byte) { msg.Signer = signer } +func (msg *MessageUnpause) SetSigner(signer []byte) { msg.Signer = signer } +func (msg *MessageChangeParameter) SetSigner(signer []byte) { msg.Signer = signer } + func (msg *MessageSend) GetMessageName() string { return getMessageType(msg) } func (msg *MessageStake) GetMessageName() string { return getMessageType(msg) } func (msg *MessageEditStake) GetMessageName() string { return getMessageType(msg) } @@ -93,12 +103,7 @@ func (msg *MessageUnstake) GetMessageRecipient() string { return "" } func (msg *MessageUnpause) GetMessageRecipient() string { return "" } func (msg *MessageChangeParameter) GetMessageRecipient() string { return "" } -func (msg *MessageSend) SetSigner(signer []byte) { /*no op*/ } -func (msg *MessageStake) SetSigner(signer []byte) { msg.Signer = signer } -func (msg *MessageEditStake) SetSigner(signer []byte) { msg.Signer = signer } -func (msg *MessageUnstake) SetSigner(signer []byte) { msg.Signer = signer } -func (msg *MessageUnpause) SetSigner(signer []byte) { msg.Signer = signer } -func (msg *MessageChangeParameter) SetSigner(signer []byte) { msg.Signer = signer } +func (msg *MessageSend) GetSigner() []byte { return msg.FromAddress } func (msg *MessageSend) GetActorType() coreTypes.ActorType { return coreTypes.ActorType_ACTOR_TYPE_UNSPECIFIED // there's no actor type for message send, so return zero to allow fee retrieval diff --git a/utility/types/message_staking.go b/utility/types/message_staking.go index 4d85f48b1..64f7ba77b 100644 --- a/utility/types/message_staking.go +++ b/utility/types/message_staking.go @@ -5,8 +5,8 @@ import ( "strconv" "strings" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" + "github.com/pokt-network/pocket/shared/utils" ) // This file captures basic logic common across all the actors that need to stake regardless of their responsibility. @@ -44,7 +44,7 @@ func validateStaker(msg stakingMessage) Error { if err := validateRelayChains(msg.GetChains()); err != nil { return err } - return validateServiceUrl(msg.GetActorType(), msg.GetServiceUrl()) + return validateServiceURL(msg.GetActorType(), msg.GetServiceUrl()) } func validateActorType(actorType coreTypes.ActorType) Error { @@ -58,13 +58,13 @@ func validateAmount(amount string) Error { if amount == "" { return ErrEmptyAmount() } - if _, err := converters.StringToBigInt(amount); err != nil { + if _, err := utils.StringToBigInt(amount); err != nil { return ErrStringToBigInt(err) } return nil } -func validateServiceUrl(actorType coreTypes.ActorType, uri string) Error { +func validateServiceURL(actorType coreTypes.ActorType, uri string) Error { if actorType == coreTypes.ActorType_ACTOR_TYPE_APP { return nil } @@ -72,25 +72,25 @@ func validateServiceUrl(actorType coreTypes.ActorType, uri string) Error { uri = strings.ToLower(uri) _, err := url.ParseRequestURI(uri) if err != nil { - return ErrInvalidServiceUrl(err.Error()) + return ErrInvalidServiceURL(err.Error()) } if !(uri[:8] == httpsPrefix || uri[:7] == httpPrefix) { - return ErrInvalidServiceUrl(invalidURLPrefix) + return ErrInvalidServiceURL(invalidURLPrefix) } urlParts := strings.Split(uri, colon) if len(urlParts) != 3 { // protocol:host:port - return ErrInvalidServiceUrl(portRequired) + return ErrInvalidServiceURL(portRequired) } port, err := strconv.Atoi(urlParts[2]) if err != nil { - return ErrInvalidServiceUrl(nonNumberPort) + return ErrInvalidServiceURL(nonNumberPort) } if port > maxPort || port < 0 { - return ErrInvalidServiceUrl(portOutOfRange) + return ErrInvalidServiceURL(portOutOfRange) } if !strings.Contains(uri, period) { - return ErrInvalidServiceUrl(noPeriod) + return ErrInvalidServiceURL(noPeriod) } return nil } diff --git a/utility/types/message_test.go b/utility/types/message_test.go index 585e4f36f..c662e3dca 100644 --- a/utility/types/message_test.go +++ b/utility/types/message_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/pokt-network/pocket/shared/codec" - "github.com/pokt-network/pocket/shared/converters" coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/utils" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" @@ -16,7 +16,7 @@ import ( var ( defaultTestingChains = []string{"0001"} defaultAmountBig = big.NewInt(1000000) - defaultAmount = converters.BigIntToString(defaultAmountBig) + defaultAmount = utils.BigIntToString(defaultAmountBig) defaultUnusedLength = -1 ) diff --git a/utility/types/proto/stake_status.proto b/utility/types/proto/stake_status.proto deleted file mode 100644 index fb6fc40af..000000000 --- a/utility/types/proto/stake_status.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package utility; - -option go_package = "github.com/pokt-network/pocket/utility/types"; - -// REFACTOR(#258): Consolidate with persistence and rename the protobuf types to follow best practices. -enum StakeStatus { - UnknownStatus = 0; - Unstaking = 1; - Staked = 2; - Unstaked = 3; -} diff --git a/utility/types/proto/transaction.proto b/utility/types/proto/transaction.proto deleted file mode 100644 index 03dcd9fde..000000000 --- a/utility/types/proto/transaction.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -package utility; - -option go_package = "github.com/pokt-network/pocket/utility/types"; - -import "google/protobuf/any.proto"; - -// `Transaction` is used to name the type for clarity & verbosity, but `tx` is used method signatures -// and variable names to be concise. https://github.com/pokt-network/pocket/pull/503 -message Transaction { - google.protobuf.Any msg = 1; // CONSOLIDATE: Should be a oneof {} message - Signature signature = 2; // CONSOLIDATE: should use a shared crypto package type - string nonce = 3; -} - -// REFACTOR: Consolidate with other signature types throughout the codebase -message Signature { - bytes public_key = 1; - bytes signature = 2; -} \ No newline at end of file diff --git a/utility/types/proto/tx_result.proto b/utility/types/proto/tx_result.proto index b0c5b08a2..d8c8b4b4e 100644 --- a/utility/types/proto/tx_result.proto +++ b/utility/types/proto/tx_result.proto @@ -4,28 +4,14 @@ package utility; option go_package = "github.com/pokt-network/pocket/utility/types"; -import "transaction.proto"; - -// INVESTIGATE: Look into a way of removing this type altogether or from shared interfaces. - +// TxResult is a hydrated (i.e. blown up) version of the `Transaction` proto. message TxResult { - uint32 code = 1; - bytes signer = 2; - bytes recipient = 3; - string message_type = 4; - int64 height = 5; - uint32 index = 6; - utility.Transaction tx = 7; -} - -// TECHDEBT: Re-evaluate the need for this type altogether -message DefaultTxResult { - bytes tx = 1; // The bytes of the indexed transaction - int64 height = 2; // The block height at which the transaction was included - int32 index = 3; // The order (i.e. position within a block) where the proposer included the transaction - int32 result_code = 4; // INVESTIGATE(andrew): look into having a `utility.Code` enum for this - string error = 5; // INVESTIGATE(andrew): look into having a `utility.Error` enum for this - string signer_addr = 6; - string recipient_addr = 7; - string message_type = 8; // CONSOLIDATE(M4): Once the message types are well defined and stable, consolidate them into an enum + bytes tx = 1; // a serialized `Transaction` proto + int64 height = 2; // the block height at which the transaction was included + int32 index = 3; // the transaction's index within the block (i.e. ordered by when the proposer received it in the mempool) + int32 result_code = 4; // 0 is no error, otherwise corresponds to error object code; // IMPROVE: Consider using enums for the result codes + string error = 5; // description of the error if the result code is non-zero; IMPROVE: Add a specific type fot he error code + string signer_addr = 6; // the address of the signer (e.g. sender) of the transaction + string recipient_addr = 7; // Optional: the address of the recipient of the transaction (if applicable) + string message_type = 8; // the message type contained in the transaction; must correspond to a proto that the node can can process (e.g. Stake, Unstake, Send, etc...) // IMPROVE: How do we document all the types? } \ No newline at end of file diff --git a/utility/types/proto/utility_messages.proto b/utility/types/proto/utility_messages.proto index e93c94998..8a43e2e2d 100644 --- a/utility/types/proto/utility_messages.proto +++ b/utility/types/proto/utility_messages.proto @@ -4,9 +4,9 @@ package utility; option go_package = "github.com/pokt-network/pocket/utility/types"; -// Messages that are sent between nodes (e.g. Evidence) for node specific business logic but are -// not intended to be stored on the blockchain or drive state transitions. +// Messages that are sent between nodes for utility specific purposes but are not intended to be store +// on-chain to derive state transitions. -message TransactionGossipMessage { - bytes tx = 1; +message TxGossipMessage { + bytes tx = 1; // TECHDEBT: Make this an explicit `Transaction` proto type } \ No newline at end of file diff --git a/utility/types/relay_chain.go b/utility/types/relay_chain.go index 899e9b3ca..7463d3d77 100644 --- a/utility/types/relay_chain.go +++ b/utility/types/relay_chain.go @@ -7,10 +7,8 @@ const ( type relayChain string -// No need for a relayChain interface abstraction for the time being -var _ Validatable = relayChain("") - // TODO: Consider adding a governance parameter for a list of valid relay chains +// ValidateBasic validates the relay chain follows a pre-determined format func (rc relayChain) ValidateBasic() Error { if rc == "" { return ErrEmptyRelayChain() diff --git a/utility/types/signature.go b/utility/types/signature.go deleted file mode 100644 index dde49d2e1..000000000 --- a/utility/types/signature.go +++ /dev/null @@ -1,14 +0,0 @@ -package types - -// No need for a Signature interface abstraction for the time being -var _ Validatable = &Signature{} - -func (s *Signature) ValidateBasic() Error { - if s.Signature == nil { - return ErrEmptySignature() - } - if s.PublicKey == nil { - return ErrEmptyPublicKey() - } - return nil -} diff --git a/utility/types/tx_result.go b/utility/types/tx_result.go index 12aedd91a..94aa4cbe1 100644 --- a/utility/types/tx_result.go +++ b/utility/types/tx_result.go @@ -1,28 +1,58 @@ package types import ( + "encoding/hex" + "github.com/pokt-network/pocket/shared/codec" + coreTypes "github.com/pokt-network/pocket/shared/core/types" "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/modules" ) -// INVESTIGATE: Look into a way of removing this type altogether or from shared interfaces. +var _ modules.TxResult = &TxResult{} -var _ modules.TxResult = &DefaultTxResult{} +func TxToTxResult( + tx *coreTypes.Transaction, + height int64, + index int, + msg Message, + msgHandlingResult Error, +) (*TxResult, Error) { + txBz, err := tx.Bytes() + if err != nil { + return nil, ErrProtoMarshal(err) + } + resultCode := int32(0) + errorMsg := "" + if msgHandlingResult != nil { + resultCode = int32(msgHandlingResult.Code()) + errorMsg = msgHandlingResult.Error() + } + return &TxResult{ + Tx: txBz, + Height: height, + Index: int32(index), + ResultCode: resultCode, // TECHDEBT: Remove or update this appropriately. + Error: errorMsg, // TECHDEBT: Remove or update this appropriately. + SignerAddr: hex.EncodeToString(msg.GetSigner()), + RecipientAddr: msg.GetMessageRecipient(), + MessageType: msg.GetMessageName(), + }, nil +} -func (txr *DefaultTxResult) Bytes() ([]byte, error) { +func (txr *TxResult) Bytes() ([]byte, error) { return codec.GetCodec().Marshal(txr) } -func (*DefaultTxResult) FromBytes(bz []byte) (modules.TxResult, error) { - result := new(DefaultTxResult) +func (*TxResult) FromBytes(bz []byte) (modules.TxResult, error) { + result := new(TxResult) if err := codec.GetCodec().Unmarshal(bz, result); err != nil { return nil, err } return result, nil } -func (txr *DefaultTxResult) Hash() ([]byte, error) { +func (txr *TxResult) Hash() ([]byte, error) { bz, err := txr.Bytes() if err != nil { return nil, err @@ -30,24 +60,6 @@ func (txr *DefaultTxResult) Hash() ([]byte, error) { return txr.HashFromBytes(bz) } -func (txr *DefaultTxResult) HashFromBytes(bz []byte) ([]byte, error) { +func (txr *TxResult) HashFromBytes(bz []byte) ([]byte, error) { return crypto.SHA3Hash(bz), nil } - -func (tx *Transaction) ToTxResult(height int64, index int, signer, recipient, msgType string, err Error) (*DefaultTxResult, Error) { - txBytes, er := tx.Bytes() - if er != nil { - return nil, ErrProtoMarshal(er) - } - code, errString := int32(0), "" - return &DefaultTxResult{ - Tx: txBytes, - Height: height, - Index: int32(index), - ResultCode: code, - Error: errString, - SignerAddr: signer, - RecipientAddr: recipient, - MessageType: msgType, - }, nil -} diff --git a/utility/types/validatable.go b/utility/types/validatable.go deleted file mode 100644 index 15747d729..000000000 --- a/utility/types/validatable.go +++ /dev/null @@ -1,7 +0,0 @@ -package types - -type Validatable interface { - // ValidateBasic` is a stateless validation check that should encapsulate all - // validations possible prior to interacting with the storage layer. - ValidateBasic() Error -} diff --git a/utility/utility_message_handler.go b/utility/utility_message_handler.go new file mode 100644 index 000000000..4a9e6d225 --- /dev/null +++ b/utility/utility_message_handler.go @@ -0,0 +1,53 @@ +package utility + +import ( + "fmt" + + "github.com/pokt-network/pocket/shared/codec" + "github.com/pokt-network/pocket/shared/messaging" + "github.com/pokt-network/pocket/utility/types" + typesUtil "github.com/pokt-network/pocket/utility/types" + "google.golang.org/protobuf/types/known/anypb" +) + +func PrepareTxGossipMessage(txBz []byte) (*anypb.Any, error) { + txGossipMessage := &typesUtil.TxGossipMessage{ + Tx: txBz, + } + + // nolint:gocritic // TODO: keeping commented out code in place because this is how it should work in the future + // pocketEnvelope, err := messaging.PackMessage(txGossipMessage) + // if err != nil { + // return nil, err + // } + + anyMessage, err := codec.GetCodec().ToAny(txGossipMessage) + if err != nil { + return nil, err + } + + return anyMessage, nil +} + +func (u *utilityModule) HandleUtilityMessage(message *anypb.Any) error { + switch message.MessageName() { + case messaging.TxGossipMessageContentType: + msg, err := codec.GetCodec().FromAny(message) + if err != nil { + return err + } + + if txGossipMsg, ok := msg.(*types.TxGossipMessage); !ok { + return fmt.Errorf("failed to cast message to UtilityMessage") + } else if err := u.HandleTransaction(txGossipMsg.Tx); err != nil { + return err + } + + u.logger.Info().Str("message_type", "TxGossipMessage").Msg("Successfully added a new message to the mempool!") + + default: + return types.ErrUnknownMessageType(message.MessageName()) + } + + return nil +} diff --git a/utility/validator.go b/utility/validator.go index 3c71a5345..774114644 100644 --- a/utility/validator.go +++ b/utility/validator.go @@ -1,5 +1,7 @@ package utility +// Internal business logic specific to validator behaviour and interactions. + import ( "math/big" @@ -7,18 +9,69 @@ import ( typesUtil "github.com/pokt-network/pocket/utility/types" ) +// handleByzantineValidators identifies & handles byzantine or faulty validators. +// This includes validators who double signed, didn't sign at all or disagree with 2/3+ majority. +// IMPROVE: Need to add more logging to this function. +// INCOMPLETE: handleByzantineValidators is a WIP and needs to be fully designed, implemented, tested and documented +func (u *utilityContext) handleByzantineValidators(prevBlockByzantineValidators [][]byte) typesUtil.Error { + maxMissedBlocks, err := u.getValidatorMaxMissedBlocks() + if err != nil { + return err + } + + for _, address := range prevBlockByzantineValidators { + // Get the latest number of missed blocks by the validator + numMissedBlocks, err := u.store.GetValidatorMissedBlocks(address, u.height) + if err != nil { + return typesUtil.ErrGetMissedBlocks(err) + } + + // increment missed blocks + numMissedBlocks++ + + // handle if under the threshold of max missed blocks + if numMissedBlocks < maxMissedBlocks { + if err := u.store.SetValidatorMissedBlocks(address, numMissedBlocks); err != nil { + return typesUtil.ErrSetMissedBlocks(err) + } + continue + } + + // pause the validator for exceeding the threshold: numMissedBlocks >= maxMissedBlocks + if err := u.store.SetValidatorPauseHeight(address, u.height); err != nil { + return typesUtil.ErrSetPauseHeight(err) + } + // update the number of blocks it missed + if err := u.store.SetValidatorMissedBlocks(address, numMissedBlocks); err != nil { + return typesUtil.ErrSetMissedBlocks(err) + } + // burn validator for missing blocks + if err := u.burnValidator(address); err != nil { + return err + } + } + return nil +} + +// burnValidator burns a validator's stake based on governance parameters for missing blocks +// and begins unstaking if the stake falls below the necessary threshold +// REFACTOR: Extend this to support burning other actors types & pools once the logic is implemented // ADDTEST: There are no good tests for this functionality, which MUST be added. -func (u *utilityContext) burnValidator(burnPercent int, addr []byte) typesUtil.Error { - // TODO: Will need to extend this to support burning from other actors types & pools when the logic is implemented - validatorActorType := coreTypes.ActorType_ACTOR_TYPE_VAL - validatorPool := coreTypes.Pools_POOLS_VALIDATOR_STAKE +func (u *utilityContext) burnValidator(addr []byte) typesUtil.Error { + actorType := coreTypes.ActorType_ACTOR_TYPE_VAL + actorPool := coreTypes.Pools_POOLS_VALIDATOR_STAKE - stakeAmount, err := u.getActorStakeAmount(validatorActorType, addr) + stakeAmount, err := u.getActorStakeAmount(actorType, addr) if err != nil { return err } - // stake after burn = current take * newStake = currentStake * burnPercent / 100 + burnPercent, err := u.getMissedBlocksBurnPercentage() + if err != nil { + return err + } + + // currentStake * burnPercent / 100 burnAmount := new(big.Float).SetInt(stakeAmount) burnAmount.Mul(burnAmount, big.NewFloat(float64(burnPercent))) burnAmount.Quo(burnAmount, big.NewFloat(100)) @@ -30,31 +83,30 @@ func (u *utilityContext) burnValidator(burnPercent int, addr []byte) typesUtil.E burnAmountTruncated = zeroBigInt } - newAmountAfterBurn := big.NewInt(0).Sub(stakeAmount, burnAmountTruncated) - - // remove from pool - if err := u.subPoolAmount(validatorPool.FriendlyName(), burnAmountTruncated); err != nil { + // remove burnt stake amount from the pool + if err := u.subPoolAmount(actorPool.FriendlyName(), burnAmountTruncated); err != nil { return err } - // remove from actor - if err := u.setActorStakeAmount(validatorActorType, addr, newAmountAfterBurn); err != nil { + // remove burnt stake from the actor + newAmountAfterBurn := big.NewInt(0).Sub(stakeAmount, burnAmountTruncated) + if err := u.setActorStakeAmount(actorType, addr, newAmountAfterBurn); err != nil { return err } - // Need to check if new stake is below min required stake - minStake, err := u.getValidatorMinimumStake() + // Need to check if the actor needs to be unstaked + minRequiredStake, err := u.getValidatorMinimumStake() if err != nil { return err } // Check if amount after burn is below the min required stake - if minStake.Cmp(newAmountAfterBurn) == -1 { - unbondingHeight, err := u.getUnbondingHeight(validatorActorType) + if minRequiredStake.Cmp(newAmountAfterBurn) == -1 { + unbondingHeight, err := u.getUnbondingHeight(actorType) if err != nil { return err } - if err := u.setActorUnstakingHeight(validatorActorType, addr, unbondingHeight); err != nil { + if err := u.setActorUnbondingHeight(actorType, addr, unbondingHeight); err != nil { return err } }