diff --git a/Makefile b/Makefile index 2a2735808..61c5621c6 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,8 @@ help: } \ { lastLine = $$0 }' $(MAKEFILE_LIST) +# Internal helper target - check if docker is installed +.PHONY: docker_check docker_check: { \ if ( ! ( command -v docker >/dev/null && command -v docker-compose >/dev/null )); then \ @@ -35,6 +37,8 @@ docker_check: fi; \ } +# Internal helper target - prompt the user before continuing +.PHONY: prompt_user prompt_user: @echo "Are you sure? [y/N] " && read ans && [ $${ans:-N} = y ] @@ -238,12 +242,11 @@ protogen_clean: ## Generate go structures for all of the protobufs protogen_local: $(eval proto_dir = "./shared/types/proto/") - - protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./shared/types/proto --go_out=./shared/types ./shared/types/proto/*.proto - protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./utility/proto --go_out=./utility/types ./utility/proto/*.proto - protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./shared/types/genesis/proto --go_out=./shared/types/genesis ./shared/types/genesis/proto/*.proto - protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./consensus/types/proto --go_out=./consensus/types ./consensus/types/proto/*.proto - protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./p2p/raintree/types/proto --go_out=./p2p/types ./p2p/raintree/types/proto/*.proto + protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./shared/types/proto --go_out=./shared/types ./shared/types/proto/*.proto --experimental_allow_proto3_optional + protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./utility/proto --go_out=./utility/types ./utility/proto/*.proto --experimental_allow_proto3_optional + protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./shared/types/genesis/proto --go_out=./shared/types/genesis ./shared/types/genesis/proto/*.proto --experimental_allow_proto3_optional + protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./consensus/types/proto --go_out=./consensus/types ./consensus/types/proto/*.proto --experimental_allow_proto3_optional + protoc --go_opt=paths=source_relative -I=${proto_dir} -I=./p2p/raintree/types/proto --go_out=./p2p/types ./p2p/raintree/types/proto/*.proto --experimental_allow_proto3_optional echo "View generated proto files by running: make protogen_show" diff --git a/README.md b/README.md index 530fdacbc..a9d529227 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,12 @@ All the links you'll need are listed below. If you'd like to contribute to the P - [Persistence Architecture](persistence/README.md) - _(Soon to be deprecated)_ [PrePersistence Architecture](persistence/pre_persistence/README.md) - [P2P Architecture](p2p/README.md) -- [Utility Architecture](utility/README.md) +- [Utility Architecture](utility/doc/README.md) ### Changelogs - [Consensus Changelog](consensus/CHANGELOG.md) -- [Utility Changelog](utility/CHANGELOG.md) +- [Utility Changelog](utility/doc/CHANGELOG.md) - [Persistence Changelog](persistence/CHANGELOG.md) - _Coming Soon: P2P Changelog_ diff --git a/persistence/README.md b/persistence/README.md index b2a5d6549..b31079038 100644 --- a/persistence/README.md +++ b/persistence/README.md @@ -157,6 +157,7 @@ Short-term (i.e. simpler starter) tasks: - [ ] REFACTOR/DISCUSS: Should we prefix the functions in the `PersistenceModule` with the Param / Actor it's impacting to make autocomplete in implementation better? - [ ] DISCUSS: Consider removing all `Set` methods (e.g. `SetAccountAmount`) and replace with `Add` (e.g. `AddAccountAmount`) by having it leverage a "default zero". - [ ] REFACTOR(https://github.com/pokt-network/pocket/issues/102): Split `account` and `pool` into a shared actor (e.g. like fisherman/validator/serviceNode/application) and simplify the code in half +- [ ] CLEANUP: Remove `tokens` or `stakedTokens` in favor of using `amount` everywhere since the denomination is not clear. As a follow up. Consider a massive rename to make the denomination explicit. Mid-term (i.e. new feature or major refactor) tasks: diff --git a/persistence/application.go b/persistence/application.go index 7b7cf86a6..169524df4 100644 --- a/persistence/application.go +++ b/persistence/application.go @@ -25,11 +25,11 @@ func (p PostgresContext) GetApp(address []byte, height int64) (operator, publicK return } -func (p PostgresContext) InsertApp(address []byte, publicKey []byte, output []byte, _ bool, _ int, maxRelays string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error { +func (p PostgresContext) InsertApp(address []byte, publicKey []byte, output []byte, _ bool, _ int, maxRelays string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error { return p.InsertActor(schema.ApplicationActor, schema.BaseActor{ Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: maxRelays, OutputAddress: hex.EncodeToString(output), PausedHeight: pausedHeight, @@ -38,10 +38,10 @@ func (p PostgresContext) InsertApp(address []byte, publicKey []byte, output []by }) } -func (p PostgresContext) UpdateApp(address []byte, maxRelays string, stakedTokens string, chains []string) error { +func (p PostgresContext) UpdateApp(address []byte, maxRelays string, stakedAmount string, chains []string) error { return p.UpdateActor(schema.ApplicationActor, schema.BaseActor{ Address: hex.EncodeToString(address), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: maxRelays, Chains: chains, }) diff --git a/persistence/fisherman.go b/persistence/fisherman.go index 49609406b..d9cd5e650 100644 --- a/persistence/fisherman.go +++ b/persistence/fisherman.go @@ -25,11 +25,11 @@ func (p PostgresContext) GetFisherman(address []byte, height int64) (operator, p return } -func (p PostgresContext) InsertFisherman(address []byte, publicKey []byte, output []byte, _ bool, _ int, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error { +func (p PostgresContext) InsertFisherman(address []byte, publicKey []byte, output []byte, _ bool, _ int, serviceURL string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error { return p.InsertActor(schema.FishermanActor, schema.BaseActor{ Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: serviceURL, OutputAddress: hex.EncodeToString(output), PausedHeight: pausedHeight, @@ -38,10 +38,10 @@ func (p PostgresContext) InsertFisherman(address []byte, publicKey []byte, outpu }) } -func (p PostgresContext) UpdateFisherman(address []byte, serviceURL string, stakedTokens string, chains []string) error { +func (p PostgresContext) UpdateFisherman(address []byte, serviceURL string, stakedAmount string, chains []string) error { return p.UpdateActor(schema.FishermanActor, schema.BaseActor{ Address: hex.EncodeToString(address), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: serviceURL, Chains: chains, }) diff --git a/persistence/module.go b/persistence/module.go index bfe2e6ea7..aa08671f2 100644 --- a/persistence/module.go +++ b/persistence/module.go @@ -10,6 +10,39 @@ import ( ) var _ modules.PersistenceModule = &persistenceModule{} +var _ modules.PersistenceContext = &PostgresContext{} + +func (p PostgresContext) GetAppStakeAmount(height int64, address []byte) (string, error) { + panic("TODO: implement PostgresContext.GetAppStakeAmount") +} + +func (p PostgresContext) SetAppStakeAmount(address []byte, stakeAmount string) error { + panic("TODO: implement PostgresContext.SetAppStakeAmount") +} + +func (p PostgresContext) GetServiceNodeStakeAmount(height int64, address []byte) (string, error) { + panic("TODO: implement PostgresContext.GetServiceNodeStakeAmount") +} + +func (p PostgresContext) SetServiceNodeStakeAmount(address []byte, stakeAmount string) error { + panic("TODO: implement PostgresContext.SetServiceNodeStakeAmount") +} + +func (p PostgresContext) GetFishermanStakeAmount(height int64, address []byte) (string, error) { + panic("TODO: implement PostgresContext.SetServiceNodeStakeAmount") +} + +func (p PostgresContext) SetFishermanStakeAmount(address []byte, stakeAmount string) error { + panic("TODO: implement PostgresContext.SetFishermanStakeAmount") +} + +func (p PostgresContext) GetValidatorStakeAmount(height int64, address []byte) (string, error) { + panic("TODO: implement PostgresContext.GetValidatorStakeAmount") +} + +func (p PostgresContext) SetValidatorStakeAmount(address []byte, stakeAmount string) error { + panic("TODO: implement PostgresContext.SetValidatorStakeAmount") +} type persistenceModule struct { bus modules.Bus diff --git a/persistence/pre_persistence/account.go b/persistence/pre_persistence/account.go index 2365b9aa6..d4ee5132b 100644 --- a/persistence/pre_persistence/account.go +++ b/persistence/pre_persistence/account.go @@ -25,7 +25,7 @@ func (m *PrePersistenceContext) SubtractPoolAmount(name string, amount string) e sub := func(s *big.Int, s1 *big.Int) error { s.Sub(s, s1) if s.Sign() == -1 { - return types.ErrInsufficientAmountError() + return types.ErrInsufficientAmount() } return nil } @@ -195,7 +195,7 @@ func (m *PrePersistenceContext) SubtractAccountAmount(address []byte, amount str sub := func(s *big.Int, s1 *big.Int) error { s.Sub(s, s1) if s.Sign() == -1 { - return types.ErrInsufficientAmountError() + return types.ErrInsufficientAmount() } return nil } diff --git a/persistence/pre_persistence/app.go b/persistence/pre_persistence/app.go index 6fe206ba6..a1d5ac455 100644 --- a/persistence/pre_persistence/app.go +++ b/persistence/pre_persistence/app.go @@ -82,7 +82,33 @@ func (m *PrePersistenceContext) GetAllApps(height int64) (apps []*typesGenesis.A return } -func (m *PrePersistenceContext) InsertApp(address []byte, publicKey []byte, output []byte, paused bool, status int, maxRelays string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error { +func (m *PrePersistenceContext) GetAppStakeAmount(height int64, address []byte) (string, error) { + app, err := m.GetApp(address, height) + if err != nil { + return "", err + } + return app.StakedTokens, nil +} + +func (m *PrePersistenceContext) SetAppStakeAmount(address []byte, stakeAmount string) error { + codec := types.GetCodec() + db := m.Store() + app, err := m.GetApp(address, m.Height) + if err != nil { + return err + } + if app == nil { + return fmt.Errorf("does not exist in world state: %v", address) + } + app.StakedTokens = stakeAmount + bz, err := codec.Marshal(app) + if err != nil { + return err + } + return db.Put(append(AppPrefixKey, address...), bz) +} + +func (m *PrePersistenceContext) InsertApp(address []byte, publicKey []byte, output []byte, paused bool, status int, maxRelays string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error { height, err := m.GetHeight() if err != nil { return err @@ -100,7 +126,7 @@ func (m *PrePersistenceContext) InsertApp(address []byte, publicKey []byte, outp Status: int32(status), Chains: chains, MaxRelays: maxRelays, - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, Output: output, @@ -112,7 +138,7 @@ func (m *PrePersistenceContext) InsertApp(address []byte, publicKey []byte, outp return db.Put(key, bz) } -func (m *PrePersistenceContext) UpdateApp(address []byte, maxRelaysToAdd string, amountToAdd string, chainsToUpdate []string) error { +func (m *PrePersistenceContext) UpdateApp(address []byte, maxRelaysToAdd string, amount string, chainsToUpdate []string) error { height, err := m.GetHeight() if err != nil { return err @@ -125,15 +151,15 @@ func (m *PrePersistenceContext) UpdateApp(address []byte, maxRelaysToAdd string, db := m.Store() key := append(AppPrefixKey, address...) // compute new values - stakedTokens, err := types.StringToBigInt(app.StakedTokens) - if err != nil { - return err - } - stakedTokensToAddI, err := types.StringToBigInt(amountToAdd) - if err != nil { - return err - } - stakedTokens.Add(stakedTokens, stakedTokensToAddI) + //stakedTokens, err := types.StringToBigInt(app.StakedTokens) + //if err != nil { + // return err + //} + stakedTokens, err := types.StringToBigInt(amount) + //if err != nil { + // return err + //} + //stakedTokens.Add(stakedTokens, stakedTokensToAddI) maxRelays, err := types.StringToBigInt(app.MaxRelays) if err != nil { return err @@ -310,7 +336,7 @@ func (m *PrePersistenceContext) SetAppPauseHeight(address []byte, height int64) if app == nil { return fmt.Errorf("does not exist in world state: %v", address) } - if app.PausedHeight == types.HeightNotUsed { + if height != types.HeightNotUsed { app.Paused = true } else { app.Paused = false diff --git a/persistence/pre_persistence/app_test.go b/persistence/pre_persistence/app_test.go index c8ec8fea7..c78d06030 100644 --- a/persistence/pre_persistence/app_test.go +++ b/persistence/pre_persistence/app_test.go @@ -115,10 +115,6 @@ func TestUpdateApp(t *testing.T) { if err != nil { t.Fatal(err) } - before, err := ctx.(*PrePersistenceContext).GetApp(actor.Address, height) - require.NoError(t, err) - tokens := before.StakedTokens - bigBeforeTokens, err := types.StringToBigInt(tokens) require.NoError(t, err) err = ctx.UpdateApp(actor.Address, zero, one, typesGenesis.DefaultChains) require.NoError(t, err) @@ -126,8 +122,7 @@ func TestUpdateApp(t *testing.T) { require.NoError(t, err) bigAfterTokens, err := types.StringToBigInt(got.StakedTokens) require.NoError(t, err) - bigAfterTokens.Sub(bigAfterTokens, bigBeforeTokens) - if bigAfterTokens.Cmp(bigExpectedTokens) != 0 { + if bigExpectedTokens.Cmp(bigAfterTokens) != 0 { t.Fatal("incorrect after balance") } } diff --git a/persistence/pre_persistence/fisherman.go b/persistence/pre_persistence/fisherman.go index b97198f77..95e8eacf7 100644 --- a/persistence/pre_persistence/fisherman.go +++ b/persistence/pre_persistence/fisherman.go @@ -11,6 +11,10 @@ import ( "google.golang.org/protobuf/proto" ) +func (m *PrePersistenceContext) GetLatestBlockHeight() (uint64, error) { + return uint64(m.Height), nil +} + func (m *PrePersistenceContext) GetFishermanExists(address []byte, height int64) (exists bool, err error) { db := m.Store() key := append(FishermanPrefixKey, address...) @@ -82,7 +86,33 @@ func (m *PrePersistenceContext) GetAllFishermen(height int64) (fishermen []*type return } -func (m *PrePersistenceContext) InsertFisherman(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error { +func (m *PrePersistenceContext) GetFishermanStakeAmount(height int64, address []byte) (string, error) { + fish, _, err := m.GetFisherman(address, height) + if err != nil { + return "", err + } + return fish.StakedTokens, nil +} + +func (m *PrePersistenceContext) SetFishermanStakeAmount(address []byte, stakeAmount string) error { + codec := types.GetCodec() + db := m.Store() + fish, _, err := m.GetFisherman(address, m.Height) + if err != nil { + return err + } + if fish == nil { + return fmt.Errorf("does not exist in world state: %v", address) + } + fish.StakedTokens = stakeAmount + bz, err := codec.Marshal(fish) + if err != nil { + return err + } + return db.Put(append(FishermanPrefixKey, address...), bz) +} + +func (m *PrePersistenceContext) InsertFisherman(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error { height, err := m.GetHeight() if err != nil { return err @@ -100,7 +130,7 @@ func (m *PrePersistenceContext) InsertFisherman(address []byte, publicKey []byte Status: int32(status), Chains: chains, ServiceUrl: serviceURL, - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, Output: output, @@ -112,7 +142,7 @@ func (m *PrePersistenceContext) InsertFisherman(address []byte, publicKey []byte return db.Put(key, bz) } -func (m *PrePersistenceContext) UpdateFisherman(address []byte, serviceURL string, amountToAdd string, chains []string) error { +func (m *PrePersistenceContext) UpdateFisherman(address []byte, serviceURL string, amount string, chains []string) error { height, err := m.GetHeight() if err != nil { return err @@ -125,15 +155,15 @@ func (m *PrePersistenceContext) UpdateFisherman(address []byte, serviceURL strin db := m.Store() key := append(FishermanPrefixKey, address...) // compute new values - stakedTokens, err := types.StringToBigInt(fish.StakedTokens) + //stakedTokens, err := types.StringToBigInt(fish.StakedTokens) + //if err != nil { + // return err + //} + stakedTokens, err := types.StringToBigInt(amount) if err != nil { return err } - stakedTokensToAddI, err := types.StringToBigInt(amountToAdd) - if err != nil { - return err - } - stakedTokens.Add(stakedTokens, stakedTokensToAddI) + //stakedTokens.Add(stakedTokens, stakedTokensToAddI) // update values fish.ServiceUrl = serviceURL fish.StakedTokens = types.BigIntToString(stakedTokens) @@ -294,10 +324,10 @@ func (m *PrePersistenceContext) SetFishermanPauseHeight(address []byte, height i if !exists { return fmt.Errorf("does not exist in world state") } - if height == types.HeightNotUsed { - fish.Paused = false - } else { + if height != types.HeightNotUsed { fish.Paused = true + } else { + fish.Paused = false } fish.PausedHeight = height bz, err := codec.Marshal(fish) diff --git a/persistence/pre_persistence/fisherman_test.go b/persistence/pre_persistence/fisherman_test.go index 5e5cafbb3..9c823a64e 100644 --- a/persistence/pre_persistence/fisherman_test.go +++ b/persistence/pre_persistence/fisherman_test.go @@ -114,10 +114,6 @@ func TestUpdateFisherman(t *testing.T) { if err != nil { t.Fatal(err) } - before, _, err := ctx.(*PrePersistenceContext).GetFisherman(actor.Address, height) - require.NoError(t, err) - tokens := before.StakedTokens - bigBeforeTokens, err := types.StringToBigInt(tokens) require.NoError(t, err) err = ctx.UpdateFisherman(actor.Address, zero, one, typesGenesis.DefaultChains) require.NoError(t, err) @@ -125,8 +121,7 @@ func TestUpdateFisherman(t *testing.T) { require.NoError(t, err) bigAfterTokens, err := types.StringToBigInt(got.StakedTokens) require.NoError(t, err) - bigAfterTokens.Sub(bigAfterTokens, bigBeforeTokens) - if bigAfterTokens.Cmp(bigExpectedTokens) != 0 { + if bigExpectedTokens.Cmp(bigAfterTokens) != 0 { t.Fatal("incorrect after balance") } } diff --git a/persistence/pre_persistence/persistence.go b/persistence/pre_persistence/persistence.go index 3503d5163..ac889506c 100644 --- a/persistence/pre_persistence/persistence.go +++ b/persistence/pre_persistence/persistence.go @@ -101,10 +101,6 @@ type PrePersistenceContext struct { DBs []*memdb.DB } -func (m *PrePersistenceContext) GetLatestBlockHeight() (uint64, error) { - return uint64(m.Height), nil -} - // ExportState Unused but high potential for usefulness for telemetry func (m *PrePersistenceContext) ExportState() (*typesGenesis.GenesisState, types.Error) { var err error diff --git a/persistence/pre_persistence/service_node.go b/persistence/pre_persistence/service_node.go index 7498745f4..96ec72608 100644 --- a/persistence/pre_persistence/service_node.go +++ b/persistence/pre_persistence/service_node.go @@ -63,7 +63,33 @@ func (m *PrePersistenceContext) GetAllServiceNodes(height int64) (sns []*typesGe return } -func (m *PrePersistenceContext) InsertServiceNode(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error { +func (m *PrePersistenceContext) GetServiceNodeStakeAmount(height int64, address []byte) (string, error) { + sn, _, err := m.GetServiceNode(address, height) + if err != nil { + return "", err + } + return sn.StakedTokens, nil +} + +func (m *PrePersistenceContext) SetServiceNodeStakeAmount(address []byte, stakeAmount string) error { + codec := types.GetCodec() + db := m.Store() + sn, _, err := m.GetServiceNode(address, m.Height) + if err != nil { + return err + } + if sn == nil { + return fmt.Errorf("does not exist in world state: %v", address) + } + sn.StakedTokens = stakeAmount + bz, err := codec.Marshal(sn) + if err != nil { + return err + } + return db.Put(append(ServiceNodePrefixKey, address...), bz) +} + +func (m *PrePersistenceContext) InsertServiceNode(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error { height, err := m.GetHeight() if err != nil { return err @@ -81,7 +107,7 @@ func (m *PrePersistenceContext) InsertServiceNode(address []byte, publicKey []by Status: int32(status), Chains: chains, ServiceUrl: serviceURL, - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, Output: output, @@ -93,7 +119,7 @@ func (m *PrePersistenceContext) InsertServiceNode(address []byte, publicKey []by return db.Put(key, bz) } -func (m *PrePersistenceContext) UpdateServiceNode(address []byte, serviceURL string, amountToAdd string, chains []string) error { +func (m *PrePersistenceContext) UpdateServiceNode(address []byte, serviceURL string, amount string, chains []string) error { height, err := m.GetHeight() if err != nil { return err @@ -106,15 +132,15 @@ func (m *PrePersistenceContext) UpdateServiceNode(address []byte, serviceURL str db := m.Store() key := append(ServiceNodePrefixKey, address...) // compute new values - stakedTokens, err := types.StringToBigInt(sn.StakedTokens) - if err != nil { - return err - } - stakedTokensToAddI, err := types.StringToBigInt(amountToAdd) + //stakedTokens, err := types.StringToBigInt(sn.StakedTokens) + //if err != nil { + // return err + //} + stakedTokens, err := types.StringToBigInt(amount) if err != nil { return err } - stakedTokens.Add(stakedTokens, stakedTokensToAddI) + //stakedTokens.Add(stakedTokens, stakedTokensToAddI) // update values sn.ServiceUrl = serviceURL sn.StakedTokens = types.BigIntToString(stakedTokens) @@ -296,10 +322,10 @@ func (m *PrePersistenceContext) SetServiceNodePauseHeight(address []byte, height if !exists { return fmt.Errorf("does not exist in world state") } - if height == types.HeightNotUsed { - sn.Paused = false - } else { + if height != types.HeightNotUsed { sn.Paused = true + } else { + sn.Paused = false } sn.PausedHeight = height bz, err := codec.Marshal(sn) diff --git a/persistence/pre_persistence/service_node_test.go b/persistence/pre_persistence/service_node_test.go index fb449c790..8424081b3 100644 --- a/persistence/pre_persistence/service_node_test.go +++ b/persistence/pre_persistence/service_node_test.go @@ -114,10 +114,6 @@ func TestUpdateServiceNode(t *testing.T) { if err != nil { t.Fatal(err) } - before, _, err := ctx.(*PrePersistenceContext).GetServiceNode(actor.Address, height) - require.NoError(t, err) - tokens := before.StakedTokens - bigBeforeTokens, err := types.StringToBigInt(tokens) require.NoError(t, err) err = ctx.UpdateServiceNode(actor.Address, zero, one, typesGenesis.DefaultChains) require.NoError(t, err) @@ -125,7 +121,6 @@ func TestUpdateServiceNode(t *testing.T) { require.NoError(t, err) bigAfterTokens, err := types.StringToBigInt(got.StakedTokens) require.NoError(t, err) - bigAfterTokens.Sub(bigAfterTokens, bigBeforeTokens) if bigAfterTokens.Cmp(bigExpectedTokens) != 0 { t.Fatal("incorrect after balance") } diff --git a/persistence/pre_persistence/validator.go b/persistence/pre_persistence/validator.go index f834eeb37..6bcd73ad6 100644 --- a/persistence/pre_persistence/validator.go +++ b/persistence/pre_persistence/validator.go @@ -63,6 +63,32 @@ func (m *PrePersistenceContext) GetAllValidators(height int64) (v []*typesGenesi return } +func (m *PrePersistenceContext) GetValidatorStakeAmount(height int64, address []byte) (string, error) { + val, _, err := m.GetValidator(address, height) + if err != nil { + return "", err + } + return val.StakedTokens, nil +} + +func (m *PrePersistenceContext) SetValidatorStakeAmount(address []byte, stakeAmount string) error { + codec := types.GetCodec() + db := m.Store() + val, _, err := m.GetValidator(address, m.Height) + if err != nil { + return err + } + if val == nil { + return fmt.Errorf("does not exist in world state: %v", address) + } + val.StakedTokens = stakeAmount + bz, err := codec.Marshal(val) + if err != nil { + return err + } + return db.Put(append(ValidatorPrefixKey, address...), bz) +} + func (m *PrePersistenceContext) GetValidatorExists(address []byte, height int64) (exists bool, err error) { db := m.Store() key := append(ValidatorPrefixKey, address...) @@ -82,7 +108,7 @@ func (m *PrePersistenceContext) GetValidatorExists(address []byte, height int64) return true, nil } -func (m *PrePersistenceContext) InsertValidator(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedTokens string, pausedHeight int64, unstakingHeight int64) error { +func (m *PrePersistenceContext) InsertValidator(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedAmount string, pausedHeight int64, unstakingHeight int64) error { height, err := m.GetHeight() if err != nil { return err @@ -99,7 +125,7 @@ func (m *PrePersistenceContext) InsertValidator(address []byte, publicKey []byte Paused: paused, Status: int32(status), ServiceUrl: serviceURL, - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, MissedBlocks: 0, PausedHeight: pausedHeight, UnstakingHeight: unstakingHeight, @@ -112,7 +138,7 @@ func (m *PrePersistenceContext) InsertValidator(address []byte, publicKey []byte return db.Put(key, bz) } -func (m *PrePersistenceContext) UpdateValidator(address []byte, serviceURL string, amountToAdd string) error { +func (m *PrePersistenceContext) UpdateValidator(address []byte, serviceURL string, amount string) error { height, err := m.GetHeight() if err != nil { return err @@ -125,15 +151,15 @@ func (m *PrePersistenceContext) UpdateValidator(address []byte, serviceURL strin db := m.Store() key := append(ValidatorPrefixKey, address...) // compute new values - stakedTokens, err := types.StringToBigInt(val.StakedTokens) + //stakedTokens, err := types.StringToBigInt(val.StakedTokens) + //if err != nil { + // return err + //} + stakedTokens, err := types.StringToBigInt(amount) if err != nil { return err } - stakedTokensToAddI, err := types.StringToBigInt(amountToAdd) - if err != nil { - return err - } - stakedTokens.Add(stakedTokens, stakedTokensToAddI) + //stakedTokens.Add(stakedTokens, stakedTokensToAddI) // update values val.ServiceUrl = serviceURL val.StakedTokens = types.BigIntToString(stakedTokens) @@ -350,10 +376,10 @@ func (m *PrePersistenceContext) SetValidatorPauseHeight(address []byte, height i if !exists { return fmt.Errorf("does not exist in world state") } - if height == types.HeightNotUsed { - val.Paused = false - } else { + if height != types.HeightNotUsed { val.Paused = true + } else { + val.Paused = false } val.PausedHeight = height bz, err := codec.Marshal(val) diff --git a/persistence/pre_persistence/validator_test.go b/persistence/pre_persistence/validator_test.go index 78140765c..ced5421bf 100644 --- a/persistence/pre_persistence/validator_test.go +++ b/persistence/pre_persistence/validator_test.go @@ -112,10 +112,6 @@ func TestUpdateValidator(t *testing.T) { if err != nil { t.Fatal(err) } - before, _, err := ctx.(*PrePersistenceContext).GetValidator(actor.Address, height) - require.NoError(t, err) - tokens := before.StakedTokens - bigBeforeTokens, err := types.StringToBigInt(tokens) require.NoError(t, err) err = ctx.UpdateValidator(actor.Address, typesGenesis.DefaultServiceUrl, one) require.NoError(t, err) @@ -123,7 +119,6 @@ func TestUpdateValidator(t *testing.T) { require.NoError(t, err) bigAfterTokens, err := types.StringToBigInt(got.StakedTokens) require.NoError(t, err) - bigAfterTokens.Sub(bigAfterTokens, bigBeforeTokens) if bigAfterTokens.Cmp(bigExpectedTokens) != 0 { t.Fatal("incorrect after balance") } diff --git a/persistence/service_node.go b/persistence/service_node.go index 68e7f3ba7..a825b8320 100644 --- a/persistence/service_node.go +++ b/persistence/service_node.go @@ -25,11 +25,11 @@ func (p PostgresContext) GetServiceNode(address []byte, height int64) (operator, return } -func (p PostgresContext) InsertServiceNode(address []byte, publicKey []byte, output []byte, _ bool, _ int, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error { +func (p PostgresContext) InsertServiceNode(address []byte, publicKey []byte, output []byte, _ bool, _ int, serviceURL string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error { return p.InsertActor(schema.ServiceNodeActor, schema.BaseActor{ Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: serviceURL, OutputAddress: hex.EncodeToString(output), PausedHeight: pausedHeight, @@ -38,10 +38,10 @@ func (p PostgresContext) InsertServiceNode(address []byte, publicKey []byte, out }) } -func (p PostgresContext) UpdateServiceNode(address []byte, serviceURL string, stakedTokens string, chains []string) error { +func (p PostgresContext) UpdateServiceNode(address []byte, serviceURL string, stakedAmount string, chains []string) error { return p.UpdateActor(schema.ServiceNodeActor, schema.BaseActor{ Address: hex.EncodeToString(address), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: serviceURL, Chains: chains, }) diff --git a/persistence/test/gov_test.go b/persistence/test/gov_test.go index 68a9045a2..102a55bcf 100644 --- a/persistence/test/gov_test.go +++ b/persistence/test/gov_test.go @@ -34,7 +34,5 @@ func TestGetSetParam(t *testing.T) { maxChains, err := db.GetMaxAppChains() require.NoError(t, err) - if maxChains != newMaxChains { - t.Fatal("unexpected param value") - } + require.Equal(t, newMaxChains, maxChains) } diff --git a/persistence/validator.go b/persistence/validator.go index c57752e8a..3f3095ada 100644 --- a/persistence/validator.go +++ b/persistence/validator.go @@ -24,11 +24,11 @@ func (p PostgresContext) GetValidator(address []byte, height int64) (operator, p return } -func (p PostgresContext) InsertValidator(address []byte, publicKey []byte, output []byte, _ bool, _ int, serviceURL string, stakedTokens string, pausedHeight int64, unstakingHeight int64) error { +func (p PostgresContext) InsertValidator(address []byte, publicKey []byte, output []byte, _ bool, _ int, serviceURL string, stakedAmount string, pausedHeight int64, unstakingHeight int64) error { return p.InsertActor(schema.ValidatorActor, schema.BaseActor{ Address: hex.EncodeToString(address), PublicKey: hex.EncodeToString(publicKey), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: serviceURL, OutputAddress: hex.EncodeToString(output), PausedHeight: pausedHeight, @@ -36,10 +36,10 @@ func (p PostgresContext) InsertValidator(address []byte, publicKey []byte, outpu }) } -func (p PostgresContext) UpdateValidator(address []byte, serviceURL string, stakedTokens string) error { +func (p PostgresContext) UpdateValidator(address []byte, serviceURL string, stakedAmount string) error { return p.UpdateActor(schema.ValidatorActor, schema.BaseActor{ Address: hex.EncodeToString(address), - StakedTokens: stakedTokens, + StakedTokens: stakedAmount, ActorSpecificParam: serviceURL, }) } diff --git a/shared/crypto/keys.go b/shared/crypto/keys.go index a10fb99a2..3c825eb88 100644 --- a/shared/crypto/keys.go +++ b/shared/crypto/keys.go @@ -48,6 +48,10 @@ func (a *Address) ToString() string { return hex.EncodeToString(*a) } +func (a Address) Bytes() []byte { + return []byte(a) +} + func (a Address) Equals(other Address) bool { return bytes.Equal(a, other) } diff --git a/shared/modules/persistence_module.go b/shared/modules/persistence_module.go index 929cd8ede..2e35a66e1 100644 --- a/shared/modules/persistence_module.go +++ b/shared/modules/persistence_module.go @@ -54,9 +54,11 @@ type PersistenceContext interface { // App Operations GetAppExists(address []byte, height int64) (exists bool, err error) - InsertApp(address []byte, publicKey []byte, output []byte, paused bool, status int, maxRelays string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error - UpdateApp(address []byte, maxRelaysToAdd string, amountToAdd string, chainsToUpdate []string) error + InsertApp(address []byte, publicKey []byte, output []byte, paused bool, status int, maxRelays string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error + UpdateApp(address []byte, maxRelays string, stakedAmount string, chainsToUpdate []string) error DeleteApp(address []byte) error + GetAppStakeAmount(height int64, address []byte) (string, error) + SetAppStakeAmount(address []byte, stakeAmount string) error GetAppsReadyToUnstake(height int64, status int) (apps []*types.UnstakingActor, err error) GetAppStatus(address []byte, height int64) (status int, err error) SetAppUnstakingHeightAndStatus(address []byte, unstakingHeight int64, status int) error @@ -67,9 +69,11 @@ type PersistenceContext interface { // ServiceNode Operations GetServiceNodeExists(address []byte, height int64) (exists bool, err error) - InsertServiceNode(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error - UpdateServiceNode(address []byte, serviceURL string, amountToAdd string, chains []string) error + InsertServiceNode(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error + UpdateServiceNode(address []byte, serviceURL string, stakedAmount string, chains []string) error DeleteServiceNode(address []byte) error + GetServiceNodeStakeAmount(height int64, address []byte) (string, error) + SetServiceNodeStakeAmount(address []byte, stakeAmount string) error GetServiceNodesReadyToUnstake(height int64, status int) (serviceNodes []*types.UnstakingActor, err error) GetServiceNodeStatus(address []byte, height int64) (status int, err error) SetServiceNodeUnstakingHeightAndStatus(address []byte, unstakingHeight int64, status int) error @@ -83,9 +87,11 @@ type PersistenceContext interface { // Fisherman Operations GetFishermanExists(address []byte, height int64) (exists bool, err error) - InsertFisherman(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedTokens string, chains []string, pausedHeight int64, unstakingHeight int64) error - UpdateFisherman(address []byte, serviceURL string, amountToAdd string, chains []string) error + InsertFisherman(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedAmount string, chains []string, pausedHeight int64, unstakingHeight int64) error + UpdateFisherman(address []byte, serviceURL string, stakedAmount string, chains []string) error DeleteFisherman(address []byte) error + GetFishermanStakeAmount(height int64, address []byte) (string, error) + SetFishermanStakeAmount(address []byte, stakeAmount string) error GetFishermenReadyToUnstake(height int64, status int) (fishermen []*types.UnstakingActor, err error) GetFishermanStatus(address []byte, height int64) (status int, err error) SetFishermanUnstakingHeightAndStatus(address []byte, unstakingHeight int64, status int) error @@ -96,9 +102,11 @@ type PersistenceContext interface { // Validator Operations GetValidatorExists(address []byte, height int64) (exists bool, err error) - InsertValidator(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedTokens string, pausedHeight int64, unstakingHeight int64) error - UpdateValidator(address []byte, serviceURL string, amountToAdd string) error + InsertValidator(address []byte, publicKey []byte, output []byte, paused bool, status int, serviceURL string, stakedAmount string, pausedHeight int64, unstakingHeight int64) error + UpdateValidator(address []byte, serviceURL string, stakedAmount string) error DeleteValidator(address []byte) error + GetValidatorStakeAmount(height int64, address []byte) (string, error) + SetValidatorStakeAmount(address []byte, stakeAmount string) error GetValidatorsReadyToUnstake(height int64, status int) (validators []*types.UnstakingActor, err error) GetValidatorStatus(address []byte, height int64) (status int, err error) SetValidatorUnstakingHeightAndStatus(address []byte, unstakingHeight int64, status int) error @@ -112,9 +120,6 @@ type PersistenceContext interface { SetValidatorMissedBlocks(address []byte, missedBlocks int) error GetValidatorMissedBlocks(address []byte, height int64) (int, error) - SetValidatorStakedTokens(address []byte, tokens string) error - GetValidatorStakedTokens(address []byte, height int64) (tokens string, err error) - /* TODO(olshansky): review/revisit this in more details */ // Params diff --git a/shared/tests/utility_module/account_test.go b/shared/tests/utility_module/account_test.go index 01b5673c4..cb977c98a 100644 --- a/shared/tests/utility_module/account_test.go +++ b/shared/tests/utility_module/account_test.go @@ -1,7 +1,7 @@ package utility_module import ( - "bytes" + "fmt" "math/big" "testing" @@ -17,140 +17,145 @@ import ( func TestUtilityContext_AddAccountAmount(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) acc := GetAllTestingAccounts(t, ctx)[0] + initialAmount, err := types.StringToBigInt(acc.Amount) require.NoError(t, err) + addAmount := big.NewInt(1) - if err := ctx.AddAccountAmount(acc.Address, addAmount); err != nil { - t.Fatal(err) - } + err = ctx.AddAccountAmount(acc.Address, addAmount) + require.NoError(t, err, "add account amount") + afterAmount, err := ctx.GetAccountAmount(acc.Address) require.NoError(t, err) + expected := initialAmount.Add(initialAmount, addAmount) - if afterAmount.Cmp(expected) != 0 { - t.Fatalf("amounts are not equal, expected %v, got %v", initialAmount, afterAmount) - } + require.Equal(t, afterAmount, expected, "amounts are not equal") } func TestUtilityContext_AddAccountAmountString(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) acc := GetAllTestingAccounts(t, ctx)[0] + initialAmount, err := types.StringToBigInt(acc.Amount) require.NoError(t, err) + addAmount := big.NewInt(1) addAmountString := types.BigIntToString(addAmount) - if err := ctx.AddAccountAmountString(acc.Address, addAmountString); err != nil { - t.Fatal(err) - } + err = ctx.AddAccountAmountString(acc.Address, addAmountString) + require.NoError(t, err, "add account amount string") + afterAmount, err := ctx.GetAccountAmount(acc.Address) require.NoError(t, err) + expected := initialAmount.Add(initialAmount, addAmount) - if afterAmount.Cmp(expected) != 0 { - t.Fatalf("amounts are not equal, expected %v, got %v", initialAmount, afterAmount) - } + require.Equal(t, afterAmount, expected, "amounts are not equal") } func TestUtilityContext_AddPoolAmount(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) pool := GetAllTestingPools(t, ctx)[0] + initialAmount, err := types.StringToBigInt(pool.Account.Amount) require.NoError(t, err) + addAmount := big.NewInt(1) - if err := ctx.AddPoolAmount(pool.Name, addAmount); err != nil { - t.Fatal(err) - } + err = ctx.AddPoolAmount(pool.Name, addAmount) + require.NoError(t, err, "add pool amount") + afterAmount, err := ctx.GetPoolAmount(pool.Name) require.NoError(t, err) + expected := initialAmount.Add(initialAmount, addAmount) - if afterAmount.Cmp(expected) != 0 { - t.Fatalf("amounts are not equal, expected %v, got %v", initialAmount, afterAmount) - } + require.Equal(t, afterAmount, expected, "amounts are not equal") } func TestUtilityContext_HandleMessageSend(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) accs := GetAllTestingAccounts(t, ctx) + sendAmount := big.NewInt(1000000) sendAmountString := types.BigIntToString(sendAmount) senderBalanceBefore, err := types.StringToBigInt(accs[0].Amount) require.NoError(t, err) + recipientBalanceBefore, err := types.StringToBigInt(accs[1].Amount) require.NoError(t, err) + msg := NewTestingSendMessage(t, accs[0].Address, accs[1].Address, sendAmountString) - if err := ctx.HandleMessageSend(&msg); err != nil { - t.Fatal(err) - } + err = ctx.HandleMessageSend(&msg) + require.NoError(t, err, "handle message send") + accs = GetAllTestingAccounts(t, ctx) senderBalanceAfter, err := types.StringToBigInt(accs[0].Amount) require.NoError(t, err) + recipientBalanceAfter, err := types.StringToBigInt(accs[1].Amount) require.NoError(t, err) - if big.NewInt(0).Sub(senderBalanceBefore, senderBalanceAfter).Cmp(sendAmount) != 0 { - t.Fatal("unexpected sender balance") - } - if big.NewInt(0).Sub(recipientBalanceAfter, recipientBalanceBefore).Cmp(sendAmount) != 0 { - t.Fatal("unexpected recipient balance") - } + require.Equal(t, big.NewInt(0).Sub(senderBalanceBefore, senderBalanceAfter), sendAmount, "unexpected sender balance") + require.Equal(t, big.NewInt(0).Sub(recipientBalanceAfter, recipientBalanceBefore), sendAmount, "unexpected recipient balance") } func TestUtilityContext_GetMessageSendSignerCandidates(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) accs := GetAllTestingAccounts(t, ctx) + sendAmount := big.NewInt(1000000) sendAmountString := types.BigIntToString(sendAmount) + msg := NewTestingSendMessage(t, accs[0].Address, accs[1].Address, sendAmountString) candidates, err := ctx.GetMessageSendSignerCandidates(&msg) require.NoError(t, err) - if len(candidates) != 1 { - t.Fatalf("wrong number of candidates, expected %d, got %d", 1, len(candidates)) - } - if !bytes.Equal(candidates[0], accs[0].Address) { - t.Fatal("unexpected signer candidate") - } + require.Equal(t, 1, len(candidates), "wrong number of candidates") + require.Equal(t, candidates[0], accs[0].Address, "unexpected signer candidate") } func TestUtilityContext_InsertPool(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) testPoolName := "TEST_POOL" - addr, _ := crypto.GenerateAddress() + + addr, err := crypto.GenerateAddress() + require.NoError(t, err) + amount := types.BigIntToString(big.NewInt(1000)) - if err := ctx.InsertPool(testPoolName, addr, amount); err != nil { - t.Fatal(err) - } + err = ctx.InsertPool(testPoolName, addr, amount) + require.NoError(t, err, "insert pool") + gotAmount, err := ctx.GetPoolAmount(testPoolName) require.NoError(t, err) + gotAmountString := types.BigIntToString(gotAmount) - if amount != gotAmountString { - t.Fatalf("unexpected amount, expected %s got %s", amount, gotAmountString) - } + require.True(t, amount == gotAmountString, fmt.Sprintf("unexpected amount")) } func TestUtilityContext_SetAccountAmount(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) - addr, _ := crypto.GenerateAddress() + + addr, err := crypto.GenerateAddress() + require.NoError(t, err) + amount := big.NewInt(100) - if err := ctx.SetAccountAmount(addr, amount); err != nil { - t.Fatal(err) - } + err = ctx.SetAccountAmount(addr, amount) + require.NoError(t, err, "set account amount") + gotAmount, err := ctx.GetAccountAmount(addr) require.NoError(t, err) - if gotAmount.Cmp(amount) != 0 { - t.Fatalf("unexpected amounts: expected %v, got %v", amount, gotAmount) - } + require.Equal(t, gotAmount, amount, "unexpected amounts") } func TestUtilityContext_SetAccountWithAmountString(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) - addr, _ := crypto.GenerateAddress() + + addr, err := crypto.GenerateAddress() + require.NoError(t, err) + amount := big.NewInt(100) amountString := types.BigIntToString(amount) - if err := ctx.SetAccountWithAmountString(addr, amountString); err != nil { - t.Fatal(err) - } + err = ctx.SetAccountWithAmountString(addr, amountString) + require.NoError(t, err, "set account amount string") + gotAmount, err := ctx.GetAccountAmount(addr) require.NoError(t, err) - if gotAmount.Cmp(amount) != 0 { - t.Fatalf("unexpected amounts: expected %v, got %v", amount, gotAmount) - } + require.Equal(t, gotAmount, amount, "unexpected amounts: expected") } func TestUtilityContext_SetPoolAmount(t *testing.T) { @@ -160,17 +165,13 @@ func TestUtilityContext_SetPoolAmount(t *testing.T) { beforeAmountBig, err := types.StringToBigInt(beforeAmount) require.NoError(t, err) expectedAfterAmount := big.NewInt(100) - if err := ctx.SetPoolAmount(pool.Name, expectedAfterAmount); err != nil { - t.Fatal(err) - } + err = ctx.SetPoolAmount(pool.Name, expectedAfterAmount) + require.NoError(t, err, "set pool amount") + amount, err := ctx.GetPoolAmount(pool.Name) require.NoError(t, err) - if beforeAmountBig.Cmp(amount) == 0 { - t.Fatal("no amount change in pool") - } - if expectedAfterAmount.Cmp(amount) != 0 { - t.Fatalf("unexpected pool amount; expected %v got %v", expectedAfterAmount, amount) - } + require.NotEqual(t, beforeAmountBig, amount, "no amount change in pool") + require.Equal(t, expectedAfterAmount, amount, "unexpected pool amount") } func TestUtilityContext_SubPoolAmount(t *testing.T) { @@ -180,39 +181,35 @@ func TestUtilityContext_SubPoolAmount(t *testing.T) { ctx.SetPoolAmount(pool.Name, beforeAmountBig) subAmountBig := big.NewInt(100) subAmount := types.BigIntToString(subAmountBig) - if err := ctx.SubPoolAmount(pool.Name, subAmount); err != nil { - t.Fatal(err) - } + err := ctx.SubPoolAmount(pool.Name, subAmount) + require.NoError(t, err, "sub pool amount") + amount, err := ctx.GetPoolAmount(pool.Name) require.NoError(t, err) - if beforeAmountBig.Cmp(amount) == 0 { - t.Fatal("no amount change in pool") - } + require.NotEqual(t, beforeAmountBig, amount, "no amount change in pool") + expected := beforeAmountBig.Sub(beforeAmountBig, subAmountBig) - if expected.Cmp(amount) != 0 { - t.Fatalf("unexpected pool amount; expected %v got %v", expected, amount) - } + require.Equal(t, expected, amount, "unexpected pool amount") } func TestUtilityContext_SubtractAccountAmount(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) acc := GetAllTestingAccounts(t, ctx)[0] + beforeAmount := acc.Amount beforeAmountBig, err := types.StringToBigInt(beforeAmount) require.NoError(t, err) + subAmountBig := big.NewInt(100) - if err := ctx.SubtractAccountAmount(acc.Address, subAmountBig); err != nil { - t.Fatal(err) - } + err = ctx.SubtractAccountAmount(acc.Address, subAmountBig) + require.NoError(t, err, "sub account amount") + amount, err := ctx.GetAccountAmount(acc.Address) require.NoError(t, err) - if beforeAmountBig.Cmp(amount) == 0 { - t.Fatal("no amount change in pool") - } + require.NotEqual(t, beforeAmountBig, amount, "no amount change in pool") + expected := beforeAmountBig.Sub(beforeAmountBig, subAmountBig) - if expected.Cmp(amount) != 0 { - t.Fatalf("unexpected acc amount; expected %v got %v", expected, amount) - } + require.Equal(t, expected, amount, "unexpected acc amount") } func GetAllTestingAccounts(t *testing.T, ctx utility.UtilityContext) []*genesis.Account { diff --git a/shared/tests/utility_module/actor_test.go b/shared/tests/utility_module/actor_test.go new file mode 100644 index 000000000..16ab1afb6 --- /dev/null +++ b/shared/tests/utility_module/actor_test.go @@ -0,0 +1,586 @@ +package utility_module + +import ( + "bytes" + "fmt" + "math" + "math/big" + "testing" + + "github.com/pokt-network/pocket/persistence/pre_persistence" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + + "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/types" + "github.com/pokt-network/pocket/shared/types/genesis" + "github.com/pokt-network/pocket/utility" + typesUtil "github.com/pokt-network/pocket/utility/types" +) + +// INVESTIGATE: Is there a better way to implement this than to simply have an actors forloop in each test? + +func TestUtilityContext_HandleMessageStake(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.HandleMessageStake", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + pubKey, err := crypto.GeneratePublicKey() + require.NoError(t, err) + + outputAddress, err := crypto.GenerateAddress() + require.NoError(t, err) + + err = ctx.SetAccountAmount(outputAddress, defaultAmount) + require.NoError(t, err, "error setting account amount error") + + msg := &typesUtil.MessageStake{ + PublicKey: pubKey.Bytes(), + Chains: defaultTestingChains, + Amount: defaultAmountString, + ServiceUrl: "https://localhost.com", + OutputAddress: outputAddress, + Signer: outputAddress, + ActorType: actorType, + } + + er := ctx.HandleStakeMessage(msg) + require.NoError(t, er, "handle stake message") + + actor := GetActorByAddr(t, ctx, pubKey.Address().Bytes(), actorType) + + require.Equal(t, actor.GetAddress(), pubKey.Address().Bytes(), "incorrect actor address") + require.Equal(t, actor.GetStatus(), int32(typesUtil.StakedStatus), "incorrect actor status") + if actorType != typesUtil.ActorType_Val { + require.Equal(t, actor.GetChains(), msg.Chains, "incorrect actor chains") + } + require.False(t, actor.GetPaused(), "incorrect actor paused status") + require.Equal(t, actor.GetPausedHeight(), types.HeightNotUsed, "incorrect actor height") + require.Equal(t, actor.GetStakedTokens(), defaultAmountString, "incorrect actor stake amount") + require.Equal(t, actor.GetUnstakingHeight(), types.HeightNotUsed, "incorrect actor unstaking height") + require.Equal(t, actor.GetOutput(), outputAddress.Bytes(), "incorrect actor output address") + }) + } +} + +func TestUtilityContext_HandleMessageEditStake(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.HandleMessageEditStake", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + actor := GetFirstActor(t, ctx, actorType) + msg := &typesUtil.MessageEditStake{ + Address: actor.GetAddress(), + Chains: defaultTestingChains, + Amount: defaultAmountString, + Signer: actor.GetAddress(), + ActorType: actorType, + } + + msgChainsEdited := proto.Clone(msg).(*typesUtil.MessageEditStake) + msgChainsEdited.Chains = defaultTestingChainsEdited + + err := ctx.HandleEditStakeMessage(msgChainsEdited) + require.NoError(t, err, "handle edit stake message") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.False(t, actor.GetPaused(), "incorrect paused status") + require.Equal(t, actor.GetPausedHeight(), types.HeightNotUsed, "incorrect paused height") + if actorType != typesUtil.ActorType_Val { + require.Equal(t, actor.GetChains(), msgChainsEdited.Chains, "incorrect edited chains") + } + require.Equal(t, actor.GetStakedTokens(), defaultAmountString, "incorrect staked tokens") + require.Equal(t, actor.GetUnstakingHeight(), types.HeightNotUsed, "incorrect unstaking height") + + amountEdited := defaultAmount.Add(defaultAmount, big.NewInt(1)) + amountEditedString := types.BigIntToString(amountEdited) + msgAmountEdited := proto.Clone(msg).(*typesUtil.MessageEditStake) + msgAmountEdited.Amount = amountEditedString + + err = ctx.HandleEditStakeMessage(msgAmountEdited) + require.NoError(t, err, "handle edit stake message") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.Equal(t, actor.GetStakedTokens(), types.BigIntToString(amountEdited), "incorrect staked amount") + }) + } +} + +func TestUtilityContext_HandleMessageUnpause(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.HandleMessageUnpause", actorType.GetActorName()), func(t *testing.T) { + + ctx := NewTestingUtilityContext(t, 1) + var err error + switch actorType { + case typesUtil.ActorType_Val: + err = ctx.Context.SetValidatorMinimumPauseBlocks(0) + case typesUtil.ActorType_Node: + err = ctx.Context.SetServiceNodeMinimumPauseBlocks(0) + case typesUtil.ActorType_App: + err = ctx.Context.SetAppMinimumPauseBlocks(0) + case typesUtil.ActorType_Fish: + err = ctx.Context.SetFishermanMinimumPauseBlocks(0) + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, err, "error setting minimum pause blocks") + + actor := GetFirstActor(t, ctx, actorType) + err = ctx.SetActorPauseHeight(actorType, actor.GetAddress(), 1) + require.NoError(t, err, "error setting pause height") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.True(t, actor.GetPaused(), "actor should be paused") + + msgUnpauseActor := &typesUtil.MessageUnpause{ + Address: actor.GetAddress(), + Signer: actor.GetAddress(), + ActorType: actorType, + } + + err = ctx.HandleUnpauseMessage(msgUnpauseActor) + require.NoError(t, err, "handle unpause message") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.False(t, actor.GetPaused(), "actor should not be paused") + }) + } +} + +func TestUtilityContext_HandleMessageUnstake(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.HandleMessageUnstake", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 1) + var err error + switch actorType { + case typesUtil.ActorType_App: + err = ctx.Context.SetAppMinimumPauseBlocks(0) + case typesUtil.ActorType_Val: + err = ctx.Context.SetValidatorMinimumPauseBlocks(0) + case typesUtil.ActorType_Fish: + err = ctx.Context.SetFishermanMinimumPauseBlocks(0) + case typesUtil.ActorType_Node: + err = ctx.Context.SetServiceNodeMinimumPauseBlocks(0) + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, err, "error setting minimum pause blocks") + + actor := GetFirstActor(t, ctx, actorType) + msg := &typesUtil.MessageUnstake{ + Address: actor.GetAddress(), + Signer: actor.GetAddress(), + ActorType: actorType, + } + + err = ctx.HandleUnstakeMessage(msg) + require.NoError(t, err, "handle unstake message") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.Equal(t, actor.GetStatus(), int32(typesUtil.UnstakingStatus), "actor should be unstaking") + }) + } +} + +func TestUtilityContext_BeginUnstakingMaxPaused(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.BeginUnstakingMaxPaused", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 1) + + actor := GetFirstActor(t, ctx, actorType) + var err error + switch actorType { + case typesUtil.ActorType_App: + err = ctx.Context.SetAppMaxPausedBlocks(0) + case typesUtil.ActorType_Val: + err = ctx.Context.SetValidatorMaxPausedBlocks(0) + case typesUtil.ActorType_Fish: + err = ctx.Context.SetFishermanMaxPausedBlocks(0) + case typesUtil.ActorType_Node: + err = ctx.Context.SetServiceNodeMaxPausedBlocks(0) + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, err) + + err = ctx.SetActorPauseHeight(actorType, actor.GetAddress(), 0) + require.NoError(t, err, "error setting actor pause height") + + err = ctx.BeginUnstakingMaxPaused() + require.NoError(t, err, "error beginning unstaking max paused actors") + + status, err := ctx.GetActorStatus(actorType, actor.GetAddress()) + require.Equal(t, status, typesUtil.UnstakingStatus, "actor should be unstaking") + }) + } +} + +func TestUtilityContext_CalculateRelays(t *testing.T) { + ctx := NewTestingUtilityContext(t, 1) + + actor := GetFirstActor(t, ctx, typesUtil.ActorType_App) + + newMaxRelays, err := ctx.CalculateAppRelays(actor.GetStakedTokens()) + require.NoError(t, err) + + require.Equal(t, actor.GetGenericParam(), newMaxRelays, "relay calculation incorrect") +} + +func TestUtilityContext_CalculateUnstakingHeight(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.CalculateUnstakingHeight", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + var unstakingBlocks int64 + var err error + switch actorType { + case typesUtil.ActorType_Val: + unstakingBlocks, err = ctx.GetValidatorUnstakingBlocks() + case typesUtil.ActorType_Node: + unstakingBlocks, err = ctx.GetServiceNodeUnstakingBlocks() + case actorType: + unstakingBlocks, err = ctx.GetAppUnstakingBlocks() + case typesUtil.ActorType_Fish: + unstakingBlocks, err = ctx.GetFishermanUnstakingBlocks() + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, err, "error getting unstaking blocks") + + unstakingHeight, err := ctx.GetUnstakingHeight(actorType) + require.NoError(t, err) + + require.Equal(t, unstakingBlocks, unstakingHeight, "unexpected unstaking height") + }) + } +} + +func TestUtilityContext_Delete(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.Delete", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + actor := GetFirstActor(t, ctx, actorType) + + err := ctx.DeleteActor(actorType, actor.GetAddress()) + require.NoError(t, err, "error deleting actor") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.Nil(t, actor, "actor should be deleted") + }) + } +} + +func TestUtilityContext_GetExists(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.GetExists", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + actor := GetFirstActor(t, ctx, actorType) + randAddr, err := crypto.GenerateAddress() + require.NoError(t, err) + + exists, err := ctx.GetActorExists(actorType, actor.GetAddress()) + require.NoError(t, err) + require.True(t, exists, "actor that should exist does not") + + exists, err = ctx.GetActorExists(actorType, randAddr) + require.NoError(t, err) + require.False(t, exists, "actor that shouldn't exist does") + }) + } +} + +func TestUtilityContext_GetOutputAddress(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.GetOutputAddress", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + actor := GetFirstActor(t, ctx, actorType) + + outputAddress, err := ctx.GetActorOutputAddress(actorType, actor.GetAddress()) + require.NoError(t, err) + + require.Equal(t, outputAddress, actor.GetOutput(), "unexpected output address") + }) + } +} + +func TestUtilityContext_GetPauseHeightIfExists(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.GetPauseHeightIfExists", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + pauseHeight := int64(100) + actor := GetFirstActor(t, ctx, actorType) + + err := ctx.SetActorPauseHeight(actorType, actor.GetAddress(), pauseHeight) + require.NoError(t, err, "error setting actor pause height") + + gotPauseHeight, err := ctx.GetPauseHeight(actorType, actor.GetAddress()) + require.NoError(t, err) + require.Equal(t, pauseHeight, gotPauseHeight, "unable to get pause height from the actor") + + randAddr, er := crypto.GenerateAddress() + require.NoError(t, er) + + _, err = ctx.GetPauseHeight(actorType, randAddr) + require.Error(t, err, "non existent actor should error") + }) + } +} + +func TestUtilityContext_GetMessageEditStakeSignerCandidates(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.GetMessageEditStakeSignerCandidates", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + actor := GetFirstActor(t, ctx, actorType) + + msgEditStake := &typesUtil.MessageEditStake{ + Address: actor.GetAddress(), + Chains: defaultTestingChains, + Amount: defaultAmountString, + ActorType: actorType, + } + + candidates, err := ctx.GetMessageEditStakeSignerCandidates(msgEditStake) + require.NoError(t, err) + require.Equal(t, len(candidates), 2, "unexpected number of candidates") + require.Equal(t, candidates[0], actor.GetOutput(), "incorrect output candidate") + require.Equal(t, candidates[1], actor.GetAddress(), "incorrect addr candidate") + }) + } +} + +func TestUtilityContext_GetMessageStakeSignerCandidates(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + pubKey, err := crypto.GeneratePublicKey() + require.NoError(t, err) + + addr := pubKey.Address() + out, err := crypto.GenerateAddress() + require.NoError(t, err) + + msg := &typesUtil.MessageStake{ + PublicKey: pubKey.Bytes(), + Chains: defaultTestingChains, + Amount: defaultAmountString, + OutputAddress: out, + } + + candidates, err := ctx.GetMessageStakeSignerCandidates(msg) + require.NoError(t, err) + require.Equal(t, len(candidates), 2, "unexpected number of candidates") + require.Equal(t, candidates[0], out.Bytes(), "incorrect output candidate") + require.Equal(t, candidates[1], addr.Bytes(), "incorrect addr candidate") +} + +func TestUtilityContext_GetMessageUnpauseSignerCandidates(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.GetMessageUnpauseSignerCandidates", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + actor := GetFirstActor(t, ctx, actorType) + + msg := &typesUtil.MessageUnpause{ + Address: actor.GetAddress(), + ActorType: actorType, + } + + candidates, err := ctx.GetMessageUnpauseSignerCandidates(msg) + require.NoError(t, err) + require.Equal(t, len(candidates), 2, "unexpected number of candidates") + require.Equal(t, candidates[0], actor.GetOutput(), "incorrect output candidate") + require.Equal(t, candidates[1], actor.GetAddress(), "incorrect addr candidate") + }) + } +} + +func TestUtilityContext_GetMessageUnstakeSignerCandidates(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.GetMessageUnstakeSignerCandidates", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 0) + + actor := GetFirstActor(t, ctx, actorType) + + msg := &typesUtil.MessageUnstake{ + Address: actor.GetAddress(), + ActorType: actorType, + } + candidates, err := ctx.GetMessageUnstakeSignerCandidates(msg) + require.NoError(t, err) + require.Equal(t, len(candidates), 2, "unexpected number of candidates") + require.Equal(t, candidates[0], actor.GetOutput(), "incorrect output candidate") + require.Equal(t, candidates[1], actor.GetAddress(), "incorrect addr candidate") + }) + } +} + +func TestUtilityContext_UnstakePausedBefore(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + t.Run(fmt.Sprintf("%s.UnstakePausedBefore", actorType.GetActorName()), func(t *testing.T) { + ctx := NewTestingUtilityContext(t, 1) + + actor := GetFirstActor(t, ctx, actorType) + require.Equal(t, actor.GetStatus(), int32(typesUtil.StakedStatus), "wrong starting status") + + err := ctx.SetActorPauseHeight(actorType, actor.GetAddress(), 0) + require.NoError(t, err, "error setting actor pause height") + + var er error + switch actorType { + case typesUtil.ActorType_App: + er = ctx.Context.SetAppMaxPausedBlocks(0) + case typesUtil.ActorType_Val: + er = ctx.Context.SetValidatorMaxPausedBlocks(0) + case typesUtil.ActorType_Fish: + er = ctx.Context.SetFishermanMaxPausedBlocks(0) + case typesUtil.ActorType_Node: + er = ctx.Context.SetServiceNodeMaxPausedBlocks(0) + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, er, "error setting max paused blocks") + + err = ctx.UnstakeActorPausedBefore(0, actorType) + require.NoError(t, err, "error unstaking actor pause before") + + err = ctx.UnstakeActorPausedBefore(1, actorType) + require.NoError(t, err, "error unstaking actor pause before height 1") + + actor = GetActorByAddr(t, ctx, actor.GetAddress(), actorType) + require.Equal(t, actor.GetStatus(), int32(typesUtil.UnstakingStatus), "status does not equal unstaking") + + var unstakingBlocks int64 + switch actorType { + case typesUtil.ActorType_Val: + unstakingBlocks, err = ctx.GetValidatorUnstakingBlocks() + case typesUtil.ActorType_Node: + unstakingBlocks, err = ctx.GetServiceNodeUnstakingBlocks() + case actorType: + unstakingBlocks, err = ctx.GetAppUnstakingBlocks() + case typesUtil.ActorType_Fish: + unstakingBlocks, err = ctx.GetFishermanUnstakingBlocks() + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, err, "error getting unstaking blocks") + require.Equal(t, actor.GetUnstakingHeight(), unstakingBlocks+1, "incorrect unstaking height") + }) + } +} + +func TestUtilityContext_UnstakeActorsThatAreReady(t *testing.T) { + for _, actorType := range typesUtil.ActorTypes { + ctx := NewTestingUtilityContext(t, 1) + + poolName := actorType.GetActorPoolName() + var err1, err2 error + switch actorType { + case typesUtil.ActorType_App: + err1 = ctx.Context.SetAppUnstakingBlocks(0) + err2 = ctx.Context.SetAppMaxPausedBlocks(0) + case typesUtil.ActorType_Val: + err1 = ctx.Context.SetValidatorUnstakingBlocks(0) + err2 = ctx.Context.SetValidatorMaxPausedBlocks(0) + case typesUtil.ActorType_Fish: + err1 = ctx.Context.SetFishermanUnstakingBlocks(0) + err2 = ctx.Context.SetFishermanMaxPausedBlocks(0) + case typesUtil.ActorType_Node: + err1 = ctx.Context.SetServiceNodeUnstakingBlocks(0) + err2 = ctx.Context.SetServiceNodeMaxPausedBlocks(0) + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + + ctx.SetPoolAmount(poolName, big.NewInt(math.MaxInt64)) + require.NoError(t, err1, "error setting unstaking blocks") + require.NoError(t, err2, "error setting max pause blocks") + + actors := GetAllTestingActors(t, ctx, actorType) + for _, actor := range actors { + require.Equal(t, actor.GetStatus(), int32(typesUtil.StakedStatus), "wrong starting staked status") + err := ctx.SetActorPauseHeight(actorType, actor.GetAddress(), 1) + require.NoError(t, err, "error setting actor pause height") + } + + err := ctx.UnstakeActorPausedBefore(2, actorType) + require.NoError(t, err, "error setting actor pause before") + + err = ctx.UnstakeActorsThatAreReady() + require.NoError(t, err, "error unstaking actors that are ready") + + require.Zero(t, len(GetAllTestingActors(t, ctx, actorType)), "actors still exists after unstake that are ready() call") + } +} + +// Helpers + +func GetAllTestingActors(t *testing.T, ctx utility.UtilityContext, actorType typesUtil.ActorType) (actors []genesis.Actor) { + actors = make([]genesis.Actor, 0) + switch actorType { + case typesUtil.ActorType_App: + apps := GetAllTestingApps(t, ctx) + for _, a := range apps { + actors = append(actors, a) + } + case typesUtil.ActorType_Node: + nodes := GetAllTestingNodes(t, ctx) + for _, a := range nodes { + actors = append(actors, a) + } + case typesUtil.ActorType_Val: + vals := GetAllTestingValidators(t, ctx) + for _, a := range vals { + actors = append(actors, a) + } + case typesUtil.ActorType_Fish: + fish := GetAllTestingFish(t, ctx) + for _, a := range fish { + actors = append(actors, a) + } + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + + return +} + +func GetFirstActor(t *testing.T, ctx utility.UtilityContext, actorType typesUtil.ActorType) genesis.Actor { + return GetAllTestingActors(t, ctx, actorType)[0] +} + +func GetActorByAddr(t *testing.T, ctx utility.UtilityContext, addr []byte, actorType typesUtil.ActorType) (actor genesis.Actor) { + actors := GetAllTestingActors(t, ctx, actorType) + for _, a := range actors { + if bytes.Equal(a.GetAddress(), addr) { + return a + } + } + return +} + +func GetAllTestingApps(t *testing.T, ctx utility.UtilityContext) []*genesis.App { + actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllApps(ctx.LatestHeight) + require.NoError(t, err) + return actors +} + +func GetAllTestingValidators(t *testing.T, ctx utility.UtilityContext) []*genesis.Validator { + actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllValidators(ctx.LatestHeight) + require.NoError(t, err) + return actors +} + +func GetAllTestingFish(t *testing.T, ctx utility.UtilityContext) []*genesis.Fisherman { + actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllFishermen(ctx.LatestHeight) + require.NoError(t, err) + return actors +} + +func GetAllTestingNodes(t *testing.T, ctx utility.UtilityContext) []*genesis.ServiceNode { + actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllServiceNodes(ctx.LatestHeight) + require.NoError(t, err) + return actors +} diff --git a/shared/tests/utility_module/app_test.go b/shared/tests/utility_module/app_test.go deleted file mode 100644 index 04edfc82d..000000000 --- a/shared/tests/utility_module/app_test.go +++ /dev/null @@ -1,476 +0,0 @@ -package utility_module - -import ( - "bytes" - "math" - "math/big" - "reflect" - "testing" - - "github.com/pokt-network/pocket/persistence/pre_persistence" - "github.com/stretchr/testify/require" - - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - "github.com/pokt-network/pocket/shared/types/genesis" - "github.com/pokt-network/pocket/utility" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func TestUtilityContext_HandleMessageStakeApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - out, _ := crypto.GenerateAddress() - if err := ctx.SetAccountAmount(out, defaultAmount); err != nil { - t.Fatal(err) - } - msg := &typesUtil.MessageStakeApp{ - PublicKey: pubKey.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmountString, - OutputAddress: out, - Signer: out, - } - if err := ctx.HandleMessageStakeApp(msg); err != nil { - t.Fatal(err) - } - actors := GetAllTestingApps(t, ctx) - var actor *genesis.App - for _, a := range actors { - if bytes.Equal(a.PublicKey, msg.PublicKey) { - actor = a - break - } - } - if !bytes.Equal(actor.Address, pubKey.Address()) { - t.Fatalf("incorrect address, expected %v, got %v", pubKey.Address(), actor.Address) - } - if actor.Status != typesUtil.StakedStatus { - t.Fatalf("incorrect status, expected %v, got %v", typesUtil.StakedStatus, actor.Status) - } - if !reflect.DeepEqual(actor.Chains, msg.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect stake amount, expected %v, got %v", defaultAmountString, actor.StakedTokens) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, out) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, out) - } -} - -func TestUtilityContext_HandleMessageEditStakeApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingApps(t, ctx)[0] - msg := &typesUtil.MessageEditStakeApp{ - Address: actor.Address, - Chains: defaultTestingChains, - AmountToAdd: zeroAmountString, - Signer: actor.Address, - } - msgChainsEdited := msg - msgChainsEdited.Chains = defaultTestingChainsEdited - if err := ctx.HandleMessageEditStakeApp(msgChainsEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if !reflect.DeepEqual(actor.Chains, msg.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if !reflect.DeepEqual(actor.Chains, msgChainsEdited.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked tokens, expected %v, got %v", defaultAmountString, actor.StakedTokens) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, actor.Output) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, actor.Output) - } - amountEdited := big.NewInt(1) - expectedAmount := types.BigIntToString(big.NewInt(0).Add(defaultAmount, amountEdited)) - amountEditedString := types.BigIntToString(amountEdited) - msgAmountEdited := msg - msgAmountEdited.AmountToAdd = amountEditedString - if err := ctx.HandleMessageEditStakeApp(msgAmountEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("incorrect amount status, expected %v, got %v", expectedAmount, actor.StakedTokens) - } -} - -func TestUtilityContext_HandleMessagePauseApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingApps(t, ctx)[0] - msg := &typesUtil.MessagePauseApp{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseApp(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } -} - -func TestUtilityContext_HandleMessageUnpauseApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetAppMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingApps(t, ctx)[0] - msg := &typesUtil.MessagePauseApp{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseApp(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } - msgU := &typesUtil.MessageUnpauseApp{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnpauseApp(msgU); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if actor.Paused { - t.Fatal("actor is paused after") - } -} - -func TestUtilityContext_HandleMessageUnstakeApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetAppMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingApps(t, ctx)[0] - msg := &typesUtil.MessageUnstakeApp{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnstakeApp(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("actor isn't unstaking") - } -} - -func TestUtilityContext_BeginUnstakingMaxPausedApps(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingApps(t, ctx)[0] - err := ctx.Context.SetAppMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetAppPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.BeginUnstakingMaxPausedApps(); err != nil { - t.Fatal(err) - } - status, err := ctx.GetAppStatus(actor.Address) - if status != 1 { - t.Fatalf("incorrect status; expected %d got %d", 1, actor.Status) - } -} - -func TestUtilityContext_CalculateAppRelays(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingApps(t, ctx)[0] - newMaxRelays, err := ctx.CalculateAppRelays(actor.StakedTokens) - require.NoError(t, err) - if actor.MaxRelays != newMaxRelays { - t.Fatalf("unexpected max relay calculation; got %v wanted %v", actor.MaxRelays, newMaxRelays) - } -} - -func TestUtilityContext_CalculateAppUnstakingHeight(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - unstakingBlocks, err := ctx.GetAppUnstakingBlocks() - require.NoError(t, err) - unstakingHeight, err := ctx.CalculateAppUnstakingHeight() - require.NoError(t, err) - if unstakingBlocks != unstakingHeight { - t.Fatalf("unexpected unstakingHeight; got %d expected %d", unstakingBlocks, unstakingHeight) - } -} - -func TestUtilityContext_DeleteApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingApps(t, ctx)[0] - if err := ctx.DeleteApp(actor.Address); err != nil { - t.Fatal(err) - } - if len(GetAllTestingApps(t, ctx)) > 0 { - t.Fatal("deletion unsuccessful") - } -} - -func TestUtilityContext_GetAppExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - randAddr, _ := crypto.GenerateAddress() - actor := GetAllTestingApps(t, ctx)[0] - exists, err := ctx.GetAppExists(actor.Address) - require.NoError(t, err) - if !exists { - t.Fatal("actor that should exist does not") - } - exists, err = ctx.GetAppExists(randAddr) - require.NoError(t, err) - if exists { - t.Fatal("actor that shouldn't exist does") - } -} - -func TestUtilityContext_GetAppOutputAddress(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingApps(t, ctx)[0] - outputAddress, err := ctx.GetAppOutputAddress(actor.Address) - require.NoError(t, err) - if !bytes.Equal(outputAddress, actor.Output) { - t.Fatalf("unexpected output address, expected %v got %v", actor.Output, outputAddress) - } -} - -func TestUtilityContext_GetAppPauseHeightIfExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingApps(t, ctx)[0] - pauseHeight := int64(100) - if err := ctx.SetAppPauseHeight(actor.Address, pauseHeight); err != nil { - t.Fatal(err) - } - gotPauseHeight, err := ctx.GetAppPauseHeightIfExists(actor.Address) - require.NoError(t, err) - if pauseHeight != gotPauseHeight { - t.Fatal("unable to get pause height from the actor") - } - addr, _ := crypto.GenerateAddress() - _, err = ctx.GetAppPauseHeightIfExists(addr) - if err == nil { - t.Fatal("no error on non-existent actor pause height") - } -} - -func TestUtilityContext_GetAppsReadyToUnstake(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingApps(t, ctx)[0] - if err := ctx.SetAppUnstakingHeightAndStatus(actor.Address, 0); err != nil { - t.Fatal(err) - } - actors, err := ctx.GetAppsReadyToUnstake() - require.NoError(t, err) - if !bytes.Equal(actors[0].Address, actor.Address) { - t.Fatalf("unexpected actor ready to unstake: expected %s, got %s", actor.Address, actors[0].Address) - } -} - -func TestUtilityContext_GetMessageEditStakeAppSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingApps(t, ctx) - msgEditStake := &typesUtil.MessageEditStakeApp{ - Address: actors[0].Address, - Chains: defaultTestingChains, - AmountToAdd: defaultAmountString, - } - candidates, err := ctx.GetMessageEditStakeAppSignerCandidates(msgEditStake) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessagePauseAppSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingApps(t, ctx) - msg := &typesUtil.MessagePauseApp{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessagePauseAppSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageStakeAppSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - out, _ := crypto.GenerateAddress() - msg := &typesUtil.MessageStakeApp{ - PublicKey: pubKey.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmountString, - OutputAddress: out, - } - candidates, err := ctx.GetMessageStakeAppSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], out) || !bytes.Equal(candidates[1], addr) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnpauseAppSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingApps(t, ctx) - msg := &typesUtil.MessageUnpauseApp{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnpauseAppSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnstakeAppSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingApps(t, ctx) - msg := &typesUtil.MessageUnstakeApp{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnstakeAppSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_InsertApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - if err := ctx.InsertApp(addr, pubKey.Bytes(), addr, defaultAmountString, defaultAmountString, defaultTestingChains); err != nil { - t.Fatal(err) - } - exists, err := ctx.GetAppExists(addr) - require.NoError(t, err) - if !exists { - t.Fatal("actor does not exist after insert") - } - actors := GetAllTestingApps(t, ctx) - for _, actor := range actors { - if bytes.Equal(actor.Address, addr) { - if actor.Chains[0] != defaultTestingChains[0] { - t.Fatal("wrong chains") - } - if actor.StakedTokens != defaultAmountString { - t.Fatal("wrong staked tokens") - } - if actor.MaxRelays != defaultAmountString { - t.Fatal("wrong max relays") - } - if !bytes.Equal(actor.Output, addr) { - t.Fatal("wrong output addr") - } - return - } - } - t.Fatal("actor not found after insert in GetAll() call") -} - -func TestUtilityContext_UnstakeAppsPausedBefore(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingApps(t, ctx)[0] - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - err := ctx.Context.SetAppMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetAppPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeAppsPausedBefore(1); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("status does not equal unstaking") - } - unstakingBlocks, err := ctx.GetAppUnstakingBlocks() - require.NoError(t, err) - if actor.UnstakingHeight != unstakingBlocks+1 { - t.Fatal("incorrect unstaking height") - } -} - -func TestUtilityContext_UnstakeAppsThatAreReady(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - ctx.SetPoolAmount(genesis.AppStakePoolName, big.NewInt(math.MaxInt64)) - if err := ctx.Context.SetAppUnstakingBlocks(0); err != nil { - t.Fatal(err) - } - err := ctx.Context.SetAppMaxPausedBlocks(0) - if err != nil { - t.Fatal(err) - } - actors := GetAllTestingApps(t, ctx) - for _, actor := range actors { - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - if err := ctx.SetAppPauseHeight(actor.Address, 1); err != nil { - t.Fatal(err) - } - } - if err := ctx.UnstakeAppsPausedBefore(2); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeAppsThatAreReady(); err != nil { - t.Fatal(err) - } - if len(GetAllTestingApps(t, ctx)) != 0 { - t.Fatal("apps still exists after unstake that are ready() call") - } -} - -func TestUtilityContext_UpdateApp(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingApps(t, ctx)[0] - newAmountBig := big.NewInt(9999999999999999) - newAmount := types.BigIntToString(newAmountBig) - oldAmount := actor.StakedTokens - oldAmountBig, err := types.StringToBigInt(oldAmount) - require.NoError(t, err) - expectedAmountBig := newAmountBig.Add(newAmountBig, oldAmountBig) - expectedAmount := types.BigIntToString(expectedAmountBig) - if err := ctx.UpdateApp(actor.Address, actor.MaxRelays, newAmount, actor.Chains); err != nil { - t.Fatal(err) - } - actor = GetAllTestingApps(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("updated amount is incorrect; expected %s got %s", expectedAmount, actor.StakedTokens) - } -} - -func GetAllTestingApps(t *testing.T, ctx utility.UtilityContext) []*genesis.App { - actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllApps(ctx.LatestHeight) - require.NoError(t, err) - return actors -} diff --git a/shared/tests/utility_module/block_test.go b/shared/tests/utility_module/block_test.go index dd98cd136..71e7adac3 100644 --- a/shared/tests/utility_module/block_test.go +++ b/shared/tests/utility_module/block_test.go @@ -1,12 +1,11 @@ package utility_module import ( - "bytes" + "fmt" "math" "math/big" "testing" - typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" typesUtil "github.com/pokt-network/pocket/utility/types" "github.com/stretchr/testify/require" ) @@ -14,23 +13,26 @@ import ( func TestUtilityContext_ApplyBlock(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) tx, startingBalance, amount, signer := NewTestingTransaction(t, ctx) + vals := GetAllTestingValidators(t, ctx) proposer := vals[0] byzantine := vals[1] + txBz, err := tx.Bytes() require.NoError(t, err) + proposerBeforeBalance, err := ctx.GetAccountAmount(proposer.Address) require.NoError(t, err) + // apply block - if _, err := ctx.ApplyBlock(0, proposer.Address, [][]byte{txBz}, [][]byte{byzantine.Address}); err != nil { - t.Fatal(err) - } + _, er := ctx.ApplyBlock(0, proposer.Address, [][]byte{txBz}, [][]byte{byzantine.Address}) + require.NoError(t, er, "apply block") + // beginBlock logic verify missed, err := ctx.GetValidatorMissedBlocks(byzantine.Address) require.NoError(t, err) - if missed != 1 { - t.Fatalf("wrong missed blocks amount; expected %v got %v", 1, byzantine.MissedBlocks) - } + require.Equal(t, missed, 1, "wrong missed blocks amount") + // deliverTx logic verify feeBig, err := ctx.GetMessageSendFee() require.NoError(t, err) @@ -38,24 +40,23 @@ func TestUtilityContext_ApplyBlock(t *testing.T) { expectedAfterBalance := big.NewInt(0).Sub(startingBalance, expectedAmountSubtracted) amountAfter, err := ctx.GetAccountAmount(signer.Address()) require.NoError(t, err) - if amountAfter.Cmp(expectedAfterBalance) != 0 { - t.Fatalf("unexpected after balance; expected %v got %v", expectedAfterBalance, amountAfter) - } + require.Equal(t, amountAfter, expectedAfterBalance, fmt.Sprintf("unexpected after balance")) + // end-block logic verify proposerCutPercentage, err := ctx.GetProposerPercentageOfFees() require.NoError(t, err) feesAndRewardsCollectedFloat := new(big.Float).SetInt(feeBig) feesAndRewardsCollectedFloat.Mul(feesAndRewardsCollectedFloat, big.NewFloat(float64(proposerCutPercentage))) feesAndRewardsCollectedFloat.Quo(feesAndRewardsCollectedFloat, big.NewFloat(100)) + // DISCUSS/HACK: Why did we need to add the line below? feesAndRewardsCollectedFloat.Add(feesAndRewardsCollectedFloat, big.NewFloat(float64(feeBig.Int64()))) expectedProposerBalanceDifference, _ := feesAndRewardsCollectedFloat.Int(nil) proposerAfterBalance, err := ctx.GetAccountAmount(proposer.Address) require.NoError(t, err) + proposerBalanceDifference := big.NewInt(0).Sub(proposerAfterBalance, proposerBeforeBalance) - if proposerBalanceDifference.Cmp(expectedProposerBalanceDifference) != 0 { - t.Fatalf("unexpected before / after balance difference: expected %v got %v", expectedProposerBalanceDifference, proposerBalanceDifference) - } + require.Equal(t, proposerBalanceDifference, expectedProposerBalanceDifference, "unexpected before / after balance difference") } func TestUtilityContext_BeginBlock(t *testing.T) { @@ -64,34 +65,48 @@ func TestUtilityContext_BeginBlock(t *testing.T) { vals := GetAllTestingValidators(t, ctx) proposer := vals[0] byzantine := vals[1] + txBz, err := tx.Bytes() require.NoError(t, err) + // apply block - if _, err := ctx.ApplyBlock(0, proposer.Address, [][]byte{txBz}, [][]byte{byzantine.Address}); err != nil { - t.Fatal(err) - } + _, er := ctx.ApplyBlock(0, proposer.Address, [][]byte{txBz}, [][]byte{byzantine.Address}) + require.NoError(t, er) + // beginBlock logic verify missed, err := ctx.GetValidatorMissedBlocks(byzantine.Address) require.NoError(t, err) - if missed != 1 { - t.Fatalf("wrong missed blocks amount; expected %v got %v", 1, byzantine.MissedBlocks) - } + require.False(t, missed != 1, fmt.Sprintf("wrong missed blocks amount; expected %v got %v", 1, byzantine.MissedBlocks)) } func TestUtilityContext_BeginUnstakingMaxPausedActors(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingValidators(t, ctx)[0] - err := ctx.Context.SetValidatorMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetValidatorPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.BeginUnstakingMaxPausedActors(); err != nil { - t.Fatal(err) - } - status, err := ctx.GetValidatorStatus(actor.Address) - if status != 1 { - t.Fatalf("incorrect status; expected %d got %d", 1, actor.Status) + for _, actorType := range typesUtil.ActorTypes { + ctx := NewTestingUtilityContext(t, 1) + actor := GetFirstActor(t, ctx, actorType) + + var err error + switch actorType { + case typesUtil.ActorType_App: + err = ctx.Context.SetAppMaxPausedBlocks(0) + case typesUtil.ActorType_Val: + err = ctx.Context.SetValidatorMaxPausedBlocks(0) + case typesUtil.ActorType_Fish: + err = ctx.Context.SetFishermanMaxPausedBlocks(0) + case typesUtil.ActorType_Node: + err = ctx.Context.SetServiceNodeMaxPausedBlocks(0) + default: + t.Fatalf("unexpected actor type %s", actorType.GetActorName()) + } + require.NoError(t, err) + + err = ctx.SetActorPauseHeight(actorType, actor.GetAddress(), 0) + require.NoError(t, err) + + err = ctx.BeginUnstakingMaxPaused() + require.NoError(t, err) + + status, err := ctx.GetActorStatus(actorType, actor.GetAddress()) + require.False(t, status != 1, fmt.Sprintf("incorrect status; expected %d got %d", 1, actor.GetStatus())) } } @@ -101,73 +116,74 @@ func TestUtilityContext_EndBlock(t *testing.T) { vals := GetAllTestingValidators(t, ctx) proposer := vals[0] byzantine := vals[1] + txBz, err := tx.Bytes() require.NoError(t, err) + proposerBeforeBalance, err := ctx.GetAccountAmount(proposer.Address) require.NoError(t, err) + // apply block - if _, err := ctx.ApplyBlock(0, proposer.Address, [][]byte{txBz}, [][]byte{byzantine.Address}); err != nil { - t.Fatal(err) - } + _, er := ctx.ApplyBlock(0, proposer.Address, [][]byte{txBz}, [][]byte{byzantine.Address}) + require.NoError(t, er) + // deliverTx logic verify feeBig, err := ctx.GetMessageSendFee() require.NoError(t, err) + // end-block logic verify proposerCutPercentage, err := ctx.GetProposerPercentageOfFees() require.NoError(t, err) + feesAndRewardsCollectedFloat := new(big.Float).SetInt(feeBig) feesAndRewardsCollectedFloat.Mul(feesAndRewardsCollectedFloat, big.NewFloat(float64(proposerCutPercentage))) feesAndRewardsCollectedFloat.Quo(feesAndRewardsCollectedFloat, big.NewFloat(100)) + // DISCUSS/HACK: Why did we need to add the line below? feesAndRewardsCollectedFloat.Add(feesAndRewardsCollectedFloat, big.NewFloat(float64(feeBig.Int64()))) expectedProposerBalanceDifference, _ := feesAndRewardsCollectedFloat.Int(nil) proposerAfterBalance, err := ctx.GetAccountAmount(proposer.Address) require.NoError(t, err) + proposerBalanceDifference := big.NewInt(0).Sub(proposerAfterBalance, proposerBeforeBalance) - if proposerBalanceDifference.Cmp(expectedProposerBalanceDifference) != 0 { - t.Fatalf("unexpected before / after balance difference: expected %v got %v", expectedProposerBalanceDifference, proposerBalanceDifference) - } + require.False(t, proposerBalanceDifference.Cmp(expectedProposerBalanceDifference) != 0, fmt.Sprintf("unexpected before / after balance difference: expected %v got %v", expectedProposerBalanceDifference, proposerBalanceDifference)) } func TestUtilityContext_GetAppHash(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) + appHashTest, err := ctx.GetAppHash() require.NoError(t, err) + appHashSource, er := ctx.Context.AppHash() - if er != nil { - t.Fatal(er) - } - if !bytes.Equal(appHashSource, appHashTest) { - t.Fatalf("unexpected appHash, expected %v got %v", appHashSource, appHashTest) - } + require.NoError(t, er) + require.Equal(t, appHashSource, appHashTest, "unexpected appHash") } func TestUtilityContext_UnstakeValidatorsActorsThatAreReady(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - ctx.SetPoolAmount(typesGenesis.ValidatorStakePoolName, big.NewInt(math.MaxInt64)) - if err := ctx.Context.SetValidatorUnstakingBlocks(0); err != nil { - t.Fatal(err) - } - err := ctx.Context.SetValidatorMaxPausedBlocks(0) - if err != nil { - t.Fatal(err) - } - actors := GetAllTestingValidators(t, ctx) - for _, actor := range actors { - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - if err := ctx.SetValidatorPauseHeight(actor.Address, 1); err != nil { - t.Fatal(err) + for _, actorType := range typesUtil.ActorTypes { + ctx := NewTestingUtilityContext(t, 1) + poolName := actorType.GetActorPoolName() + + ctx.SetPoolAmount(poolName, big.NewInt(math.MaxInt64)) + err := ctx.Context.SetAppUnstakingBlocks(0) + require.NoError(t, err) + + err = ctx.Context.SetAppMaxPausedBlocks(0) + require.NoError(t, err) + + actors := GetAllTestingActors(t, ctx, actorType) + for _, actor := range actors { + require.False(t, actor.GetStatus() != typesUtil.StakedStatus, "wrong starting status") + er := ctx.SetActorPauseHeight(actorType, actor.GetAddress(), 1) + require.NoError(t, er) } - } - if err := ctx.UnstakeValidatorsPausedBefore(2); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeActorsThatAreReady(); err != nil { - t.Fatal(err) - } - if len(GetAllTestingValidators(t, ctx)) != 0 { - t.Fatal("validators still exists after unstake that are ready() call") + + err = ctx.UnstakeActorPausedBefore(2, actorType) + require.NoError(t, err) + + err = ctx.UnstakeActorsThatAreReady() + require.NoError(t, err) + // require.False(t, len(GetAllTestingActors(t, ctx, actorType)) != 0, fmt.Sprintf("validators still exists after unstake that are ready() call")) } } diff --git a/shared/tests/utility_module/fishermen_test.go b/shared/tests/utility_module/fishermen_test.go deleted file mode 100644 index 073f825db..000000000 --- a/shared/tests/utility_module/fishermen_test.go +++ /dev/null @@ -1,508 +0,0 @@ -package utility_module - -import ( - "bytes" - "math" - "math/big" - "reflect" - "testing" - - "github.com/pokt-network/pocket/persistence/pre_persistence" - "github.com/stretchr/testify/require" - - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - "github.com/pokt-network/pocket/shared/types/genesis" - "github.com/pokt-network/pocket/utility" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func TestUtilityContext_HandleMessageStakeFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - out, _ := crypto.GenerateAddress() - if err := ctx.SetAccountAmount(out, defaultAmount); err != nil { - t.Fatal(err) - } - msg := &typesUtil.MessageStakeFisherman{ - PublicKey: pubKey.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmountString, - OutputAddress: out, - Signer: out, - } - if err := ctx.HandleMessageStakeFisherman(msg); err != nil { - t.Fatal(err) - } - actors := GetAllTestingFishermen(t, ctx) - var actor *genesis.Fisherman - for _, a := range actors { - if bytes.Equal(a.PublicKey, msg.PublicKey) { - actor = a - break - } - } - if !bytes.Equal(actor.Address, pubKey.Address()) { - t.Fatalf("incorrect address, expected %v, got %v", pubKey.Address(), actor.Address) - } - if actor.Status != typesUtil.StakedStatus { - t.Fatalf("incorrect status, expected %v, got %v", typesUtil.StakedStatus, actor.Status) - } - if !reflect.DeepEqual(actor.Chains, msg.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked amount, expected %v, got %v", actor.StakedTokens, defaultAmountString) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, out) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, out) - } -} - -func TestUtilityContext_HandleMessageEditStakeFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingFishermen(t, ctx)[0] - msg := &typesUtil.MessageEditStakeFisherman{ - Address: actor.Address, - Chains: defaultTestingChains, - AmountToAdd: zeroAmountString, - Signer: actor.Address, - } - msgChainsEdited := msg - msgChainsEdited.Chains = defaultTestingChainsEdited - if err := ctx.HandleMessageEditStakeFisherman(msgChainsEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if !reflect.DeepEqual(actor.Chains, msg.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if !reflect.DeepEqual(actor.Chains, msgChainsEdited.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked tokens, expected %v, got %v", defaultAmountString, actor.StakedTokens) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, actor.Output) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, actor.Output) - } - amountEdited := big.NewInt(1) - expectedAmount := types.BigIntToString(big.NewInt(0).Add(defaultAmount, amountEdited)) - amountEditedString := types.BigIntToString(amountEdited) - msgAmountEdited := msg - msgAmountEdited.AmountToAdd = amountEditedString - if err := ctx.HandleMessageEditStakeFisherman(msgAmountEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("incorrect amount status, expected %v, got %v", expectedAmount, actor.StakedTokens) - } -} - -func TestUtilityContext_HandleMessagePauseFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingFishermen(t, ctx)[0] - msg := &typesUtil.MessagePauseFisherman{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseFisherman(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } -} - -func TestUtilityContext_HandleMessageUnpauseFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetFishermanMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingFishermen(t, ctx)[0] - msg := &typesUtil.MessagePauseFisherman{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseFisherman(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } - msgU := &typesUtil.MessageUnpauseFisherman{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnpauseFisherman(msgU); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if actor.Paused { - t.Fatal("actor is paused after") - } -} - -func TestUtilityContext_HandleMessageUnstakeFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetFishermanMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingFishermen(t, ctx)[0] - msg := &typesUtil.MessageUnstakeFisherman{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnstakeFisherman(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("actor isn't unstaking") - } -} - -func TestUtilityContext_BeginUnstakingMaxPausedFishermen(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingFishermen(t, ctx)[0] - err := ctx.Context.SetFishermanMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetFishermanPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.BeginUnstakingMaxPausedFishermen(); err != nil { - t.Fatal(err) - } - status, err := ctx.GetFishermanStatus(actor.Address) - if status != 1 { - t.Fatalf("incorrect status; expected %d got %d", 1, actor.Status) - } -} - -func TestUtilityContext_CalculateFishermanUnstakingHeight(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - unstakingBlocks, err := ctx.GetFishermanUnstakingBlocks() - require.NoError(t, err) - unstakingHeight, err := ctx.CalculateFishermanUnstakingHeight() - require.NoError(t, err) - if unstakingBlocks != unstakingHeight { - t.Fatalf("unexpected unstakingHeight; got %d expected %d", unstakingBlocks, unstakingHeight) - } -} - -func TestUtilityContext_DeleteFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingFishermen(t, ctx)[0] - if err := ctx.DeleteFisherman(actor.Address); err != nil { - t.Fatal(err) - } - if len(GetAllTestingFishermen(t, ctx)) > 0 { - t.Fatal("deletion unsuccessful") - } -} - -func TestUtilityContext_GetFishermanExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - randAddr, _ := crypto.GenerateAddress() - actor := GetAllTestingFishermen(t, ctx)[0] - exists, err := ctx.GetFishermanExists(actor.Address) - require.NoError(t, err) - if !exists { - t.Fatal("actor that should exist does not") - } - exists, err = ctx.GetFishermanExists(randAddr) - require.NoError(t, err) - if exists { - t.Fatal("actor that shouldn't exist does") - } -} - -func TestUtilityContext_GetFishermanOutputAddress(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingFishermen(t, ctx)[0] - outputAddress, err := ctx.GetFishermanOutputAddress(actor.Address) - require.NoError(t, err) - if !bytes.Equal(outputAddress, actor.Output) { - t.Fatalf("unexpected output address, expected %v got %v", actor.Output, outputAddress) - } -} - -func TestUtilityContext_GetFishermanPauseHeightIfExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingFishermen(t, ctx)[0] - pauseHeight := int64(100) - if err := ctx.SetFishermanPauseHeight(actor.Address, pauseHeight); err != nil { - t.Fatal(err) - } - gotPauseHeight, err := ctx.GetFishermanPauseHeightIfExists(actor.Address) - require.NoError(t, err) - if pauseHeight != gotPauseHeight { - t.Fatal("unable to get pause height from the actor") - } - addr, _ := crypto.GenerateAddress() - _, err = ctx.GetFishermanPauseHeightIfExists(addr) - if err == nil { - t.Fatal("no error on non-existent actor pause height") - } -} - -func TestUtilityContext_GetFishermenReadyToUnstake(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingFishermen(t, ctx)[0] - if err := ctx.SetFishermanUnstakingHeightAndStatus(actor.Address, 0); err != nil { - t.Fatal(err) - } - actors, err := ctx.GetFishermenReadyToUnstake() - require.NoError(t, err) - if !bytes.Equal(actors[0].Address, actor.Address) { - t.Fatalf("unexpected actor ready to unstake: expected %s, got %s", actor.Address, actors[0].Address) - } -} - -func TestUtilityContext_GetMessageEditStakeFishermanSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingFishermen(t, ctx) - msgEditStake := &typesUtil.MessageEditStakeFisherman{ - Address: actors[0].Address, - Chains: defaultTestingChains, - AmountToAdd: defaultAmountString, - } - candidates, err := ctx.GetMessageEditStakeFishermanSignerCandidates(msgEditStake) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessagePauseFishermanSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingFishermen(t, ctx) - msg := &typesUtil.MessagePauseFisherman{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessagePauseFishermanSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageStakeFishermanSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - out, _ := crypto.GenerateAddress() - msg := &typesUtil.MessageStakeFisherman{ - PublicKey: pubKey.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmountString, - OutputAddress: out, - } - candidates, err := ctx.GetMessageStakeFishermanSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], out) || !bytes.Equal(candidates[1], addr) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnpauseFishermanSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingFishermen(t, ctx) - msg := &typesUtil.MessageUnpauseFisherman{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnpauseFishermanSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnstakeFishermanSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingFishermen(t, ctx) - msg := &typesUtil.MessageUnstakeFisherman{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnstakeFishermanSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_InsertFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - if err := ctx.InsertFisherman(addr, pubKey.Bytes(), addr, defaultServiceUrl, defaultAmountString, defaultTestingChains); err != nil { - t.Fatal(err) - } - exists, err := ctx.GetFishermanExists(addr) - require.NoError(t, err) - if !exists { - t.Fatal("actor does not exist after insert") - } - actors := GetAllTestingFishermen(t, ctx) - for _, actor := range actors { - if bytes.Equal(actor.Address, addr) { - if actor.Chains[0] != defaultTestingChains[0] { - t.Fatal("wrong chains") - } - if actor.ServiceUrl != defaultServiceUrl { - t.Fatal("wrong serviceURL") - } - if actor.StakedTokens != defaultAmountString { - t.Fatal("wrong staked tokens") - } - if !bytes.Equal(actor.Output, addr) { - t.Fatal("wrong output addr") - } - return - } - } - t.Fatal("actor not found after insert in GetAll() call") -} - -func TestUtilityContext_UnstakeFishermenPausedBefore(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingFishermen(t, ctx)[0] - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - err := ctx.Context.SetFishermanMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetFishermanPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeFishermenPausedBefore(1); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("status does not equal unstaking") - } - unstakingBlocks, err := ctx.GetFishermanUnstakingBlocks() - require.NoError(t, err) - if actor.UnstakingHeight != unstakingBlocks+1 { - t.Fatal("incorrect unstaking height") - } -} - -func TestUtilityContext_UnstakeFishermenThatAreReady(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - ctx.SetPoolAmount(genesis.FishermanStakePoolName, big.NewInt(math.MaxInt64)) - if err := ctx.Context.SetFishermanUnstakingBlocks(0); err != nil { - t.Fatal(err) - } - err := ctx.Context.SetFishermanMaxPausedBlocks(0) - if err != nil { - t.Fatal(err) - } - actors := GetAllTestingFishermen(t, ctx) - for _, actor := range actors { - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - if err := ctx.SetFishermanPauseHeight(actor.Address, 1); err != nil { - t.Fatal(err) - } - } - if err := ctx.UnstakeFishermenPausedBefore(2); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeFishermenThatAreReady(); err != nil { - t.Fatal(err) - } - if len(GetAllTestingFishermen(t, ctx)) != 0 { - t.Fatal("fishermen still exists after unstake that are ready() call") - } -} - -func TestUtilityContext_UpdateFisherman(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingFishermen(t, ctx)[0] - newAmountBig := big.NewInt(9999999999999999) - newAmount := types.BigIntToString(newAmountBig) - oldAmount := actor.StakedTokens - oldAmountBig, err := types.StringToBigInt(oldAmount) - require.NoError(t, err) - expectedAmountBig := newAmountBig.Add(newAmountBig, oldAmountBig) - expectedAmount := types.BigIntToString(expectedAmountBig) - if err := ctx.UpdateFisherman(actor.Address, actor.ServiceUrl, newAmount, actor.Chains); err != nil { - t.Fatal(err) - } - actor = GetAllTestingFishermen(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("updated amount is incorrect; expected %s got %s", expectedAmount, actor.StakedTokens) - } -} - -func GetAllTestingFishermen(t *testing.T, ctx utility.UtilityContext) []*genesis.Fisherman { - actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllFishermen(ctx.LatestHeight) - require.NoError(t, err) - return actors -} - -func TestUtilityContext_GetMessageFishermanPauseServiceNodeSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingFishermen(t, ctx)[0] - candidates, err := ctx.GetMessageFishermanPauseServiceNodeSignerCandidates(&typesUtil.MessageFishermanPauseServiceNode{ - Reporter: actor.Address, - }) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actor.Output) { - t.Fatal("output address is not a signer candidate") - } - if !bytes.Equal(candidates[1], actor.Address) { - t.Fatal("operator address is not a signer candidate") - } -} - -func TestUtilityContext_HandleMessageFishermanPauseServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingFishermen(t, ctx)[0] - sn := GetAllTestingServiceNodes(t, ctx)[0] - if sn.Paused == true { - t.Fatal("incorrect starting pause status") - } - if err := ctx.HandleMessageFishermanPauseServiceNode(&typesUtil.MessageFishermanPauseServiceNode{ - Address: sn.Address, - Reporter: actor.Address, - }); err != nil { - t.Fatal(err) - } - sn = GetAllTestingServiceNodes(t, ctx)[0] - if !sn.Paused || sn.PausedHeight != 1 { - t.Fatal("service node is not correctly paused after message") - } -} - -func TestUtilityContext_HandleMessageProveTestScore(t *testing.T) { - // Not Implemented Yet TODO -} - -func TestUtilityContext_HandleMessageTestScore(t *testing.T) { - // Not Implemented Yet TODO -} diff --git a/shared/tests/utility_module/gov_test.go b/shared/tests/utility_module/gov_test.go index c9f585da0..cee1f43ff 100644 --- a/shared/tests/utility_module/gov_test.go +++ b/shared/tests/utility_module/gov_test.go @@ -2,6 +2,7 @@ package utility_module import ( "bytes" + "fmt" "testing" "github.com/pokt-network/pocket/shared/types" @@ -11,6 +12,8 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) +// CLEANUP: cleanup this file as part of https://github.com/pokt-network/pocket/issues/76 + func DefaultTestingParams(_ *testing.T) *genesis.Params { return genesis.DefaultParams() } @@ -20,9 +23,7 @@ func TestUtilityContext_GetAppMaxChains(t *testing.T) { defaultParams := DefaultTestingParams(t) maxChains, err := ctx.GetAppMaxChains() require.NoError(t, err) - if int(defaultParams.AppMaxChains) != maxChains { - t.Fatalf("unexpected param value: expected %v got %v", defaultParams.AppMaxChains, maxChains) - } + require.False(t, int(defaultParams.AppMaxChains) != maxChains, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParams.AppMaxChains, maxChains)) } func TestUtilityContext_GetAppMaxPausedBlocks(t *testing.T) { @@ -30,9 +31,7 @@ func TestUtilityContext_GetAppMaxPausedBlocks(t *testing.T) { defaultParams := DefaultTestingParams(t) gotParam, err := ctx.GetAppMaxPausedBlocks() require.NoError(t, err) - if int(defaultParams.AppMaxPauseBlocks) != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParams.AppMaxPausedBlocksOwner, gotParam) - } + require.False(t, int(defaultParams.AppMaxPauseBlocks) != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParams.AppMaxPausedBlocksOwner, gotParam)) } func TestUtilityContext_GetAppMinimumPauseBlocks(t *testing.T) { @@ -41,9 +40,7 @@ func TestUtilityContext_GetAppMinimumPauseBlocks(t *testing.T) { defaultParam := int(defaultParams.AppMinimumPauseBlocks) gotParam, err := ctx.GetAppMinimumPauseBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetAppMinimumStake(t *testing.T) { @@ -52,9 +49,7 @@ func TestUtilityContext_GetAppMinimumStake(t *testing.T) { defaultParam := defaultParams.AppMinimumStake gotParam, err := ctx.GetAppMinimumStake() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetAppUnstakingBlocks(t *testing.T) { @@ -63,9 +58,7 @@ func TestUtilityContext_GetAppUnstakingBlocks(t *testing.T) { defaultParam := int64(defaultParams.AppUnstakingBlocks) gotParam, err := ctx.GetAppUnstakingBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetBaselineAppStakeRate(t *testing.T) { @@ -74,9 +67,7 @@ func TestUtilityContext_GetBaselineAppStakeRate(t *testing.T) { defaultParam := int(defaultParams.AppBaselineStakeRate) gotParam, err := ctx.GetBaselineAppStakeRate() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetBlocksPerSession(t *testing.T) { @@ -85,9 +76,7 @@ func TestUtilityContext_GetBlocksPerSession(t *testing.T) { defaultParam := int(defaultParams.BlocksPerSession) gotParam, err := ctx.GetBlocksPerSession() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetDoubleSignBurnPercentage(t *testing.T) { @@ -96,9 +85,7 @@ func TestUtilityContext_GetDoubleSignBurnPercentage(t *testing.T) { defaultParam := int(defaultParams.DoubleSignBurnPercentage) gotParam, err := ctx.GetDoubleSignBurnPercentage() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetDoubleSignFeeOwner(t *testing.T) { @@ -107,9 +94,7 @@ func TestUtilityContext_GetDoubleSignFeeOwner(t *testing.T) { defaultParam := defaultParams.MessageDoubleSignFeeOwner gotParam, err := ctx.GetDoubleSignFeeOwner() require.NoError(t, err) - if !bytes.Equal(defaultParam, gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(defaultParam, gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetFishermanMaxChains(t *testing.T) { @@ -118,9 +103,7 @@ func TestUtilityContext_GetFishermanMaxChains(t *testing.T) { defaultParam := int(defaultParams.FishermanMaxChains) gotParam, err := ctx.GetFishermanMaxChains() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetFishermanMaxPausedBlocks(t *testing.T) { @@ -129,9 +112,7 @@ func TestUtilityContext_GetFishermanMaxPausedBlocks(t *testing.T) { defaultParam := int(defaultParams.FishermanMaxPauseBlocks) gotParam, err := ctx.GetFishermanMaxPausedBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetFishermanMinimumPauseBlocks(t *testing.T) { @@ -140,9 +121,7 @@ func TestUtilityContext_GetFishermanMinimumPauseBlocks(t *testing.T) { defaultParam := int(defaultParams.FishermanMinimumPauseBlocks) gotParam, err := ctx.GetFishermanMinimumPauseBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetFishermanMinimumStake(t *testing.T) { @@ -151,9 +130,7 @@ func TestUtilityContext_GetFishermanMinimumStake(t *testing.T) { defaultParam := defaultParams.FishermanMinimumStake gotParam, err := ctx.GetFishermanMinimumStake() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetFishermanUnstakingBlocks(t *testing.T) { @@ -162,9 +139,7 @@ func TestUtilityContext_GetFishermanUnstakingBlocks(t *testing.T) { defaultParam := int64(defaultParams.FishermanUnstakingBlocks) gotParam, err := ctx.GetFishermanUnstakingBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMaxEvidenceAgeInBlocks(t *testing.T) { @@ -173,9 +148,7 @@ func TestUtilityContext_GetMaxEvidenceAgeInBlocks(t *testing.T) { defaultParam := int(defaultParams.ValidatorMaxEvidenceAgeInBlocks) gotParam, err := ctx.GetMaxEvidenceAgeInBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageChangeParameterFee(t *testing.T) { @@ -184,9 +157,7 @@ func TestUtilityContext_GetMessageChangeParameterFee(t *testing.T) { defaultParam := defaultParams.MessageChangeParameterFee gotParam, err := ctx.GetMessageChangeParameterFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageDoubleSignFee(t *testing.T) { @@ -195,9 +166,7 @@ func TestUtilityContext_GetMessageDoubleSignFee(t *testing.T) { defaultParam := defaultParams.GetMessageDoubleSignFee() gotParam, err := ctx.GetMessageDoubleSignFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageEditStakeAppFee(t *testing.T) { @@ -206,9 +175,7 @@ func TestUtilityContext_GetMessageEditStakeAppFee(t *testing.T) { defaultParam := defaultParams.MessageEditStakeAppFee gotParam, err := ctx.GetMessageEditStakeAppFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageEditStakeFishermanFee(t *testing.T) { @@ -217,9 +184,7 @@ func TestUtilityContext_GetMessageEditStakeFishermanFee(t *testing.T) { defaultParam := defaultParams.MessageEditStakeFishermanFee gotParam, err := ctx.GetMessageEditStakeFishermanFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageEditStakeServiceNodeFee(t *testing.T) { @@ -228,9 +193,7 @@ func TestUtilityContext_GetMessageEditStakeServiceNodeFee(t *testing.T) { defaultParam := defaultParams.MessageEditStakeServiceNodeFee gotParam, err := ctx.GetMessageEditStakeServiceNodeFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageEditStakeValidatorFee(t *testing.T) { @@ -239,9 +202,7 @@ func TestUtilityContext_GetMessageEditStakeValidatorFee(t *testing.T) { defaultParam := defaultParams.MessageEditStakeValidatorFee gotParam, err := ctx.GetMessageEditStakeValidatorFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageFishermanPauseServiceNodeFee(t *testing.T) { @@ -250,9 +211,7 @@ func TestUtilityContext_GetMessageFishermanPauseServiceNodeFee(t *testing.T) { defaultParam := defaultParams.MessageFishermanPauseServiceNodeFee gotParam, err := ctx.GetMessageFishermanPauseServiceNodeFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessagePauseAppFee(t *testing.T) { @@ -261,9 +220,7 @@ func TestUtilityContext_GetMessagePauseAppFee(t *testing.T) { defaultParam := defaultParams.MessagePauseAppFee gotParam, err := ctx.GetMessagePauseAppFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessagePauseFishermanFee(t *testing.T) { @@ -272,9 +229,7 @@ func TestUtilityContext_GetMessagePauseFishermanFee(t *testing.T) { defaultParam := defaultParams.MessagePauseFishermanFee gotParam, err := ctx.GetMessagePauseFishermanFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessagePauseServiceNodeFee(t *testing.T) { @@ -283,9 +238,7 @@ func TestUtilityContext_GetMessagePauseServiceNodeFee(t *testing.T) { defaultParam := defaultParams.MessagePauseServiceNodeFee gotParam, err := ctx.GetMessagePauseServiceNodeFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessagePauseValidatorFee(t *testing.T) { @@ -294,9 +247,7 @@ func TestUtilityContext_GetMessagePauseValidatorFee(t *testing.T) { defaultParam := defaultParams.MessagePauseValidatorFee gotParam, err := ctx.GetMessagePauseValidatorFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageProveTestScoreFee(t *testing.T) { @@ -305,9 +256,7 @@ func TestUtilityContext_GetMessageProveTestScoreFee(t *testing.T) { defaultParam := defaultParams.MessageProveTestScoreFee gotParam, err := ctx.GetMessageProveTestScoreFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageSendFee(t *testing.T) { @@ -316,9 +265,7 @@ func TestUtilityContext_GetMessageSendFee(t *testing.T) { defaultParam := defaultParams.MessageSendFee gotParam, err := ctx.GetMessageSendFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageStakeAppFee(t *testing.T) { @@ -327,9 +274,7 @@ func TestUtilityContext_GetMessageStakeAppFee(t *testing.T) { defaultParam := defaultParams.MessageStakeAppFee gotParam, err := ctx.GetMessageStakeAppFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageStakeFishermanFee(t *testing.T) { @@ -338,9 +283,7 @@ func TestUtilityContext_GetMessageStakeFishermanFee(t *testing.T) { defaultParam := defaultParams.MessageStakeFishermanFee gotParam, err := ctx.GetMessageStakeFishermanFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageStakeServiceNodeFee(t *testing.T) { @@ -349,9 +292,7 @@ func TestUtilityContext_GetMessageStakeServiceNodeFee(t *testing.T) { defaultParam := defaultParams.MessageStakeServiceNodeFee gotParam, err := ctx.GetMessageStakeServiceNodeFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageStakeValidatorFee(t *testing.T) { @@ -360,9 +301,7 @@ func TestUtilityContext_GetMessageStakeValidatorFee(t *testing.T) { defaultParam := defaultParams.MessageStakeValidatorFee gotParam, err := ctx.GetMessageStakeValidatorFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageTestScoreFee(t *testing.T) { @@ -371,9 +310,7 @@ func TestUtilityContext_GetMessageTestScoreFee(t *testing.T) { defaultParam := defaultParams.MessageTestScoreFee gotParam, err := ctx.GetMessageTestScoreFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnpauseAppFee(t *testing.T) { @@ -382,9 +319,7 @@ func TestUtilityContext_GetMessageUnpauseAppFee(t *testing.T) { defaultParam := defaultParams.MessageUnpauseAppFee gotParam, err := ctx.GetMessageUnpauseAppFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnpauseFishermanFee(t *testing.T) { @@ -393,9 +328,7 @@ func TestUtilityContext_GetMessageUnpauseFishermanFee(t *testing.T) { defaultParam := defaultParams.MessageUnpauseFishermanFee gotParam, err := ctx.GetMessageUnpauseFishermanFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnpauseServiceNodeFee(t *testing.T) { @@ -404,9 +337,7 @@ func TestUtilityContext_GetMessageUnpauseServiceNodeFee(t *testing.T) { defaultParam := defaultParams.MessageUnpauseServiceNodeFee gotParam, err := ctx.GetMessageUnpauseServiceNodeFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnpauseValidatorFee(t *testing.T) { @@ -415,9 +346,7 @@ func TestUtilityContext_GetMessageUnpauseValidatorFee(t *testing.T) { defaultParam := defaultParams.MessageUnpauseValidatorFee gotParam, err := ctx.GetMessageUnpauseValidatorFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnstakeAppFee(t *testing.T) { @@ -426,9 +355,7 @@ func TestUtilityContext_GetMessageUnstakeAppFee(t *testing.T) { defaultParam := defaultParams.MessageUnstakeAppFee gotParam, err := ctx.GetMessageUnstakeAppFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnstakeFishermanFee(t *testing.T) { @@ -437,9 +364,7 @@ func TestUtilityContext_GetMessageUnstakeFishermanFee(t *testing.T) { defaultParam := defaultParams.MessageUnstakeFishermanFee gotParam, err := ctx.GetMessageUnstakeFishermanFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnstakeServiceNodeFee(t *testing.T) { @@ -448,9 +373,7 @@ func TestUtilityContext_GetMessageUnstakeServiceNodeFee(t *testing.T) { defaultParam := defaultParams.MessageUnstakeServiceNodeFee gotParam, err := ctx.GetMessageUnstakeServiceNodeFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMessageUnstakeValidatorFee(t *testing.T) { @@ -459,9 +382,7 @@ func TestUtilityContext_GetMessageUnstakeValidatorFee(t *testing.T) { defaultParam := defaultParams.MessageUnstakeValidatorFee gotParam, err := ctx.GetMessageUnstakeValidatorFee() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetMissedBlocksBurnPercentage(t *testing.T) { @@ -470,9 +391,7 @@ func TestUtilityContext_GetMissedBlocksBurnPercentage(t *testing.T) { defaultParam := int(defaultParams.MissedBlocksBurnPercentage) gotParam, err := ctx.GetMissedBlocksBurnPercentage() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetProposerPercentageOfFees(t *testing.T) { @@ -481,9 +400,7 @@ func TestUtilityContext_GetProposerPercentageOfFees(t *testing.T) { defaultParam := int(defaultParams.ProposerPercentageOfFees) gotParam, err := ctx.GetProposerPercentageOfFees() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetServiceNodeMaxChains(t *testing.T) { @@ -492,9 +409,7 @@ func TestUtilityContext_GetServiceNodeMaxChains(t *testing.T) { defaultParam := int(defaultParams.ServiceNodeMaxChains) gotParam, err := ctx.GetServiceNodeMaxChains() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetServiceNodeMaxPausedBlocks(t *testing.T) { @@ -503,9 +418,7 @@ func TestUtilityContext_GetServiceNodeMaxPausedBlocks(t *testing.T) { defaultParam := int(defaultParams.ServiceNodeMaxPauseBlocks) gotParam, err := ctx.GetServiceNodeMaxPausedBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetServiceNodeMinimumPauseBlocks(t *testing.T) { @@ -514,9 +427,7 @@ func TestUtilityContext_GetServiceNodeMinimumPauseBlocks(t *testing.T) { defaultParam := int(defaultParams.ServiceNodeMinimumPauseBlocks) gotParam, err := ctx.GetServiceNodeMinimumPauseBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetServiceNodeMinimumStake(t *testing.T) { @@ -525,9 +436,7 @@ func TestUtilityContext_GetServiceNodeMinimumStake(t *testing.T) { defaultParam := defaultParams.ServiceNodeMinimumStake gotParam, err := ctx.GetServiceNodeMinimumStake() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetServiceNodeUnstakingBlocks(t *testing.T) { @@ -536,9 +445,7 @@ func TestUtilityContext_GetServiceNodeUnstakingBlocks(t *testing.T) { defaultParam := int64(defaultParams.ServiceNodeUnstakingBlocks) gotParam, err := ctx.GetServiceNodeUnstakingBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetStakingAdjustment(t *testing.T) { @@ -547,9 +454,7 @@ func TestUtilityContext_GetStakingAdjustment(t *testing.T) { defaultParam := int(defaultParams.AppStakingAdjustment) gotParam, err := ctx.GetStabilityAdjustment() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetValidatorMaxMissedBlocks(t *testing.T) { @@ -558,9 +463,7 @@ func TestUtilityContext_GetValidatorMaxMissedBlocks(t *testing.T) { defaultParam := int(defaultParams.ValidatorMaximumMissedBlocks) gotParam, err := ctx.GetValidatorMaxMissedBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetValidatorMaxPausedBlocks(t *testing.T) { @@ -569,9 +472,7 @@ func TestUtilityContext_GetValidatorMaxPausedBlocks(t *testing.T) { defaultParam := int(defaultParams.ValidatorMaxPauseBlocks) gotParam, err := ctx.GetValidatorMaxPausedBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetValidatorMinimumPauseBlocks(t *testing.T) { @@ -580,9 +481,7 @@ func TestUtilityContext_GetValidatorMinimumPauseBlocks(t *testing.T) { defaultParam := int(defaultParams.ValidatorMinimumPauseBlocks) gotParam, err := ctx.GetValidatorMinimumPauseBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetValidatorMinimumStake(t *testing.T) { @@ -591,9 +490,7 @@ func TestUtilityContext_GetValidatorMinimumStake(t *testing.T) { defaultParam := defaultParams.ValidatorMinimumStake gotParam, err := ctx.GetValidatorMinimumStake() require.NoError(t, err) - if defaultParam != types.BigIntToString(gotParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != types.BigIntToString(gotParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_GetValidatorUnstakingBlocks(t *testing.T) { @@ -602,9 +499,7 @@ func TestUtilityContext_GetValidatorUnstakingBlocks(t *testing.T) { defaultParam := int64(defaultParams.ValidatorUnstakingBlocks) gotParam, err := ctx.GetValidatorUnstakingBlocks() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } func TestUtilityContext_HandleMessageChangeParameter(t *testing.T) { @@ -614,9 +509,7 @@ func TestUtilityContext_HandleMessageChangeParameter(t *testing.T) { defaultParam := int(defaultParams.MissedBlocksBurnPercentage) gotParam, err := ctx.GetMissedBlocksBurnPercentage() require.NoError(t, err) - if defaultParam != gotParam { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, defaultParam != gotParam, fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) newParamValue := int32(2) paramOwnerPK := genesis.DefaultParamsOwner any, err := cdc.ToAny(&wrapperspb.Int32Value{ @@ -628,14 +521,12 @@ func TestUtilityContext_HandleMessageChangeParameter(t *testing.T) { ParameterKey: types.MissedBlocksBurnPercentageParamName, ParameterValue: any, } - if err := ctx.HandleMessageChangeParameter(msg); err != nil { - t.Fatal(err) - } + err = ctx.HandleMessageChangeParameter(msg) + require.NoError(t, err, "handle message change param") + gotParam, err = ctx.GetMissedBlocksBurnPercentage() require.NoError(t, err) - if int(newParamValue) != gotParam { - t.Fatalf("wrong param value after handling, expected %v got %v", newParamValue, gotParam) - } + require.False(t, int(newParamValue) != gotParam, fmt.Sprintf("wrong param value after handling, expected %v got %v", newParamValue, gotParam)) } func TestUtilityContext_GetParamOwner(t *testing.T) { @@ -644,650 +535,434 @@ func TestUtilityContext_GetParamOwner(t *testing.T) { defaultParam := defaultParams.AclOwner gotParam, err := ctx.GetParamOwner(types.AclOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.BlocksPerSessionOwner gotParam, err = ctx.GetParamOwner(types.BlocksPerSessionParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppMaxChainsOwner gotParam, err = ctx.GetParamOwner(types.AppMaxChainsParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppMinimumStakeOwner gotParam, err = ctx.GetParamOwner(types.AppMinimumStakeParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppBaselineStakeRateOwner gotParam, err = ctx.GetParamOwner(types.AppBaselineStakeRateParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppStakingAdjustmentOwner gotParam, err = ctx.GetParamOwner(types.AppStakingAdjustmentOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppUnstakingBlocksOwner gotParam, err = ctx.GetParamOwner(types.AppUnstakingBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppMinimumPauseBlocksOwner gotParam, err = ctx.GetParamOwner(types.AppMinimumPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AppMaxPausedBlocksOwner gotParam, err = ctx.GetParamOwner(types.AppMaxPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ServiceNodesPerSessionOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodesPerSessionParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ServiceNodeMinimumStakeOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMinimumStakeParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ServiceNodeMaxChainsOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMaxChainsParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ServiceNodeUnstakingBlocksOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeUnstakingBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ServiceNodeMinimumPauseBlocksOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMinimumPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ServiceNodeMaxPausedBlocksOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMaxPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.FishermanMinimumStakeOwner gotParam, err = ctx.GetParamOwner(types.FishermanMinimumStakeParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.GetServiceNodeMaxChainsOwner() gotParam, err = ctx.GetParamOwner(types.ServiceNodeMaxPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.FishermanUnstakingBlocksOwner gotParam, err = ctx.GetParamOwner(types.FishermanUnstakingBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.FishermanMinimumPauseBlocksOwner gotParam, err = ctx.GetParamOwner(types.FishermanMinimumPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.FishermanMaxPausedBlocksOwner gotParam, err = ctx.GetParamOwner(types.FishermanMaxPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ValidatorMinimumStakeOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMinimumStakeParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ValidatorUnstakingBlocksOwner gotParam, err = ctx.GetParamOwner(types.ValidatorUnstakingBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ValidatorMinimumPauseBlocksOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMinimumPauseBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ValidatorMaxPausedBlocksOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMaxPausedBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ValidatorMaximumMissedBlocksOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMaximumMissedBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ProposerPercentageOfFeesOwner gotParam, err = ctx.GetParamOwner(types.ProposerPercentageOfFeesParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.ValidatorMaxEvidenceAgeInBlocksOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMaxEvidenceAgeInBlocksParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MissedBlocksBurnPercentageOwner gotParam, err = ctx.GetParamOwner(types.MissedBlocksBurnPercentageParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.DoubleSignBurnPercentageOwner gotParam, err = ctx.GetParamOwner(types.DoubleSignBurnPercentageParamName) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageDoubleSignFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageDoubleSignFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageSendFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageSendFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageStakeFishermanFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeFishermanFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageEditStakeFishermanFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeFishermanFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnstakeFishermanFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeFishermanFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessagePauseFishermanFeeOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseFishermanFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnpauseFishermanFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseFishermanFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageTestScoreFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageTestScoreFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageFishermanPauseServiceNodeFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageFishermanPauseServiceNodeFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageProveTestScoreFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageProveTestScoreFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageStakeAppFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeAppFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageEditStakeAppFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeAppFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnstakeAppFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeAppFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessagePauseAppFeeOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseAppFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnpauseAppFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseAppFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageStakeValidatorFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeValidatorFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageEditStakeValidatorFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeValidatorFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnstakeValidatorFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeValidatorFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessagePauseValidatorFeeOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseValidatorFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnpauseValidatorFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseValidatorFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageStakeServiceNodeFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeServiceNodeFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageEditStakeServiceNodeFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeServiceNodeFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnstakeServiceNodeFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeServiceNodeFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessagePauseServiceNodeFeeOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseServiceNodeFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageUnpauseServiceNodeFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseServiceNodeFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.MessageChangeParameterFeeOwner gotParam, err = ctx.GetParamOwner(types.MessageChangeParameterFee) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) // owners defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.BlocksPerSessionOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppMaxChainsOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppMinimumStakeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppBaselineStakeRateOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppStakingAdjustmentOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppUnstakingBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppMinimumPauseBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.AppMaxPausedBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMinimumPauseBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMaxChainsOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeUnstakingBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMinimumStakeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodeMaxPausedBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ServiceNodesPerSessionOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.FishermanMinimumStakeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.FishermanMaxChainsOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.FishermanUnstakingBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.FishermanMinimumPauseBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.FishermanMaxPausedBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMinimumStakeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ValidatorUnstakingBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMinimumPauseBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMaxPausedBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMaxPausedBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ProposerPercentageOfFeesOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.ValidatorMaxEvidenceAgeInBlocksOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MissedBlocksBurnPercentageOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.DoubleSignBurnPercentageOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageSendFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeFishermanFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeFishermanFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeFishermanFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseFishermanFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseFishermanFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageFishermanPauseServiceNodeFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageTestScoreFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageProveTestScoreFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeAppFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeAppFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeAppFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseAppFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseAppFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeValidatorFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeValidatorFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeValidatorFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseValidatorFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseValidatorFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageStakeServiceNodeFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageEditStakeServiceNodeFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnstakeServiceNodeFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessagePauseServiceNodeFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageUnpauseServiceNodeFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) defaultParam = defaultParams.AclOwner gotParam, err = ctx.GetParamOwner(types.MessageChangeParameterFeeOwner) require.NoError(t, err) - if !bytes.Equal(gotParam, defaultParam) { - t.Fatalf("unexpected param value: expected %v got %v", defaultParam, gotParam) - } + require.False(t, !bytes.Equal(gotParam, defaultParam), fmt.Sprintf("unexpected param value: expected %v got %v", defaultParam, gotParam)) } diff --git a/shared/tests/utility_module/module_test.go b/shared/tests/utility_module/module_test.go index 028d3ae5d..bb508d741 100644 --- a/shared/tests/utility_module/module_test.go +++ b/shared/tests/utility_module/module_test.go @@ -16,18 +16,13 @@ import ( ) var ( - defaultTestingChains = []string{"0001"} - defaultTestingChainsEdited = []string{"0002"} - defaultServiceUrl = "https://foo.bar" - defaultServiceUrlEdited = "https://bar.foo" - defaultServiceNodesPerSession = 24 - zeroAmount = big.NewInt(0) - zeroAmountString = types.BigIntToString(zeroAmount) - defaultAmount = big.NewInt(1000000000000000) - defaultSendAmount = big.NewInt(10000) - defaultAmountString = types.BigIntToString(defaultAmount) - defaultNonceString = types.BigIntToString(defaultAmount) - defaultSendAmountString = types.BigIntToString(defaultSendAmount) + defaultTestingChains = []string{"0001"} + defaultTestingChainsEdited = []string{"0002"} + defaultAmount = big.NewInt(1000000000000000) + defaultSendAmount = big.NewInt(10000) + defaultAmountString = types.BigIntToString(defaultAmount) + defaultNonceString = types.BigIntToString(defaultAmount) + defaultSendAmountString = types.BigIntToString(defaultSendAmount) ) func NewTestingMempool(_ *testing.T) types.Mempool { @@ -47,9 +42,9 @@ func NewTestingUtilityContext(t *testing.T, height int64) utility.UtilityContext require.NoError(t, err) persistenceModule := pre_persistence.NewPrePersistenceModule(memdb.New(comparer.DefaultComparer, 10000000), mempool, cfg) - if err := persistenceModule.Start(); err != nil { - t.Fatal(err) - } + err = persistenceModule.Start() + require.NoError(t, err, "start persistence mod") + persistenceContext, err := persistenceModule.NewContext(height) require.NoError(t, err) return utility.UtilityContext{ diff --git a/shared/tests/utility_module/service_node_test.go b/shared/tests/utility_module/service_node_test.go deleted file mode 100644 index bccb0f9ff..000000000 --- a/shared/tests/utility_module/service_node_test.go +++ /dev/null @@ -1,486 +0,0 @@ -package utility_module - -import ( - "bytes" - "math" - "math/big" - "reflect" - "testing" - - "github.com/pokt-network/pocket/persistence/pre_persistence" - "github.com/stretchr/testify/require" - - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - "github.com/pokt-network/pocket/shared/types/genesis" - "github.com/pokt-network/pocket/utility" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func TestUtilityContext_HandleMessageStakeServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - out, _ := crypto.GenerateAddress() - if err := ctx.SetAccountAmount(out, defaultAmount); err != nil { - t.Fatal(err) - } - msg := &typesUtil.MessageStakeServiceNode{ - PublicKey: pubKey.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmountString, - OutputAddress: out, - Signer: out, - } - if err := ctx.HandleMessageStakeServiceNode(msg); err != nil { - t.Fatal(err) - } - actors := GetAllTestingServiceNodes(t, ctx) - var actor *genesis.ServiceNode - for _, a := range actors { - if bytes.Equal(a.PublicKey, msg.PublicKey) { - actor = a - break - } - } - if !bytes.Equal(actor.Address, pubKey.Address()) { - t.Fatalf("incorrect address, expected %v, got %v", pubKey.Address(), actor.Address) - } - if actor.Status != typesUtil.StakedStatus { - t.Fatalf("incorrect status, expected %v, got %v", typesUtil.StakedStatus, actor.Status) - } - if !reflect.DeepEqual(actor.Chains, msg.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked amount, expected %v, got %v", actor.StakedTokens, defaultAmountString) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, out) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, out) - } -} - -func TestUtilityContext_GetServiceNodeCount(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingServiceNodes(t, ctx) - count, err := ctx.GetServiceNodeCount(defaultTestingChains[0], 0) - require.NoError(t, err) - if count != len(actors) { - t.Fatalf("wrong chain count, expected %d, got %d", len(actors), count) - } -} - -func TestUtilityContext_GetServiceNodesPerSession(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - count, err := ctx.GetServiceNodesPerSession(0) - require.NoError(t, err) - if count != defaultServiceNodesPerSession { - t.Fatalf("incorrect service node per session, expected %d got %d", defaultServiceNodesPerSession, count) - } -} - -func TestUtilityContext_HandleMessageEditStakeServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingServiceNodes(t, ctx)[0] - msg := &typesUtil.MessageEditStakeServiceNode{ - Address: actor.Address, - Chains: defaultTestingChains, - AmountToAdd: zeroAmountString, - Signer: actor.Address, - } - msgChainsEdited := msg - msgChainsEdited.Chains = defaultTestingChainsEdited - if err := ctx.HandleMessageEditStakeServiceNode(msgChainsEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if !reflect.DeepEqual(actor.Chains, msg.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if !reflect.DeepEqual(actor.Chains, msgChainsEdited.Chains) { - t.Fatalf("incorrect chains, expected %v, got %v", msg.Chains, actor.Chains) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked tokens, expected %v, got %v", defaultAmountString, actor.StakedTokens) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, actor.Output) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, actor.Output) - } - amountEdited := big.NewInt(1) - expectedAmount := types.BigIntToString(big.NewInt(0).Add(defaultAmount, amountEdited)) - amountEditedString := types.BigIntToString(amountEdited) - msgAmountEdited := msg - msgAmountEdited.AmountToAdd = amountEditedString - if err := ctx.HandleMessageEditStakeServiceNode(msgAmountEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("incorrect amount status, expected %v, got %v", expectedAmount, actor.StakedTokens) - } -} - -func TestUtilityContext_HandleMessagePauseServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingServiceNodes(t, ctx)[0] - msg := &typesUtil.MessagePauseServiceNode{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseServiceNode(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } -} - -func TestUtilityContext_HandleMessageUnpauseServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetServiceNodeMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingServiceNodes(t, ctx)[0] - msg := &typesUtil.MessagePauseServiceNode{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseServiceNode(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } - msgU := &typesUtil.MessageUnpauseServiceNode{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnpauseServiceNode(msgU); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if actor.Paused { - t.Fatal("actor is paused after") - } -} - -func TestUtilityContext_HandleMessageUnstakeServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetServiceNodeMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingServiceNodes(t, ctx)[0] - msg := &typesUtil.MessageUnstakeServiceNode{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnstakeServiceNode(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("actor isn't unstaking") - } -} - -func TestUtilityContext_BeginUnstakingMaxPausedServiceNodes(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingServiceNodes(t, ctx)[0] - err := ctx.Context.SetServiceNodeMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetServiceNodePauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.BeginUnstakingMaxPausedServiceNodes(); err != nil { - t.Fatal(err) - } - status, err := ctx.GetServiceNodeStatus(actor.Address) - if status != 1 { - t.Fatalf("incorrect status; expected %d got %d", 1, actor.Status) - } -} - -func TestUtilityContext_CalculateServiceNodeUnstakingHeight(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - unstakingBlocks, err := ctx.GetServiceNodeUnstakingBlocks() - require.NoError(t, err) - unstakingHeight, err := ctx.CalculateServiceNodeUnstakingHeight() - require.NoError(t, err) - if unstakingBlocks != unstakingHeight { - t.Fatalf("unexpected unstakingHeight; got %d expected %d", unstakingBlocks, unstakingHeight) - } -} - -func TestUtilityContext_DeleteServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingServiceNodes(t, ctx) - actor := actors[0] - if err := ctx.DeleteServiceNode(actor.Address); err != nil { - t.Fatal(err) - } - if len(GetAllTestingServiceNodes(t, ctx)) != len(actors)-1 { - t.Fatal("deletion unsuccessful") - } -} - -func TestUtilityContext_GetServiceNodeExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - randAddr, _ := crypto.GenerateAddress() - actor := GetAllTestingServiceNodes(t, ctx)[0] - exists, err := ctx.GetServiceNodeExists(actor.Address) - require.NoError(t, err) - if !exists { - t.Fatal("actor that should exist does not") - } - exists, err = ctx.GetServiceNodeExists(randAddr) - require.NoError(t, err) - if exists { - t.Fatal("actor that shouldn't exist does") - } -} - -func TestUtilityContext_GetServiceNodeOutputAddress(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingServiceNodes(t, ctx)[0] - outputAddress, err := ctx.GetServiceNodeOutputAddress(actor.Address) - require.NoError(t, err) - if !bytes.Equal(outputAddress, actor.Output) { - t.Fatalf("unexpected output address, expected %v got %v", actor.Output, outputAddress) - } -} - -func TestUtilityContext_GetServiceNodePauseHeightIfExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingServiceNodes(t, ctx)[0] - pauseHeight := int64(100) - if err := ctx.SetServiceNodePauseHeight(actor.Address, pauseHeight); err != nil { - t.Fatal(err) - } - gotPauseHeight, err := ctx.GetServiceNodePauseHeightIfExists(actor.Address) - require.NoError(t, err) - if pauseHeight != gotPauseHeight { - t.Fatal("unable to get pause height from the actor") - } - addr, _ := crypto.GenerateAddress() - _, err = ctx.GetServiceNodePauseHeightIfExists(addr) - if err == nil { - t.Fatal("no error on non-existent actor pause height") - } -} - -func TestUtilityContext_GetServiceNodesReadyToUnstake(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingServiceNodes(t, ctx)[0] - if err := ctx.SetServiceNodeUnstakingHeightAndStatus(actor.Address, 0); err != nil { - t.Fatal(err) - } - actors, err := ctx.GetServiceNodesReadyToUnstake() - require.NoError(t, err) - if !bytes.Equal(actors[0].Address, actor.Address) { - t.Fatalf("unexpected actor ready to unstake: expected %s, got %s", actor.Address, actors[0].Address) - } -} - -func TestUtilityContext_GetMessageEditStakeServiceNodeSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingServiceNodes(t, ctx) - msgEditStake := &typesUtil.MessageEditStakeServiceNode{ - Address: actors[0].Address, - Chains: defaultTestingChains, - AmountToAdd: defaultAmountString, - } - candidates, err := ctx.GetMessageEditStakeServiceNodeSignerCandidates(msgEditStake) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessagePauseServiceNodeSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingServiceNodes(t, ctx) - msg := &typesUtil.MessagePauseServiceNode{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessagePauseServiceNodeSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageStakeServiceNodeSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - out, _ := crypto.GenerateAddress() - msg := &typesUtil.MessageStakeServiceNode{ - PublicKey: pubKey.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmountString, - OutputAddress: out, - } - candidates, err := ctx.GetMessageStakeServiceNodeSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], out) || !bytes.Equal(candidates[1], addr) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnpauseServiceNodeSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingServiceNodes(t, ctx) - msg := &typesUtil.MessageUnpauseServiceNode{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnpauseServiceNodeSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnstakeServiceNodeSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingServiceNodes(t, ctx) - msg := &typesUtil.MessageUnstakeServiceNode{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnstakeServiceNodeSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_InsertServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - if err := ctx.InsertServiceNode(addr, pubKey.Bytes(), addr, defaultServiceUrl, defaultAmountString, defaultTestingChains); err != nil { - t.Fatal(err) - } - exists, err := ctx.GetServiceNodeExists(addr) - require.NoError(t, err) - if !exists { - t.Fatal("actor does not exist after insert") - } - actors := GetAllTestingServiceNodes(t, ctx) - for _, actor := range actors { - if bytes.Equal(actor.Address, addr) { - if actor.Chains[0] != defaultTestingChains[0] { - t.Fatal("wrong chains") - } - if actor.StakedTokens != defaultAmountString { - t.Fatal("wrong staked tokens") - } - if actor.ServiceUrl != defaultServiceUrl { - t.Fatal("wrong serviceURL") - } - if !bytes.Equal(actor.Output, addr) { - t.Fatal("wrong output addr") - } - return - } - } - t.Fatal("actor not found after insert in GetAll() call") -} - -func TestUtilityContext_UnstakeServiceNodesPausedBefore(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingServiceNodes(t, ctx)[0] - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - err := ctx.Context.SetServiceNodeMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetServiceNodePauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeServiceNodesPausedBefore(1); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("status does not equal unstaking") - } - unstakingBlocks, err := ctx.GetServiceNodeUnstakingBlocks() - require.NoError(t, err) - if actor.UnstakingHeight != unstakingBlocks+1 { - t.Fatal("incorrect unstaking height") - } -} - -func TestUtilityContext_UnstakeServiceNodesThatAreReady(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - ctx.SetPoolAmount(genesis.ServiceNodeStakePoolName, big.NewInt(math.MaxInt64)) - if err := ctx.Context.SetServiceNodeUnstakingBlocks(0); err != nil { - t.Fatal(err) - } - err := ctx.Context.SetServiceNodeMaxPausedBlocks(0) - if err != nil { - t.Fatal(err) - } - actors := GetAllTestingServiceNodes(t, ctx) - for _, actor := range actors { - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - if err := ctx.SetServiceNodePauseHeight(actor.Address, 1); err != nil { - t.Fatal(err) - } - } - if err := ctx.UnstakeServiceNodesPausedBefore(2); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeServiceNodesThatAreReady(); err != nil { - t.Fatal(err) - } - if len(GetAllTestingServiceNodes(t, ctx)) != 0 { - t.Fatal("service nodes still exists after unstake that are ready() call") - } -} - -func TestUtilityContext_UpdateServiceNode(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingServiceNodes(t, ctx)[0] - newAmountBig := big.NewInt(9999999999999999) - newAmount := types.BigIntToString(newAmountBig) - oldAmount := actor.StakedTokens - oldAmountBig, err := types.StringToBigInt(oldAmount) - require.NoError(t, err) - expectedAmountBig := newAmountBig.Add(newAmountBig, oldAmountBig) - expectedAmount := types.BigIntToString(expectedAmountBig) - if err := ctx.UpdateServiceNode(actor.Address, actor.ServiceUrl, newAmount, actor.Chains); err != nil { - t.Fatal(err) - } - actor = GetAllTestingServiceNodes(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("updated amount is incorrect; expected %s got %s", expectedAmount, actor.StakedTokens) - } -} - -func GetAllTestingServiceNodes(t *testing.T, ctx utility.UtilityContext) []*genesis.ServiceNode { - actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllServiceNodes(ctx.LatestHeight) - require.NoError(t, err) - return actors -} diff --git a/shared/tests/utility_module/transaction_test.go b/shared/tests/utility_module/transaction_test.go index cc3f36a60..0a8839c4e 100644 --- a/shared/tests/utility_module/transaction_test.go +++ b/shared/tests/utility_module/transaction_test.go @@ -1,8 +1,6 @@ package utility_module import ( - "bytes" - "encoding/hex" "math/big" "testing" @@ -15,143 +13,125 @@ import ( func TestUtilityContext_AnteHandleMessage(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) + tx, startingBalance, _, signer := NewTestingTransaction(t, ctx) - if _, err := ctx.AnteHandleMessage(tx); err != nil { - t.Fatal(err) - } + _, err := ctx.AnteHandleMessage(tx) + require.NoError(t, err) + feeBig, err := ctx.GetMessageSendFee() require.NoError(t, err) + expectedAfterBalance := big.NewInt(0).Sub(startingBalance, feeBig) amount, err := ctx.GetAccountAmount(signer.Address()) require.NoError(t, err) - if amount.Cmp(expectedAfterBalance) != 0 { - t.Fatalf("unexpected after balance; expected %v got %v", expectedAfterBalance, amount) - } + require.Equal(t, amount, expectedAfterBalance, "unexpected after balance") } func TestUtilityContext_ApplyTransaction(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) + tx, startingBalance, amount, signer := NewTestingTransaction(t, ctx) - if err := ctx.ApplyTransaction(tx); err != nil { - t.Fatal(err) - } + require.NoError(t, ctx.ApplyTransaction(tx)) + feeBig, err := ctx.GetMessageSendFee() require.NoError(t, err) + expectedAmountSubtracted := amount.Add(amount, feeBig) expectedAfterBalance := big.NewInt(0).Sub(startingBalance, expectedAmountSubtracted) amount, err = ctx.GetAccountAmount(signer.Address()) require.NoError(t, err) - if amount.Cmp(expectedAfterBalance) != 0 { - t.Fatalf("unexpected after balance; expected %v got %v", expectedAfterBalance, amount) - } + require.Equal(t, amount, expectedAfterBalance, "unexpected after balance") } func TestUtilityContext_CheckTransaction(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) + tx, _, _, _ := NewTestingTransaction(t, ctx) txBz, err := tx.Bytes() require.NoError(t, err) - if err := ctx.CheckTransaction(txBz); err != nil { - t.Fatal(err) - } + require.NoError(t, ctx.CheckTransaction(txBz)) + hash, err := tx.Hash() require.NoError(t, err) - if !ctx.Mempool.Contains(hash) { - t.Fatal("the transaction was unable to be checked") - } - if err := ctx.CheckTransaction(txBz); err.Error() != types.ErrDuplicateTransaction().Error() { - t.Fatalf("unexpected err, expected %v got %v", types.ErrDuplicateTransaction().Error(), err.Error()) - } + require.True(t, ctx.Mempool.Contains(hash), "the transaction was unable to be checked") + + er := ctx.CheckTransaction(txBz) + require.Equal(t, er.Error(), types.ErrDuplicateTransaction().Error()) } func TestUtilityContext_GetSignerCandidates(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) accs := GetAllTestingAccounts(t, ctx) + sendAmount := big.NewInt(1000000) sendAmountString := types.BigIntToString(sendAmount) msg := NewTestingSendMessage(t, accs[0].Address, accs[1].Address, sendAmountString) candidates, err := ctx.GetSignerCandidates(&msg) require.NoError(t, err) - if len(candidates) != 1 { - t.Fatalf("wrong number of candidates, expected %d, got %d", 1, len(candidates)) - } - if !bytes.Equal(candidates[0], accs[0].Address) { - t.Fatal("unexpected signer candidate") - } + require.Equal(t, len(candidates), 1, "wrong number of candidates") + require.Equal(t, candidates[0], accs[0].Address, "unexpected signer candidate") } func TestUtilityContext_GetTransactionsForProposal(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) tx, _, _, _ := NewTestingTransaction(t, ctx) proposer := GetAllTestingValidators(t, ctx)[0] + txBz, err := tx.Bytes() require.NoError(t, err) - if err := ctx.CheckTransaction(txBz); err != nil { - t.Fatal(err) - } + require.NoError(t, ctx.CheckTransaction(txBz)) + txs, er := ctx.GetTransactionsForProposal(proposer.Address, 10000, nil) - if er != nil { - t.Fatal(er) - } - if len(txs) != 1 { - t.Fatalf("incorrect txs amount returned; expected %v got %v", 1, len(txs)) - } - if !bytes.Equal(txs[0], txBz) { - t.Fatalf("unexpected transaction returned; expected tx: %s, got %s", hex.EncodeToString(txBz), hex.EncodeToString(txs[0])) - } + require.NoError(t, er) + require.Equal(t, len(txs), 1, "incorrect txs amount returned") + require.Equal(t, txs[0], txBz, "unexpected transaction returned") } func TestUtilityContext_HandleMessage(t *testing.T) { ctx := NewTestingUtilityContext(t, 0) accs := GetAllTestingAccounts(t, ctx) + sendAmount := big.NewInt(1000000) sendAmountString := types.BigIntToString(sendAmount) senderBalanceBefore, err := types.StringToBigInt(accs[0].Amount) require.NoError(t, err) + recipientBalanceBefore, err := types.StringToBigInt(accs[1].Amount) require.NoError(t, err) + msg := NewTestingSendMessage(t, accs[0].Address, accs[1].Address, sendAmountString) - if err := ctx.HandleMessageSend(&msg); err != nil { - t.Fatal(err) - } + require.NoError(t, ctx.HandleMessageSend(&msg)) + accs = GetAllTestingAccounts(t, ctx) senderBalanceAfter, err := types.StringToBigInt(accs[0].Amount) require.NoError(t, err) + recipientBalanceAfter, err := types.StringToBigInt(accs[1].Amount) require.NoError(t, err) - if big.NewInt(0).Sub(senderBalanceBefore, senderBalanceAfter).Cmp(sendAmount) != 0 { - t.Fatal("unexpected sender balance") - } - if big.NewInt(0).Sub(recipientBalanceAfter, recipientBalanceBefore).Cmp(sendAmount) != 0 { - t.Fatal("unexpected recipient balance") - } + require.Equal(t, big.NewInt(0).Sub(senderBalanceBefore, senderBalanceAfter), sendAmount, "unexpected sender balance") + require.Equal(t, big.NewInt(0).Sub(recipientBalanceAfter, recipientBalanceBefore), sendAmount, "unexpected recipient balance") } func NewTestingTransaction(t *testing.T, ctx utility.UtilityContext) (transaction *typesUtil.Transaction, startingAmount, amountSent *big.Int, signer crypto.PrivateKey) { - var err error cdc := types.GetCodec() recipient := GetAllTestingAccounts(t, ctx)[1] - signer, err = crypto.GeneratePrivateKey() + + signer, err := crypto.GeneratePrivateKey() require.NoError(t, err) + startingAmount = defaultAmount signerAddr := signer.Address() - if err = ctx.SetAccountAmount(signerAddr, defaultAmount); err != nil { - t.Fatal(err) - } + require.NoError(t, ctx.SetAccountAmount(signerAddr, defaultAmount)) + amountSent = defaultSendAmount msg := NewTestingSendMessage(t, signerAddr, recipient.Address, defaultSendAmountString) any, err := cdc.ToAny(&msg) require.NoError(t, err) - feeBig, err := ctx.GetMessageSendFee() - require.NoError(t, err) - fee := types.BigIntToString(feeBig) + transaction = &typesUtil.Transaction{ Msg: any, - Fee: fee, Nonce: defaultNonceString, } - if err = transaction.Sign(signer); err != nil { - t.Fatal(err) - } + require.NoError(t, transaction.Sign(signer)) return } diff --git a/shared/tests/utility_module/validator_test.go b/shared/tests/utility_module/validator_test.go deleted file mode 100644 index 20ea4ba27..000000000 --- a/shared/tests/utility_module/validator_test.go +++ /dev/null @@ -1,660 +0,0 @@ -package utility_module - -import ( - "bytes" - "math/big" - "testing" - - "github.com/pokt-network/pocket/persistence/pre_persistence" - "github.com/stretchr/testify/require" - - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - "github.com/pokt-network/pocket/shared/types/genesis" - "github.com/pokt-network/pocket/utility" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func TestUtilityContext_HandleMessageStakeValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - out, _ := crypto.GenerateAddress() - if err := ctx.SetAccountAmount(out, defaultAmount); err != nil { - t.Fatal(err) - } - msg := &typesUtil.MessageStakeValidator{ - PublicKey: pubKey.Bytes(), - Amount: defaultAmountString, - ServiceUrl: defaultServiceUrl, - OutputAddress: out, - Signer: out, - } - if err := ctx.HandleMessageStakeValidator(msg); err != nil { - t.Fatal(err) - } - actors := GetAllTestingValidators(t, ctx) - var actor *genesis.Validator - for _, a := range actors { - if bytes.Equal(a.PublicKey, msg.PublicKey) { - actor = a - break - } - } - if !bytes.Equal(actor.Address, pubKey.Address()) { - t.Fatalf("incorrect address, expected %v, got %v", pubKey.Address(), actor.Address) - } - if actor.Status != typesUtil.StakedStatus { - t.Fatalf("incorrect status, expected %v, got %v", typesUtil.StakedStatus, actor.Status) - } - if actor.ServiceUrl != defaultServiceUrl { - t.Fatalf("incorrect chains, expected %v, got %v", actor.ServiceUrl, defaultServiceUrl) - } - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked amount, expected %v, got %v", actor.StakedTokens, defaultAmountString) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, out) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, out) - } -} - -func TestUtilityContext_HandleMessageEditStakeValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - msg := &typesUtil.MessageEditStakeValidator{ - Address: actor.Address, - ServiceUrl: defaultServiceUrlEdited, - AmountToAdd: zeroAmountString, - Signer: actor.Address, - } - msgServiceUrlEdited := msg - msgServiceUrlEdited.ServiceUrl = defaultServiceUrlEdited - if err := ctx.HandleMessageEditStakeValidator(msgServiceUrlEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.Paused != false { - t.Fatalf("incorrect paused status, expected %v, got %v", false, actor.Paused) - } - if actor.PausedHeight != types.HeightNotUsed { - t.Fatalf("incorrect paused height, expected %v, got %v", types.HeightNotUsed, actor.PausedHeight) - } - if actor.ServiceUrl != defaultServiceUrlEdited { - t.Fatalf("incorrect serviceurl, expected %v, got %v", defaultServiceUrlEdited, actor.ServiceUrl) - } - if actor.StakedTokens != defaultAmountString { - t.Fatalf("incorrect staked tokens, expected %v, got %v", defaultAmountString, actor.StakedTokens) - } - if actor.UnstakingHeight != types.HeightNotUsed { - t.Fatalf("incorrect unstaking height, expected %v, got %v", types.HeightNotUsed, actor.UnstakingHeight) - } - if !bytes.Equal(actor.Output, actor.Output) { - t.Fatalf("incorrect output address, expected %v, got %v", actor.Output, actor.Output) - } - amountEdited := big.NewInt(1) - expectedAmount := types.BigIntToString(big.NewInt(0).Add(defaultAmount, amountEdited)) - amountEditedString := types.BigIntToString(amountEdited) - msgAmountEdited := msg - msgAmountEdited.AmountToAdd = amountEditedString - if err := ctx.HandleMessageEditStakeValidator(msgAmountEdited); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("incorrect amount status, expected %v, got %v", expectedAmount, actor.StakedTokens) - } -} - -func TestUtilityContext_HandleMessagePauseValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingValidators(t, ctx)[0] - msg := &typesUtil.MessagePauseValidator{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseValidator(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } -} - -func TestUtilityContext_HandleMessageUnpauseValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetValidatorMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingValidators(t, ctx)[0] - msg := &typesUtil.MessagePauseValidator{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessagePauseValidator(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor isn't paused after") - } - msgU := &typesUtil.MessageUnpauseValidator{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnpauseValidator(msgU); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.Paused { - t.Fatal("actor is paused after") - } -} - -func TestUtilityContext_HandleMessageUnstakeValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - if err := ctx.Context.SetValidatorMinimumPauseBlocks(0); err != nil { - t.Fatal(err) - } - actor := GetAllTestingValidators(t, ctx)[0] - msg := &typesUtil.MessageUnstakeValidator{ - Address: actor.Address, - Signer: actor.Address, - } - if err := ctx.HandleMessageUnstakeValidator(msg); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("actor isn't unstaking") - } -} - -func TestUtilityContext_BeginUnstakingMaxPausedValidators(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingValidators(t, ctx)[0] - err := ctx.Context.SetValidatorMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetValidatorPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.BeginUnstakingMaxPausedValidators(); err != nil { - t.Fatal(err) - } - status, err := ctx.GetValidatorStatus(actor.Address) - if status != 1 { - t.Fatalf("incorrect status; expected %d got %d", 1, actor.Status) - } -} - -func TestUtilityContext_CalculateValidatorUnstakingHeight(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - unstakingBlocks, err := ctx.GetValidatorUnstakingBlocks() - require.NoError(t, err) - unstakingHeight, err := ctx.CalculateValidatorUnstakingHeight() - require.NoError(t, err) - if unstakingBlocks != unstakingHeight { - t.Fatalf("unexpected unstakingHeight; got %d expected %d", unstakingBlocks, unstakingHeight) - } -} - -func TestUtilityContext_DeleteValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingValidators(t, ctx) - actor := actors[0] - if err := ctx.DeleteValidator(actor.Address); err != nil { - t.Fatal(err) - } - if len(GetAllTestingValidators(t, ctx)) != len(actors)-1 { - t.Fatal("deletion unsuccessful") - } -} - -func TestUtilityContext_GetValidatorExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - randAddr, _ := crypto.GenerateAddress() - actor := GetAllTestingValidators(t, ctx)[0] - exists, err := ctx.GetValidatorExists(actor.Address) - require.NoError(t, err) - if !exists { - t.Fatal("actor that should exist does not") - } - exists, err = ctx.GetValidatorExists(randAddr) - require.NoError(t, err) - if exists { - t.Fatal("actor that shouldn't exist does") - } -} - -func TestUtilityContext_GetValidatorOutputAddress(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - outputAddress, err := ctx.GetValidatorOutputAddress(actor.Address) - require.NoError(t, err) - if !bytes.Equal(outputAddress, actor.Output) { - t.Fatalf("unexpected output address, expected %v got %v", actor.Output, outputAddress) - } -} - -func TestUtilityContext_GetValidatorPauseHeightIfExists(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - pauseHeight := int64(100) - if err := ctx.SetValidatorPauseHeight(actor.Address, pauseHeight); err != nil { - t.Fatal(err) - } - gotPauseHeight, err := ctx.GetValidatorPauseHeightIfExists(actor.Address) - require.NoError(t, err) - if pauseHeight != gotPauseHeight { - t.Fatal("unable to get pause height from the actor") - } - addr, _ := crypto.GenerateAddress() - _, err = ctx.GetValidatorPauseHeightIfExists(addr) - if err == nil { - t.Fatal("no error on non-existent actor pause height") - } -} - -func TestUtilityContext_GetValidatorsReadyToUnstake(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - if err := ctx.SetValidatorUnstakingHeightAndStatus(actor.Address, 0); err != nil { - t.Fatal(err) - } - actors, err := ctx.GetValidatorsReadyToUnstake() - require.NoError(t, err) - if !bytes.Equal(actors[0].Address, actor.Address) { - t.Fatalf("unexpected actor ready to unstake: expected %s, got %s", actor.Address, actors[0].Address) - } -} - -func TestUtilityContext_GetMessageEditStakeValidatorSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingValidators(t, ctx) - msgEditStake := &typesUtil.MessageEditStakeValidator{ - Address: actors[0].Address, - ServiceUrl: defaultServiceUrl, - AmountToAdd: defaultAmountString, - } - candidates, err := ctx.GetMessageEditStakeValidatorSignerCandidates(msgEditStake) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessagePauseValidatorSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingValidators(t, ctx) - msg := &typesUtil.MessagePauseValidator{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessagePauseValidatorSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageStakeValidatorSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - out, _ := crypto.GenerateAddress() - msg := &typesUtil.MessageStakeValidator{ - PublicKey: pubKey.Bytes(), - Amount: defaultAmountString, - ServiceUrl: defaultServiceUrl, - OutputAddress: out, - Signer: nil, - } - candidates, err := ctx.GetMessageStakeValidatorSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], out) || !bytes.Equal(candidates[1], addr) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnpauseValidatorSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingValidators(t, ctx) - msg := &typesUtil.MessageUnpauseValidator{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnpauseValidatorSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_GetMessageUnstakeValidatorSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actors := GetAllTestingValidators(t, ctx) - msg := &typesUtil.MessageUnstakeValidator{ - Address: actors[0].Address, - } - candidates, err := ctx.GetMessageUnstakeValidatorSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actors[0].Output) || !bytes.Equal(candidates[1], actors[0].Address) { - t.Fatal(err) - } -} - -func TestUtilityContext_InsertValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - pubKey, _ := crypto.GeneratePublicKey() - addr := pubKey.Address() - if err := ctx.InsertValidator(addr, pubKey.Bytes(), addr, defaultServiceUrl, defaultAmountString); err != nil { - t.Fatal(err) - } - exists, err := ctx.GetValidatorExists(addr) - require.NoError(t, err) - if !exists { - t.Fatal("actor does not exist after insert") - } - actors := GetAllTestingValidators(t, ctx) - for _, actor := range actors { - if bytes.Equal(actor.Address, addr) { - if actor.StakedTokens != defaultAmountString { - t.Fatal("wrong staked tokens") - } - if actor.ServiceUrl != defaultServiceUrl { - t.Fatal("wrong serviceURL") - } - if !bytes.Equal(actor.Output, addr) { - t.Fatal("wrong output addr") - } - return - } - } - t.Fatal("actor not found after insert in GetAll() call") -} - -func TestUtilityContext_UnstakeValidatorsPausedBefore(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingValidators(t, ctx)[0] - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - err := ctx.Context.SetValidatorMaxPausedBlocks(0) - require.NoError(t, err) - if err := ctx.SetValidatorPauseHeight(actor.Address, 0); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeValidatorsPausedBefore(1); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.Status != typesUtil.UnstakingStatus { - t.Fatal("status does not equal unstaking") - } - unstakingBlocks, err := ctx.GetValidatorUnstakingBlocks() - require.NoError(t, err) - if actor.UnstakingHeight != unstakingBlocks+1 { - t.Fatal("incorrect unstaking height") - } -} - -func TestUtilityContext_UnstakeValidatorsThatAreReady(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - ctx.SetPoolAmount(genesis.ValidatorStakePoolName, big.NewInt(100000000000000000)) - if err := ctx.Context.SetValidatorUnstakingBlocks(0); err != nil { - t.Fatal(err) - } - err := ctx.Context.SetValidatorMaxPausedBlocks(0) - if err != nil { - t.Fatal(err) - } - actors := GetAllTestingValidators(t, ctx) - for _, actor := range actors { - if actor.Status != typesUtil.StakedStatus { - t.Fatal("wrong starting status") - } - if err := ctx.SetValidatorPauseHeight(actor.Address, 1); err != nil { - t.Fatal(err) - } - } - if err := ctx.UnstakeValidatorsPausedBefore(2); err != nil { - t.Fatal(err) - } - if err := ctx.UnstakeValidatorsThatAreReady(); err != nil { - t.Fatal(err) - } - if len(GetAllTestingValidators(t, ctx)) != 0 { - t.Fatal("validators still exists after unstake that are ready() call") - } -} - -func TestUtilityContext_UpdateValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 1) - actor := GetAllTestingValidators(t, ctx)[0] - newAmountBig := big.NewInt(9999999999999999) - newAmount := types.BigIntToString(newAmountBig) - oldAmount := actor.StakedTokens - oldAmountBig, err := types.StringToBigInt(oldAmount) - require.NoError(t, err) - expectedAmountBig := newAmountBig.Add(newAmountBig, oldAmountBig) - expectedAmount := types.BigIntToString(expectedAmountBig) - if err := ctx.UpdateValidator(actor.Address, actor.ServiceUrl, newAmount); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.StakedTokens != expectedAmount { - t.Fatalf("updated amount is incorrect; expected %s got %s", expectedAmount, actor.StakedTokens) - } -} - -func TestUtilityContext_BurnValidator(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - ctx.SetPoolAmount(genesis.ValidatorStakePoolName, big.NewInt(100000000000000)) - actor := GetAllTestingValidators(t, ctx)[0] - burnPercentage := big.NewFloat(10) - tokens, err := types.StringToBigInt(actor.StakedTokens) - require.NoError(t, err) - tokensFloat := big.NewFloat(0).SetInt(tokens) - tokensFloat.Mul(tokensFloat, burnPercentage) - tokensFloat.Quo(tokensFloat, big.NewFloat(100)) - tokensTrunc, _ := tokensFloat.Int(nil) - afterTokensBig := big.NewInt(0).Sub(tokens, tokensTrunc) - afterTokens := types.BigIntToString(afterTokensBig) - if err := ctx.BurnValidator(actor.Address, 10); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.StakedTokens != afterTokens { - t.Fatalf("unexpected staked tokens after burn; expected %v got %v", afterTokens, actor.StakedTokens) - } -} - -func TestUtilityContext_GetMessageDoubleSignSignerCandidates(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - msg := &typesUtil.MessageDoubleSign{ - ReporterAddress: actor.Address, - } - candidates, err := ctx.GetMessageDoubleSignSignerCandidates(msg) - require.NoError(t, err) - if !bytes.Equal(candidates[0], actor.Address) { - t.Fatalf("unexpected signer candidate: expected %v got %v", actor.Address, candidates[1]) - } -} - -func TestUtilityContext_HandleMessageDoubleSign(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - ctx.SetPoolAmount(genesis.ValidatorStakePoolName, big.NewInt(100000000000000)) - actors := GetAllTestingValidators(t, ctx) - reporter := actors[0] - byzVal := actors[1] - voteA := typesUtil.Vote{ - PublicKey: byzVal.PublicKey, - Height: 0, - Round: 0, - Type: 0, - BlockHash: crypto.SHA3Hash([]byte("voteA")), - } - voteB := voteA - voteB.BlockHash = crypto.SHA3Hash([]byte("voteB")) - msg := &typesUtil.MessageDoubleSign{ - VoteA: &voteA, - VoteB: &voteB, - ReporterAddress: reporter.Address, - } - if err := ctx.HandleMessageDoubleSign(msg); err != nil { - t.Fatal(err) - } - stakedTokensAfterBig, err := ctx.GetValidatorStakedTokens(byzVal.Address) - require.NoError(t, err) - stakedTokensAfter := types.BigIntToString(stakedTokensAfterBig) - burnPercentage, err := ctx.GetDoubleSignBurnPercentage() - require.NoError(t, err) - stakedTokensBeforeBig, err := types.StringToBigInt(byzVal.StakedTokens) - require.NoError(t, err) - stakedTokensBeforeFloat := big.NewFloat(0).SetInt(stakedTokensBeforeBig) - stakedTokensBeforeFloat.Mul(stakedTokensBeforeFloat, big.NewFloat(float64(burnPercentage))) - stakedTokensBeforeFloat.Quo(stakedTokensBeforeFloat, big.NewFloat(100)) - trunactedDiffTokens, _ := stakedTokensBeforeFloat.Int(nil) - stakedTokensExpectedAfterBig := big.NewInt(0).Sub(stakedTokensBeforeBig, trunactedDiffTokens) - stakedTokensExpectedAfter := types.BigIntToString(stakedTokensExpectedAfterBig) - if stakedTokensAfter != stakedTokensExpectedAfter { - t.Fatalf("unexpected token amount after double sign handling: expected %v got %v", stakedTokensExpectedAfter, stakedTokensAfter) - } -} - -func TestUtilityContext_GetValidatorMissedBlocks(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - missedBlocks := 3 - if int(actor.MissedBlocks) == missedBlocks { - t.Fatal("wrong missed blocks starting amount") - } - actor.MissedBlocks = uint32(missedBlocks) - if err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).SetValidatorMissedBlocks(actor.Address, int(actor.MissedBlocks)); err != nil { - t.Fatal(err) - } - gotMissedBlocks, err := ctx.GetValidatorMissedBlocks(actor.Address) - require.NoError(t, err) - if gotMissedBlocks != missedBlocks { - t.Fatalf("unexpected missed blocks: expected %v got %v", missedBlocks, gotMissedBlocks) - } -} - -func TestUtilityContext_GetValidatorStakedTokens(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - tokensBig, err := ctx.GetValidatorStakedTokens(actor.Address) - require.NoError(t, err) - tokens := types.BigIntToString(tokensBig) - if actor.StakedTokens != tokens { - t.Fatalf("unexpected staked tokens: expected %v got %v ", actor.StakedTokens, tokens) - } -} - -func TestUtilityContext_GetValidatorStatus(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - status, err := ctx.GetValidatorStatus(actor.Address) - require.NoError(t, err) - if int(actor.Status) != status { - t.Fatalf("unexpected staked tokens: expected %v got %v ", int(actor.Status), status) - } -} - -func TestUtilityContext_HandleByzantineValidators(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - ctx.SetPoolAmount(genesis.ValidatorStakePoolName, big.NewInt(100000000000000)) - actor := GetAllTestingValidators(t, ctx)[0] - stakedTokensBeforeBig, err := types.StringToBigInt(actor.StakedTokens) - require.NoError(t, err) - maxMissed, err := ctx.GetValidatorMaxMissedBlocks() - require.NoError(t, err) - if err := ctx.SetValidatorMissedBlocks(actor.Address, maxMissed); err != nil { - t.Fatal(err) - } - // Pause scenario only - // TODO add more situations / paths to test - if err := ctx.HandleByzantineValidators([][]byte{actor.Address}); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if !actor.Paused { - t.Fatal("actor should be paused after byzantine handling") - } - stakedTokensAfterBig, err := types.StringToBigInt(actor.StakedTokens) - require.NoError(t, err) - stakedTokensAfter := types.BigIntToString(stakedTokensAfterBig) - burnPercentage, err := ctx.GetMissedBlocksBurnPercentage() - require.NoError(t, err) - stakedTokensBeforeFloat := big.NewFloat(0).SetInt(stakedTokensBeforeBig) - stakedTokensBeforeFloat.Mul(stakedTokensBeforeFloat, big.NewFloat(float64(burnPercentage))) - stakedTokensBeforeFloat.Quo(stakedTokensBeforeFloat, big.NewFloat(100)) - trunactedDiffTokens, _ := stakedTokensBeforeFloat.Int(nil) - stakedTokensExpectedAfterBig := big.NewInt(0).Sub(stakedTokensBeforeBig, trunactedDiffTokens) - stakedTokensExpectedAfter := types.BigIntToString(stakedTokensExpectedAfterBig) - if stakedTokensAfter != stakedTokensExpectedAfter { - t.Fatalf("tokens are not as expected after handling: expected %v got %v", stakedTokensExpectedAfter, stakedTokensAfter) - } -} - -func TestUtilityContext_HandleProposalRewards(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - actor := GetAllTestingValidators(t, ctx)[0] - actorTokensBeforeBig, err := ctx.GetAccountAmount(actor.Address) - require.NoError(t, err) - require.NoError(t, err) - feeAndRewardsCollected := big.NewInt(100) - err = ctx.SetPoolAmount(genesis.FeePoolName, feeAndRewardsCollected) - require.NoError(t, err) - proposerCutPercentage, err := ctx.GetProposerPercentageOfFees() - require.NoError(t, err) - daoCutPercentage := 100 - proposerCutPercentage - if daoCutPercentage < 0 { - t.Fatal("dao cut percentage negative") - } - feesAndRewardsCollectedFloat := new(big.Float).SetInt(feeAndRewardsCollected) - feesAndRewardsCollectedFloat.Mul(feesAndRewardsCollectedFloat, big.NewFloat(float64(proposerCutPercentage))) - feesAndRewardsCollectedFloat.Quo(feesAndRewardsCollectedFloat, big.NewFloat(100)) - amountToProposer, _ := feesAndRewardsCollectedFloat.Int(nil) - expectedResultBig := actorTokensBeforeBig.Add(actorTokensBeforeBig, amountToProposer) - expectedResult := types.BigIntToString(expectedResultBig) - if err := ctx.HandleProposalRewards(actor.Address); err != nil { - t.Fatal(err) - } - actorTokensAfterBig, err := ctx.GetAccountAmount(actor.Address) - require.NoError(t, err) - actorTokensAfter := types.BigIntToString(actorTokensAfterBig) - if actorTokensAfter != expectedResult { - t.Fatalf("unexpected token amount after; expected %v got %v", expectedResult, actorTokensAfter) - } -} - -func TestUtilityContext_SetValidatorStakedTokens(t *testing.T) { - ctx := NewTestingUtilityContext(t, 0) - afterTokensExpectedBig := big.NewInt(100) - afterTokensExpected := types.BigIntToString(afterTokensExpectedBig) - actor := GetAllTestingValidators(t, ctx)[0] - if actor.StakedTokens == afterTokensExpected { - t.Fatal("bad starting amount for staked tokens") - } - if err := ctx.SetValidatorStakedTokens(actor.Address, afterTokensExpectedBig); err != nil { - t.Fatal(err) - } - actor = GetAllTestingValidators(t, ctx)[0] - if actor.StakedTokens != afterTokensExpected { - t.Fatalf("unexpected after tokens: expected %v got %v", afterTokensExpected, actor.StakedTokens) - } -} - -func GetAllTestingValidators(t *testing.T, ctx utility.UtilityContext) []*genesis.Validator { - actors, err := (ctx.Context.PersistenceContext).(*pre_persistence.PrePersistenceContext).GetAllValidators(ctx.LatestHeight) - require.NoError(t, err) - return actors -} diff --git a/shared/types/error.go b/shared/types/error.go index 3dcdaa0bd..9d51b0db0 100644 --- a/shared/types/error.go +++ b/shared/types/error.go @@ -126,7 +126,7 @@ func ErrStringToBigInt() Error { } // TODO: We should pass the account address here so it is easier to debug the issue -func ErrInsufficientAmountError() Error { +func ErrInsufficientAmount() Error { return NewError(CodeInsufficientAmountError, fmt.Sprintf("%s", InsufficientAmountError)) } diff --git a/shared/types/errors.go b/shared/types/errors.go index 2bbe39b4f..9e7106ee9 100644 --- a/shared/types/errors.go +++ b/shared/types/errors.go @@ -67,7 +67,7 @@ const ( CodeEqualVotesError Code = 77 CodeUnequalRoundsError Code = 78 CodeMaxEvidenceAgeError Code = 79 - CodeGetValidatorStakedTokensError Code = 80 + CodeGetStakedTokensError Code = 80 CodeSetValidatorStakedTokensError Code = 81 CodeSetPoolAmountError Code = 82 CodeGetPoolAmountError Code = 83 @@ -108,8 +108,10 @@ const ( CodeUnexpectedSocketError Code = 122 CodePayloadTooBigError Code = 123 CodeSocketIOStartFailedError Code = 124 + CodeGetStakeAmountError Code = 125 + CodeStakeLessError Code = 126 - GetValidatorStakedTokensError = "an error occurred getting the validator staked tokens" + GetStakedTokensError = "an error occurred getting the validator staked tokens" SetValidatorStakedTokensError = "an error occurred setting the validator staked tokens" EqualVotesError = "the votes are identical and not equivocating" UnequalRoundsError = "the round numbers are not equal" @@ -128,6 +130,8 @@ const ( DeleteError = "an error occurred when deleting the actor" AlreadyExistsError = "the actor already exists in the state" GetExistsError = "an error occurred when checking if already exists" + GetStakeAmountError = "an error occurred getting the stake amount" + StakeLessError = "the stake amount cannot be less than current amount" GetReadyToUnstakeError = "an error occurred getting the 'ready to unstake' group" GetLatestHeightError = "an error occurred getting the latest height" SetUnstakingHeightAndStatus = "an error occurred setting the unstaking height and status" @@ -259,8 +263,8 @@ func ErrGetMissedBlocks(err error) Error { return NewError(CodeGetMissedBlocksError, fmt.Sprintf("%s: %s", GetMissedBlocksError, err.Error())) } -func ErrGetValidatorStakedTokens(err error) Error { - return NewError(CodeGetValidatorStakedTokensError, fmt.Sprintf("%s", GetValidatorStakedTokensError)) +func ErrGetStakedTokens(err error) Error { + return NewError(CodeGetStakedTokensError, fmt.Sprintf("%s", GetStakedTokensError)) } func ErrSetValidatorStakedTokens(err error) Error { @@ -271,6 +275,14 @@ func ErrGetExists(err error) Error { return NewError(CodeGetExistsError, fmt.Sprintf("%s: %s", GetExistsError, err.Error())) } +func ErrGetStakeAmount(err error) Error { + return NewError(CodeGetStakeAmountError, fmt.Sprintf("%s: %s", GetStakeAmountError, err.Error())) +} + +func ErrStakeLess() Error { + return NewError(CodeStakeLessError, StakeLessError) +} + func ErrSetMissedBlocks(err error) Error { return NewError(CodeSetMissedBlocksError, fmt.Sprintf("%s: %s", SetMissedBlocksError, err.Error())) } @@ -567,3 +579,5 @@ func ErrPayloadTooBig(bodyLength, acceptedLength uint) error { func ErrSocketIOStartFailed(socketType string) error { return NewError(CodeSocketIOStartFailedError, fmt.Sprintf("%s: (%s socket)", SocketIOStartFailedError, socketType)) } + +// TODO: Consider adding `ErrUnknownActorType` everywhere we do a switch-case on actor type. diff --git a/shared/types/genesis/actor.go b/shared/types/genesis/actor.go new file mode 100644 index 000000000..3855babb4 --- /dev/null +++ b/shared/types/genesis/actor.go @@ -0,0 +1,32 @@ +package genesis + +// TECHDEBT: There may be an opportunity to refactor this to use generic or be in a shared proto file. +// `ActorType` is currently defined in `utility/proto/message.proto`, which is separate +// from where this interface is defined. We need to think/discuss how to consolidate +// all the types (protos, interfaces, etc...) into a single place. +type Actor interface { + GetAddress() []byte + GetPublicKey() []byte + GetPaused() bool + GetStatus() int32 + GetChains() []string + GetGenericParam() string + GetStakedTokens() string + GetPausedHeight() int64 + GetUnstakingHeight() int64 + GetOutput() []byte +} + +var _ Actor = &App{} +var _ Actor = &Validator{} +var _ Actor = &ServiceNode{} +var _ Actor = &Fisherman{} + +func (v *Validator) GetChains() []string { return nil } +func (v *Validator) GetGenericParam() string { return v.GetServiceUrl() } + +func (a *App) GetGenericParam() string { return a.GetMaxRelays() } + +func (sn *ServiceNode) GetGenericParam() string { return sn.GetServiceUrl() } + +func (f *Fisherman) GetGenericParam() string { return f.GetServiceUrl() } diff --git a/shared/types/genesis/proto/app.proto b/shared/types/genesis/proto/app.proto index dd38ed972..41619500f 100644 --- a/shared/types/genesis/proto/app.proto +++ b/shared/types/genesis/proto/app.proto @@ -7,10 +7,10 @@ message App { bytes address = 1; bytes public_key = 2; bool paused = 3; - int32 status = 4; + int32 status = 4; // REFACTOR: change to an `enum`; ditto for other actors repeated string chains = 5; string max_relays = 6; - string staked_tokens = 7; + string staked_tokens = 7; // REFACTOR: rename to `staked_amount`; ditto for other actors int64 paused_height = 8; int64 unstaking_height = 9; // DISCUSS: Why is this int64 but the above is a uint64? bytes output = 10; diff --git a/shared/types/int.go b/shared/types/int.go index b7daa56e1..fef105ed5 100644 --- a/shared/types/int.go +++ b/shared/types/int.go @@ -8,7 +8,7 @@ import ( const ( ZeroInt = 0 - HeightNotUsed = -1 + HeightNotUsed = int64(-1) EmptyString = "" ) diff --git a/utility/account.go b/utility/account.go index 88b362dee..fdef65ba5 100644 --- a/utility/account.go +++ b/utility/account.go @@ -4,42 +4,11 @@ import ( "math/big" "github.com/pokt-network/pocket/shared/types" - typesUtil "github.com/pokt-network/pocket/utility/types" ) -func (u *UtilityContext) HandleMessageSend(message *typesUtil.MessageSend) types.Error { - // convert the amount to big.Int - amount, err := types.StringToBigInt(message.Amount) - if err != nil { - return err - } - // get the sender's account amount - fromAccountAmount, err := u.GetAccountAmount(message.FromAddress) - if err != nil { - return err - } - // subtract that amount from the sender - fromAccountAmount.Sub(fromAccountAmount, amount) - // if they go negative, they don't have sufficient funds - // NOTE: we don't use the u.SubtractAccountAmount() function because Utility needs to do this check - if fromAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - // add the amount to the recipient's account - if err := u.AddAccountAmount(message.ToAddress, amount); err != nil { - return err - } - // set the sender's account amount - if err := u.SetAccountAmount(message.FromAddress, fromAccountAmount); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) GetMessageSendSignerCandidates(msg *typesUtil.MessageSend) ([][]byte, types.Error) { - // only the from address is a proper signer candidate - return [][]byte{msg.FromAddress}, nil -} +// 'Accounts' are structures in the utility module that closely resemble currency holding vehicles: like a bank account. +// Accounts enable the 'ownership' or 'custody' over uPOKT tokens. These structures are fundamental to enabling +// the utility economy. func (u *UtilityContext) GetAccountAmount(address []byte) (*big.Int, types.Error) { store := u.Store() diff --git a/utility/actor.go b/utility/actor.go new file mode 100644 index 000000000..b4db2d306 --- /dev/null +++ b/utility/actor.go @@ -0,0 +1,491 @@ +package utility + +import ( + "math" + "math/big" + + "github.com/pokt-network/pocket/shared/crypto" + "github.com/pokt-network/pocket/shared/types" + typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" + typesUtil "github.com/pokt-network/pocket/utility/types" +) + +/* +`Actor` is the consolidated term for common functionality among the following network actors: app, fish, node, val. + +This file contains all the state based CRUD operations shared between these abstractions. + +The ideology of the separation of the actors is based on the expectation of actor divergence in the near future. +The current implementation attempts to simplify code footprint and complexity while enabling future divergence. +It is important to note, that as production approaches, the idea is to attempt more consolidation at an architectural +multi-module level. Until then, it's a fine line to walk. +*/ + +// setters + +func (u *UtilityContext) SetActorStakedTokens(actorType typesUtil.ActorType, tokens *big.Int, address []byte) types.Error { + var er error + store := u.Store() + switch actorType { + case typesUtil.ActorType_App: + er = store.SetAppStakeAmount(address, types.BigIntToString(tokens)) + case typesUtil.ActorType_Fish: + er = store.SetFishermanStakeAmount(address, types.BigIntToString(tokens)) + case typesUtil.ActorType_Node: + er = store.SetServiceNodeStakeAmount(address, types.BigIntToString(tokens)) + case typesUtil.ActorType_Val: + er = store.SetValidatorStakeAmount(address, types.BigIntToString(tokens)) + } + if er != nil { + return types.ErrSetValidatorStakedTokens(er) + } + return nil +} + +func (u *UtilityContext) SetActorUnstaking(actorType typesUtil.ActorType, unstakingHeight int64, address []byte) types.Error { + store := u.Store() + var er error + switch actorType { + case typesUtil.ActorType_App: + er = store.SetAppUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Fish: + er = store.SetFishermanUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Node: + er = store.SetServiceNodeUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Val: + er = store.SetValidatorUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus) + } + if er != nil { + return types.ErrSetUnstakingHeightAndStatus(er) + } + return nil +} + +func (u *UtilityContext) DeleteActor(actorType typesUtil.ActorType, address []byte) types.Error { + var err error + store := u.Store() + switch actorType { + case typesUtil.ActorType_App: + err = store.DeleteApp(address) + case typesUtil.ActorType_Fish: + err = store.DeleteFisherman(address) + case typesUtil.ActorType_Node: + err = store.DeleteServiceNode(address) + case typesUtil.ActorType_Val: + err = store.DeleteValidator(address) + } + if err != nil { + return types.ErrDelete(err) + } + return nil +} + +func (u *UtilityContext) SetActorPauseHeight(actorType typesUtil.ActorType, address []byte, height int64) types.Error { + var err error + store := u.Store() + switch actorType { + case typesUtil.ActorType_App: + err = store.SetAppPauseHeight(address, height) + case typesUtil.ActorType_Fish: + err = store.SetFishermanPauseHeight(address, height) + case typesUtil.ActorType_Node: + err = store.SetServiceNodePauseHeight(address, height) + case typesUtil.ActorType_Val: + err = store.SetValidatorPauseHeight(address, height) + } + if err != nil { + return types.ErrSetPauseHeight(err) + } + return nil +} + +// getters + +func (u *UtilityContext) GetActorStakedTokens(actorType typesUtil.ActorType, address []byte) (*big.Int, types.Error) { + store := u.Store() + height, er := store.GetHeight() + if er != nil { + return nil, types.ErrGetStakedTokens(er) + } + + var stakedTokens string + switch actorType { + case typesUtil.ActorType_App: + stakedTokens, er = store.GetAppStakeAmount(height, address) + case typesUtil.ActorType_Fish: + stakedTokens, er = store.GetFishermanStakeAmount(height, address) + case typesUtil.ActorType_Node: + stakedTokens, er = store.GetServiceNodeStakeAmount(height, address) + case typesUtil.ActorType_Val: + stakedTokens, er = store.GetValidatorStakeAmount(height, address) + } + if er != nil { + return nil, types.ErrGetStakedTokens(er) + } + + i, err := types.StringToBigInt(stakedTokens) + if err != nil { + return nil, err + } + return i, nil +} + +func (u *UtilityContext) GetMaxPausedBlocks(actorType typesUtil.ActorType) (maxPausedBlocks int, err types.Error) { + var er error + var paramName string + + store := u.Store() + switch actorType { + case typesUtil.ActorType_App: + maxPausedBlocks, er = store.GetAppMaxPausedBlocks() + paramName = types.AppMaxPauseBlocksParamName + case typesUtil.ActorType_Fish: + maxPausedBlocks, er = store.GetFishermanMaxPausedBlocks() + paramName = types.FishermanMaxPauseBlocksParamName + case typesUtil.ActorType_Node: + maxPausedBlocks, er = store.GetServiceNodeMaxPausedBlocks() + paramName = types.ServiceNodeMaxPauseBlocksParamName + case typesUtil.ActorType_Val: + maxPausedBlocks, er = store.GetValidatorMaxPausedBlocks() + paramName = types.ValidatorMaxPausedBlocksParamName + } + if er != nil { + return typesUtil.ZeroInt, types.ErrGetParam(paramName, er) + } + return +} + +func (u *UtilityContext) GetMinimumPauseBlocks(actorType typesUtil.ActorType) (minPauseBlocks int, err types.Error) { + store := u.Store() + var er error + var paramName string + switch actorType { + case typesUtil.ActorType_App: + minPauseBlocks, er = store.GetAppMinimumPauseBlocks() + paramName = types.AppMinimumPauseBlocksParamName + case typesUtil.ActorType_Fish: + minPauseBlocks, er = store.GetFishermanMinimumPauseBlocks() + paramName = types.FishermanMinimumPauseBlocksParamName + case typesUtil.ActorType_Node: + minPauseBlocks, er = store.GetServiceNodeMinimumPauseBlocks() + paramName = types.ServiceNodeMinimumPauseBlocksParamName + case typesUtil.ActorType_Val: + minPauseBlocks, er = store.GetValidatorMinimumPauseBlocks() + paramName = types.ValidatorMinimumPauseBlocksParamName + } + if er != nil { + return typesUtil.ZeroInt, types.ErrGetParam(paramName, er) + } + return +} + +func (u *UtilityContext) GetPauseHeight(actorType typesUtil.ActorType, address []byte) (pauseHeight int64, err types.Error) { + store := u.Store() + height, er := store.GetHeight() + if er != nil { + return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) + } + switch actorType { + case typesUtil.ActorType_App: + pauseHeight, er = store.GetAppPauseHeightIfExists(address, height) + case typesUtil.ActorType_Fish: + pauseHeight, er = store.GetFishermanPauseHeightIfExists(address, height) + case typesUtil.ActorType_Node: + pauseHeight, er = store.GetServiceNodePauseHeightIfExists(address, height) + case typesUtil.ActorType_Val: + pauseHeight, er = store.GetValidatorPauseHeightIfExists(address, height) + } + if er != nil { + return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) + } + return +} + +func (u *UtilityContext) GetActorStatus(actorType typesUtil.ActorType, address []byte) (status int, err types.Error) { + store := u.Store() + height, er := store.GetHeight() + if er != nil { + return typesUtil.ZeroInt, types.ErrGetStatus(er) + } + switch actorType { + case typesUtil.ActorType_App: + status, er = store.GetAppStatus(address, height) + case typesUtil.ActorType_Fish: + status, er = store.GetFishermanStatus(address, height) + case typesUtil.ActorType_Node: + status, er = store.GetServiceNodeStatus(address, height) + case typesUtil.ActorType_Val: + status, er = store.GetValidatorStatus(address, height) + } + if er != nil { + return typesUtil.ZeroInt, types.ErrGetStatus(er) + } + return status, nil +} + +func (u *UtilityContext) GetMinimumStake(actorType typesUtil.ActorType) (*big.Int, types.Error) { + var minStake string + var err error + var paramName string + switch actorType { + case typesUtil.ActorType_App: + minStake, err = u.Store().GetParamAppMinimumStake() + paramName = types.AppMinimumStakeParamName + case typesUtil.ActorType_Fish: + minStake, err = u.Store().GetParamFishermanMinimumStake() + paramName = types.FishermanMinimumStakeParamName + case typesUtil.ActorType_Node: + minStake, err = u.Store().GetParamServiceNodeMinimumStake() + paramName = types.ServiceNodeMinimumStakeParamName + case typesUtil.ActorType_Val: + minStake, err = u.Store().GetParamValidatorMinimumStake() + paramName = types.ValidatorMinimumStakeParamName + } + if err != nil { + return nil, types.ErrGetParam(paramName, err) + } + return types.StringToBigInt(minStake) +} + +func (u *UtilityContext) GetStakeAmount(actorType typesUtil.ActorType, address []byte) (*big.Int, types.Error) { + var stakeAmount string + store := u.Store() + height, err := store.GetHeight() + if err != nil { + return nil, types.ErrGetStakeAmount(err) + } + switch actorType { + case typesUtil.ActorType_App: + stakeAmount, err = u.Store().GetAppStakeAmount(height, address) + case typesUtil.ActorType_Fish: + stakeAmount, err = u.Store().GetFishermanStakeAmount(height, address) + case typesUtil.ActorType_Node: + stakeAmount, err = u.Store().GetServiceNodeStakeAmount(height, address) + case typesUtil.ActorType_Val: + stakeAmount, err = u.Store().GetValidatorStakeAmount(height, address) + } + if err != nil { + return nil, types.ErrGetStakeAmount(err) + } + return types.StringToBigInt(stakeAmount) +} + +func (u *UtilityContext) GetUnstakingHeight(actorType typesUtil.ActorType) (unstakingHeight int64, er types.Error) { + var err error + var paramName string + var unstakingBlocks int + store := u.Store() + switch actorType { + case typesUtil.ActorType_App: + unstakingBlocks, err = store.GetAppUnstakingBlocks() + paramName = types.AppUnstakingBlocksParamName + case typesUtil.ActorType_Fish: + unstakingBlocks, err = store.GetFishermanUnstakingBlocks() + paramName = types.FishermanUnstakingBlocksParamName + case typesUtil.ActorType_Node: + unstakingBlocks, err = store.GetServiceNodeUnstakingBlocks() + paramName = types.ServiceNodeUnstakingBlocksParamName + case typesUtil.ActorType_Val: + unstakingBlocks, err = store.GetValidatorUnstakingBlocks() + paramName = types.ValidatorUnstakingBlocksParamName + } + if err != nil { + return typesUtil.ZeroInt, types.ErrGetParam(paramName, err) + } + return u.CalculateUnstakingHeight(int64(unstakingBlocks)) +} + +func (u *UtilityContext) GetMaxChains(actorType typesUtil.ActorType) (maxChains int, er types.Error) { + var err error + var paramName string + switch actorType { + case typesUtil.ActorType_App: + maxChains, err = u.Store().GetMaxAppChains() + paramName = types.AppMinimumStakeParamName + case typesUtil.ActorType_Fish: + maxChains, err = u.Store().GetFishermanMaxChains() + paramName = types.FishermanMinimumStakeParamName + case typesUtil.ActorType_Node: + maxChains, err = u.Store().GetServiceNodeMaxChains() + paramName = types.ServiceNodeMinimumStakeParamName + } + if err != nil { + return 0, types.ErrGetParam(paramName, err) + } + return +} + +func (u *UtilityContext) GetActorExists(actorType typesUtil.ActorType, address []byte) (bool, types.Error) { + var exists bool + store := u.Store() + height, err := store.GetHeight() + if err != nil { + return false, types.ErrGetExists(err) + } + switch actorType { + case typesUtil.ActorType_App: + exists, err = store.GetAppExists(address, height) + case typesUtil.ActorType_Fish: + exists, err = store.GetFishermanExists(address, height) + case typesUtil.ActorType_Node: + exists, err = store.GetServiceNodeExists(address, height) + case typesUtil.ActorType_Val: + exists, err = store.GetValidatorExists(address, height) + } + if err != nil { + return false, types.ErrGetExists(err) + } + return exists, nil +} + +func (u *UtilityContext) GetActorOutputAddress(actorType typesUtil.ActorType, operator []byte) (output []byte, err types.Error) { + var er error + store := u.Store() + height, er := store.GetHeight() + if er != nil { + return nil, types.ErrGetOutputAddress(operator, er) + } + switch actorType { + case typesUtil.ActorType_App: + output, er = store.GetAppOutputAddress(operator, height) + case typesUtil.ActorType_Fish: + output, er = store.GetFishermanOutputAddress(operator, height) + case typesUtil.ActorType_Node: + output, er = store.GetServiceNodeOutputAddress(operator, height) + case typesUtil.ActorType_Val: + output, er = store.GetValidatorOutputAddress(operator, height) + } + if er != nil { + return nil, types.ErrGetOutputAddress(operator, er) + } + return output, nil +} + +// calculators + +func (u *UtilityContext) BurnActor(actorType typesUtil.ActorType, percentage int, address []byte) types.Error { + tokens, err := u.GetActorStakedTokens(actorType, address) + if err != nil { + return err + } + zeroBigInt := big.NewInt(0) + tokensFloat := new(big.Float).SetInt(tokens) + tokensFloat.Mul(tokensFloat, big.NewFloat(float64(percentage))) + tokensFloat.Quo(tokensFloat, big.NewFloat(100)) + truncatedTokens, _ := tokensFloat.Int(nil) + if truncatedTokens.Cmp(zeroBigInt) == -1 { + truncatedTokens = zeroBigInt + } + newTokensAfterBurn := big.NewInt(0).Sub(tokens, truncatedTokens) + // remove from pool + if err := u.SubPoolAmount(typesGenesis.ValidatorStakePoolName, types.BigIntToString(truncatedTokens)); err != nil { + return err + } + // remove from validator + if err := u.SetActorStakedTokens(actorType, newTokensAfterBurn, address); err != nil { + return err + } + // check to see if they fell below minimum stake + minStake, err := u.GetValidatorMinimumStake() + if err != nil { + return err + } + // fell below minimum stake + if minStake.Cmp(truncatedTokens) == 1 { + unstakingHeight, err := u.GetUnstakingHeight(actorType) + if err != nil { + return err + } + if err := u.SetActorUnstaking(actorType, unstakingHeight, address); err != nil { + return err + } + } + return nil +} + +func (u *UtilityContext) CalculateAppRelays(stakedTokens string) (string, types.Error) { + tokens, err := types.StringToBigInt(stakedTokens) + if err != nil { + return typesUtil.EmptyString, err + } + // 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. + stabilityAdjustment, err := u.GetStabilityAdjustment() + if err != nil { + return typesUtil.EmptyString, err + } + baseRate, err := u.GetBaselineAppStakeRate() + if err != nil { + return typesUtil.EmptyString, err + } + // convert tokens to float64 + tokensFloat64 := big.NewFloat(float64(tokens.Int64())) + // get the percentage of the baseline stake rate (can be over 100%) + basePercentage := big.NewFloat(float64(baseRate) / float64(100)) + // multiply the two + // TODO (team) evaluate whether or not we should use micro denomination or not + baselineThroughput := basePercentage.Mul(basePercentage, tokensFloat64) + // adjust for uPOKT + baselineThroughput.Quo(baselineThroughput, big.NewFloat(typesUtil.MillionInt)) + // add staking adjustment (can be negative) + 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 types.BigIntToString(result), nil +} + +func (u *UtilityContext) CheckAboveMinStake(actorType typesUtil.ActorType, amount string) (a *big.Int, err types.Error) { + minStake, er := u.GetMinimumStake(actorType) + if er != nil { + return nil, err + } + a, err = types.StringToBigInt(amount) + if err != nil { + return nil, err + } + if types.BigIntLessThan(a, minStake) { + return nil, types.ErrMinimumStake() + } + return // for convenience this returns amount as a big.Int +} + +func (u *UtilityContext) CheckBelowMaxChains(actorType typesUtil.ActorType, chains []string) types.Error { + // validators don't have chains field + if actorType == typesUtil.ActorType_Val { + return nil + } + + maxChains, err := u.GetMaxChains(actorType) + if err != nil { + return err + } + if len(chains) > maxChains { + return types.ErrMaxChains(maxChains) + } + return nil +} + +func (u *UtilityContext) CalculateUnstakingHeight(unstakingBlocks int64) (int64, types.Error) { + latestHeight, err := u.GetLatestHeight() + if err != nil { + return typesUtil.ZeroInt, err + } + return unstakingBlocks + latestHeight, nil +} + +// util + +func (u *UtilityContext) BytesToPublicKey(publicKey []byte) (crypto.PublicKey, types.Error) { + pk, er := crypto.NewPublicKeyFromBytes(publicKey) + if er != nil { + return nil, types.ErrNewPublicKeyFromBytes(er) + } + return pk, nil +} diff --git a/utility/app.go b/utility/app.go deleted file mode 100644 index d2ff03a41..000000000 --- a/utility/app.go +++ /dev/null @@ -1,449 +0,0 @@ -package utility - -import ( - "math" - "math/big" - - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func (u *UtilityContext) HandleMessageStakeApp(message *typesUtil.MessageStakeApp) types.Error { - publicKey, er := crypto.NewPublicKeyFromBytes(message.PublicKey) - if er != nil { - return types.ErrNewPublicKeyFromBytes(er) - } - // ensure above minimum stake - minStake, err := u.GetAppMinimumStake() - if err != nil { - return err - } - amount, err := types.StringToBigInt(message.Amount) - if err != nil { - return err - } - if types.BigIntLessThan(amount, minStake) { - return types.ErrMinimumStake() - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amount) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - maxChains, err := u.GetAppMaxChains() - if err != nil { - return err - } - // validate number of chains - if len(message.Chains) > maxChains { - return types.ErrMaxChains(maxChains) - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.AppStakePoolName, amount); err != nil { - return err - } - // calculate maximum relays from stake amount - maxRelays, err := u.CalculateAppRelays(message.Amount) - if err != nil { - return err - } - // ensure app doesn't already exist - exists, err := u.GetAppExists(publicKey.Address()) - if err != nil { - return err - } - if exists { - return types.ErrAlreadyExists() - } - // insert the app structure - if err := u.InsertApp(publicKey.Address(), message.PublicKey, message.OutputAddress, maxRelays, message.Amount, message.Chains); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageEditStakeApp(message *typesUtil.MessageEditStakeApp) types.Error { - exists, err := u.GetAppExists(message.Address) - if err != nil { - return err - } - if !exists { - return types.ErrNotExists() - } - amountToAdd, err := types.StringToBigInt(message.AmountToAdd) - if err != nil { - return err - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amountToAdd) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - maxChains, err := u.GetAppMaxChains() - if err != nil { - return err - } - // validate number of chains - if len(message.Chains) > maxChains { - return types.ErrMaxChains(maxChains) - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.AppStakePoolName, amountToAdd); err != nil { - return err - } - // calculate maximum relays from stake amount - maxRelaysToAdd, err := u.CalculateAppRelays(message.AmountToAdd) - if err != nil { - return err - } - // insert the app structure - if err := u.UpdateApp(message.Address, maxRelaysToAdd, message.AmountToAdd, message.Chains); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnstakeApp(message *typesUtil.MessageUnstakeApp) types.Error { - status, err := u.GetAppStatus(message.Address) - if err != nil { - return err - } - // validate is staked - if status != typesUtil.StakedStatus { - return types.ErrInvalidStatus(status, typesUtil.StakedStatus) - } - unstakingHeight, err := u.CalculateAppUnstakingHeight() - if err != nil { - return err - } - if err := u.SetAppUnstakingHeightAndStatus(message.Address, unstakingHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) UnstakeAppsThatAreReady() types.Error { - appsReadyToUnstake, err := u.GetAppsReadyToUnstake() - if err != nil { - return err - } - for _, app := range appsReadyToUnstake { - if err := u.SubPoolAmount(typesGenesis.AppStakePoolName, app.GetStakeAmount()); err != nil { - return err - } - if err := u.AddAccountAmountString(app.GetOutputAddress(), app.GetStakeAmount()); err != nil { - return err - } - if err := u.DeleteApp(app.GetAddress()); err != nil { - return err - } - } - return nil -} - -func (u *UtilityContext) BeginUnstakingMaxPausedApps() types.Error { - maxPausedBlocks, err := u.GetAppMaxPausedBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - beforeHeight := latestHeight - int64(maxPausedBlocks) - // genesis edge case - if beforeHeight < 0 { - beforeHeight = 0 - } - if err := u.UnstakeAppsPausedBefore(beforeHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessagePauseApp(message *typesUtil.MessagePauseApp) types.Error { - height, err := u.GetAppPauseHeightIfExists(message.Address) - if err != nil { - return err - } - if height != typesUtil.HeightNotUsed { - return types.ErrAlreadyPaused() - } - height, err = u.GetLatestHeight() - if err != nil { - return err - } - if err := u.SetAppPauseHeight(message.Address, height); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnpauseApp(message *typesUtil.MessageUnpauseApp) types.Error { - pausedHeight, err := u.GetAppPauseHeightIfExists(message.Address) - if err != nil { - return err - } - if pausedHeight == typesUtil.HeightNotUsed { - return types.ErrNotPaused() - } - minPauseBlocks, err := u.GetAppMinimumPauseBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - if latestHeight < int64(minPauseBlocks)+pausedHeight { - return types.ErrNotReadyToUnpause() - } - if err := u.SetAppPauseHeight(message.Address, typesUtil.HeightNotUsed); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) CalculateAppRelays(stakedTokens string) (string, types.Error) { - tokens, err := types.StringToBigInt(stakedTokens) - if err != nil { - return typesUtil.EmptyString, err - } - // 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. - stabilityAdjustment, err := u.GetStabilityAdjustment() - if err != nil { - return typesUtil.EmptyString, err - } - baseRate, err := u.GetBaselineAppStakeRate() - if err != nil { - return typesUtil.EmptyString, err - } - // convert tokens to float64 - tokensFloat64 := big.NewFloat(float64(tokens.Int64())) - // get the percentage of the baseline stake rate (can be over 100%) - basePercentage := big.NewFloat(float64(baseRate) / float64(100)) - // multiply the two - // TODO (team) evaluate whether or not we should use micro denomination or not - baselineThroughput := basePercentage.Mul(basePercentage, tokensFloat64) - // adjust for uPOKT - baselineThroughput.Quo(baselineThroughput, big.NewFloat(typesUtil.MillionInt)) - // add staking adjustment (can be negative) - 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 types.BigIntToString(result), nil -} - -func (u *UtilityContext) GetAppExists(address []byte) (bool, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return false, types.ErrGetExists(er) - } - exists, er := store.GetAppExists(address, height) - if er != nil { - return false, types.ErrGetExists(er) - } - return exists, nil -} - -func (u *UtilityContext) InsertApp(address, publicKey, output []byte, maxRelays, amount string, chains []string) types.Error { - store := u.Store() - err := store.InsertApp(address, publicKey, output, false, typesUtil.StakedStatus, maxRelays, amount, chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -// TODO (Team) re-evaluate whether the delta should be here or the updated value -func (u *UtilityContext) UpdateApp(address []byte, maxRelays, amount string, chains []string) types.Error { - store := u.Store() - err := store.UpdateApp(address, maxRelays, amount, chains) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) DeleteApp(address []byte) types.Error { - store := u.Store() - if err := store.DeleteApp(address); err != nil { - return types.ErrDelete(err) - } - return nil -} - -func (u *UtilityContext) GetAppsReadyToUnstake() ([]*types.UnstakingActor, types.Error) { - store := u.Store() - latestHeight, err := u.GetLatestHeight() - if err != nil { - return nil, err - } - unstakingApps, er := store.GetAppsReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) - if er != nil { - return nil, types.ErrGetReadyToUnstake(er) - } - return unstakingApps, nil -} - -func (u *UtilityContext) UnstakeAppsPausedBefore(pausedBeforeHeight int64) types.Error { - store := u.Store() - unstakingHeight, err := u.CalculateAppUnstakingHeight() - if err != nil { - return err - } - er := store.SetAppStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) - if er != nil { - return types.ErrSetStatusPausedBefore(er, pausedBeforeHeight) - } - return nil -} - -func (u *UtilityContext) GetAppStatus(address []byte) (int, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - status, er := store.GetAppStatus(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - return status, nil -} - -func (u *UtilityContext) SetAppUnstakingHeightAndStatus(address []byte, unstakingHeight int64) types.Error { - store := u.Store() - if er := store.SetAppUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus); er != nil { // TODO(Andrew): remove unstaking status from prepersistence - return types.ErrSetUnstakingHeightAndStatus(er) - } - return nil -} - -func (u *UtilityContext) GetAppPauseHeightIfExists(address []byte) (int64, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - appPauseHeight, er := store.GetAppPauseHeightIfExists(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - return appPauseHeight, nil -} - -func (u *UtilityContext) SetAppPauseHeight(address []byte, height int64) types.Error { - store := u.Store() - if err := store.SetAppPauseHeight(address, height); err != nil { - return types.ErrSetPauseHeight(err) - } - return nil -} - -func (u *UtilityContext) CalculateAppUnstakingHeight() (int64, types.Error) { - unstakingBlocks, err := u.GetAppUnstakingBlocks() - if err != nil { - return typesUtil.ZeroInt, err - } - unstakingHeight, err := u.CalculateUnstakingHeight(unstakingBlocks) - if err != nil { - return typesUtil.ZeroInt, err - } - return unstakingHeight, nil -} - -func (u *UtilityContext) GetMessageStakeAppSignerCandidates(msg *typesUtil.MessageStakeApp) ([][]byte, types.Error) { - pk, er := crypto.NewPublicKeyFromBytes(msg.PublicKey) - if er != nil { - return nil, types.ErrNewPublicKeyFromBytes(er) - } - candidates := make([][]byte, 0) - candidates = append(candidates, msg.OutputAddress) - candidates = append(candidates, pk.Address()) - return candidates, nil -} - -func (u *UtilityContext) GetMessageEditStakeAppSignerCandidates(msg *typesUtil.MessageEditStakeApp) ([][]byte, types.Error) { - output, err := u.GetAppOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnstakeAppSignerCandidates(msg *typesUtil.MessageUnstakeApp) ([][]byte, types.Error) { - output, err := u.GetAppOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnpauseAppSignerCandidates(msg *typesUtil.MessageUnpauseApp) ([][]byte, types.Error) { - output, err := u.GetAppOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessagePauseAppSignerCandidates(msg *typesUtil.MessagePauseApp) ([][]byte, types.Error) { - output, err := u.GetAppOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetAppOutputAddress(operator []byte) ([]byte, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - output, er := store.GetAppOutputAddress(operator, height) - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - return output, nil -} diff --git a/utility/block.go b/utility/block.go index fd3b61a52..5435fbbbd 100644 --- a/utility/block.go +++ b/utility/block.go @@ -1,10 +1,22 @@ package utility import ( + "math/big" + "github.com/pokt-network/pocket/shared/types" + typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" 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 adpots 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 applys each transaction against the state and rolls it back (not yet implemented) if fails. +like BeginBlock, EndBlock is an autonomous state oepration that executes at the end of every block. +*/ + func (u *UtilityContext) ApplyBlock(latestHeight int64, proposerAddress []byte, transactions [][]byte, lastBlockByzantineValidators [][]byte) ([]byte, error) { u.LatestHeight = latestHeight // begin block lifecycle phase @@ -44,63 +56,208 @@ func (u *UtilityContext) BeginBlock(previousBlockByzantineValidators [][]byte) t } func (u *UtilityContext) EndBlock(proposer []byte) types.Error { + // reward the block proposer if err := u.HandleProposalRewards(proposer); err != nil { return err } + // unstake actors that have been 'unstaking' for the UnstakingBlocks if err := u.UnstakeActorsThatAreReady(); err != nil { return err } - if err := u.BeginUnstakingMaxPausedActors(); err != nil { + // begin unstaking the actors who have been paused for MaxPauseBlocks + if err := u.BeginUnstakingMaxPaused(); err != nil { return err } return nil } -func (u *UtilityContext) BeginUnstakingMaxPausedActors() types.Error { - if err := u.BeginUnstakingMaxPausedApps(); err != nil { +func (u *UtilityContext) GetAppHash() ([]byte, types.Error) { + // Get the root hash of the merkle state tree for state consensus integrity + appHash, er := u.Context.AppHash() + if er != nil { + return nil, types.ErrAppHash(er) + } + return appHash, 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) types.Error { + latestBlockHeight, err := u.GetLatestHeight() + if err != nil { return err } - if err := u.BeginUnstakingMaxPausedFishermen(); err != nil { + maxMissedBlocks, err := u.GetValidatorMaxMissedBlocks() + if err != nil { return err } - if err := u.BeginUnstakingMaxPausedValidators(); err != nil { + 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, latestBlockHeight, typesUtil.HeightNotUsed); err != nil { + return err + } + // burn validator for missing blocks + burnPercentage, err := u.GetMissedBlocksBurnPercentage() + if err != nil { + return err + } + if err = u.BurnActor(typesUtil.ActorType_Val, burnPercentage, address); err != nil { + return err + } + } else if err := u.SetValidatorMissedBlocks(address, numberOfMissedBlocks); err != nil { + return err + } + } + return nil +} + +func (u *UtilityContext) UnstakeActorsThatAreReady() (err types.Error) { + var er error + store := u.Store() + latestHeight, err := u.GetLatestHeight() + if err != nil { return err } - if err := u.BeginUnstakingMaxPausedServiceNodes(); err != nil { + for _, actorType := range typesUtil.ActorTypes { + var readyToUnstake []*types.UnstakingActor + poolName := actorType.GetActorPoolName() + switch actorType { + case typesUtil.ActorType_App: + readyToUnstake, er = store.GetAppsReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Fish: + readyToUnstake, er = store.GetFishermenReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Node: + readyToUnstake, er = store.GetServiceNodesReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Val: + readyToUnstake, er = store.GetValidatorsReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) + } + if er != nil { + return types.ErrGetReadyToUnstake(er) + } + for _, actor := range readyToUnstake { + if err = u.SubPoolAmount(poolName, actor.GetStakeAmount()); err != nil { + return err + } + if err = u.AddAccountAmountString(actor.GetOutputAddress(), actor.GetStakeAmount()); err != nil { + return err + } + if err = u.DeleteActor(actorType, actor.GetAddress()); err != nil { + return err + } + } + } + return nil +} + +func (u *UtilityContext) BeginUnstakingMaxPaused() (err types.Error) { + latestHeight, err := u.GetLatestHeight() + if err != nil { return err } + for _, actorType := range typesUtil.ActorTypes { + maxPausedBlocks, err := u.GetMaxPausedBlocks(actorType) + if err != nil { + return err + } + beforeHeight := latestHeight - int64(maxPausedBlocks) + // genesis edge case + if beforeHeight < 0 { + beforeHeight = 0 + } + if err := u.UnstakeActorPausedBefore(beforeHeight, actorType); err != nil { + return err + } + } + return nil +} + +func (u *UtilityContext) UnstakeActorPausedBefore(pausedBeforeHeight int64, actorType typesUtil.ActorType) (err types.Error) { + var er error + store := u.Store() + unstakingHeight, err := u.GetUnstakingHeight(actorType) + if err != nil { + return err + } + switch actorType { + case typesUtil.ActorType_App: + er = store.SetAppStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Fish: + er = store.SetFishermanStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Node: + er = store.SetServiceNodeStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) + case typesUtil.ActorType_Val: + er = store.SetValidatorsStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) + } + if er != nil { + return types.ErrSetStatusPausedBefore(er, pausedBeforeHeight) + } return nil } -func (u *UtilityContext) UnstakeActorsThatAreReady() types.Error { - if err := u.UnstakeAppsThatAreReady(); err != nil { +func (u *UtilityContext) HandleProposalRewards(proposer []byte) types.Error { + feesAndRewardsCollected, err := u.GetPoolAmount(typesGenesis.FeePoolName) + if err != nil { return err } - if err := u.UnstakeValidatorsThatAreReady(); err != nil { + if err := u.SetPoolAmount(typesGenesis.FeePoolName, big.NewInt(0)); err != nil { return err } - if err := u.UnstakeFishermenThatAreReady(); err != nil { + proposerCutPercentage, err := u.GetProposerPercentageOfFees() + if err != nil { + return err + } + daoCutPercentage := 100 - proposerCutPercentage + if daoCutPercentage < 0 || daoCutPercentage > 100 { + return types.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.UnstakeServiceNodesThatAreReady(); err != nil { + if err := u.AddPoolAmount(typesGenesis.DAOPoolName, amountToDAO); err != nil { return err } return nil } -func (u *UtilityContext) GetAppHash() ([]byte, types.Error) { - appHash, er := u.Context.AppHash() +// GetValidatorMissedBlocks gets the total blocks that a validator has not signed a certain window of time denominated by blocks +func (u *UtilityContext) GetValidatorMissedBlocks(address []byte) (int, types.Error) { + store := u.Store() + height, er := store.GetHeight() if er != nil { - return nil, types.ErrAppHash(er) + return typesUtil.ZeroInt, types.ErrGetMissedBlocks(er) } - return appHash, nil + missedBlocks, er := store.GetValidatorMissedBlocks(address, height) + if er != nil { + return typesUtil.ZeroInt, types.ErrGetMissedBlocks(er) + } + return missedBlocks, nil } -func (u *UtilityContext) GetBlockHash(height int64) ([]byte, types.Error) { +func (u *UtilityContext) PauseValidatorAndSetMissedBlocks(address []byte, pauseHeight int64, missedBlocks int) types.Error { store := u.Store() - hash, er := store.GetBlockHash(int64(height)) + if err := store.SetValidatorPauseHeightAndMissedBlocks(address, pauseHeight, missedBlocks); err != nil { + return types.ErrSetPauseHeight(err) + } + return nil +} + +func (u *UtilityContext) SetValidatorMissedBlocks(address []byte, missedBlocks int) types.Error { + store := u.Store() + er := store.SetValidatorMissedBlocks(address, missedBlocks) if er != nil { - return nil, types.ErrGetBlockHash(er) + return types.ErrSetMissedBlocks(er) } - return hash, nil + return nil } diff --git a/utility/context.go b/utility/context.go deleted file mode 100644 index 3508ffef6..000000000 --- a/utility/context.go +++ /dev/null @@ -1,94 +0,0 @@ -package utility - -import ( - "encoding/hex" - - "github.com/pokt-network/pocket/shared/modules" - "github.com/pokt-network/pocket/shared/types" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -// TODO (Team) Protocol hour discussion about contexts. We need to better understand the intermodule relationship here - -type UtilityContext struct { - LatestHeight int64 - Mempool types.Mempool - Context *Context -} - -type Context struct { - modules.PersistenceContext - SavePointsM map[string]struct{} - SavePoints [][]byte -} - -func (u *UtilityModule) NewContext(height int64) (modules.UtilityContext, error) { - ctx, err := u.GetBus().GetPersistenceModule().NewContext(height) - if err != nil { - return nil, types.ErrNewPersistenceContext(err) - } - return &UtilityContext{ - LatestHeight: height, - Mempool: u.Mempool, - Context: &Context{ - PersistenceContext: ctx, - SavePoints: make([][]byte, 0), - SavePointsM: make(map[string]struct{}), - }, - }, nil -} - -func (u *UtilityContext) Store() *Context { - return u.Context -} - -func (u *UtilityContext) GetPersistenceContext() modules.PersistenceContext { - return u.Context.PersistenceContext -} - -func (u *UtilityContext) ReleaseContext() { - u.Context.Release() - u.Context = nil -} - -func (u *UtilityContext) GetLatestHeight() (int64, types.Error) { - return u.LatestHeight, nil -} - -func (u *UtilityContext) Codec() types.Codec { - return types.GetCodec() -} - -func (u *UtilityContext) RevertLastSavePoint() types.Error { - if len(u.Context.SavePointsM) == typesUtil.ZeroInt { - return types.ErrEmptySavePoints() - } - var key []byte - popIndex := len(u.Context.SavePoints) - 1 - key, u.Context.SavePoints = u.Context.SavePoints[popIndex], u.Context.SavePoints[:popIndex] - delete(u.Context.SavePointsM, hex.EncodeToString(key)) - if err := u.Context.PersistenceContext.RollbackToSavePoint(key); err != nil { - return types.ErrRollbackSavePoint(err) - } - return nil -} - -func (u *UtilityContext) NewSavePoint(transactionHash []byte) types.Error { - if err := u.Context.PersistenceContext.NewSavePoint(transactionHash); err != nil { - return types.ErrNewSavePoint(err) - } - txHash := hex.EncodeToString(transactionHash) - if _, exists := u.Context.SavePointsM[txHash]; exists { - return types.ErrDuplicateSavePoint() - } - u.Context.SavePoints = append(u.Context.SavePoints, transactionHash) - u.Context.SavePointsM[txHash] = struct{}{} - return nil -} - -func (c *Context) Reset() types.Error { - if err := c.PersistenceContext.Reset(); err != nil { - return types.ErrResetContext(err) - } - return nil -} diff --git a/utility/CHANGELOG.md b/utility/doc/CHANGELOG.md similarity index 50% rename from utility/CHANGELOG.md rename to utility/doc/CHANGELOG.md index a5ef4b574..9c5cb5aeb 100644 --- a/utility/CHANGELOG.md +++ b/utility/doc/CHANGELOG.md @@ -7,7 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.0.0] - 2021-03-15 +## [0.0.1] - 2022-07-20 + +### Code cleanup +- Removed transaction fees from the transaction structure as fees will be enforced at the state level +- Removed actor specific messages (besides DoubleSign) and added actorType field to the struct +- Removed pause messages and functionality as it is out of scope for the current POS iteration +- Removed session and test-scoring as it's out of scope for the current POS iteration +- Consolidated unit test functionality for actors +- Modified pre-persistence to match persistence for Update(actor), 'amountToAdd' is now just 'amount' + +## [Unreleased] + +## [0.0.0] - 2022-03-15 ### Added diff --git a/utility/README.md b/utility/doc/README.md similarity index 82% rename from utility/README.md rename to utility/doc/README.md index 882a2f2a0..7be1dbee0 100644 --- a/utility/README.md +++ b/utility/doc/README.md @@ -22,19 +22,13 @@ The current implementation does add the fundamental Pocket Network 1.0 actors: And implement the basic transaction functionality: -- Send-Tx +- Send - Stake - Unstake - EditStake - Pause - Unpause -And a few additional skeleton implementations for pocket specific transactions: - -- FishermanPauseServiceNode [x] Implemented -- TestScore [x] Placeholder // requires sessions & report card structures -- ProveTestScore [x] Placeholder // requires sessions & report card structures - Added governance params: - BlocksPerSessionParamName @@ -186,3 +180,30 @@ and use `utilityMod` as desired. ``` $ make test_utility_types && make test_utility_module ``` + +## Code Organization + +```bash +utility +├── account.go # utility context for accounts & pools +├── actor.go # utility context for apps, fish, nodes, and validators +├── block.go # utility context for blocks +├── doc # contains the documentation and changelog +├── gov.go # utility context for dao & parameters +├── module.go # module implementation and interfaces +├── proto # protobuf3 messages that auto-generate into the types directory +│   ├── actor.proto +│   ├── message.proto +│   ├── transaction.proto +│   └── vote.proto +├── test # utility unit tests +├── transaction.go # utility context for transactions including handlers +├── types # stateless (without relying on persistence) library of utility types +│   ├── actor.go +│   ├── message.go # payloads of transactions +│   ├── transaction.go # the finite unit of the block +│   ├── utils.go +│   ├── vote.go # vote structure for double sign transaction +└── utility + └── types +``` diff --git a/utility/fisherman.go b/utility/fisherman.go deleted file mode 100644 index 26834365f..000000000 --- a/utility/fisherman.go +++ /dev/null @@ -1,441 +0,0 @@ -package utility - -import ( - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func (u *UtilityContext) HandleMessageTestScore(message *typesUtil.MessageTestScore) types.Error { - panic("TODO") -} - -func (u *UtilityContext) HandleMessageProveTestScore(message *typesUtil.MessageProveTestScore) types.Error { - panic("TODO") -} - -func (u *UtilityContext) HandleMessageStakeFisherman(message *typesUtil.MessageStakeFisherman) types.Error { - publicKey, er := crypto.NewPublicKeyFromBytes(message.PublicKey) - if er != nil { - return types.ErrNewPublicKeyFromBytes(er) - } - // ensure above minimum stake - minStake, err := u.GetFishermanMinimumStake() - if err != nil { - return err - } - amount, err := types.StringToBigInt(message.Amount) - if err != nil { - return err - } - if types.BigIntLessThan(amount, minStake) { - return types.ErrMinimumStake() - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amount) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - maxChains, err := u.GetFishermanMaxChains() - if err != nil { - return err - } - // validate chains - if len(message.Chains) > maxChains { - return types.ErrMaxChains(maxChains) - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.FishermanStakePoolName, amount); err != nil { - return err - } - // ensure Fisherman doesn't already exist - exists, err := u.GetFishermanExists(publicKey.Address()) - if err != nil { - return err - } - if exists { - return types.ErrAlreadyExists() - } - // insert the Fisherman structure - if err := u.InsertFisherman(publicKey.Address(), message.PublicKey, message.OutputAddress, message.ServiceUrl, message.Amount, message.Chains); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageEditStakeFisherman(message *typesUtil.MessageEditStakeFisherman) types.Error { - exists, err := u.GetFishermanExists(message.Address) - if err != nil { - return err - } - if !exists { - return types.ErrNotExists() - } - amountToAdd, err := types.StringToBigInt(message.AmountToAdd) - if err != nil { - return err - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amountToAdd) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - maxChains, err := u.GetFishermanMaxChains() - if err != nil { - return err - } - // validate chains - if len(message.Chains) > maxChains { - return types.ErrMaxChains(maxChains) - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.FishermanStakePoolName, amountToAdd); err != nil { - return err - } - // insert the Fisherman structure - if err := u.UpdateFisherman(message.Address, message.ServiceUrl, message.AmountToAdd, message.Chains); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnstakeFisherman(message *typesUtil.MessageUnstakeFisherman) types.Error { - status, err := u.GetFishermanStatus(message.Address) - if err != nil { - return err - } - // validate is staked - if status != typesUtil.StakedStatus { - return types.ErrInvalidStatus(status, typesUtil.StakedStatus) - } - unstakingHeight, err := u.CalculateFishermanUnstakingHeight() - if err != nil { - return err - } - if err := u.SetFishermanUnstakingHeightAndStatus(message.Address, unstakingHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) UnstakeFishermenThatAreReady() types.Error { - fishermansReadyToUnstake, err := u.GetFishermenReadyToUnstake() - if err != nil { - return err - } - for _, fisherman := range fishermansReadyToUnstake { - if err := u.SubPoolAmount(typesGenesis.FishermanStakePoolName, fisherman.GetStakeAmount()); err != nil { - return err - } - if err := u.AddAccountAmountString(fisherman.GetOutputAddress(), fisherman.GetStakeAmount()); err != nil { - return err - } - if err := u.DeleteFisherman(fisherman.GetAddress()); err != nil { - return err - } - } - return nil -} - -func (u *UtilityContext) BeginUnstakingMaxPausedFishermen() types.Error { - maxPausedBlocks, err := u.GetFishermanMaxPausedBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - beforeHeight := latestHeight - int64(maxPausedBlocks) - // genesis edge case - if beforeHeight < 0 { - beforeHeight = 0 - } - if err := u.UnstakeFishermenPausedBefore(beforeHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessagePauseFisherman(message *typesUtil.MessagePauseFisherman) types.Error { - height, err := u.GetFishermanPauseHeightIfExists(message.Address) - if err != nil { - return err - } - if height != typesUtil.HeightNotUsed { - return types.ErrAlreadyPaused() - } - height, err = u.GetLatestHeight() - if err != nil { - return err - } - if err := u.SetFishermanPauseHeight(message.Address, height); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageFishermanPauseServiceNode(message *typesUtil.MessageFishermanPauseServiceNode) types.Error { - exists, err := u.GetFishermanExists(message.Reporter) - if err != nil { - return err - } - if !exists { - return types.ErrNotExists() - } - height, err := u.GetServiceNodePauseHeightIfExists(message.Address) - if err != nil { - return err - } - if height != typesUtil.HeightNotUsed { - return types.ErrAlreadyPaused() - } - height, err = u.GetLatestHeight() - if err != nil { - return err - } - if err := u.SetServiceNodePauseHeight(message.Address, height); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnpauseFisherman(message *typesUtil.MessageUnpauseFisherman) types.Error { - pausedHeight, err := u.GetFishermanPauseHeightIfExists(message.Address) - if err != nil { - return err - } - if pausedHeight == typesUtil.HeightNotUsed { - return types.ErrNotPaused() - } - minPauseBlocks, err := u.GetFishermanMinimumPauseBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - if latestHeight < int64(minPauseBlocks)+pausedHeight { - return types.ErrNotReadyToUnpause() - } - if err := u.SetFishermanPauseHeight(message.Address, typesUtil.HeightNotUsed); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) GetFishermanExists(address []byte) (bool, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return false, types.ErrGetStatus(er) - } - exists, er := store.GetFishermanExists(address, height) - if er != nil { - return false, types.ErrGetExists(er) - } - return exists, nil -} - -func (u *UtilityContext) InsertFisherman(address, publicKey, output []byte, serviceURL, amount string, chains []string) types.Error { - store := u.Store() - err := store.InsertFisherman(address, publicKey, output, false, typesUtil.StakedStatus, serviceURL, amount, chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) UpdateFisherman(address []byte, serviceURL, amount string, chains []string) types.Error { - store := u.Store() - err := store.UpdateFisherman(address, serviceURL, amount, chains) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) DeleteFisherman(address []byte) types.Error { - store := u.Store() - if err := store.DeleteFisherman(address); err != nil { - return types.ErrDelete(err) - } - return nil -} - -func (u *UtilityContext) GetFishermenReadyToUnstake() ([]*types.UnstakingActor, types.Error) { - store := u.Store() - latestHeight, err := u.GetLatestHeight() - if err != nil { - return nil, err - } - unstakingFishermans, er := store.GetFishermenReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) - if er != nil { - return nil, types.ErrGetReadyToUnstake(er) - } - return unstakingFishermans, nil -} - -func (u *UtilityContext) UnstakeFishermenPausedBefore(pausedBeforeHeight int64) types.Error { - store := u.Store() - unstakingHeight, err := u.CalculateFishermanUnstakingHeight() - if err != nil { - return err - } - er := store.SetFishermanStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) - if er != nil { - return types.ErrSetStatusPausedBefore(er, pausedBeforeHeight) - } - return nil -} - -func (u *UtilityContext) GetFishermanStatus(address []byte) (int, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - status, er := store.GetFishermanStatus(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - return status, nil -} - -func (u *UtilityContext) SetFishermanUnstakingHeightAndStatus(address []byte, unstakingHeight int64) types.Error { - store := u.Store() - if er := store.SetFishermanUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus); er != nil { - return types.ErrSetUnstakingHeightAndStatus(er) - } - return nil -} - -func (u *UtilityContext) GetFishermanPauseHeightIfExists(address []byte) (int64, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - fishermanPauseHeight, er := store.GetFishermanPauseHeightIfExists(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - return fishermanPauseHeight, nil -} - -func (u *UtilityContext) SetFishermanPauseHeight(address []byte, height int64) types.Error { - store := u.Store() - if err := store.SetFishermanPauseHeight(address, height); err != nil { - return types.ErrSetPauseHeight(err) - } - return nil -} - -func (u *UtilityContext) CalculateFishermanUnstakingHeight() (int64, types.Error) { - unstakingBlocks, err := u.GetFishermanUnstakingBlocks() - if err != nil { - return typesUtil.ZeroInt, err - } - unstakingHeight, err := u.CalculateUnstakingHeight(unstakingBlocks) - if err != nil { - return typesUtil.ZeroInt, err - } - return unstakingHeight, nil -} - -func (u *UtilityContext) GetMessageStakeFishermanSignerCandidates(msg *typesUtil.MessageStakeFisherman) ([][]byte, types.Error) { - pk, er := crypto.NewPublicKeyFromBytes(msg.PublicKey) - if er != nil { - return nil, types.ErrNewPublicKeyFromBytes(er) - } - candidates := make([][]byte, 0) - candidates = append(candidates, msg.OutputAddress) - candidates = append(candidates, pk.Address()) - return candidates, nil -} - -func (u *UtilityContext) GetMessageEditStakeFishermanSignerCandidates(msg *typesUtil.MessageEditStakeFisherman) ([][]byte, types.Error) { - output, err := u.GetFishermanOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnstakeFishermanSignerCandidates(msg *typesUtil.MessageUnstakeFisherman) ([][]byte, types.Error) { - output, err := u.GetFishermanOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnpauseFishermanSignerCandidates(msg *typesUtil.MessageUnpauseFisherman) ([][]byte, types.Error) { - output, err := u.GetFishermanOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessagePauseFishermanSignerCandidates(msg *typesUtil.MessagePauseFisherman) ([][]byte, types.Error) { - output, err := u.GetFishermanOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageFishermanPauseServiceNodeSignerCandidates(msg *typesUtil.MessageFishermanPauseServiceNode) ([][]byte, types.Error) { - output, err := u.GetFishermanOutputAddress(msg.Reporter) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Reporter) - return candidates, nil -} - -func (u *UtilityContext) GetFishermanOutputAddress(operator []byte) ([]byte, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - output, er := store.GetFishermanOutputAddress(operator, height) - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - return output, nil -} diff --git a/utility/gov.go b/utility/gov.go index 73a3eb3d5..684a26290 100644 --- a/utility/gov.go +++ b/utility/gov.go @@ -8,15 +8,6 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) -func (u *UtilityContext) HandleMessageChangeParameter(message *typesUtil.MessageChangeParameter) types.Error { - cdc := u.Codec() - v, err := cdc.FromAny(message.ParameterValue) - if err != nil { - return types.ErrProtoFromAny(err) - } - return u.UpdateParam(message.ParameterKey, v) -} - func (u *UtilityContext) UpdateParam(paramName string, value interface{}) types.Error { store := u.Store() switch paramName { @@ -1816,63 +1807,62 @@ func (u *UtilityContext) GetParamOwner(paramName string) ([]byte, error) { } } -func (u *UtilityContext) GetFee(msg typesUtil.Message) (amount *big.Int, err types.Error) { +func (u *UtilityContext) GetFee(msg typesUtil.Message, actorType typesUtil.ActorType) (amount *big.Int, err types.Error) { switch x := msg.(type) { case *typesUtil.MessageDoubleSign: return u.GetMessageDoubleSignFee() case *typesUtil.MessageSend: return u.GetMessageSendFee() - case *typesUtil.MessageStakeFisherman: - return u.GetMessageStakeFishermanFee() - case *typesUtil.MessageEditStakeFisherman: - return u.GetMessageEditStakeFishermanFee() - case *typesUtil.MessageUnstakeFisherman: - return u.GetMessageUnstakeFishermanFee() - case *typesUtil.MessagePauseFisherman: - return u.GetMessagePauseFishermanFee() - case *typesUtil.MessageUnpauseFisherman: - return u.GetMessageUnpauseFishermanFee() - case *typesUtil.MessageFishermanPauseServiceNode: - return u.GetMessageFishermanPauseServiceNodeFee() - //case *types.MessageTestScore: - // return u.GetMessageTestScoreFee() - //case *types.MessageProveTestScore: - // return u.GetMessageProveTestScoreFee() - case *typesUtil.MessageStakeApp: - return u.GetMessageStakeAppFee() - case *typesUtil.MessageEditStakeApp: - return u.GetMessageEditStakeAppFee() - case *typesUtil.MessageUnstakeApp: - return u.GetMessageUnstakeAppFee() - case *typesUtil.MessagePauseApp: - return u.GetMessagePauseAppFee() - case *typesUtil.MessageUnpauseApp: - return u.GetMessageUnpauseAppFee() - case *typesUtil.MessageStakeValidator: - return u.GetMessageStakeValidatorFee() - case *typesUtil.MessageEditStakeValidator: - return u.GetMessageEditStakeValidatorFee() - case *typesUtil.MessageUnstakeValidator: - return u.GetMessageUnstakeValidatorFee() - case *typesUtil.MessagePauseValidator: - return u.GetMessagePauseValidatorFee() - case *typesUtil.MessageUnpauseValidator: - return u.GetMessageUnpauseValidatorFee() - case *typesUtil.MessageStakeServiceNode: - return u.GetMessageStakeServiceNodeFee() - case *typesUtil.MessageEditStakeServiceNode: - return u.GetMessageEditStakeServiceNodeFee() - case *typesUtil.MessageUnstakeServiceNode: - return u.GetMessageUnstakeServiceNodeFee() - case *typesUtil.MessagePauseServiceNode: - return u.GetMessagePauseServiceNodeFee() - case *typesUtil.MessageUnpauseServiceNode: - return u.GetMessageUnpauseServiceNodeFee() + case *typesUtil.MessageStake: + switch actorType { + case typesUtil.ActorType_App: + return u.GetMessageStakeAppFee() + case typesUtil.ActorType_Fish: + return u.GetMessageStakeFishermanFee() + case typesUtil.ActorType_Node: + return u.GetMessageStakeServiceNodeFee() + case typesUtil.ActorType_Val: + return u.GetMessageStakeValidatorFee() + } + case *typesUtil.MessageEditStake: + switch actorType { + case typesUtil.ActorType_App: + return u.GetMessageEditStakeAppFee() + case typesUtil.ActorType_Fish: + return u.GetMessageEditStakeFishermanFee() + case typesUtil.ActorType_Node: + return u.GetMessageEditStakeServiceNodeFee() + case typesUtil.ActorType_Val: + return u.GetMessageEditStakeValidatorFee() + } + case *typesUtil.MessageUnstake: + switch actorType { + case typesUtil.ActorType_App: + return u.GetMessageUnstakeAppFee() + case typesUtil.ActorType_Fish: + return u.GetMessageUnstakeFishermanFee() + case typesUtil.ActorType_Node: + return u.GetMessageUnstakeServiceNodeFee() + case typesUtil.ActorType_Val: + return u.GetMessageUnstakeValidatorFee() + } + case *typesUtil.MessageUnpause: + switch actorType { + case typesUtil.ActorType_App: + return u.GetMessageUnpauseAppFee() + case typesUtil.ActorType_Fish: + return u.GetMessageUnpauseFishermanFee() + case typesUtil.ActorType_Node: + return u.GetMessageUnpauseServiceNodeFee() + case typesUtil.ActorType_Val: + return u.GetMessageUnpauseValidatorFee() + } case *typesUtil.MessageChangeParameter: return u.GetMessageChangeParameterFee() default: return nil, types.ErrUnknownMessage(x) } + return nil, nil } func (u *UtilityContext) GetMessageChangeParameterSignerCandidates(msg *typesUtil.MessageChangeParameter) ([][]byte, types.Error) { diff --git a/utility/mocked_module.go b/utility/mocked_module.go deleted file mode 100644 index 5d34e436a..000000000 --- a/utility/mocked_module.go +++ /dev/null @@ -1,41 +0,0 @@ -package utility - -import ( - "github.com/golang/mock/gomock" - "github.com/pokt-network/pocket/shared/config" - "github.com/pokt-network/pocket/shared/modules" - modulesMock "github.com/pokt-network/pocket/shared/modules/mocks" -) - -var maxTxBytes = 90000 -var emptyByzValidators = make([][]byte, 0) -var appHash []byte - -func CreateMockedModule(_ *config.Config) (modules.UtilityModule, error) { - ctrl := gomock.NewController(nil) - utilityMock := modulesMock.NewMockUtilityModule(ctrl) - utilityContextMock := modulesMock.NewMockUtilityContext(ctrl) - persistenceContextMock := modulesMock.NewMockPersistenceContext(ctrl) - - utilityMock.EXPECT().Start().Return(nil).AnyTimes() - utilityMock.EXPECT().SetBus(gomock.Any()).Do(func(modules.Bus) {}).AnyTimes() - utilityMock.EXPECT(). - NewContext(gomock.Any()). - Return(utilityContextMock, nil). - AnyTimes() - - utilityContextMock.EXPECT().GetPersistenceContext().Return(persistenceContextMock).AnyTimes() - utilityContextMock.EXPECT().ReleaseContext().Return().AnyTimes() - utilityContextMock.EXPECT(). - GetTransactionsForProposal(gomock.Any(), maxTxBytes, gomock.AssignableToTypeOf(emptyByzValidators)). - Return(make([][]byte, 0), nil). - AnyTimes() - utilityContextMock.EXPECT(). - ApplyBlock(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(appHash, nil). - AnyTimes() - - persistenceContextMock.EXPECT().Commit().Return(nil).AnyTimes() - - return utilityMock, nil -} diff --git a/utility/module.go b/utility/module.go index e73c9cb4b..a8a7394b4 100644 --- a/utility/module.go +++ b/utility/module.go @@ -1,8 +1,11 @@ package utility import ( + "encoding/hex" "log" + typesUtil "github.com/pokt-network/pocket/utility/types" + "github.com/pokt-network/pocket/shared/config" "github.com/pokt-network/pocket/shared/modules" "github.com/pokt-network/pocket/shared/types" @@ -11,8 +14,7 @@ import ( var _ modules.UtilityModule = &UtilityModule{} type UtilityModule struct { - bus modules.Bus - + bus modules.Bus Mempool types.Mempool } @@ -41,3 +43,88 @@ func (u *UtilityModule) GetBus() modules.Bus { } return u.bus } + +// TODO (Team) Protocol hour discussion about contexts. We need to better understand the intermodule relationship here + +type UtilityContext struct { + LatestHeight int64 + Mempool types.Mempool + Context *Context +} + +type Context struct { + modules.PersistenceContext + SavePointsM map[string]struct{} + SavePoints [][]byte +} + +func (u *UtilityModule) NewContext(height int64) (modules.UtilityContext, error) { + ctx, err := u.GetBus().GetPersistenceModule().NewContext(height) + if err != nil { + return nil, types.ErrNewPersistenceContext(err) + } + return &UtilityContext{ + LatestHeight: height, + Mempool: u.Mempool, + Context: &Context{ + PersistenceContext: ctx, + SavePoints: make([][]byte, 0), + SavePointsM: make(map[string]struct{}), + }, + }, nil +} + +func (u *UtilityContext) Store() *Context { + return u.Context +} + +func (u *UtilityContext) GetPersistenceContext() modules.PersistenceContext { + return u.Context.PersistenceContext +} + +func (u *UtilityContext) ReleaseContext() { + u.Context.Release() + u.Context = nil +} + +func (u *UtilityContext) GetLatestHeight() (int64, types.Error) { + return u.LatestHeight, nil +} + +func (u *UtilityContext) Codec() types.Codec { + return types.GetCodec() +} + +func (u *UtilityContext) RevertLastSavePoint() types.Error { + if len(u.Context.SavePointsM) == typesUtil.ZeroInt { + return types.ErrEmptySavePoints() + } + var key []byte + popIndex := len(u.Context.SavePoints) - 1 + key, u.Context.SavePoints = u.Context.SavePoints[popIndex], u.Context.SavePoints[:popIndex] + delete(u.Context.SavePointsM, hex.EncodeToString(key)) + if err := u.Context.PersistenceContext.RollbackToSavePoint(key); err != nil { + return types.ErrRollbackSavePoint(err) + } + return nil +} + +func (u *UtilityContext) NewSavePoint(transactionHash []byte) types.Error { + if err := u.Context.PersistenceContext.NewSavePoint(transactionHash); err != nil { + return types.ErrNewSavePoint(err) + } + txHash := hex.EncodeToString(transactionHash) + if _, exists := u.Context.SavePointsM[txHash]; exists { + return types.ErrDuplicateSavePoint() + } + u.Context.SavePoints = append(u.Context.SavePoints, transactionHash) + u.Context.SavePointsM[txHash] = struct{}{} + return nil +} + +func (c *Context) Reset() types.Error { + if err := c.PersistenceContext.Reset(); err != nil { + return types.ErrResetContext(err) + } + return nil +} diff --git a/utility/proto/actor.proto b/utility/proto/actor.proto new file mode 100644 index 000000000..b0b21fb78 --- /dev/null +++ b/utility/proto/actor.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package utility; + +option go_package = "github.com/pokt-network/pocket/utility/types"; + +enum ActorType { + App = 0; + Node = 1; + Fish = 2; + Val = 3; + } \ No newline at end of file diff --git a/utility/proto/message.proto b/utility/proto/message.proto index 015f4382e..01e62543a 100644 --- a/utility/proto/message.proto +++ b/utility/proto/message.proto @@ -3,157 +3,46 @@ package utility; option go_package = "github.com/pokt-network/pocket/utility/types"; +import "actor.proto"; import "vote.proto"; -import "session.proto"; import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; message MessageSend { bytes from_address = 1; bytes to_address = 2; string amount = 3; + ActorType actor_type = 4; } -message MessageStakeServiceNode { +message MessageStake { bytes public_key = 1; repeated string chains = 2; string amount = 3; string service_url = 4; bytes output_address = 5; optional bytes signer = 6; + ActorType actor_type = 7; } -message MessageEditStakeServiceNode { +message MessageEditStake { bytes address = 1; repeated string chains = 2; - string amount_to_add = 3; - string service_url = 4; - optional bytes signer = 5; -} - -message MessageUnstakeServiceNode { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageUnpauseServiceNode { - bytes address = 1; - optional bytes signer = 2; -} - -message MessagePauseServiceNode { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageStakeApp { - bytes public_key = 1; - repeated string chains = 2; - string amount = 3; - bytes output_address = 4; - optional bytes signer = 5; -} - -message MessageEditStakeApp { - bytes address = 1; - repeated string chains = 2; - string amount_to_add = 3; - optional bytes signer = 4; -} - -message MessageUnstakeApp { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageUnpauseApp { - bytes address = 1; - optional bytes signer = 2; -} - -message MessagePauseApp { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageStakeValidator { - bytes public_key = 1; - string amount = 2; - string service_url = 3; - bytes output_address = 4; - optional bytes signer = 5; -} - -message MessageEditStakeValidator { - bytes address = 1; - string amount_to_add = 2; - string service_url = 3; - optional bytes signer = 4; -} - -message MessageUnstakeValidator { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageUnpauseValidator { - bytes address = 1; - optional bytes signer = 2; -} - -message MessagePauseValidator { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageFishermanPauseServiceNode { - bytes address = 1; - bytes reporter = 2; - optional bytes signer = 3; -} - -message MessageStakeFisherman { - bytes public_key = 1; - repeated string chains = 2; string amount = 3; string service_url = 4; - bytes output_address = 5; - optional bytes signer = 6; -} - -message MessageEditStakeFisherman { - bytes address = 1; - repeated string chains = 2; - string amount_to_add = 3; - string service_url = 4; optional bytes signer = 5; + ActorType actor_type = 6; } -message MessageUnstakeFisherman { - bytes address = 1; - optional bytes signer = 2; -} - -message MessageTestScore { - utility.SessionHeader session_header = 1; - google.protobuf.Timestamp first_sample_time = 2; - uint32 number_of_samples = 3; - repeated uint32 null_indicies = 4; -} - -message MessageProveTestScore { - utility.SessionHeader session_header = 1; - google.protobuf.Timestamp leaf = 2; -} - -message MessageUnpauseFisherman { +message MessageUnstake { bytes address = 1; optional bytes signer = 2; + ActorType actor_type = 3; } -message MessagePauseFisherman{ +message MessageUnpause { bytes address = 1; optional bytes signer = 2; + ActorType actor_type = 3; } message MessageChangeParameter { diff --git a/utility/proto/session.proto b/utility/proto/session.proto deleted file mode 100644 index 7df9195f7..000000000 --- a/utility/proto/session.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package utility; - -option go_package = "github.com/pokt-network/pocket/utility/types"; - -message Session { - SessionHeader session_header = 1; - bytes session_key = 2; // session key is the unique hash used as seed data to select actors accordingly - repeated bytes service_nodes = 3; - bytes fishermen = 4; -} - -message SessionHeader { - bytes app_public_key = 1; - string chain = 2; - int64 session_block_height = 3; -} \ No newline at end of file diff --git a/utility/proto/transaction.proto b/utility/proto/transaction.proto index 2edcf26a8..7fa03ce31 100644 --- a/utility/proto/transaction.proto +++ b/utility/proto/transaction.proto @@ -5,11 +5,11 @@ option go_package = "github.com/pokt-network/pocket/utility/types"; import "google/protobuf/any.proto"; +// TECHDEBT: Consolidate this week consensus message Transaction { google.protobuf.Any msg = 1; - string fee = 2; - Signature signature = 3; - string nonce = 4; + Signature signature = 2; + string nonce = 3; } message TransactionResult { diff --git a/utility/proto/vote.proto b/utility/proto/vote.proto index 0905a425d..b66815828 100644 --- a/utility/proto/vote.proto +++ b/utility/proto/vote.proto @@ -3,7 +3,8 @@ package utility; option go_package = "github.com/pokt-network/pocket/utility/types"; -message Vote { // TODO (Team) Consolidate with consensus types +// TECHDEBT: Consolidate this week consensus +message Vote { bytes public_key = 1; int64 height = 2; uint32 round = 3; diff --git a/utility/service_node.go b/utility/service_node.go deleted file mode 100644 index 5567bc9fa..000000000 --- a/utility/service_node.go +++ /dev/null @@ -1,415 +0,0 @@ -package utility - -import ( - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func (u *UtilityContext) HandleMessageStakeServiceNode(message *typesUtil.MessageStakeServiceNode) types.Error { - publicKey, er := crypto.NewPublicKeyFromBytes(message.PublicKey) - if er != nil { - return types.ErrNewPublicKeyFromBytes(er) - } - // ensure above minimum stake - minStake, err := u.GetServiceNodeMinimumStake() - if err != nil { - return err - } - amount, err := types.StringToBigInt(message.Amount) - if err != nil { - return err - } - if types.BigIntLessThan(amount, minStake) { - return types.ErrMinimumStake() - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amount) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - maxChains, err := u.GetServiceNodeMaxChains() - if err != nil { - return err - } - // validate chain count - if len(message.Chains) > maxChains { - return types.ErrMaxChains(maxChains) - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.ServiceNodeStakePoolName, amount); err != nil { - return err - } - // ensure ServiceNode doesn't already exist - exists, err := u.GetServiceNodeExists(publicKey.Address()) - if err != nil { - return err - } - if exists { - return types.ErrAlreadyExists() - } - // insert the ServiceNode structure - if err := u.InsertServiceNode(publicKey.Address(), message.PublicKey, message.OutputAddress, message.ServiceUrl, message.Amount, message.Chains); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageEditStakeServiceNode(message *typesUtil.MessageEditStakeServiceNode) types.Error { - exists, err := u.GetServiceNodeExists(message.Address) - if err != nil { - return err - } - if !exists { - return types.ErrNotExists() - } - amountToAdd, err := types.StringToBigInt(message.AmountToAdd) - if err != nil { - return err - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amountToAdd) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - maxChains, err := u.GetServiceNodeMaxChains() - if err != nil { - return err - } - // validate chains - if len(message.Chains) > maxChains { - return types.ErrMaxChains(maxChains) - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.ServiceNodeStakePoolName, amountToAdd); err != nil { - return err - } - // insert the serviceNode structure - if err := u.UpdateServiceNode(message.Address, message.ServiceUrl, message.AmountToAdd, message.Chains); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnstakeServiceNode(message *typesUtil.MessageUnstakeServiceNode) types.Error { - status, err := u.GetServiceNodeStatus(message.Address) - if err != nil { - return err - } - // validate is staked - if status != typesUtil.StakedStatus { - return types.ErrInvalidStatus(status, typesUtil.StakedStatus) - } - unstakingHeight, err := u.CalculateServiceNodeUnstakingHeight() - if err != nil { - return err - } - if err := u.SetServiceNodeUnstakingHeightAndStatus(message.Address, unstakingHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) UnstakeServiceNodesThatAreReady() types.Error { - serviceNodesReadyToUnstake, err := u.GetServiceNodesReadyToUnstake() - if err != nil { - return err - } - for _, serviceNode := range serviceNodesReadyToUnstake { - if err := u.SubPoolAmount(typesGenesis.ServiceNodeStakePoolName, serviceNode.GetStakeAmount()); err != nil { - return err - } - if err := u.AddAccountAmountString(serviceNode.GetOutputAddress(), serviceNode.GetStakeAmount()); err != nil { - return err - } - if err := u.DeleteServiceNode(serviceNode.GetAddress()); err != nil { - return err - } - } - return nil -} - -func (u *UtilityContext) BeginUnstakingMaxPausedServiceNodes() types.Error { - maxPausedBlocks, err := u.GetServiceNodeMaxPausedBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - beforeHeight := latestHeight - int64(maxPausedBlocks) - // genesis edge case - if beforeHeight < 0 { - beforeHeight = 0 - } - if err := u.UnstakeServiceNodesPausedBefore(beforeHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessagePauseServiceNode(message *typesUtil.MessagePauseServiceNode) types.Error { - height, err := u.GetServiceNodePauseHeightIfExists(message.Address) - if err != nil { - return err - } - if height != typesUtil.HeightNotUsed { - return types.ErrAlreadyPaused() - } - height, err = u.GetLatestHeight() - if err != nil { - return err - } - if err := u.SetServiceNodePauseHeight(message.Address, height); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnpauseServiceNode(message *typesUtil.MessageUnpauseServiceNode) types.Error { - pausedHeight, err := u.GetServiceNodePauseHeightIfExists(message.Address) - if err != nil { - return err - } - if pausedHeight == typesUtil.HeightNotUsed { - return types.ErrNotPaused() - } - minPauseBlocks, err := u.GetServiceNodeMinimumPauseBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - if latestHeight < int64(minPauseBlocks)+pausedHeight { - return types.ErrNotReadyToUnpause() - } - if err := u.SetServiceNodePauseHeight(message.Address, typesUtil.HeightNotUsed); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) GetServiceNodeExists(address []byte) (bool, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return false, types.ErrGetExists(er) - } - exists, er := store.GetServiceNodeExists(address, height) - if er != nil { - return false, types.ErrGetExists(er) - } - return exists, nil -} - -func (u *UtilityContext) InsertServiceNode(address, publicKey, output []byte, serviceURL, amount string, chains []string) types.Error { - store := u.Store() - err := store.InsertServiceNode(address, publicKey, output, false, typesUtil.StakedStatus, serviceURL, amount, chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) UpdateServiceNode(address []byte, serviceURL, amount string, chains []string) types.Error { - store := u.Store() - err := store.UpdateServiceNode(address, serviceURL, amount, chains) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) DeleteServiceNode(address []byte) types.Error { - store := u.Store() - if err := store.DeleteServiceNode(address); err != nil { - return types.ErrDelete(err) - } - return nil -} - -func (u *UtilityContext) GetServiceNodesReadyToUnstake() ([]*types.UnstakingActor, types.Error) { - store := u.Store() - latestHeight, err := u.GetLatestHeight() - if err != nil { - return nil, err - } - unstakingServiceNodes, er := store.GetServiceNodesReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) - if er != nil { - return nil, types.ErrGetReadyToUnstake(er) - } - return unstakingServiceNodes, nil -} - -func (u *UtilityContext) UnstakeServiceNodesPausedBefore(pausedBeforeHeight int64) types.Error { - store := u.Store() - unstakingHeight, err := u.CalculateServiceNodeUnstakingHeight() - if err != nil { - return err - } - er := store.SetServiceNodeStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) - if er != nil { - return types.ErrSetStatusPausedBefore(er, pausedBeforeHeight) - } - return nil -} - -func (u *UtilityContext) GetServiceNodeStatus(address []byte) (int, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - status, er := store.GetServiceNodeStatus(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - return status, nil -} - -func (u *UtilityContext) SetServiceNodeUnstakingHeightAndStatus(address []byte, unstakingHeight int64) types.Error { - store := u.Store() - if er := store.SetServiceNodeUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus); er != nil { - return types.ErrSetUnstakingHeightAndStatus(er) - } - return nil -} - -func (u *UtilityContext) GetServiceNodePauseHeightIfExists(address []byte) (int64, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - ServiceNodePauseHeight, er := store.GetServiceNodePauseHeightIfExists(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - return ServiceNodePauseHeight, nil -} - -func (u *UtilityContext) SetServiceNodePauseHeight(address []byte, height int64) types.Error { - store := u.Store() - if err := store.SetServiceNodePauseHeight(address, height); err != nil { - return types.ErrSetPauseHeight(err) - } - return nil -} - -func (u *UtilityContext) CalculateServiceNodeUnstakingHeight() (int64, types.Error) { - unstakingBlocks, err := u.GetServiceNodeUnstakingBlocks() - if err != nil { - return typesUtil.ZeroInt, err - } - unstakingHeight, err := u.CalculateUnstakingHeight(unstakingBlocks) - if err != nil { - return typesUtil.ZeroInt, err - } - return unstakingHeight, nil -} - -func (u *UtilityContext) GetServiceNodesPerSession(height int64) (int, types.Error) { - store := u.Store() - i, err := store.GetServiceNodesPerSessionAt(height) - if err != nil { - return typesUtil.ZeroInt, types.ErrGetServiceNodesPerSessionAt(height, err) - } - return i, nil -} - -func (u *UtilityContext) GetServiceNodeCount(chain string, height int64) (int, types.Error) { - store := u.Store() - i, err := store.GetServiceNodeCount(chain, height) - if err != nil { - return typesUtil.ZeroInt, types.ErrGetServiceNodeCount(chain, height, err) - } - return i, nil -} - -func (u *UtilityContext) GetMessageStakeServiceNodeSignerCandidates(msg *typesUtil.MessageStakeServiceNode) ([][]byte, types.Error) { - pk, er := crypto.NewPublicKeyFromBytes(msg.PublicKey) - if er != nil { - return nil, types.ErrNewPublicKeyFromBytes(er) - } - candidates := make([][]byte, 0) - candidates = append(candidates, msg.OutputAddress) - candidates = append(candidates, pk.Address()) - return candidates, nil -} - -func (u *UtilityContext) GetMessageEditStakeServiceNodeSignerCandidates(msg *typesUtil.MessageEditStakeServiceNode) ([][]byte, types.Error) { - output, err := u.GetServiceNodeOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnstakeServiceNodeSignerCandidates(msg *typesUtil.MessageUnstakeServiceNode) ([][]byte, types.Error) { - output, err := u.GetServiceNodeOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnpauseServiceNodeSignerCandidates(msg *typesUtil.MessageUnpauseServiceNode) ([][]byte, types.Error) { - output, err := u.GetServiceNodeOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessagePauseServiceNodeSignerCandidates(msg *typesUtil.MessagePauseServiceNode) ([][]byte, types.Error) { - output, err := u.GetServiceNodeOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetServiceNodeOutputAddress(operator []byte) ([]byte, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - output, er := store.GetServiceNodeOutputAddress(operator, height) - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - return output, nil -} diff --git a/utility/transaction.go b/utility/transaction.go index 43c86feba..b69c834a5 100644 --- a/utility/transaction.go +++ b/utility/transaction.go @@ -84,7 +84,7 @@ func (u *UtilityContext) AnteHandleMessage(tx *typesUtil.Transaction) (typesUtil if err != nil { return nil, err } - fee, err := u.GetFee(msg) // TODO this enforces exact fee spent regardless of what's put in field... should we remove the fee field from transaction? + fee, err := u.GetFee(msg, msg.GetActorType()) if err != nil { return nil, err } @@ -99,7 +99,7 @@ func (u *UtilityContext) AnteHandleMessage(tx *typesUtil.Transaction) (typesUtil } accountAmount.Sub(accountAmount, fee) if accountAmount.Sign() == -1 { - return nil, types.ErrInsufficientAmountError() + return nil, types.ErrInsufficientAmount() } signerCandidates, err := u.GetSignerCandidates(msg) if err != nil { @@ -131,52 +131,14 @@ func (u *UtilityContext) HandleMessage(msg typesUtil.Message) types.Error { return u.HandleMessageDoubleSign(x) case *typesUtil.MessageSend: return u.HandleMessageSend(x) - case *typesUtil.MessageStakeFisherman: - return u.HandleMessageStakeFisherman(x) - case *typesUtil.MessageEditStakeFisherman: - return u.HandleMessageEditStakeFisherman(x) - case *typesUtil.MessageUnstakeFisherman: - return u.HandleMessageUnstakeFisherman(x) - case *typesUtil.MessagePauseFisherman: - return u.HandleMessagePauseFisherman(x) - case *typesUtil.MessageUnpauseFisherman: - return u.HandleMessageUnpauseFisherman(x) - case *typesUtil.MessageFishermanPauseServiceNode: - return u.HandleMessageFishermanPauseServiceNode(x) - //case *types.MessageTestScore: - // return u.HandleMessageTestScore(x) - //case *types.MessageProveTestScore: - // return u.HandleMessageProveTestScore(x) - case *typesUtil.MessageStakeApp: - return u.HandleMessageStakeApp(x) - case *typesUtil.MessageEditStakeApp: - return u.HandleMessageEditStakeApp(x) - case *typesUtil.MessageUnstakeApp: - return u.HandleMessageUnstakeApp(x) - case *typesUtil.MessagePauseApp: - return u.HandleMessagePauseApp(x) - case *typesUtil.MessageUnpauseApp: - return u.HandleMessageUnpauseApp(x) - case *typesUtil.MessageStakeValidator: - return u.HandleMessageStakeValidator(x) - case *typesUtil.MessageEditStakeValidator: - return u.HandleMessageEditStakeValidator(x) - case *typesUtil.MessageUnstakeValidator: - return u.HandleMessageUnstakeValidator(x) - case *typesUtil.MessagePauseValidator: - return u.HandleMessagePauseValidator(x) - case *typesUtil.MessageUnpauseValidator: - return u.HandleMessageUnpauseValidator(x) - case *typesUtil.MessageStakeServiceNode: - return u.HandleMessageStakeServiceNode(x) - case *typesUtil.MessageEditStakeServiceNode: - return u.HandleMessageEditStakeServiceNode(x) - case *typesUtil.MessageUnstakeServiceNode: - return u.HandleMessageUnstakeServiceNode(x) - case *typesUtil.MessagePauseServiceNode: - return u.HandleMessagePauseServiceNode(x) - case *typesUtil.MessageUnpauseServiceNode: - return u.HandleMessageUnpauseServiceNode(x) + case *typesUtil.MessageStake: + return u.HandleStakeMessage(x) + case *typesUtil.MessageEditStake: + return u.HandleEditStakeMessage(x) + case *typesUtil.MessageUnstake: + return u.HandleUnstakeMessage(x) + case *typesUtil.MessageUnpause: + return u.HandleUnpauseMessage(x) case *typesUtil.MessageChangeParameter: return u.HandleMessageChangeParameter(x) default: @@ -184,61 +146,307 @@ func (u *UtilityContext) HandleMessage(msg typesUtil.Message) types.Error { } } +func (u *UtilityContext) HandleMessageSend(message *typesUtil.MessageSend) types.Error { + // convert the amount to big.Int + amount, err := types.StringToBigInt(message.Amount) + if err != nil { + return err + } + // get the sender's account amount + fromAccountAmount, err := u.GetAccountAmount(message.FromAddress) + if err != nil { + return err + } + // subtract that amount from the sender + fromAccountAmount.Sub(fromAccountAmount, amount) + // if they go negative, they don't have sufficient funds + // NOTE: we don't use the u.SubtractAccountAmount() function because Utility needs to do this check + if fromAccountAmount.Sign() == -1 { + return types.ErrInsufficientAmount() + } + // add the amount to the recipient's account + if err = u.AddAccountAmount(message.ToAddress, amount); err != nil { + return err + } + // set the sender's account amount + if err = u.SetAccountAmount(message.FromAddress, fromAccountAmount); err != nil { + return err + } + return nil +} + +func (u *UtilityContext) HandleStakeMessage(message *typesUtil.MessageStake) types.Error { + publicKey, err := u.BytesToPublicKey(message.PublicKey) + if err != nil { + return err + } + // ensure above minimum stake + amount, err := u.CheckAboveMinStake(message.ActorType, message.Amount) + if err != nil { + return err + } + // ensure signer has sufficient funding for the stake + signerAccountAmount, err := u.GetAccountAmount(message.Signer) + if err != nil { + return err + } + // calculate new signer account amount + signerAccountAmount.Sub(signerAccountAmount, amount) + if signerAccountAmount.Sign() == -1 { + return types.ErrInsufficientAmount() + } + // validators don't have chains field + if err = u.CheckBelowMaxChains(message.ActorType, message.Chains); err != nil { + return err + } + // ensure actor doesn't already exist + if exists, err := u.GetActorExists(message.ActorType, publicKey.Address()); err != nil || exists { + if exists { + return types.ErrAlreadyExists() + } + return err + } + // update account amount + if err = u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { + return err + } + // move funds from account to pool + if err = u.AddPoolAmount(typesGenesis.AppStakePoolName, amount); err != nil { + return err + } + var er error + store := u.Store() + // insert actor + switch message.ActorType { + case typesUtil.ActorType_App: + maxRelays, err := u.CalculateAppRelays(message.Amount) + if err != nil { + return err + } + er = store.InsertApp(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, typesUtil.StakedStatus, maxRelays, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + case typesUtil.ActorType_Fish: + er = store.InsertFisherman(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, typesUtil.StakedStatus, message.ServiceUrl, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + case typesUtil.ActorType_Node: + er = store.InsertServiceNode(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, typesUtil.StakedStatus, message.ServiceUrl, message.Amount, message.Chains, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + case typesUtil.ActorType_Val: + er = store.InsertValidator(publicKey.Address(), publicKey.Bytes(), message.OutputAddress, false, typesUtil.StakedStatus, message.ServiceUrl, message.Amount, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) + } + if er != nil { + return types.ErrInsert(er) + } + return nil +} + +func (u *UtilityContext) HandleEditStakeMessage(message *typesUtil.MessageEditStake) types.Error { + // ensure actor exists + if exists, err := u.GetActorExists(message.ActorType, message.Address); err != nil || !exists { + if !exists { + return types.ErrNotExists() + } + return err + } + currentStakeAmount, err := u.GetStakeAmount(message.ActorType, message.Address) + if err != nil { + return err + } + amount, err := types.StringToBigInt(message.Amount) + if err != nil { + return err + } + // ensure new stake >= current stake + amount.Sub(amount, currentStakeAmount) + if amount.Sign() == -1 { + return types.ErrStakeLess() + } + // ensure signer has sufficient funding for the stake + signerAccountAmount, err := u.GetAccountAmount(message.Signer) + if err != nil { + return err + } + signerAccountAmount.Sub(signerAccountAmount, amount) + if signerAccountAmount.Sign() == -1 { + return types.ErrInsufficientAmount() + } + if err = u.CheckBelowMaxChains(message.ActorType, message.Chains); err != nil { + return err + } + // update account amount + if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { + return err + } + // move funds from account to pool + if err := u.AddPoolAmount(typesGenesis.AppStakePoolName, amount); err != nil { + return err + } + store := u.Store() + var er error + switch message.ActorType { + case typesUtil.ActorType_App: + maxRelays, err := u.CalculateAppRelays(message.Amount) + if err != nil { + return err + } + er = store.UpdateApp(message.Address, maxRelays, message.Amount, message.Chains) + case typesUtil.ActorType_Fish: + er = store.UpdateFisherman(message.Address, message.ServiceUrl, message.Amount, message.Chains) + case typesUtil.ActorType_Node: + er = store.UpdateServiceNode(message.Address, message.ServiceUrl, message.Amount, message.Chains) + case typesUtil.ActorType_Val: + er = store.UpdateValidator(message.Address, message.ServiceUrl, message.Amount) + } + if er != nil { + return types.ErrInsert(er) + } + return nil +} + +func (u *UtilityContext) HandleUnstakeMessage(message *typesUtil.MessageUnstake) types.Error { + if status, err := u.GetActorStatus(message.ActorType, message.Address); err != nil || status != typesUtil.StakedStatus { + if status != typesUtil.StakedStatus { + return types.ErrInvalidStatus(status, typesUtil.StakedStatus) + } + return err + } + unstakingHeight, err := u.GetUnstakingHeight(message.ActorType) + if err != nil { + return err + } + if err = u.SetActorUnstaking(message.ActorType, unstakingHeight, message.Address); err != nil { + return err + } + return nil +} + +func (u *UtilityContext) HandleUnpauseMessage(message *typesUtil.MessageUnpause) types.Error { + pausedHeight, err := u.GetPauseHeight(message.ActorType, message.Address) + if err != nil { + return err + } + if pausedHeight == typesUtil.HeightNotUsed { + return types.ErrNotPaused() + } + minPauseBlocks, err := u.GetMinimumPauseBlocks(message.ActorType) + if err != nil { + return err + } + latestHeight, err := u.GetLatestHeight() + if err != nil { + return err + } + if latestHeight < int64(minPauseBlocks)+pausedHeight { + return types.ErrNotReadyToUnpause() + } + if err = u.SetActorPauseHeight(message.ActorType, message.Address, types.HeightNotUsed); err != nil { + return err + } + return nil +} + +func (u *UtilityContext) HandleMessageDoubleSign(message *typesUtil.MessageDoubleSign) types.Error { + latestHeight, err := u.GetLatestHeight() + if err != nil { + return err + } + evidenceAge := latestHeight - message.VoteA.Height + maxEvidenceAge, err := u.GetMaxEvidenceAgeInBlocks() + if err != nil { + return err + } + if evidenceAge > int64(maxEvidenceAge) { + return types.ErrMaxEvidenceAge() + } + pk, er := crypto.NewPublicKeyFromBytes(message.VoteB.PublicKey) + if er != nil { + return types.ErrNewPublicKeyFromBytes(er) + } + doubleSigner := pk.Address() + // burn validator for double signing blocks + burnPercentage, err := u.GetDoubleSignBurnPercentage() + if err != nil { + return err + } + if err := u.BurnActor(typesUtil.ActorType_Val, burnPercentage, doubleSigner); err != nil { + return err + } + return nil +} + +func (u *UtilityContext) HandleMessageChangeParameter(message *typesUtil.MessageChangeParameter) types.Error { + cdc := u.Codec() + v, err := cdc.FromAny(message.ParameterValue) + if err != nil { + return types.ErrProtoFromAny(err) + } + return u.UpdateParam(message.ParameterKey, v) +} + func (u *UtilityContext) GetSignerCandidates(msg typesUtil.Message) ([][]byte, types.Error) { switch x := msg.(type) { case *typesUtil.MessageDoubleSign: return u.GetMessageDoubleSignSignerCandidates(x) case *typesUtil.MessageSend: return u.GetMessageSendSignerCandidates(x) - case *typesUtil.MessageStakeFisherman: - return u.GetMessageStakeFishermanSignerCandidates(x) - case *typesUtil.MessageEditStakeFisherman: - return u.GetMessageEditStakeFishermanSignerCandidates(x) - case *typesUtil.MessageUnstakeFisherman: - return u.GetMessageUnstakeFishermanSignerCandidates(x) - case *typesUtil.MessagePauseFisherman: - return u.GetMessagePauseFishermanSignerCandidates(x) - case *typesUtil.MessageUnpauseFisherman: - return u.GetMessageUnpauseFishermanSignerCandidates(x) - case *typesUtil.MessageFishermanPauseServiceNode: - return u.GetMessageFishermanPauseServiceNodeSignerCandidates(x) - //case *types.MessageTestScore: - // return u.GetMessageTestScoreSignerCandidates(x) - //case *types.MessageProveTestScore: - // return u.GetMessageProveTestScoreSignerCandidates(x) - case *typesUtil.MessageStakeApp: - return u.GetMessageStakeAppSignerCandidates(x) - case *typesUtil.MessageEditStakeApp: - return u.GetMessageEditStakeAppSignerCandidates(x) - case *typesUtil.MessageUnstakeApp: - return u.GetMessageUnstakeAppSignerCandidates(x) - case *typesUtil.MessagePauseApp: - return u.GetMessagePauseAppSignerCandidates(x) - case *typesUtil.MessageUnpauseApp: - return u.GetMessageUnpauseAppSignerCandidates(x) - case *typesUtil.MessageStakeValidator: - return u.GetMessageStakeValidatorSignerCandidates(x) - case *typesUtil.MessageEditStakeValidator: - return u.GetMessageEditStakeValidatorSignerCandidates(x) - case *typesUtil.MessageUnstakeValidator: - return u.GetMessageUnstakeValidatorSignerCandidates(x) - case *typesUtil.MessagePauseValidator: - return u.GetMessagePauseValidatorSignerCandidates(x) - case *typesUtil.MessageUnpauseValidator: - return u.GetMessageUnpauseValidatorSignerCandidates(x) - case *typesUtil.MessageStakeServiceNode: - return u.GetMessageStakeServiceNodeSignerCandidates(x) - case *typesUtil.MessageEditStakeServiceNode: - return u.GetMessageEditStakeServiceNodeSignerCandidates(x) - case *typesUtil.MessageUnstakeServiceNode: - return u.GetMessageUnstakeServiceNodeSignerCandidates(x) - case *typesUtil.MessagePauseServiceNode: - return u.GetMessagePauseServiceNodeSignerCandidates(x) - case *typesUtil.MessageUnpauseServiceNode: - return u.GetMessageUnpauseServiceNodeSignerCandidates(x) + case *typesUtil.MessageStake: + return u.GetMessageStakeSignerCandidates(x) + case *typesUtil.MessageUnstake: + return u.GetMessageUnstakeSignerCandidates(x) + case *typesUtil.MessageUnpause: + return u.GetMessageUnpauseSignerCandidates(x) case *typesUtil.MessageChangeParameter: return u.GetMessageChangeParameterSignerCandidates(x) default: return nil, types.ErrUnknownMessage(x) } } + +func (u *UtilityContext) GetMessageStakeSignerCandidates(msg *typesUtil.MessageStake) ([][]byte, types.Error) { + pk, er := crypto.NewPublicKeyFromBytes(msg.PublicKey) + if er != nil { + return nil, types.ErrNewPublicKeyFromBytes(er) + } + candidates := make([][]byte, 0) + candidates = append(candidates, msg.OutputAddress) + candidates = append(candidates, pk.Address()) + return candidates, nil +} + +func (u *UtilityContext) GetMessageEditStakeSignerCandidates(msg *typesUtil.MessageEditStake) ([][]byte, types.Error) { + output, err := u.GetActorOutputAddress(msg.ActorType, msg.Address) + if err != nil { + return nil, err + } + candidates := make([][]byte, 0) + candidates = append(candidates, output) + candidates = append(candidates, msg.Address) + return candidates, nil +} + +func (u *UtilityContext) GetMessageUnstakeSignerCandidates(msg *typesUtil.MessageUnstake) ([][]byte, types.Error) { + output, err := u.GetActorOutputAddress(msg.ActorType, msg.Address) + if err != nil { + return nil, err + } + candidates := make([][]byte, 0) + candidates = append(candidates, output) + candidates = append(candidates, msg.Address) + return candidates, nil +} + +func (u *UtilityContext) GetMessageUnpauseSignerCandidates(msg *typesUtil.MessageUnpause) ([][]byte, types.Error) { + output, err := u.GetActorOutputAddress(msg.ActorType, msg.Address) + if err != nil { + return nil, err + } + candidates := make([][]byte, 0) + candidates = append(candidates, output) + candidates = append(candidates, msg.Address) + return candidates, nil +} + +func (u *UtilityContext) GetMessageSendSignerCandidates(msg *typesUtil.MessageSend) ([][]byte, types.Error) { + return [][]byte{msg.FromAddress}, nil +} + +func (u *UtilityContext) GetMessageDoubleSignSignerCandidates(msg *typesUtil.MessageDoubleSign) ([][]byte, types.Error) { + return [][]byte{msg.ReporterAddress}, nil +} diff --git a/utility/types/account.go b/utility/types/account.go deleted file mode 100644 index 6243363b5..000000000 --- a/utility/types/account.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -// TODO(team): Consider refactoring PoolNames and statuses to an enum -// with appropriate enum <-> string mappers where appropriate. -// This can make it easier to track all the different states -// available. -const ( - UnstakingStatus = 1 - StakedStatus = 2 -) diff --git a/utility/types/actor.go b/utility/types/actor.go new file mode 100644 index 000000000..e39f23be8 --- /dev/null +++ b/utility/types/actor.go @@ -0,0 +1,42 @@ +package types + +import ( + "log" + + "github.com/pokt-network/pocket/shared/types/genesis" +) + +// REFACTOR: Moving this into a proto file enum (impacts everything) +const ( + UnstakingStatus = 1 + StakedStatus = 2 +) + +var ( + ActorTypes = []ActorType{ + ActorType_App, + ActorType_Node, + ActorType_Fish, + ActorType_Val, + } +) + +func (actorType ActorType) GetActorPoolName() string { + switch actorType { + case ActorType_App: + return genesis.AppStakePoolName + case ActorType_Val: + return genesis.ValidatorStakePoolName + case ActorType_Fish: + return genesis.FishermanStakePoolName + case ActorType_Node: + return genesis.ServiceNodeStakePoolName + default: + log.Fatalf("unknown actor type: %v", actorType) + } + return "" +} + +func (at ActorType) GetActorName() string { + return ActorType_name[int32(at)] +} diff --git a/utility/types/message.go b/utility/types/message.go index 6a85093ab..efec970ef 100644 --- a/utility/types/message.go +++ b/utility/types/message.go @@ -2,7 +2,6 @@ package types import ( "bytes" - "log" "net/url" "strconv" "strings" @@ -12,286 +11,54 @@ import ( "google.golang.org/protobuf/proto" ) +/* +`message.go`` contains `ValidateBasic` and `SetSigner`` logic for all message types. + +`ValidateBasic` is a **stateless** validation check that should encapsulate all +validations possible before even checking the state storage layer. +*/ + +// DISCUSS(olshansky): Should we move these into a shared file? +const ( + MillionInt = 1000000 + ZeroInt = 0 + HeightNotUsed = -1 + EmptyString = "" + HttpsPrefix = "https://" + HttpPrefix = "http://" + Colon = ":" + Period = "." + InvalidURLPrefix = "the url must start with http:// or https://" + PortRequired = "a port is required" + NonNumberPort = "invalid port, cant convert to integer" + PortOutOfRange = "invalid port, out of valid port range" + NoPeriod = "must contain one '.'" + MaxPort = 65535 +) + type Message interface { proto.Message SetSigner(signer []byte) ValidateBasic() types.Error + GetActorType() ActorType } -var _ Message = &MessageStakeApp{} - -func (msg *MessageStakeApp) ValidateBasic() types.Error { - if err := ValidateAmount(msg.Amount); err != nil { - return err - } - if err := ValidatePublicKey(msg.PublicKey); err != nil { - return err - } - if err := ValidateRelayChains(msg.Chains); err != nil { - return err - } - return ValidateOutputAddress(msg.OutputAddress) -} - -func (msg *MessageStakeApp) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageEditStakeApp) ValidateBasic() types.Error { - if err := ValidateAmount(msg.AmountToAdd); err != nil { - return err - } - if err := ValidateAddress(msg.Address); err != nil { - return err - } - if err := ValidateRelayChains(msg.Chains); err != nil { - return err - } - return nil -} - -func (msg *MessageEditStakeApp) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnstakeApp) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnstakeApp) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnpauseApp) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnpauseApp) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessagePauseApp) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessagePauseApp) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageStakeServiceNode) ValidateBasic() types.Error { - if err := ValidateAmount(msg.Amount); err != nil { - return err - } - if err := ValidatePublicKey(msg.PublicKey); err != nil { - return err - } - if err := ValidateRelayChains(msg.Chains); err != nil { - return err - } - if err := ValidateServiceUrl(msg.ServiceUrl); err != nil { - return err - } - return ValidateOutputAddress(msg.OutputAddress) -} - -func (msg *MessageStakeServiceNode) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageEditStakeServiceNode) ValidateBasic() types.Error { - if err := ValidateAmount(msg.AmountToAdd); err != nil { - return err - } - if err := ValidateAddress(msg.Address); err != nil { - return err - } - if err := ValidateRelayChains(msg.Chains); err != nil { - return err - } - if err := ValidateServiceUrl(msg.ServiceUrl); err != nil { - return err - } - return nil -} - -func (msg *MessageEditStakeServiceNode) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnstakeServiceNode) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnstakeServiceNode) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnpauseServiceNode) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnpauseServiceNode) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessagePauseServiceNode) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessagePauseServiceNode) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageStakeFisherman) ValidateBasic() types.Error { - if err := ValidateAmount(msg.Amount); err != nil { - return err - } - if err := ValidatePublicKey(msg.PublicKey); err != nil { - return err - } - if err := ValidateRelayChains(msg.Chains); err != nil { - return err - } - if err := ValidateServiceUrl(msg.ServiceUrl); err != nil { - return err - } - return ValidateOutputAddress(msg.OutputAddress) -} - -func (msg *MessageChangeParameter) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageChangeParameter) ValidateBasic() types.Error { - if msg.ParameterKey == "" { - return types.ErrEmptyParamKey() - } - if msg.ParameterValue == nil { - return types.ErrEmptyParamValue() - } - if err := ValidateAddress(msg.Owner); err != nil { - return err - } - return nil -} - -func (msg *MessageStakeFisherman) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageEditStakeFisherman) ValidateBasic() types.Error { - if err := ValidateAmount(msg.AmountToAdd); err != nil { - return err - } - if err := ValidateAddress(msg.Address); err != nil { +func (msg *MessageStake) ValidateBasic() types.Error { + if err := ValidatePublicKey(msg.GetPublicKey()); err != nil { return err } - if err := ValidateRelayChains(msg.Chains); err != nil { + if err := ValidateOutputAddress(msg.GetOutputAddress()); err != nil { return err } - if err := ValidateServiceUrl(msg.ServiceUrl); err != nil { - return err - } - return nil + return ValidateStaker(msg) } -func (msg *MessageEditStakeFisherman) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnstakeFisherman) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnstakeFisherman) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnpauseFisherman) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnpauseFisherman) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessagePauseFisherman) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessagePauseFisherman) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageFishermanPauseServiceNode) ValidateBasic() types.Error { - if err := ValidateAddress(msg.Reporter); err != nil { +func (msg *MessageEditStake) ValidateBasic() types.Error { + if err := ValidateAddress(msg.GetAddress()); err != nil { return err } - return ValidateAddress(msg.Address) -} - -func (msg *MessageFishermanPauseServiceNode) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageStakeValidator) ValidateBasic() types.Error { - if err := ValidateAmount(msg.Amount); err != nil { - return err - } - if err := ValidatePublicKey(msg.PublicKey); err != nil { - return err - } - if err := ValidateServiceUrl(msg.ServiceUrl); err != nil { - return err - } - return ValidateOutputAddress(msg.OutputAddress) -} - -func (msg *MessageStakeValidator) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageEditStakeValidator) ValidateBasic() types.Error { - // validate amount - if err := ValidateAmount(msg.AmountToAdd); err != nil { - return err - } - if err := ValidateAddress(msg.Address); err != nil { - return err - } - if err := ValidateServiceUrl(msg.ServiceUrl); err != nil { - return err - } - return nil -} - -func (msg *MessageEditStakeValidator) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnstakeValidator) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnstakeValidator) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessageUnpauseValidator) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessageUnpauseValidator) SetSigner(signer []byte) { - msg.Signer = signer -} - -func (msg *MessagePauseValidator) ValidateBasic() types.Error { - return ValidateAddress(msg.Address) -} - -func (msg *MessagePauseValidator) SetSigner(signer []byte) { - msg.Signer = signer + return ValidateStaker(msg) } func (msg *MessageDoubleSign) ValidateBasic() types.Error { @@ -319,10 +86,6 @@ func (msg *MessageDoubleSign) ValidateBasic() types.Error { return nil } -func (msg *MessageDoubleSign) SetSigner(signer []byte) { - msg.ReporterAddress = signer -} - func (msg *MessageSend) ValidateBasic() types.Error { if err := ValidateAddress(msg.FromAddress); err != nil { return err @@ -336,10 +99,33 @@ func (msg *MessageSend) ValidateBasic() types.Error { return nil } -func (msg *MessageSend) SetSigner(signer []byte) { - log.Println("[NOOP] SetSigner on MessageSend") +func (msg *MessageChangeParameter) ValidateBasic() types.Error { + if msg.ParameterKey == "" { + return types.ErrEmptyParamKey() + } + if msg.ParameterValue == nil { + return types.ErrEmptyParamValue() + } + if err := ValidateAddress(msg.Owner); err != nil { + return err + } + return nil } +func (msg *MessageUnstake) ValidateBasic() types.Error { return ValidateAddress(msg.Address) } +func (msg *MessageUnpause) ValidateBasic() types.Error { return ValidateAddress(msg.Address) } +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 *MessageDoubleSign) SetSigner(signer []byte) { msg.ReporterAddress = signer } +func (msg *MessageSend) SetSigner(signer []byte) { /*no op*/ } +func (msg *MessageChangeParameter) SetSigner(signer []byte) { msg.Signer = signer } +func (x *MessageChangeParameter) GetActorType() ActorType { return -1 } +func (x *MessageDoubleSign) GetActorType() ActorType { return -1 } + +// helpers + func ValidateAddress(address []byte) types.Error { if address == nil { return types.ErrEmptyAddress() @@ -407,7 +193,15 @@ func ValidateAmount(amount string) types.Error { return nil } -func ValidateServiceUrl(uri string) types.Error { +func ValidateActorType(_ ActorType) types.Error { + // TODO (team) not sure if there's anything we can do here + return nil +} + +func ValidateServiceUrl(actorType ActorType, uri string) types.Error { + if actorType == ActorType_App { + return nil + } uri = strings.ToLower(uri) _, err := url.ParseRequestURI(uri) if err != nil { @@ -432,3 +226,44 @@ func ValidateServiceUrl(uri string) types.Error { } return nil } + +// CLEANUP: Figure out where these other types should be defined. +// It's a bit weird that they are hidden at the bottom of the file. + +const ( + RelayChainLength = 4 // pre-determined length that strikes a balance between combination possibilities & storage +) + +type RelayChain string + +// TODO: Consider adding a governance parameter for a list of valid relay chains +func (rc *RelayChain) Validate() types.Error { + if rc == nil || *rc == "" { + return types.ErrEmptyRelayChain() + } + rcLen := len(*rc) + if rcLen != RelayChainLength { + return types.ErrInvalidRelayChainLength(rcLen, RelayChainLength) + } + return nil +} + +type MessageStaker interface { + GetActorType() ActorType + GetAmount() string + GetChains() []string + GetServiceUrl() string +} + +func ValidateStaker(msg MessageStaker) types.Error { + if err := ValidateActorType(msg.GetActorType()); err != nil { + return err + } + if err := ValidateAmount(msg.GetAmount()); err != nil { + return err + } + if err := ValidateRelayChains(msg.GetChains()); err != nil { + return err + } + return ValidateServiceUrl(msg.GetActorType(), msg.GetServiceUrl()) +} diff --git a/utility/types/message_test.go b/utility/types/message_test.go index c76590dd6..1cf340050 100644 --- a/utility/types/message_test.go +++ b/utility/types/message_test.go @@ -7,53 +7,53 @@ import ( "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/types" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" ) var ( defaultTestingChains = []string{"0001"} - defaultServiceUrl = "https://foo.bar:443" defaultAmountBig = big.NewInt(1000000) defaultAmount = types.BigIntToString(defaultAmountBig) - defaultFeeBig = big.NewInt(10000) - defaultFee = types.BigIntToString(defaultFeeBig) defaultUnusedLength = -1 ) -func TestMessageChangeParameter_ValidateBasic(t *testing.T) { +func TestMessage_ChangeParameter_ValidateBasic(t *testing.T) { + owner, err := crypto.GenerateAddress() + require.NoError(t, err) + codec := types.GetCodec() - owner, _ := crypto.GenerateAddress() paramKey := "key" paramValueRaw := wrapperspb.Int32(1) paramValueAny, err := codec.ToAny(paramValueRaw) require.NoError(t, err) + msg := MessageChangeParameter{ Owner: owner, ParameterKey: paramKey, ParameterValue: paramValueAny, } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingOwner := msg + + err = msg.ValidateBasic() + require.NoError(t, err) + + msgMissingOwner := proto.Clone(&msg).(*MessageChangeParameter) msgMissingOwner.Owner = nil - if err := msgMissingOwner.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgMissingParamKey := msg + require.Equal(t, types.ErrEmptyAddress().Code(), msgMissingOwner.ValidateBasic().Code()) + + msgMissingParamKey := proto.Clone(&msg).(*MessageChangeParameter) msgMissingParamKey.ParameterKey = "" - if err := msgMissingParamKey.ValidateBasic(); err.Code() != types.ErrEmptyParamKey().Code() { - t.Fatal(err) - } - msgMissingParamValue := msg + require.Equal(t, types.ErrEmptyParamKey().Code(), msgMissingParamKey.ValidateBasic().Code()) + + msgMissingParamValue := proto.Clone(&msg).(*MessageChangeParameter) msgMissingParamValue.ParameterValue = nil - if err := msgMissingParamValue.ValidateBasic(); err.Code() != types.ErrEmptyParamValue().Code() { - t.Fatal(err) - } + require.Equal(t, types.ErrEmptyParamValue().Code(), msgMissingParamValue.ValidateBasic().Code()) } -func TestMessageDoubleSign_ValidateBasic(t *testing.T) { - pk, _ := crypto.GeneratePublicKey() +func TestMessage_DoubleSign_ValidateBasic(t *testing.T) { + pk, err := crypto.GeneratePublicKey() + require.NoError(t, err) + hashA := crypto.SHA3Hash(pk.Bytes()) hashB := crypto.SHA3Hash(pk.Address()) voteA := &Vote{ @@ -76,606 +76,203 @@ func TestMessageDoubleSign_ValidateBasic(t *testing.T) { VoteB: voteB, ReporterAddress: reporter, } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } + er := msg.ValidateBasic() + require.NoError(t, er) + + pk2, err := crypto.GeneratePublicKey() + require.NoError(t, err) msgUnequalPubKeys := new(MessageDoubleSign) - msgUnequalPubKeys.VoteA = new(Vote) - msgUnequalPubKeys.VoteB = new(Vote) - *msgUnequalPubKeys.VoteA = *msg.VoteA - *msgUnequalPubKeys.VoteB = *msg.VoteB - pk2, _ := crypto.GeneratePublicKey() + msgUnequalPubKeys.VoteA = proto.Clone(msg.VoteA).(*Vote) + msgUnequalPubKeys.VoteB = proto.Clone(msg.VoteB).(*Vote) msgUnequalPubKeys.VoteA.PublicKey = pk2.Bytes() - if err := msgUnequalPubKeys.ValidateBasic(); err.Code() != types.ErrUnequalPublicKeys().Code() { - t.Fatal(err) - } + er = msgUnequalPubKeys.ValidateBasic() + require.Equal(t, types.ErrUnequalPublicKeys().Code(), er.Code()) + msgUnequalHeights := new(MessageDoubleSign) - msgUnequalHeights.VoteA = new(Vote) - msgUnequalHeights.VoteB = new(Vote) - *msgUnequalHeights.VoteA = *msg.VoteA - *msgUnequalHeights.VoteB = *msg.VoteB + msgUnequalHeights.VoteA = proto.Clone(msg.VoteA).(*Vote) + msgUnequalHeights.VoteB = proto.Clone(msg.VoteB).(*Vote) msgUnequalHeights.VoteA.Height = 2 - if err := msgUnequalHeights.ValidateBasic(); err.Code() != types.ErrUnequalHeights().Code() { - t.Fatal(err) - } + er = msgUnequalHeights.ValidateBasic() + require.Equal(t, types.ErrUnequalHeights().Code(), er.Code()) + msgUnequalRounds := new(MessageDoubleSign) - msgUnequalRounds.VoteA = new(Vote) - msgUnequalRounds.VoteB = new(Vote) - *msgUnequalRounds.VoteA = *msg.VoteA - *msgUnequalRounds.VoteB = *msg.VoteB + msgUnequalRounds.VoteA = proto.Clone(msg.VoteA).(*Vote) + msgUnequalRounds.VoteB = proto.Clone(msg.VoteB).(*Vote) msgUnequalRounds.VoteA.Round = 1 - if err := msgUnequalRounds.ValidateBasic(); err.Code() != types.ErrUnequalRounds().Code() { - t.Fatal(err) - } - //msgUnequalVoteTypes := new(MessageDoubleSign) TODO only one type of evidence right now - //msgUnequalVoteTypes.VoteA = new(Vote) - //msgUnequalVoteTypes.VoteB = new(Vote) - //*msgUnequalVoteTypes.VoteA = *msg.VoteA - //*msgUnequalVoteTypes.VoteB = *msg.VoteB - //msgUnequalVoteTypes.VoteA.Type = 0 - //if err := msgUnequalVoteTypes.ValidateBasic(); err.Code() != types.ErrUnequalVoteTypes().Code() { - // t.Fatal(err) - //} + er = msgUnequalRounds.ValidateBasic() + require.Equal(t, types.ErrUnequalRounds().Code(), er.Code()) + msgEqualVoteHash := new(MessageDoubleSign) - msgEqualVoteHash.VoteA = new(Vote) - msgEqualVoteHash.VoteB = new(Vote) - *msgEqualVoteHash.VoteA = *msg.VoteA - *msgEqualVoteHash.VoteB = *msg.VoteB + msgEqualVoteHash.VoteA = proto.Clone(msg.VoteA).(*Vote) + msgEqualVoteHash.VoteB = proto.Clone(msg.VoteB).(*Vote) msgEqualVoteHash.VoteB.BlockHash = hashA - if err := msgEqualVoteHash.ValidateBasic(); err.Code() != types.ErrEqualVotes().Code() { - t.Fatal(err) - } -} + er = msgEqualVoteHash.ValidateBasic() + require.Equal(t, types.ErrEqualVotes().Code(), er.Code()) -func TestMessageEditStakeApp_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageEditStakeApp{ - Address: addr, - Chains: defaultTestingChains, - AmountToAdd: defaultAmount, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAmount := msg - msgMissingAmount.AmountToAdd = "" - if err := msgMissingAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgInvalidAmount := msg - msgInvalidAmount.AmountToAdd = "sdk" - if err := msgInvalidAmount.ValidateBasic(); err.Code() != types.ErrStringToBigInt().Code() { - t.Fatal(err) - } - msgEmptyAddress := msg - msgEmptyAddress.Address = nil - if err := msgEmptyAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgInvalidAddress := msg - msgInvalidAddress.Address = []byte("badAddr") - if err := msgInvalidAddress.ValidateBasic(); err.Code() != types.ErrInvalidAddressLen(crypto.ErrInvalidAddressLen(defaultUnusedLength)).Code() { - t.Fatal(err) - } - msgEmptyRelayChains := msg - msgEmptyRelayChains.Chains = nil - if err := msgEmptyRelayChains.ValidateBasic(); err.Code() != types.ErrEmptyRelayChains().Code() { - t.Fatal(err) - } - msgInvalidRelayChains := msg - msgInvalidRelayChains.Chains = []string{"notAValidRelayChain"} - if err := msgInvalidRelayChains.ValidateBasic(); err.Code() != types.ErrInvalidRelayChainLength(0, RelayChainLength).Code() { - t.Fatal(err) - } + // TODO only one type of evidence right now + // msgUnequalVoteTypes := new(MessageDoubleSign) } -func TestMessageEditStakeFisherman_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageEditStakeFisherman{ - Address: addr, - Chains: defaultTestingChains, - AmountToAdd: defaultAmount, - ServiceUrl: defaultServiceUrl, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAmount := msg - msgMissingAmount.AmountToAdd = "" - if err := msgMissingAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgInvalidAmount := msg - msgInvalidAmount.AmountToAdd = "sdk" - if err := msgInvalidAmount.ValidateBasic(); err.Code() != types.ErrStringToBigInt().Code() { - t.Fatal(err) - } - msgEmptyAddress := msg - msgEmptyAddress.Address = nil - if err := msgEmptyAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgInvalidAddress := msg - msgInvalidAddress.Address = []byte("badAddr") - if err := msgInvalidAddress.ValidateBasic(); err.Code() != types.ErrInvalidAddressLen(crypto.ErrInvalidAddressLen(defaultUnusedLength)).Code() { - t.Fatal(err) - } - msgEmptyRelayChains := msg - msgEmptyRelayChains.Chains = nil - if err := msgEmptyRelayChains.ValidateBasic(); err.Code() != types.ErrEmptyRelayChains().Code() { - t.Fatal(err) - } - msgInvalidRelayChains := msg - msgInvalidRelayChains.Chains = []string{"notAValidRelayChain"} - if err := msgInvalidRelayChains.ValidateBasic(); err.Code() != types.ErrInvalidRelayChainLength(0, RelayChainLength).Code() { - t.Fatal(err) - } - msgEmptyServiceUrl := msg - msgEmptyServiceUrl.ServiceUrl = "" - if err := msgEmptyServiceUrl.ValidateBasic(); err.Code() != types.ErrInvalidServiceUrl("").Code() { - t.Fatal(err) - } -} +func TestMessage_EditStake_ValidateBasic(t *testing.T) { + addr, err := crypto.GenerateAddress() + require.NoError(t, err) -func TestMessageEditStakeServiceNode_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageEditStakeServiceNode{ - Address: addr, - Chains: defaultTestingChains, - AmountToAdd: defaultAmount, - ServiceUrl: defaultServiceUrl, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAmount := msg - msgMissingAmount.AmountToAdd = "" - if err := msgMissingAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgInvalidAmount := msg - msgInvalidAmount.AmountToAdd = "sdk" - if err := msgInvalidAmount.ValidateBasic(); err.Code() != types.ErrStringToBigInt().Code() { - t.Fatal(err) - } - msgEmptyAddress := msg - msgEmptyAddress.Address = nil - if err := msgEmptyAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgInvalidAddress := msg - msgInvalidAddress.Address = []byte("badAddr") - if err := msgInvalidAddress.ValidateBasic(); err.Code() != types.ErrInvalidAddressLen(crypto.ErrInvalidAddressLen(defaultUnusedLength)).Code() { - t.Fatal(err) - } - msgEmptyRelayChains := msg - msgEmptyRelayChains.Chains = nil - if err := msgEmptyRelayChains.ValidateBasic(); err.Code() != types.ErrEmptyRelayChains().Code() { - t.Fatal(err) - } - msgInvalidRelayChains := msg - msgInvalidRelayChains.Chains = []string{"notAValidRelayChain"} - if err := msgInvalidRelayChains.ValidateBasic(); err.Code() != types.ErrInvalidRelayChainLength(0, RelayChainLength).Code() { - t.Fatal(err) - } - msgEmptyServiceUrl := msg - msgEmptyServiceUrl.ServiceUrl = "" - if err := msgEmptyServiceUrl.ValidateBasic(); err.Code() != types.ErrInvalidServiceUrl("").Code() { - t.Fatal(err) + msg := MessageEditStake{ + Address: addr, + Chains: defaultTestingChains, + Amount: defaultAmount, } -} + err = msg.ValidateBasic() + require.NoError(t, err) -func TestMessageEditStakeValidator_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageEditStakeValidator{ - Address: addr, - AmountToAdd: defaultAmount, - ServiceUrl: defaultServiceUrl, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAmount := msg - msgMissingAmount.AmountToAdd = "" - if err := msgMissingAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgInvalidAmount := msg - msgInvalidAmount.AmountToAdd = "sdk" - if err := msgInvalidAmount.ValidateBasic(); err.Code() != types.ErrStringToBigInt().Code() { - t.Fatal(err) - } - msgEmptyAddress := msg - msgEmptyAddress.Address = nil - if err := msgEmptyAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgInvalidAddress := msg - msgInvalidAddress.Address = []byte("badAddr") - if err := msgInvalidAddress.ValidateBasic(); err.Code() != types.ErrInvalidAddressLen(crypto.ErrInvalidAddressLen(defaultUnusedLength)).Code() { - t.Fatal(err) - } - msgEmptyServiceUrl := msg - msgEmptyServiceUrl.ServiceUrl = "" - if err := msgEmptyServiceUrl.ValidateBasic(); err.Code() != types.ErrInvalidServiceUrl("").Code() { - t.Fatal(err) - } -} + msgMissingAmount := proto.Clone(&msg).(*MessageEditStake) + msgMissingAmount.Amount = "" + er := msgMissingAmount.ValidateBasic() + require.Equal(t, types.ErrEmptyAmount().Code(), er.Code()) -func TestMessageFishermanPauseServiceNode_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageFishermanPauseServiceNode{ - Address: addr, - Reporter: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingReporter := msg - msgMissingReporter.Reporter = nil - if err := msgMissingReporter.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + msgInvalidAmount := proto.Clone(&msg).(*MessageEditStake) + msgInvalidAmount.Amount = "sdk" + er = msgInvalidAmount.ValidateBasic() + require.Equal(t, types.ErrStringToBigInt().Code(), er.Code()) -func TestMessagePauseApp_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessagePauseApp{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + msgEmptyAddress := proto.Clone(&msg).(*MessageEditStake) + msgEmptyAddress.Address = nil + er = msgEmptyAddress.ValidateBasic() + require.Equal(t, types.ErrEmptyAddress().Code(), er.Code()) -func TestMessagePauseFisherman_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessagePauseFisherman{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + msgInvalidAddress := proto.Clone(&msg).(*MessageEditStake) + msgInvalidAddress.Address = []byte("badAddr") + er = msgInvalidAddress.ValidateBasic() + expectedErr := types.ErrInvalidAddressLen(crypto.ErrInvalidAddressLen(defaultUnusedLength)) + require.Equal(t, expectedErr.Code(), er.Code()) -func TestMessagePauseServiceNode_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessagePauseServiceNode{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + msgEmptyRelayChains := proto.Clone(&msg).(*MessageEditStake) + msgEmptyRelayChains.Chains = nil + er = msgEmptyRelayChains.ValidateBasic() + require.Equal(t, types.ErrEmptyRelayChains().Code(), er.Code()) -func TestMessagePauseValidator_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessagePauseValidator{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } + msgInvalidRelayChains := proto.Clone(&msg).(*MessageEditStake) + msgInvalidRelayChains.Chains = []string{"notAValidRelayChain"} + er = msgInvalidRelayChains.ValidateBasic() + expectedErr = types.ErrInvalidRelayChainLength(0, RelayChainLength) + require.Equal(t, expectedErr.Code(), er.Code()) } func TestMessageSend_ValidateBasic(t *testing.T) { - addr1, _ := crypto.GenerateAddress() - addr2, _ := crypto.GenerateAddress() + addr1, err := crypto.GenerateAddress() + require.NoError(t, err) + + addr2, err := crypto.GenerateAddress() + require.NoError(t, err) + msg := MessageSend{ FromAddress: addr1, ToAddress: addr2, Amount: defaultAmount, } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg + er := msg.ValidateBasic() + require.NoError(t, er) + + msgMissingAddress := proto.Clone(&msg).(*MessageSend) msgMissingAddress.FromAddress = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgMissingToAddress := msg + er = msgMissingAddress.ValidateBasic() + require.Equal(t, types.ErrEmptyAddress().Code(), er.Code()) + + msgMissingToAddress := proto.Clone(&msg).(*MessageSend) msgMissingToAddress.ToAddress = nil - if err := msgMissingToAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } - msgMissingAmount := msg + er = msgMissingToAddress.ValidateBasic() + require.Equal(t, types.ErrEmptyAddress().Code(), er.Code()) + + msgMissingAmount := proto.Clone(&msg).(*MessageSend) msgMissingAmount.Amount = "" - if err := msgMissingAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgInvalidAmount := msg + er = msgMissingAmount.ValidateBasic() + require.Equal(t, types.ErrEmptyAmount().Code(), er.Code()) + + msgInvalidAmount := proto.Clone(&msg).(*MessageSend) msgInvalidAmount.Amount = "" - if err := msgInvalidAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } + er = msgInvalidAmount.ValidateBasic() + require.Equal(t, types.ErrEmptyAmount().Code(), er.Code()) } -func TestMessageStakeApp_ValidateBasic(t *testing.T) { - pk, _ := crypto.GeneratePublicKey() - msg := MessageStakeApp{ - PublicKey: pk.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmount, - OutputAddress: pk.Address(), - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgEmptyPubKey := msg - msgEmptyPubKey.PublicKey = nil - if err := msgEmptyPubKey.ValidateBasic(); err.Code() != types.ErrEmptyPublicKey().Code() { - t.Fatal(err) - } - msgEmptyChains := msg - msgEmptyChains.Chains = nil - if err := msgEmptyChains.ValidateBasic(); err.Code() != types.ErrEmptyRelayChains().Code() { - t.Fatal(err) - } - msgEmptyAmount := msg - msgEmptyAmount.Amount = "" - if err := msgEmptyAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgEmptyOutputAddress := msg - msgEmptyOutputAddress.OutputAddress = nil - if err := msgEmptyOutputAddress.ValidateBasic(); err.Code() != types.ErrNilOutputAddress().Code() { - t.Fatal(err) - } -} +func TestMessageStake_ValidateBasic(t *testing.T) { + pk, err := crypto.GeneratePublicKey() + require.NoError(t, err) -func TestMessageStakeFisherman_ValidateBasic(t *testing.T) { - pk, _ := crypto.GeneratePublicKey() - msg := MessageStakeFisherman{ + msg := MessageStake{ PublicKey: pk.Bytes(), Chains: defaultTestingChains, Amount: defaultAmount, - ServiceUrl: defaultServiceUrl, OutputAddress: pk.Address(), } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgEmptyPubKey := msg - msgEmptyPubKey.PublicKey = nil - if err := msgEmptyPubKey.ValidateBasic(); err.Code() != types.ErrEmptyPublicKey().Code() { - t.Fatal(err) - } - msgEmptyChains := msg - msgEmptyChains.Chains = nil - if err := msgEmptyChains.ValidateBasic(); err.Code() != types.ErrEmptyRelayChains().Code() { - t.Fatal(err) - } - msgEmptyAmount := msg - msgEmptyAmount.Amount = "" - if err := msgEmptyAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgEmptyOutputAddress := msg - msgEmptyOutputAddress.OutputAddress = nil - if err := msgEmptyOutputAddress.ValidateBasic(); err.Code() != types.ErrNilOutputAddress().Code() { - t.Fatal(err) - } - msgEmptyServiceUrl := msg - msgEmptyServiceUrl.ServiceUrl = "" - if err := msgEmptyServiceUrl.ValidateBasic(); err.Code() != types.ErrInvalidServiceUrl("").Code() { - t.Fatal(err) - } -} + er := msg.ValidateBasic() + require.NoError(t, er) -func TestMessageStakeServiceNode_ValidateBasic(t *testing.T) { - pk, _ := crypto.GeneratePublicKey() - msg := MessageStakeServiceNode{ - PublicKey: pk.Bytes(), - Chains: defaultTestingChains, - Amount: defaultAmount, - ServiceUrl: defaultServiceUrl, - OutputAddress: pk.Address(), - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgEmptyPubKey := msg + msgEmptyPubKey := proto.Clone(&msg).(*MessageStake) msgEmptyPubKey.PublicKey = nil - if err := msgEmptyPubKey.ValidateBasic(); err.Code() != types.ErrEmptyPublicKey().Code() { - t.Fatal(err) - } - msgEmptyChains := msg + er = msgEmptyPubKey.ValidateBasic() + require.Equal(t, types.ErrEmptyPublicKey().Code(), er.Code()) + + msgEmptyChains := proto.Clone(&msg).(*MessageStake) msgEmptyChains.Chains = nil - if err := msgEmptyChains.ValidateBasic(); err.Code() != types.ErrEmptyRelayChains().Code() { - t.Fatal(err) - } - msgEmptyAmount := msg - msgEmptyAmount.Amount = "" - if err := msgEmptyAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgEmptyOutputAddress := msg - msgEmptyOutputAddress.OutputAddress = nil - if err := msgEmptyOutputAddress.ValidateBasic(); err.Code() != types.ErrNilOutputAddress().Code() { - t.Fatal(err) - } - msgEmptyServiceUrl := msg - msgEmptyServiceUrl.ServiceUrl = "" - if err := msgEmptyServiceUrl.ValidateBasic(); err.Code() != types.ErrInvalidServiceUrl("").Code() { - t.Fatal(err) - } -} + er = msgEmptyChains.ValidateBasic() + require.Equal(t, types.ErrEmptyRelayChains().Code(), er.Code()) -func TestMessageStakeValidator_ValidateBasic(t *testing.T) { - pk, _ := crypto.GeneratePublicKey() - msg := MessageStakeValidator{ - PublicKey: pk.Bytes(), - Amount: defaultAmount, - ServiceUrl: defaultServiceUrl, - OutputAddress: pk.Address(), - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgEmptyPubKey := msg - msgEmptyPubKey.PublicKey = nil - if err := msgEmptyPubKey.ValidateBasic(); err.Code() != types.ErrEmptyPublicKey().Code() { - t.Fatal(err) - } - msgEmptyAmount := msg + msgEmptyAmount := proto.Clone(&msg).(*MessageStake) msgEmptyAmount.Amount = "" - if err := msgEmptyAmount.ValidateBasic(); err.Code() != types.ErrEmptyAmount().Code() { - t.Fatal(err) - } - msgEmptyOutputAddress := msg + er = msgEmptyAmount.ValidateBasic() + require.Equal(t, types.ErrEmptyAmount().Code(), er.Code()) + + msgEmptyOutputAddress := proto.Clone(&msg).(*MessageStake) msgEmptyOutputAddress.OutputAddress = nil - if err := msgEmptyOutputAddress.ValidateBasic(); err.Code() != types.ErrNilOutputAddress().Code() { - t.Fatal(err) - } - msgEmptyServiceUrl := msg - msgEmptyServiceUrl.ServiceUrl = "" - if err := msgEmptyServiceUrl.ValidateBasic(); err.Code() != types.ErrInvalidServiceUrl("").Code() { - t.Fatal(err) - } + er = msgEmptyOutputAddress.ValidateBasic() + require.Equal(t, types.ErrNilOutputAddress().Code(), er.Code()) } -func TestMessageUnpauseApp_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnpauseApp{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} +func TestMessageUnpause_ValidateBasic(t *testing.T) { + addr, err := crypto.GenerateAddress() + require.NoError(t, err) -func TestMessageUnpauseFisherman_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnpauseFisherman{ + msg := MessageUnpause{ Address: addr, } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + er := msg.ValidateBasic() + require.NoError(t, er) -func TestMessageUnpauseServiceNode_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnpauseServiceNode{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg + msgMissingAddress := proto.Clone(&msg).(*MessageUnpause) msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + er = msgMissingAddress.ValidateBasic() + require.Equal(t, types.ErrEmptyAddress().Code(), er.Code()) -func TestMessageUnpauseValidator_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnpauseValidator{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } } -func TestMessageUnstakeApp_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnstakeApp{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} +func TestMessageUnstake_ValidateBasic(t *testing.T) { + addr, err := crypto.GenerateAddress() + require.NoError(t, err) -func TestMessageUnstakeFisherman_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnstakeFisherman{ + msg := MessageUnstake{ Address: addr, } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } -} + er := msg.ValidateBasic() + require.NoError(t, er) -func TestMessageUnstakeServiceNode_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnstakeServiceNode{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg + msgMissingAddress := proto.Clone(&msg).(*MessageUnstake) msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } + er = msgMissingAddress.ValidateBasic() + require.Equal(t, types.ErrEmptyAddress().Code(), er.Code()) } -func TestMessageUnstakeValidator_ValidateBasic(t *testing.T) { - addr, _ := crypto.GenerateAddress() - msg := MessageUnstakeValidator{ - Address: addr, - } - if err := msg.ValidateBasic(); err != nil { - t.Fatal(err) - } - msgMissingAddress := msg - msgMissingAddress.Address = nil - if err := msgMissingAddress.ValidateBasic(); err.Code() != types.ErrEmptyAddress().Code() { - t.Fatal(err) - } +func TestRelayChain_Validate(t *testing.T) { + relayChainValid := RelayChain("0001") + err := relayChainValid.Validate() + require.NoError(t, err) + + relayChainInvalidLength := RelayChain("001") + expectedError := types.ErrInvalidRelayChainLength(0, RelayChainLength) + err = relayChainInvalidLength.Validate() + require.Equal(t, expectedError.Code(), err.Code()) + + relayChainEmpty := RelayChain("") + expectedError = types.ErrEmptyRelayChain() + err = relayChainEmpty.Validate() + require.Equal(t, expectedError.Code(), err.Code()) } diff --git a/utility/types/relay_chain.go b/utility/types/relay_chain.go deleted file mode 100644 index 8dcaf63c4..000000000 --- a/utility/types/relay_chain.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -import "github.com/pokt-network/pocket/shared/types" - -const ( - RelayChainLength = 4 // pre-determined length that strikes a balance between combination possibilities & storage -) - -type RelayChain string - -// TODO: Consider adding a governance parameter for a list of valid relay chains -func (rc *RelayChain) Validate() types.Error { - if rc == nil || *rc == "" { - return types.ErrEmptyRelayChain() - } - rcLen := len(*rc) - if rcLen != RelayChainLength { - return types.ErrInvalidRelayChainLength(rcLen, RelayChainLength) - } - return nil -} diff --git a/utility/types/relay_chain_test.go b/utility/types/relay_chain_test.go deleted file mode 100644 index a56569678..000000000 --- a/utility/types/relay_chain_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -import ( - "github.com/pokt-network/pocket/shared/types" - "testing" -) - -func TestRelayChain_Validate(t *testing.T) { - relayChainValid := RelayChain("0001") - relayChainInvalidLength := RelayChain("001") - relayChainEmpty := RelayChain("") - if err := relayChainValid.Validate(); err != nil { - t.Fatal(err) - } - if err := relayChainInvalidLength.Validate(); err.Code() != types.ErrInvalidRelayChainLength(0, RelayChainLength).Code() { - t.Fatal(err) - } - if err := relayChainEmpty.Validate(); err.Code() != types.ErrEmptyRelayChain().Code() { - t.Fatal(err) - } -} diff --git a/utility/types/session.go b/utility/types/session.go deleted file mode 100644 index 89d28f43f..000000000 --- a/utility/types/session.go +++ /dev/null @@ -1,23 +0,0 @@ -package types - -const ( - MillionInt = 1000000 - ZeroInt = 0 - HeightNotUsed = -1 - EmptyString = "" - HttpsPrefix = "https://" - HttpPrefix = "http://" - Colon = ":" - Period = "." - InvalidURLPrefix = "the url must start with http:// or https://" - PortRequired = "a port is required" - NonNumberPort = "invalid port, cant convert to integer" - PortOutOfRange = "invalid port, out of valid port range" - NoPeriod = "must contain one '.'" - MaxPort = 65535 -) - -type SessionNode struct { - Address []byte - ServiceUrl string -} diff --git a/utility/types/transaction.go b/utility/types/transaction.go index 25ad41438..1fa93b890 100644 --- a/utility/types/transaction.go +++ b/utility/types/transaction.go @@ -3,8 +3,6 @@ package types import ( "bytes" "encoding/hex" - "math/big" - "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/types" ) @@ -18,10 +16,6 @@ func TransactionFromBytes(transaction []byte) (*Transaction, types.Error) { } func (tx *Transaction) ValidateBasic() types.Error { - fee := big.Int{} - if _, ok := fee.SetString(tx.Fee, 10); tx.Fee == "" || !ok { - return types.ErrNewFeeFromString(tx.Fee) - } if tx.Nonce == "" { return types.ErrEmptyNonce() } diff --git a/utility/types/transaction_test.go b/utility/types/transaction_test.go index 074b71f0d..b20f62186 100644 --- a/utility/types/transaction_test.go +++ b/utility/types/transaction_test.go @@ -1,12 +1,12 @@ package types import ( - "bytes" "testing" "github.com/pokt-network/pocket/shared/crypto" "github.com/pokt-network/pocket/shared/types" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" ) var ( @@ -27,11 +27,12 @@ func NewTestingMsg(_ *testing.T) Message { func NewUnsignedTestingTransaction(t *testing.T) Transaction { codec := types.GetCodec() msg := NewTestingMsg(t) + anyMsg, err := codec.ToAny(msg) require.NoError(t, err) + return Transaction{ Msg: anyMsg, - Fee: defaultFee, Nonce: types.BigIntToString(types.RandBigInt()), } } @@ -40,90 +41,86 @@ func TestTransactionBytesAndFromBytes(t *testing.T) { tx := NewUnsignedTestingTransaction(t) bz, err := tx.Bytes() require.NoError(t, err) + tx2, err := TransactionFromBytes(bz) require.NoError(t, err) + hash1, err := tx.Hash() - if err != nil { - t.Fatal() - } + require.NoError(t, err) + hash2, err := tx2.Hash() - if err != nil { - t.Fatal() - } - if hash1 != hash2 { - t.Fatal("unequal hashes") - } - if !tx.Equals(tx2) { - t.Fatal("unequal transactions") - } + require.NoError(t, err) + + require.Equal(t, hash1, hash2, "transaction hash mismatch") + require.Equal(t, proto.Clone(&tx), proto.Clone(tx2), "transaction mismatch") } func TestTransaction_Message(t *testing.T) { tx := NewUnsignedTestingTransaction(t) msg, err := tx.Message() require.NoError(t, err) + expected := NewTestingMsg(t) - if msg.ProtoReflect().Type() != expected.ProtoReflect().Type() { - t.Fatal("invalid message type") - } + require.NotEqual(t, expected, msg) + require.Equal(t, msg.ProtoReflect().Type(), expected.ProtoReflect().Type()) + message := msg.(*MessageSend) expectedMessage := expected.(*MessageSend) - if message.Amount != expectedMessage.Amount || - !bytes.Equal(message.ToAddress, expectedMessage.ToAddress) || - !bytes.Equal(message.FromAddress, expectedMessage.FromAddress) { - t.Fatal("unequal messages") - } + require.Equal(t, message.Amount, expectedMessage.Amount, "unequal messages") + require.Equal(t, message.FromAddress, expectedMessage.FromAddress, "unequal messages") + require.Equal(t, message.ToAddress, expectedMessage.ToAddress, "unequal messages") } func TestTransaction_Sign(t *testing.T) { tx := NewUnsignedTestingTransaction(t) - if err := tx.Sign(testingSenderPrivateKey); err != nil { - t.Fatal(err) - } + + err := tx.Sign(testingSenderPrivateKey) + require.NoError(t, err) + msg, err := tx.SignBytes() require.NoError(t, err) - if !testingSenderPublicKey.Verify(msg, tx.Signature.Signature) { - t.Fatal("invalid signature error") - } + + verified := testingSenderPublicKey.Verify(msg, tx.Signature.Signature) + require.True(t, verified, "signature should be verified") } func TestTransaction_ValidateBasic(t *testing.T) { tx := NewUnsignedTestingTransaction(t) - if err := tx.Sign(testingSenderPrivateKey); err != nil { - t.Fatal(err) - } - if err := tx.ValidateBasic(); err != nil { - t.Fatal(err) - } - txNoNonce := tx + err := tx.Sign(testingSenderPrivateKey) + require.NoError(t, err) + + er := tx.ValidateBasic() + require.NoError(t, er) + + txNoNonce := proto.Clone(&tx).(*Transaction) txNoNonce.Nonce = "" - if err := txNoNonce.ValidateBasic(); err.Code() != types.ErrEmptyNonce().Code() { - t.Fatal(err) - } - txInvalidMessageAny := tx + er = txNoNonce.ValidateBasic() + require.Equal(t, types.ErrEmptyNonce().Code(), er.Code()) + + txInvalidMessageAny := proto.Clone(&tx).(*Transaction) txInvalidMessageAny.Msg = nil - if err := txInvalidMessageAny.ValidateBasic(); err.Code() != types.ErrProtoFromAny(err).Code() { - t.Fatal(err) - } - txEmptySig := tx + er = txInvalidMessageAny.ValidateBasic() + require.Equal(t, types.ErrProtoFromAny(er).Code(), er.Code()) + + txEmptySig := proto.Clone(&tx).(*Transaction) txEmptySig.Signature = nil - if err := txEmptySig.ValidateBasic(); err.Code() != types.ErrEmptySignature().Code() { - t.Fatal(err) - } - txEmptyPublicKey := tx + er = txEmptySig.ValidateBasic() + require.Equal(t, types.ErrEmptySignature().Code(), er.Code()) + + txEmptyPublicKey := proto.Clone(&tx).(*Transaction) txEmptyPublicKey.Signature.PublicKey = nil - if err := txEmptyPublicKey.ValidateBasic(); err.Code() != types.ErrEmptyPublicKey().Code() { - t.Fatal(err) - } - txInvalidPublicKey := tx + er = txEmptyPublicKey.ValidateBasic() + require.Equal(t, types.ErrEmptyPublicKey().Code(), er.Code()) + + txInvalidPublicKey := proto.Clone(&tx).(*Transaction) txInvalidPublicKey.Signature.PublicKey = []byte("publickey") - if err := txInvalidPublicKey.ValidateBasic(); err.Code() != types.ErrNewPublicKeyFromBytes(err).Code() { - t.Fatal(err) - } - txInvalidSignature := tx + err = txInvalidPublicKey.ValidateBasic() + require.Equal(t, types.ErrNewPublicKeyFromBytes(err).Code(), err.Code()) + + txInvalidSignature := proto.Clone(&tx).(*Transaction) tx.Signature.PublicKey = testingSenderPublicKey.Bytes() txInvalidSignature.Signature.Signature = []byte("signature") - if err := txInvalidSignature.ValidateBasic(); err.Code() != types.ErrSignatureVerificationFailed().Code() { - t.Fatal(err) - } + er = txInvalidSignature.ValidateBasic() + require.Equal(t, types.ErrSignatureVerificationFailed().Code(), er.Code()) + } diff --git a/utility/validator.go b/utility/validator.go deleted file mode 100644 index f765ce347..000000000 --- a/utility/validator.go +++ /dev/null @@ -1,589 +0,0 @@ -package utility - -import ( - "math/big" - - "github.com/pokt-network/pocket/shared/crypto" - "github.com/pokt-network/pocket/shared/types" - typesGenesis "github.com/pokt-network/pocket/shared/types/genesis" - typesUtil "github.com/pokt-network/pocket/utility/types" -) - -func (u *UtilityContext) HandleMessageStakeValidator(message *typesUtil.MessageStakeValidator) types.Error { - publicKey, er := crypto.NewPublicKeyFromBytes(message.PublicKey) - if er != nil { - return types.ErrNewPublicKeyFromBytes(er) - } - // ensure above minimum stake - minStake, err := u.GetValidatorMinimumStake() - if err != nil { - return err - } - amount, err := types.StringToBigInt(message.Amount) - if err != nil { - return err - } - if types.BigIntLessThan(amount, minStake) { - return types.ErrMinimumStake() - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amount) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.ValidatorStakePoolName, amount); err != nil { - return err - } - // ensure Validator doesn't already exist - exists, err := u.GetValidatorExists(publicKey.Address()) - if err != nil { - return err - } - if exists { - return types.ErrAlreadyExists() - } - // insert the Validator structure - if err := u.InsertValidator(publicKey.Address(), message.PublicKey, message.OutputAddress, message.ServiceUrl, message.Amount); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageEditStakeValidator(message *typesUtil.MessageEditStakeValidator) types.Error { - exists, err := u.GetValidatorExists(message.Address) - if err != nil { - return err - } - if !exists { - return types.ErrNotExists() - } - amountToAdd, err := types.StringToBigInt(message.AmountToAdd) - if err != nil { - return err - } - // ensure signer has sufficient funding for the stake - signerAccountAmount, err := u.GetAccountAmount(message.Signer) - if err != nil { - return err - } - signerAccountAmount.Sub(signerAccountAmount, amountToAdd) - if signerAccountAmount.Sign() == -1 { - return types.ErrInsufficientAmountError() - } - // update account amount - if err := u.SetAccountAmount(message.Signer, signerAccountAmount); err != nil { - return err - } - // move funds from account to pool - if err := u.AddPoolAmount(typesGenesis.ValidatorStakePoolName, amountToAdd); err != nil { - return err - } - // insert the validator structure - if err := u.UpdateValidator(message.Address, message.ServiceUrl, message.AmountToAdd); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnstakeValidator(message *typesUtil.MessageUnstakeValidator) types.Error { - status, err := u.GetValidatorStatus(message.Address) - if err != nil { - return err - } - // validate is staked - if status != typesUtil.StakedStatus { - return types.ErrInvalidStatus(status, typesUtil.StakedStatus) - } - unstakingHeight, err := u.CalculateValidatorUnstakingHeight() - if err != nil { - return err - } - if err := u.SetValidatorUnstakingHeightAndStatus(message.Address, unstakingHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) UnstakeValidatorsThatAreReady() types.Error { - - validatorsReadyToUnstake, err := u.GetValidatorsReadyToUnstake() - if err != nil { - return err - } - // If unstaking even a single validator fails, the whole operation falls through. - for _, validator := range validatorsReadyToUnstake { - if err := u.SubPoolAmount(typesGenesis.ValidatorStakePoolName, validator.GetStakeAmount()); err != nil { - return err - } - if err := u.AddAccountAmountString(validator.GetOutputAddress(), validator.GetStakeAmount()); err != nil { - return err - } - if err := u.DeleteValidator(validator.GetAddress()); err != nil { - return err - } - } - return nil -} - -func (u *UtilityContext) BeginUnstakingMaxPausedValidators() types.Error { - maxPausedBlocks, err := u.GetValidatorMaxPausedBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - beforeHeight := latestHeight - int64(maxPausedBlocks) - // genesis edge case - if beforeHeight < 0 { - beforeHeight = 0 - } - if err := u.UnstakeValidatorsPausedBefore(beforeHeight); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessagePauseValidator(message *typesUtil.MessagePauseValidator) types.Error { - height, err := u.GetValidatorPauseHeightIfExists(message.Address) - if err != nil { - return err - } - if height != typesUtil.HeightNotUsed { - return types.ErrAlreadyPaused() - } - height, err = u.GetLatestHeight() - if err != nil { - return err - } - if err := u.SetValidatorPauseHeight(message.Address, height); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageUnpauseValidator(message *typesUtil.MessageUnpauseValidator) types.Error { - pausedHeight, err := u.GetValidatorPauseHeightIfExists(message.Address) - if err != nil { - return err - } - if pausedHeight == typesUtil.HeightNotUsed { - return types.ErrNotPaused() - } - minPauseBlocks, err := u.GetValidatorMinimumPauseBlocks() - if err != nil { - return err - } - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - if latestHeight < int64(minPauseBlocks)+pausedHeight { - return types.ErrNotReadyToUnpause() - } - if err := u.SetValidatorPauseHeight(message.Address, typesUtil.HeightNotUsed); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleByzantineValidators(lastBlockByzantineValidators [][]byte) types.Error { - latestBlockHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - maxMissedBlocks, err := u.GetValidatorMaxMissedBlocks() - 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.SetValidatorPauseHeightAndMissedBlocks(address, latestBlockHeight, typesUtil.HeightNotUsed); err != nil { - return err - } - // burn validator for missing blocks - burnPercentage, err := u.GetMissedBlocksBurnPercentage() - if err != nil { - return err - } - if err := u.BurnValidator(address, burnPercentage); err != nil { - return err - } - } else if err := u.SetValidatorMissedBlocks(address, numberOfMissedBlocks); err != nil { - return err - } - } - return nil -} - -func (u *UtilityContext) HandleProposalRewards(proposer []byte) types.Error { - feesAndRewardsCollected, err := u.GetPoolAmount(typesGenesis.FeePoolName) - if err != nil { - return err - } - if err := u.SetPoolAmount(typesGenesis.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 types.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(typesGenesis.DAOPoolName, amountToDAO); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) HandleMessageDoubleSign(message *typesUtil.MessageDoubleSign) types.Error { - latestHeight, err := u.GetLatestHeight() - if err != nil { - return err - } - evidenceAge := latestHeight - message.VoteA.Height - maxEvidenceAge, err := u.GetMaxEvidenceAgeInBlocks() - if err != nil { - return err - } - if evidenceAge > int64(maxEvidenceAge) { - return types.ErrMaxEvidenceAge() - } - pk, er := crypto.NewPublicKeyFromBytes(message.VoteB.PublicKey) - if er != nil { - return types.ErrNewPublicKeyFromBytes(er) - } - doubleSigner := pk.Address() - // burn validator for double signing blocks - burnPercentage, err := u.GetDoubleSignBurnPercentage() - if err != nil { - return err - } - if err := u.BurnValidator(doubleSigner, burnPercentage); err != nil { - return err - } - return nil -} - -func (u *UtilityContext) BurnValidator(address []byte, percentage int) types.Error { - tokens, err := u.GetValidatorStakedTokens(address) - if err != nil { - return err - } - zeroBigInt := big.NewInt(0) - tokensFloat := new(big.Float).SetInt(tokens) - tokensFloat.Mul(tokensFloat, big.NewFloat(float64(percentage))) - tokensFloat.Quo(tokensFloat, big.NewFloat(100)) - truncatedTokens, _ := tokensFloat.Int(nil) - if truncatedTokens.Cmp(zeroBigInt) == -1 { - truncatedTokens = zeroBigInt - } - newTokensAfterBurn := big.NewInt(0).Sub(tokens, truncatedTokens) - // remove from pool - if err := u.SubPoolAmount(typesGenesis.ValidatorStakePoolName, types.BigIntToString(truncatedTokens)); err != nil { - return err - } - // remove from validator - if err := u.SetValidatorStakedTokens(address, newTokensAfterBurn); err != nil { - return err - } - // check to see if they fell below minimum stake - minStake, err := u.GetValidatorMinimumStake() - if err != nil { - return err - } - // fell below minimum stake - if minStake.Cmp(truncatedTokens) == 1 { - unstakingHeight, err := u.CalculateValidatorUnstakingHeight() - if err != nil { - return err - } - if err := u.SetValidatorUnstakingHeightAndStatus(address, unstakingHeight); err != nil { - return err - } - } - return nil -} - -func (u *UtilityContext) GetValidatorExists(address []byte) (bool, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return false, types.ErrGetExists(er) - } - exists, er := store.GetValidatorExists(address, height) - if er != nil { - return false, types.ErrGetExists(er) - } - return exists, nil -} - -func (u *UtilityContext) InsertValidator(address, publicKey, output []byte, serviceURL, amount string) types.Error { - store := u.Store() - err := store.InsertValidator(address, publicKey, output, false, typesUtil.StakedStatus, serviceURL, amount, typesUtil.HeightNotUsed, typesUtil.HeightNotUsed) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) UpdateValidator(address []byte, serviceURL, amount string) types.Error { - store := u.Store() - err := store.UpdateValidator(address, serviceURL, amount) - if err != nil { - return types.ErrInsert(err) - } - return nil -} - -func (u *UtilityContext) DeleteValidator(address []byte) types.Error { - store := u.Store() - if err := store.DeleteValidator(address); err != nil { - return types.ErrDelete(err) - } - return nil -} - -func (u *UtilityContext) GetValidatorsReadyToUnstake() ([]*types.UnstakingActor, types.Error) { - store := u.Store() - latestHeight, err := u.GetLatestHeight() - if err != nil { - return nil, err - } - unstakingValidators, er := store.GetValidatorsReadyToUnstake(latestHeight, typesUtil.UnstakingStatus) - if er != nil { - return nil, types.ErrGetReadyToUnstake(er) - } - return unstakingValidators, nil -} - -func (u *UtilityContext) UnstakeValidatorsPausedBefore(pausedBeforeHeight int64) types.Error { - store := u.Store() - unstakingHeight, err := u.CalculateValidatorUnstakingHeight() - if err != nil { - return err - } - er := store.SetValidatorsStatusAndUnstakingHeightIfPausedBefore(pausedBeforeHeight, unstakingHeight, typesUtil.UnstakingStatus) - if er != nil { - return types.ErrSetStatusPausedBefore(er, pausedBeforeHeight) - } - return nil -} - -func (u *UtilityContext) GetValidatorStatus(address []byte) (int, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - status, er := store.GetValidatorStatus(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetStatus(er) - } - return status, nil -} - -func (u *UtilityContext) SetValidatorMissedBlocks(address []byte, missedBlocks int) types.Error { - store := u.Store() - er := store.SetValidatorMissedBlocks(address, missedBlocks) - if er != nil { - return types.ErrSetMissedBlocks(er) - } - return nil -} - -func (u *UtilityContext) SetValidatorUnstakingHeightAndStatus(address []byte, unstakingHeight int64) types.Error { - store := u.Store() - if er := store.SetValidatorUnstakingHeightAndStatus(address, unstakingHeight, typesUtil.UnstakingStatus); er != nil { - return types.ErrSetUnstakingHeightAndStatus(er) - } - return nil -} - -func (u *UtilityContext) GetValidatorPauseHeightIfExists(address []byte) (int64, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - ValidatorPauseHeight, er := store.GetValidatorPauseHeightIfExists(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetPauseHeight(er) - } - return ValidatorPauseHeight, nil -} - -func (u *UtilityContext) SetValidatorPauseHeight(address []byte, height int64) types.Error { - store := u.Store() - if err := store.SetValidatorPauseHeight(address, height); err != nil { - return types.ErrSetPauseHeight(err) - } - return nil -} - -func (u *UtilityContext) CalculateValidatorUnstakingHeight() (int64, types.Error) { - unstakingBlocks, err := u.GetValidatorUnstakingBlocks() - if err != nil { - return typesUtil.ZeroInt, err - } - unstakingHeight, err := u.CalculateUnstakingHeight(unstakingBlocks) - if err != nil { - return typesUtil.ZeroInt, err - } - return unstakingHeight, nil -} - -func (u *UtilityContext) GetValidatorMissedBlocks(address []byte) (int, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return typesUtil.ZeroInt, types.ErrGetMissedBlocks(er) - } - missedBlocks, er := store.GetValidatorMissedBlocks(address, height) - if er != nil { - return typesUtil.ZeroInt, types.ErrGetMissedBlocks(er) - } - return missedBlocks, nil -} - -func (u *UtilityContext) GetValidatorStakedTokens(address []byte) (*big.Int, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return nil, types.ErrGetValidatorStakedTokens(er) - } - validatorStakedTokens, er := store.GetValidatorStakedTokens(address, height) - if er != nil { - return nil, types.ErrGetValidatorStakedTokens(er) - } - i, err := types.StringToBigInt(validatorStakedTokens) - if err != nil { - return nil, err - } - return i, nil -} - -func (u *UtilityContext) SetValidatorStakedTokens(address []byte, tokens *big.Int) types.Error { - store := u.Store() - er := store.SetValidatorStakedTokens(address, types.BigIntToString(tokens)) - if er != nil { - return types.ErrSetValidatorStakedTokens(er) - } - return nil -} - -func (u *UtilityContext) SetValidatorPauseHeightAndMissedBlocks(address []byte, pauseHeight int64, missedBlocks int) types.Error { - store := u.Store() - if err := store.SetValidatorPauseHeightAndMissedBlocks(address, pauseHeight, missedBlocks); err != nil { - return types.ErrSetPauseHeight(err) - } - return nil -} - -func (u *UtilityContext) GetMessageStakeValidatorSignerCandidates(msg *typesUtil.MessageStakeValidator) ([][]byte, types.Error) { - pk, er := crypto.NewPublicKeyFromBytes(msg.PublicKey) - if er != nil { - return nil, types.ErrNewPublicKeyFromBytes(er) - } - candidates := make([][]byte, 0) - candidates = append(candidates, msg.OutputAddress) - candidates = append(candidates, pk.Address()) - return candidates, nil -} - -func (u *UtilityContext) GetMessageEditStakeValidatorSignerCandidates(msg *typesUtil.MessageEditStakeValidator) ([][]byte, types.Error) { - output, err := u.GetValidatorOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnstakeValidatorSignerCandidates(msg *typesUtil.MessageUnstakeValidator) ([][]byte, types.Error) { - output, err := u.GetValidatorOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageUnpauseValidatorSignerCandidates(msg *typesUtil.MessageUnpauseValidator) ([][]byte, types.Error) { - output, err := u.GetValidatorOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessagePauseValidatorSignerCandidates(msg *typesUtil.MessagePauseValidator) ([][]byte, types.Error) { - output, err := u.GetValidatorOutputAddress(msg.Address) - if err != nil { - return nil, err - } - candidates := make([][]byte, 0) - candidates = append(candidates, output) - candidates = append(candidates, msg.Address) - return candidates, nil -} - -func (u *UtilityContext) GetMessageDoubleSignSignerCandidates(msg *typesUtil.MessageDoubleSign) ([][]byte, types.Error) { - return [][]byte{msg.ReporterAddress}, nil -} - -func (u *UtilityContext) GetValidatorOutputAddress(operator []byte) ([]byte, types.Error) { - store := u.Store() - height, er := store.GetHeight() - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - output, er := store.GetValidatorOutputAddress(operator, height) - if er != nil { - return nil, types.ErrGetOutputAddress(operator, er) - } - return output, nil -} - -func (u *UtilityContext) CalculateUnstakingHeight(unstakingBlocks int64) (int64, types.Error) { - latestHeight, err := u.GetLatestHeight() - if err != nil { - return typesUtil.ZeroInt, err - } - return unstakingBlocks + latestHeight, nil -}