From dc0e67039bb1dadee3a36d09dc0448ce789a0063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadej=20Jane=C5=BE?= Date: Tue, 26 May 2020 13:03:39 +0200 Subject: [PATCH] go: Transition staking code to use go/staking/api.Address --- .../tendermint/apps/keymanager/keymanager.go | 7 +- .../tendermint/apps/registry/registry.go | 4 +- .../tendermint/apps/registry/transactions.go | 26 +- .../tendermint/apps/roothash/roothash.go | 7 +- .../tendermint/apps/scheduler/genesis.go | 21 +- .../tendermint/apps/scheduler/scheduler.go | 34 ++- go/consensus/tendermint/apps/staking/auth.go | 4 +- go/consensus/tendermint/apps/staking/fees.go | 71 ++--- .../tendermint/apps/staking/genesis.go | 3 +- .../apps/staking/proposing_rewards.go | 11 +- go/consensus/tendermint/apps/staking/query.go | 27 +- .../apps/staking/signing_rewards.go | 12 +- .../tendermint/apps/staking/slashing.go | 3 +- .../tendermint/apps/staking/slashing_test.go | 7 +- .../tendermint/apps/staking/staking.go | 36 +-- .../apps/staking/state/accumulator.go | 61 +++-- .../apps/staking/state/accumulator_test.go | 25 +- .../tendermint/apps/staking/state/gas.go | 18 +- .../tendermint/apps/staking/state/state.go | 244 ++++++++++-------- .../apps/staking/state/state_test.go | 86 +++--- .../tendermint/apps/staking/transactions.go | 84 +++--- .../apps/staking/transactions_test.go | 21 +- .../apps/supplementarysanity/checks.go | 11 +- go/consensus/tendermint/staking/staking.go | 7 +- go/consensus/tendermint/tendermint.go | 6 +- go/genesis/genesis_test.go | 22 +- .../cmd/debug/consim/xfer_workload.go | 33 ++- go/oasis-node/cmd/debug/txsource/txsource.go | 2 +- .../cmd/debug/txsource/workload/commission.go | 19 +- .../cmd/debug/txsource/workload/delegation.go | 31 ++- .../cmd/debug/txsource/workload/oversized.go | 16 +- .../cmd/debug/txsource/workload/parallel.go | 14 +- .../cmd/debug/txsource/workload/transfer.go | 33 +-- .../cmd/debug/txsource/workload/workload.go | 31 ++- go/oasis-node/cmd/genesis/genesis.go | 11 +- go/oasis-node/cmd/stake/account.go | 21 +- go/oasis-node/cmd/stake/stake.go | 17 +- .../scenario/e2e/gas_fees_staking.go | 22 +- .../scenario/e2e/runtime_dynamic.go | 5 +- .../scenario/e2e/stake_cli.go | 4 +- go/registry/api/sanity_check.go | 34 +-- go/staking/api/api.go | 85 +++--- go/staking/api/grpc.go | 13 +- go/staking/api/sanity_check.go | 116 ++++++--- go/staking/gen_vectors/main.go | 9 +- go/staking/tests/debug/debug_stake.go | 18 +- go/staking/tests/tester.go | 140 +++++----- go/upgrade/migrations/dummy.go | 3 +- 48 files changed, 878 insertions(+), 657 deletions(-) diff --git a/go/consensus/tendermint/apps/keymanager/keymanager.go b/go/consensus/tendermint/apps/keymanager/keymanager.go index 2f83c1f297d..8fb5d183786 100644 --- a/go/consensus/tendermint/apps/keymanager/keymanager.go +++ b/go/consensus/tendermint/apps/keymanager/keymanager.go @@ -21,6 +21,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/keymanager/api" keymanager "github.com/oasisprotocol/oasis-core/go/keymanager/api" registry "github.com/oasisprotocol/oasis-core/go/registry/api" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) var emptyHashSha3 = sha3.Sum256(nil) @@ -123,10 +124,12 @@ func (app *keymanagerApplication) onEpochChange(ctx *tmapi.Context, epoch epocht // Suspend the runtime in case the registering entity no longer has enough stake to cover // the entity and runtime deposits. if !params.DebugBypassStake { - if err = stakeAcc.CheckStakeClaims(rt.EntityID); err != nil { + acctAddr := staking.NewFromPublicKey(rt.EntityID) + if err = stakeAcc.CheckStakeClaims(acctAddr); err != nil { ctx.Logger().Warn("insufficient stake for key manager runtime operation", "err", err, - "entity_id", rt.EntityID, + "entity", rt.EntityID, + "account", acctAddr, ) // Suspend runtime. diff --git a/go/consensus/tendermint/apps/registry/registry.go b/go/consensus/tendermint/apps/registry/registry.go index cc793f86793..a797666e2ec 100644 --- a/go/consensus/tendermint/apps/registry/registry.go +++ b/go/consensus/tendermint/apps/registry/registry.go @@ -18,6 +18,7 @@ import ( stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" epochtime "github.com/oasisprotocol/oasis-core/go/epochtime/api" registry "github.com/oasisprotocol/oasis-core/go/registry/api" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) var _ abci.Application = (*registryApplication)(nil) @@ -190,7 +191,8 @@ func (app *registryApplication) onRegistryEpochChanged(ctx *api.Context, registr // Remove the stake claim for the given node. if !params.DebugBypassStake { - if err = stakeAcc.RemoveStakeClaim(node.EntityID, registry.StakeClaimForNode(node.ID)); err != nil { + acctAddr := staking.NewFromPublicKey(node.EntityID) + if err = stakeAcc.RemoveStakeClaim(acctAddr, registry.StakeClaimForNode(node.ID)); err != nil { return fmt.Errorf("registry: onRegistryEpochChanged: couldn't remove stake claim: %w", err) } } diff --git a/go/consensus/tendermint/apps/registry/transactions.go b/go/consensus/tendermint/apps/registry/transactions.go index 263b166f313..39ae016b54d 100644 --- a/go/consensus/tendermint/apps/registry/transactions.go +++ b/go/consensus/tendermint/apps/registry/transactions.go @@ -50,10 +50,12 @@ func (app *registryApplication) registerEntity( } if !params.DebugBypassStake { - if err = stakingState.AddStakeClaim(ctx, ent.ID, registry.StakeClaimRegisterEntity, []staking.ThresholdKind{staking.KindEntity}); err != nil { - ctx.Logger().Error("RegisterEntity: Insufficent stake", + acctAddr := staking.NewFromPublicKey(ent.ID) + if err = stakingState.AddStakeClaim(ctx, acctAddr, registry.StakeClaimRegisterEntity, []staking.ThresholdKind{staking.KindEntity}); err != nil { + ctx.Logger().Error("RegisterEntity: Insufficient stake", "err", err, - "id", ent.ID, + "entity", ent.ID, + "account", acctAddr, ) return err } @@ -130,7 +132,8 @@ func (app *registryApplication) deregisterEntity(ctx *api.Context, state *regist } if !params.DebugBypassStake { - if err = stakingState.RemoveStakeClaim(ctx, id, registry.StakeClaimRegisterEntity); err != nil { + acctAddr := staking.NewFromPublicKey(id) + if err = stakingState.RemoveStakeClaim(ctx, acctAddr, registry.StakeClaimRegisterEntity); err != nil { panic(fmt.Errorf("DeregisterEntity: failed to remove stake claim: %w", err)) } } @@ -307,11 +310,13 @@ func (app *registryApplication) registerNode( // nolint: gocyclo claim := registry.StakeClaimForNode(newNode.ID) thresholds := registry.StakeThresholdsForNode(newNode) + acctAddr := staking.NewFromPublicKey(newNode.EntityID) - if err = stakeAcc.AddStakeClaim(newNode.EntityID, claim, thresholds); err != nil { + if err = stakeAcc.AddStakeClaim(acctAddr, claim, thresholds); err != nil { ctx.Logger().Error("RegisterNode: insufficient stake for new node", "err", err, "entity", newNode.EntityID, + "account", acctAddr, ) return err } @@ -381,7 +386,8 @@ func (app *registryApplication) registerNode( // nolint: gocyclo // Only resume a runtime if the entity has enough stake to avoid having the runtime be // suspended again on the next epoch transition. if !params.DebugBypassStake { - if err = stakeAcc.CheckStakeClaims(rt.EntityID); err != nil { + acctAddr := staking.NewFromPublicKey(rt.EntityID) + if err = stakeAcc.CheckStakeClaims(acctAddr); err != nil { continue } } @@ -579,11 +585,13 @@ func (app *registryApplication) registerRuntime( // nolint: gocyclo if !params.DebugBypassStake { claim := registry.StakeClaimForRuntime(rt.ID) thresholds := registry.StakeThresholdsForRuntime(rt) + acctAddr := staking.NewFromPublicKey(rt.EntityID) - if err = stakingState.AddStakeClaim(ctx, rt.EntityID, claim, thresholds); err != nil { - ctx.Logger().Error("RegisterRuntime: Insufficent stake", + if err = stakingState.AddStakeClaim(ctx, acctAddr, claim, thresholds); err != nil { + ctx.Logger().Error("RegisterRuntime: Insufficient stake", "err", err, - "entity_id", rt.EntityID, + "entity", rt.EntityID, + "account", acctAddr, ) return err } diff --git a/go/consensus/tendermint/apps/roothash/roothash.go b/go/consensus/tendermint/apps/roothash/roothash.go index 5e5b6def619..e3ebac1a770 100644 --- a/go/consensus/tendermint/apps/roothash/roothash.go +++ b/go/consensus/tendermint/apps/roothash/roothash.go @@ -29,6 +29,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/roothash/api/block" "github.com/oasisprotocol/oasis-core/go/roothash/api/commitment" scheduler "github.com/oasisprotocol/oasis-core/go/scheduler/api" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) // timerKindRound is the round timer kind. @@ -135,10 +136,12 @@ func (app *rootHashApplication) onCommitteeChanged(ctx *tmapi.Context, epoch epo // suspended anyway due to nobody being there to pay maintenance fees). sufficientStake := true if !empty && !params.DebugBypassStake { - if err = stakeAcc.CheckStakeClaims(rt.EntityID); err != nil { + acctAddr := staking.NewFromPublicKey(rt.EntityID) + if err = stakeAcc.CheckStakeClaims(acctAddr); err != nil { ctx.Logger().Warn("insufficient stake for runtime operation", "err", err, - "entity_id", rt.EntityID, + "entity", rt.EntityID, + "account", acctAddr, ) sufficientStake = false } diff --git a/go/consensus/tendermint/apps/scheduler/genesis.go b/go/consensus/tendermint/apps/scheduler/genesis.go index 700c1ab02e2..ad821984857 100644 --- a/go/consensus/tendermint/apps/scheduler/genesis.go +++ b/go/consensus/tendermint/apps/scheduler/genesis.go @@ -134,16 +134,19 @@ func (app *schedulerApplication) InitChain(ctx *abciAPI.Context, req types.Reque expectedPower = 1 } else { var account *staking.Account - account, err = stakeState.Account(ctx, n.EntityID) + acctAddr := staking.NewFromPublicKey(n.EntityID) + account, err = stakeState.Account(ctx, acctAddr) if err != nil { ctx.Logger().Error("couldn't get account for genesis validator entity", "err", err, - "node_id", n.ID, - "entity_id", n.EntityID, + "node", n.ID, + "entity", n.EntityID, + "accont", acctAddr, ) - return fmt.Errorf("scheduler: getting account %s for genesis validator %s entity: %w", - n.EntityID, + return fmt.Errorf("scheduler: getting account %s for genesis validator %s of entity %s: %w", + acctAddr, n.ID, + n.EntityID, err, ) } @@ -151,13 +154,15 @@ func (app *schedulerApplication) InitChain(ctx *abciAPI.Context, req types.Reque if err != nil { ctx.Logger().Error("computing voting power from tokens failed", "err", err, - "node_id", n.ID, - "entity_id", n.EntityID, + "node", n.ID, + "entity", n.EntityID, + "account", acctAddr, "tokens", &account.Escrow.Active.Balance, ) - return fmt.Errorf("scheduler: getting computing voting power from tokens (node %s entity %s tokens %v): %w", + return fmt.Errorf("scheduler: getting computing voting power from tokens (node %s entity %s account %s tokens %v): %w", n.ID, n.EntityID, + acctAddr, &account.Escrow.Active.Balance, err, ) diff --git a/go/consensus/tendermint/apps/scheduler/scheduler.go b/go/consensus/tendermint/apps/scheduler/scheduler.go index fd979b481cc..b577975e400 100644 --- a/go/consensus/tendermint/apps/scheduler/scheduler.go +++ b/go/consensus/tendermint/apps/scheduler/scheduler.go @@ -30,6 +30,7 @@ import ( epochtime "github.com/oasisprotocol/oasis-core/go/epochtime/api" registry "github.com/oasisprotocol/oasis-core/go/registry/api" scheduler "github.com/oasisprotocol/oasis-core/go/scheduler/api" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) var ( @@ -194,9 +195,13 @@ func (app *schedulerApplication) BeginBlock(ctx *api.Context, request types.Requ ) if entitiesEligibleForReward != nil { - accounts := publicKeyMapToSortedSlice(entitiesEligibleForReward) + accountAddrs := []staking.Address{} + for _, entity := range publicKeyMapToSortedSlice(entitiesEligibleForReward) { + accountAddrs = append(accountAddrs, staking.NewFromPublicKey(entity)) + } + stakingSt := stakingState.NewMutableState(ctx.State()) - if err = stakingSt.AddRewards(ctx, epoch, ¶ms.RewardFactorEpochElectionAny, accounts); err != nil { + if err = stakingSt.AddRewards(ctx, epoch, ¶ms.RewardFactorEpochElectionAny, accountAddrs); err != nil { return fmt.Errorf("tendermint/scheduler: failed to add rewards: %w", err) } } @@ -428,8 +433,9 @@ func (app *schedulerApplication) electCommittee( for _, n := range nodes { // Check if an entity has enough stake. + acctAddr := staking.NewFromPublicKey(n.EntityID) if stakeAcc != nil { - if err = stakeAcc.CheckStakeClaims(n.EntityID); err != nil { + if err = stakeAcc.CheckStakeClaims(acctAddr); err != nil { continue } } @@ -554,7 +560,8 @@ func (app *schedulerApplication) electValidators( continue } if stakeAcc != nil { - if err := stakeAcc.CheckStakeClaims(n.EntityID); err != nil { + acctAddr := staking.NewFromPublicKey(n.EntityID) + if err := stakeAcc.CheckStakeClaims(acctAddr); err != nil { continue } } @@ -621,13 +628,20 @@ electLoop: power = 1 } else { var stake *quantity.Quantity - stake, err = stakeAcc.GetEscrowBalance(v) + acctAddr := staking.NewFromPublicKey(v) + stake, err = stakeAcc.GetEscrowBalance(acctAddr) if err != nil { - return fmt.Errorf("failed to fetch escrow balance for entity %s: %w", v, err) + return fmt.Errorf( + "failed to fetch escrow balance for entity %s with account %s: %w", + v, acctAddr, err, + ) } power, err = scheduler.VotingPowerFromTokens(stake) if err != nil { - return fmt.Errorf("computing voting power for entity %s with balance %v: %w", v, stake, err) + return fmt.Errorf( + "computing voting power for entity %s with balance %v: %w", + v, stake, err, + ) } } @@ -683,12 +697,14 @@ func publicKeyMapToSliceByStake( // Stable-sort the shuffled slice by descending escrow balance. var balanceErr error sort.SliceStable(entities, func(i, j int) bool { - iBal, err := stakeAcc.GetEscrowBalance(entities[i]) + iAcctAddr := staking.NewFromPublicKey(entities[i]) + iBal, err := stakeAcc.GetEscrowBalance(iAcctAddr) if err != nil { balanceErr = err return false } - jBal, err := stakeAcc.GetEscrowBalance(entities[j]) + jAcctAddr := staking.NewFromPublicKey(entities[j]) + jBal, err := stakeAcc.GetEscrowBalance(jAcctAddr) if err != nil { balanceErr = err return false diff --git a/go/consensus/tendermint/apps/staking/auth.go b/go/consensus/tendermint/apps/staking/auth.go index 4249a337267..8b7ebb0599c 100644 --- a/go/consensus/tendermint/apps/staking/auth.go +++ b/go/consensus/tendermint/apps/staking/auth.go @@ -8,6 +8,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/abci" abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) var _ abci.TransactionAuthHandler = (*stakingApplication)(nil) @@ -19,7 +20,8 @@ func (app *stakingApplication) GetSignerNonce(ctx context.Context, req *api.GetS return 0, err } - acct, err := q.AccountInfo(ctx, req.ID) + addr := staking.NewFromPublicKey(req.ID) + acct, err := q.AccountInfo(ctx, addr) if err != nil { return 0, err } diff --git a/go/consensus/tendermint/apps/staking/fees.go b/go/consensus/tendermint/apps/staking/fees.go index 0d09ab33a7d..50f68226dd2 100644 --- a/go/consensus/tendermint/apps/staking/fees.go +++ b/go/consensus/tendermint/apps/staking/fees.go @@ -64,21 +64,22 @@ func (app *stakingApplication) disburseFeesP( // Pay the proposer. feeProposerAmt := totalFees.Clone() if proposerEntity != nil { - acct, err := stakeState.Account(ctx, *proposerEntity) + proposerAddr := staking.NewFromPublicKey(*proposerEntity) + proposerAcct, err := stakeState.Account(ctx, proposerAddr) if err != nil { return fmt.Errorf("failed to fetch proposer account: %w", err) } - if err = quantity.Move(&acct.General.Balance, totalFees, feeProposerAmt); err != nil { + if err = quantity.Move(&proposerAcct.General.Balance, totalFees, feeProposerAmt); err != nil { return fmt.Errorf("move feeProposerAmt: %w", err) } - if err = stakeState.SetAccount(ctx, *proposerEntity, acct); err != nil { + if err = stakeState.SetAccount(ctx, proposerAddr, proposerAcct); err != nil { return fmt.Errorf("failed to set account: %w", err) } // Emit transfer event. evt := &staking.TransferEvent{ - From: staking.FeeAccumulatorAccountID, - To: *proposerEntity, + From: staking.FeeAccumulatorAddress, + To: proposerAddr, Tokens: *feeProposerAmt, } ctx.EmitEvent(abciAPI.NewEventBuilder(app.Name()).Attribute(KeyTransfer, cbor.Marshal(evt))) @@ -100,8 +101,8 @@ func (app *stakingApplication) disburseFeesP( // Emit transfer event. evt := &staking.TransferEvent{ - From: staking.FeeAccumulatorAccountID, - To: staking.CommonPoolAccountID, + From: staking.FeeAccumulatorAddress, + To: staking.CommonPoolAddress, Tokens: *remaining, } ctx.EmitEvent(abciAPI.NewEventBuilder(app.Name()).Attribute(KeyTransfer, cbor.Marshal(evt))) @@ -178,47 +179,47 @@ func (app *stakingApplication) disburseFeesVQ( } // Pay the next proposer. - if !nextProposerTotal.IsZero() { - if proposerEntity != nil { - acct, err := stakeState.Account(ctx, *proposerEntity) - if err != nil { - return fmt.Errorf("failed to fetch next proposer account: %w", err) - } - if err = quantity.Move(&acct.General.Balance, lastBlockFees, nextProposerTotal); err != nil { - return fmt.Errorf("move nextProposerTotal: %w", err) - } - if err = stakeState.SetAccount(ctx, *proposerEntity, acct); err != nil { - return fmt.Errorf("failed to set next proposer account: %w", err) - } + if !nextProposerTotal.IsZero() && proposerEntity != nil { + proposerAddr := staking.NewFromPublicKey(*proposerEntity) + proposerAcct, err := stakeState.Account(ctx, proposerAddr) + if err != nil { + return fmt.Errorf("failed to fetch next proposer account: %w", err) + } + if err = quantity.Move(&proposerAcct.General.Balance, lastBlockFees, nextProposerTotal); err != nil { + return fmt.Errorf("move nextProposerTotal: %w", err) + } + if err = stakeState.SetAccount(ctx, proposerAddr, proposerAcct); err != nil { + return fmt.Errorf("failed to set next proposer account: %w", err) + } - // Emit transfer event. - evt := &staking.TransferEvent{ - From: staking.FeeAccumulatorAccountID, - To: *proposerEntity, - Tokens: *nextProposerTotal, - } - ctx.EmitEvent(abciAPI.NewEventBuilder(app.Name()).Attribute(KeyTransfer, cbor.Marshal(evt))) + // Emit transfer event. + evt := &staking.TransferEvent{ + From: staking.FeeAccumulatorAddress, + To: proposerAddr, + Tokens: *nextProposerTotal, } + ctx.EmitEvent(abciAPI.NewEventBuilder(app.Name()).Attribute(KeyTransfer, cbor.Marshal(evt))) } // Pay the voters. if !shareVote.IsZero() { for _, voterEntity := range votingEntities { - acct, err := stakeState.Account(ctx, voterEntity) + voterAddr := staking.NewFromPublicKey(voterEntity) + voterAcct, err := stakeState.Account(ctx, voterAddr) if err != nil { - return fmt.Errorf("failed to fetch voter %s account: %w", voterEntity, err) + return fmt.Errorf("failed to fetch voter account %s: %w", voterAddr, err) } - if err = quantity.Move(&acct.General.Balance, lastBlockFees, shareVote); err != nil { + if err = quantity.Move(&voterAcct.General.Balance, lastBlockFees, shareVote); err != nil { return fmt.Errorf("move shareVote: %w", err) } - if err = stakeState.SetAccount(ctx, voterEntity, acct); err != nil { - return fmt.Errorf("failed to set voter %s account: %w", voterEntity, err) + if err = stakeState.SetAccount(ctx, voterAddr, voterAcct); err != nil { + return fmt.Errorf("failed to set voter account %s: %w", voterAddr, err) } // Emit transfer event. evt := &staking.TransferEvent{ - From: staking.FeeAccumulatorAccountID, - To: voterEntity, + From: staking.FeeAccumulatorAddress, + To: voterAddr, Tokens: *shareVote, } ctx.EmitEvent(abciAPI.NewEventBuilder(app.Name()).Attribute(KeyTransfer, cbor.Marshal(evt))) @@ -241,8 +242,8 @@ func (app *stakingApplication) disburseFeesVQ( // Emit transfer event. evt := &staking.TransferEvent{ - From: staking.FeeAccumulatorAccountID, - To: staking.CommonPoolAccountID, + From: staking.FeeAccumulatorAddress, + To: staking.CommonPoolAddress, Tokens: *remaining, } ctx.EmitEvent(abciAPI.NewEventBuilder(app.Name()).Attribute(KeyTransfer, cbor.Marshal(evt))) diff --git a/go/consensus/tendermint/apps/staking/genesis.go b/go/consensus/tendermint/apps/staking/genesis.go index 1916b48e30f..e0a67ba89a0 100644 --- a/go/consensus/tendermint/apps/staking/genesis.go +++ b/go/consensus/tendermint/apps/staking/genesis.go @@ -6,7 +6,6 @@ import ( "github.com/tendermint/tendermint/abci/types" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/quantity" abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" @@ -292,7 +291,7 @@ func (sq *stakingQuerier) Genesis(ctx context.Context) (*staking.Genesis, error) if err != nil { return nil, err } - ledger := make(map[signature.PublicKey]*staking.Account) + ledger := make(map[staking.Address]*staking.Account) for _, acctID := range accounts { var acct *staking.Account acct, err = sq.state.Account(ctx, acctID) diff --git a/go/consensus/tendermint/apps/staking/proposing_rewards.go b/go/consensus/tendermint/apps/staking/proposing_rewards.go index 64a3896fac2..b837f1ea0da 100644 --- a/go/consensus/tendermint/apps/staking/proposing_rewards.go +++ b/go/consensus/tendermint/apps/staking/proposing_rewards.go @@ -11,6 +11,7 @@ import ( registryState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/registry/state" stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" epochtime "github.com/oasisprotocol/oasis-core/go/epochtime/api" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) func (app *stakingApplication) resolveEntityIDFromProposer( @@ -40,6 +41,7 @@ func (app *stakingApplication) rewardBlockProposing( if proposingEntity == nil { return nil } + proposerAddr := staking.NewFromPublicKey(*proposingEntity) params, err := stakeState.ConsensusParameters(ctx) if err != nil { @@ -56,7 +58,14 @@ func (app *stakingApplication) rewardBlockProposing( return nil } // Reward the proposer based on the `(number of included votes) / (size of the validator set)` ratio. - if err = stakeState.AddRewardSingleAttenuated(ctx, epoch, ¶ms.RewardFactorBlockProposed, numSigningEntities, numEligibleValidators, *proposingEntity); err != nil { + if err = stakeState.AddRewardSingleAttenuated( + ctx, + epoch, + ¶ms.RewardFactorBlockProposed, + numSigningEntities, + numEligibleValidators, + proposerAddr, + ); err != nil { return fmt.Errorf("adding rewards: %w", err) } return nil diff --git a/go/consensus/tendermint/apps/staking/query.go b/go/consensus/tendermint/apps/staking/query.go index efc8cebeaeb..c2649764376 100644 --- a/go/consensus/tendermint/apps/staking/query.go +++ b/go/consensus/tendermint/apps/staking/query.go @@ -3,7 +3,6 @@ package staking import ( "context" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/quantity" abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" @@ -18,10 +17,10 @@ type Query interface { LastBlockFees(context.Context) (*quantity.Quantity, error) Threshold(context.Context, staking.ThresholdKind) (*quantity.Quantity, error) DebondingInterval(context.Context) (epochtime.EpochTime, error) - Accounts(context.Context) ([]signature.PublicKey, error) - AccountInfo(context.Context, signature.PublicKey) (*staking.Account, error) - Delegations(context.Context, signature.PublicKey) (map[signature.PublicKey]*staking.Delegation, error) - DebondingDelegations(context.Context, signature.PublicKey) (map[signature.PublicKey][]*staking.DebondingDelegation, error) + Accounts(context.Context) ([]staking.Address, error) + AccountInfo(context.Context, staking.Address) (*staking.Account, error) + Delegations(context.Context, staking.Address) (map[staking.Address]*staking.Delegation, error) + DebondingDelegations(context.Context, staking.Address) (map[staking.Address][]*staking.DebondingDelegation, error) Genesis(context.Context) (*staking.Genesis, error) ConsensusParameters(context.Context) (*staking.ConsensusParameters, error) } @@ -73,13 +72,13 @@ func (sq *stakingQuerier) DebondingInterval(ctx context.Context) (epochtime.Epoc return sq.state.DebondingInterval(ctx) } -func (sq *stakingQuerier) Accounts(ctx context.Context) ([]signature.PublicKey, error) { +func (sq *stakingQuerier) Accounts(ctx context.Context) ([]staking.Address, error) { return sq.state.Accounts(ctx) } -func (sq *stakingQuerier) AccountInfo(ctx context.Context, id signature.PublicKey) (*staking.Account, error) { +func (sq *stakingQuerier) AccountInfo(ctx context.Context, addr staking.Address) (*staking.Account, error) { switch { - case id.Equal(staking.CommonPoolAccountID): + case addr.Equal(staking.CommonPoolAddress): cp, err := sq.state.CommonPool(ctx) if err != nil { return nil, err @@ -89,7 +88,7 @@ func (sq *stakingQuerier) AccountInfo(ctx context.Context, id signature.PublicKe Balance: *cp, }, }, nil - case id.Equal(staking.FeeAccumulatorAccountID): + case addr.Equal(staking.FeeAccumulatorAddress): fa, err := sq.state.LastBlockFees(ctx) if err != nil { return nil, err @@ -100,16 +99,16 @@ func (sq *stakingQuerier) AccountInfo(ctx context.Context, id signature.PublicKe }, }, nil default: - return sq.state.Account(ctx, id) + return sq.state.Account(ctx, addr) } } -func (sq *stakingQuerier) Delegations(ctx context.Context, id signature.PublicKey) (map[signature.PublicKey]*staking.Delegation, error) { - return sq.state.DelegationsFor(ctx, id) +func (sq *stakingQuerier) Delegations(ctx context.Context, addr staking.Address) (map[staking.Address]*staking.Delegation, error) { + return sq.state.DelegationsFor(ctx, addr) } -func (sq *stakingQuerier) DebondingDelegations(ctx context.Context, id signature.PublicKey) (map[signature.PublicKey][]*staking.DebondingDelegation, error) { - return sq.state.DebondingDelegationsFor(ctx, id) +func (sq *stakingQuerier) DebondingDelegations(ctx context.Context, addr staking.Address) (map[staking.Address][]*staking.DebondingDelegation, error) { + return sq.state.DebondingDelegationsFor(ctx, addr) } func (sq *stakingQuerier) ConsensusParameters(ctx context.Context) (*staking.ConsensusParameters, error) { diff --git a/go/consensus/tendermint/apps/staking/signing_rewards.go b/go/consensus/tendermint/apps/staking/signing_rewards.go index 9e1d811e35d..e0bc35a014a 100644 --- a/go/consensus/tendermint/apps/staking/signing_rewards.go +++ b/go/consensus/tendermint/apps/staking/signing_rewards.go @@ -7,6 +7,7 @@ import ( abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" epochtime "github.com/oasisprotocol/oasis-core/go/epochtime/api" + staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) func (app *stakingApplication) updateEpochSigning( @@ -57,12 +58,19 @@ func (app *stakingApplication) rewardEpochSigning(ctx *abciAPI.Context, time epo return nil } - eligibleEntities, err := epochSigning.EligibleEntities(params.SigningRewardThresholdNumerator, params.SigningRewardThresholdDenominator) + eligibleEntities, err := epochSigning.EligibleEntities( + params.SigningRewardThresholdNumerator, + params.SigningRewardThresholdDenominator, + ) if err != nil { return fmt.Errorf("determining eligibility: %w", err) } + eligibleEntitiesAddrs := []staking.Address{} + for _, entity := range eligibleEntities { + eligibleEntitiesAddrs = append(eligibleEntitiesAddrs, staking.NewFromPublicKey(entity)) + } - if err := stakeState.AddRewards(ctx, time, ¶ms.RewardFactorEpochSigned, eligibleEntities); err != nil { + if err := stakeState.AddRewards(ctx, time, ¶ms.RewardFactorEpochSigned, eligibleEntitiesAddrs); err != nil { return fmt.Errorf("adding rewards: %w", err) } diff --git a/go/consensus/tendermint/apps/staking/slashing.go b/go/consensus/tendermint/apps/staking/slashing.go index 0862a13c868..986596cbb8f 100644 --- a/go/consensus/tendermint/apps/staking/slashing.go +++ b/go/consensus/tendermint/apps/staking/slashing.go @@ -86,7 +86,8 @@ func onEvidenceDoubleSign( } // Slash validator. - _, err = stakeState.SlashEscrow(ctx, node.EntityID, &penalty.Amount) + entityAddr := staking.NewFromPublicKey(node.EntityID) + _, err = stakeState.SlashEscrow(ctx, entityAddr, &penalty.Amount) if err != nil { ctx.Logger().Error("failed to slash validator entity", "err", err, diff --git a/go/consensus/tendermint/apps/staking/slashing_test.go b/go/consensus/tendermint/apps/staking/slashing_test.go index 1dba219d64b..c672be585e4 100644 --- a/go/consensus/tendermint/apps/staking/slashing_test.go +++ b/go/consensus/tendermint/apps/staking/slashing_test.go @@ -92,12 +92,15 @@ func TestOnEvidenceDoubleSign(t *testing.T) { err = onEvidenceDoubleSign(ctx, validatorAddress, 1, now, 1) require.Error(err, "should fail when validator has no stake") + // Computes entity's staking address. + addr := staking.NewFromPublicKey(ent.ID) + // Get the validator some stake. var balance quantity.Quantity _ = balance.FromUint64(200) var totalShares quantity.Quantity _ = totalShares.FromUint64(200) - err = stakeState.SetAccount(ctx, ent.ID, &staking.Account{ + err = stakeState.SetAccount(ctx, addr, &staking.Account{ Escrow: staking.EscrowAccount{ Active: staking.SharePool{ Balance: balance, @@ -112,7 +115,7 @@ func TestOnEvidenceDoubleSign(t *testing.T) { require.NoError(err, "slashing should succeed") // Entity stake should be slashed. - acct, err := stakeState.Account(ctx, ent.ID) + acct, err := stakeState.Account(ctx, addr) require.NoError(err, "Account") _ = balance.Sub(&slashAmount) require.EqualValues(balance, acct.Escrow.Active.Balance, "entity stake should be slashed") diff --git a/go/consensus/tendermint/apps/staking/staking.go b/go/consensus/tendermint/apps/staking/staking.go index c9319bd9dc2..0573ed55093 100644 --- a/go/consensus/tendermint/apps/staking/staking.go +++ b/go/consensus/tendermint/apps/staking/staking.go @@ -171,17 +171,17 @@ func (app *stakingApplication) onEpochChange(ctx *api.Context, epoch epochtime.E for _, e := range expiredDebondingQueue { deb := e.Delegation shareAmount := deb.Shares.Clone() - delegator, err := state.Account(ctx, e.DelegatorID) + delegator, err := state.Account(ctx, e.DelegatorAddr) if err != nil { return fmt.Errorf("failed to query delegator account: %w", err) } // NOTE: Could be the same account, so make sure to not have two duplicate // copies of it and overwrite it later. var escrow *staking.Account - if e.DelegatorID.Equal(e.EscrowID) { + if e.DelegatorAddr.Equal(e.EscrowAddr) { escrow = delegator } else { - escrow, err = state.Account(ctx, e.EscrowID) + escrow, err = state.Account(ctx, e.EscrowAddr) if err != nil { return fmt.Errorf("failed to query escrow account: %w", err) } @@ -191,8 +191,8 @@ func (app *stakingApplication) onEpochChange(ctx *api.Context, epoch epochtime.E if err = escrow.Escrow.Debonding.Withdraw(&tokens, &deb.Shares, shareAmount); err != nil { ctx.Logger().Error("failed to redeem debonding shares", "err", err, - "escrow_id", e.EscrowID, - "delegator_id", e.DelegatorID, + "escrow_addr", e.EscrowAddr, + "delegator_addr", e.DelegatorAddr, "shares", deb.Shares, ) return fmt.Errorf("staking/tendermint: failed to redeem debonding shares: %w", err) @@ -202,38 +202,38 @@ func (app *stakingApplication) onEpochChange(ctx *api.Context, epoch epochtime.E if err = quantity.Move(&delegator.General.Balance, &tokens, tokenAmount); err != nil { ctx.Logger().Error("failed to move debonded tokens", "err", err, - "escrow_id", e.EscrowID, - "delegator_id", e.DelegatorID, + "escrow_addr", e.EscrowAddr, + "delegator_addr", e.DelegatorAddr, "shares", deb.Shares, ) return fmt.Errorf("staking/tendermint: failed to redeem debonding shares: %w", err) } // Update state. - if err = state.RemoveFromDebondingQueue(ctx, e.Epoch, e.DelegatorID, e.EscrowID, e.Seq); err != nil { + if err = state.RemoveFromDebondingQueue(ctx, e.Epoch, e.DelegatorAddr, e.EscrowAddr, e.Seq); err != nil { return fmt.Errorf("failed to remove from debonding queue: %w", err) } - if err = state.SetDebondingDelegation(ctx, e.DelegatorID, e.EscrowID, e.Seq, nil); err != nil { + if err = state.SetDebondingDelegation(ctx, e.DelegatorAddr, e.EscrowAddr, e.Seq, nil); err != nil { return fmt.Errorf("failed to set debonding delegation: %w", err) } - if err = state.SetAccount(ctx, e.DelegatorID, delegator); err != nil { - return fmt.Errorf("failed to set delegator (%s) account: %w", e.DelegatorID, err) + if err = state.SetAccount(ctx, e.DelegatorAddr, delegator); err != nil { + return fmt.Errorf("failed to set delegator (%s) account: %w", e.DelegatorAddr, err) } - if !e.DelegatorID.Equal(e.EscrowID) { - if err = state.SetAccount(ctx, e.EscrowID, escrow); err != nil { - return fmt.Errorf("failed to set escrow (%s) account: %w", e.EscrowID, err) + if !e.DelegatorAddr.Equal(e.EscrowAddr) { + if err = state.SetAccount(ctx, e.EscrowAddr, escrow); err != nil { + return fmt.Errorf("failed to set escrow (%s) account: %w", e.EscrowAddr, err) } } ctx.Logger().Debug("released tokens", - "escrow_id", e.EscrowID, - "delegator_id", e.DelegatorID, + "escrow_addr", e.EscrowAddr, + "delegator_addr", e.DelegatorAddr, "amount", tokenAmount, ) evt := staking.ReclaimEscrowEvent{ - Owner: e.DelegatorID, - Escrow: e.EscrowID, + Owner: e.DelegatorAddr, + Escrow: e.EscrowAddr, Tokens: *tokenAmount, } ctx.EmitEvent(api.NewEventBuilder(app.Name()).Attribute(KeyReclaimEscrow, cbor.Marshal(evt))) diff --git a/go/consensus/tendermint/apps/staking/state/accumulator.go b/go/consensus/tendermint/apps/staking/state/accumulator.go index 697b6b3e6eb..f99b9395569 100644 --- a/go/consensus/tendermint/apps/staking/state/accumulator.go +++ b/go/consensus/tendermint/apps/staking/state/accumulator.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/quantity" abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" staking "github.com/oasisprotocol/oasis-core/go/staking/api" @@ -18,32 +17,32 @@ type StakeAccumulatorCache struct { state *MutableState // accounts is a map of staking accounts that we are changing. - accounts map[signature.PublicKey]*staking.Account + accounts map[staking.Address]*staking.Account // thresholds is a cache of the threshold map. thresholds map[staking.ThresholdKind]quantity.Quantity } -func (c *StakeAccumulatorCache) getAccount(id signature.PublicKey) (*staking.Account, error) { +func (c *StakeAccumulatorCache) getAccount(addr staking.Address) (*staking.Account, error) { if c.accounts == nil { - c.accounts = make(map[signature.PublicKey]*staking.Account) + c.accounts = make(map[staking.Address]*staking.Account) } - if a := c.accounts[id]; a != nil { + if a := c.accounts[addr]; a != nil { return a, nil } - a, err := c.state.Account(c.ctx, id) + a, err := c.state.Account(c.ctx, addr) if err != nil { return nil, err } - c.accounts[id] = a + c.accounts[addr] = a return a, nil } // CheckStakeClaims checks whether the escrow account balance satisfies all the stake claims. -func (c *StakeAccumulatorCache) CheckStakeClaims(id signature.PublicKey) error { - acct, err := c.getAccount(id) +func (c *StakeAccumulatorCache) CheckStakeClaims(addr staking.Address) error { + acct, err := c.getAccount(addr) if err != nil { return err } @@ -52,10 +51,14 @@ func (c *StakeAccumulatorCache) CheckStakeClaims(id signature.PublicKey) error { // AddStakeClaim attempts to add a stake claim to the given escrow account. // -// In case there is insufficient stake to cover the claim or an error occurrs, no modifications are +// In case there is insufficient stake to cover the claim or an error occurs, no modifications are // made to the stake accumulator. -func (c *StakeAccumulatorCache) AddStakeClaim(id signature.PublicKey, claim staking.StakeClaim, thresholds []staking.ThresholdKind) error { - acct, err := c.getAccount(id) +func (c *StakeAccumulatorCache) AddStakeClaim( + addr staking.Address, + claim staking.StakeClaim, + thresholds []staking.ThresholdKind, +) error { + acct, err := c.getAccount(addr) if err != nil { return err } @@ -65,8 +68,11 @@ func (c *StakeAccumulatorCache) AddStakeClaim(id signature.PublicKey, claim stak // RemoveStakeClaim removes a given stake claim. // // It is an error if the stake claim does not exist. -func (c *StakeAccumulatorCache) RemoveStakeClaim(id signature.PublicKey, claim staking.StakeClaim) error { - acct, err := c.getAccount(id) +func (c *StakeAccumulatorCache) RemoveStakeClaim( + addr staking.Address, + claim staking.StakeClaim, +) error { + acct, err := c.getAccount(addr) if err != nil { return err } @@ -74,8 +80,8 @@ func (c *StakeAccumulatorCache) RemoveStakeClaim(id signature.PublicKey, claim s } // GetEscrowBalance returns a given account's escrow balance. -func (c *StakeAccumulatorCache) GetEscrowBalance(id signature.PublicKey) (*quantity.Quantity, error) { - acct, err := c.getAccount(id) +func (c *StakeAccumulatorCache) GetEscrowBalance(addr staking.Address) (*quantity.Quantity, error) { + acct, err := c.getAccount(addr) if err != nil { return nil, err } @@ -85,9 +91,9 @@ func (c *StakeAccumulatorCache) GetEscrowBalance(id signature.PublicKey) (*quant // Commit commits the stake accumulator changes. The caller must ensure that this does not overwrite // any outstanding account updates. func (c *StakeAccumulatorCache) Commit() error { - for id, acct := range c.accounts { - if err := c.state.SetAccount(c.ctx, id, acct); err != nil { - return fmt.Errorf("failed to set account %s: %w", id, err) + for addr, acct := range c.accounts { + if err := c.state.SetAccount(c.ctx, addr, acct); err != nil { + return fmt.Errorf("failed to set account %s: %w", addr, err) } } return nil @@ -118,12 +124,17 @@ func NewStakeAccumulatorCache(ctx *abciAPI.Context) (*StakeAccumulatorCache, err // // In case there is no errors, the added claim is automatically committed. The caller must ensure // that this does not overwrite any outstanding account updates. -func AddStakeClaim(ctx *abciAPI.Context, id signature.PublicKey, claim staking.StakeClaim, thresholds []staking.ThresholdKind) error { +func AddStakeClaim( + ctx *abciAPI.Context, + addr staking.Address, + claim staking.StakeClaim, + thresholds []staking.ThresholdKind, +) error { sa, err := NewStakeAccumulatorCache(ctx) if err != nil { return err } - if err = sa.AddStakeClaim(id, claim, thresholds); err != nil { + if err = sa.AddStakeClaim(addr, claim, thresholds); err != nil { return err } return sa.Commit() @@ -133,24 +144,24 @@ func AddStakeClaim(ctx *abciAPI.Context, id signature.PublicKey, claim staking.S // // In case there is no errors, the removed claim is automatically committed. The caller must ensure // that this does not overwrite any outstanding account updates. -func RemoveStakeClaim(ctx *abciAPI.Context, id signature.PublicKey, claim staking.StakeClaim) error { +func RemoveStakeClaim(ctx *abciAPI.Context, addr staking.Address, claim staking.StakeClaim) error { sa, err := NewStakeAccumulatorCache(ctx) if err != nil { return err } - if err = sa.RemoveStakeClaim(id, claim); err != nil { + if err = sa.RemoveStakeClaim(addr, claim); err != nil { return err } return sa.Commit() } // CheckStakeClaims is a convenience function for checking a single entity's stake claims. -func CheckStakeClaims(ctx *abciAPI.Context, id signature.PublicKey) error { +func CheckStakeClaims(ctx *abciAPI.Context, addr staking.Address) error { sa, err := NewStakeAccumulatorCache(ctx) if err != nil { return err } defer sa.Discard() - return sa.CheckStakeClaims(id) + return sa.CheckStakeClaims(addr) } diff --git a/go/consensus/tendermint/apps/staking/state/accumulator_test.go b/go/consensus/tendermint/apps/staking/state/accumulator_test.go index c2fbffc0596..05b7f47dbd1 100644 --- a/go/consensus/tendermint/apps/staking/state/accumulator_test.go +++ b/go/consensus/tendermint/apps/staking/state/accumulator_test.go @@ -41,51 +41,52 @@ func TestStakeAccumulatorCache(t *testing.T) { // changes are propagated correctly. ent, _, _ := entity.TestEntity() + addr := staking.NewFromPublicKey(ent.ID) var acct staking.Account acct.Escrow.Active.Balance = *q.Clone() - err = stakeState.SetAccount(ctx, ent.ID, &acct) + err = stakeState.SetAccount(ctx, addr, &acct) require.NoError(err, "SetAccount") - err = acc.AddStakeClaim(ent.ID, staking.StakeClaim("claim"), []staking.ThresholdKind{staking.KindEntity}) + err = acc.AddStakeClaim(addr, staking.StakeClaim("claim"), []staking.ThresholdKind{staking.KindEntity}) require.NoError(err, "AddStakeClaim") - err = acc.CheckStakeClaims(ent.ID) + err = acc.CheckStakeClaims(addr) require.NoError(err, "CheckStakeClaims") - balance, err := acc.GetEscrowBalance(ent.ID) + balance, err := acc.GetEscrowBalance(addr) require.NoError(err, "GetEscrowBalance") require.Equal(&acct.Escrow.Active.Balance, balance, "GetEscrowBalance should return the correct balance") // Check that nothing has been committed yet. - acct2, err := stakeState.Account(ctx, ent.ID) + acct2, err := stakeState.Account(ctx, addr) require.NoError(err, "Account") require.Len(acct2.Escrow.StakeAccumulator.Claims, 0, "claims should not be updated yet") // Now commit and re-check. err = acc.Commit() require.NoError(err, "Commit") - acct2, err = stakeState.Account(ctx, ent.ID) + acct2, err = stakeState.Account(ctx, addr) require.NoError(err, "Account") require.Len(acct2.Escrow.StakeAccumulator.Claims, 1, "claims should be correct") - err = acc.RemoveStakeClaim(ent.ID, staking.StakeClaim("claim")) + err = acc.RemoveStakeClaim(addr, staking.StakeClaim("claim")) require.NoError(err, "RemoveStakeClaim") // Check that nothing has been committed. - acct2, err = stakeState.Account(ctx, ent.ID) + acct2, err = stakeState.Account(ctx, addr) require.NoError(err, "Account") require.Len(acct2.Escrow.StakeAccumulator.Claims, 1, "claims should not be updated") acc.Discard() - acct2, err = stakeState.Account(ctx, ent.ID) + acct2, err = stakeState.Account(ctx, addr) require.NoError(err, "Account") require.Len(acct2.Escrow.StakeAccumulator.Claims, 1, "claims should not be updated") // Test convenience functions. - err = AddStakeClaim(ctx, ent.ID, staking.StakeClaim("claim"), []staking.ThresholdKind{staking.KindEntity}) + err = AddStakeClaim(ctx, addr, staking.StakeClaim("claim"), []staking.ThresholdKind{staking.KindEntity}) require.NoError(err, "AddStakeClaim") - err = RemoveStakeClaim(ctx, ent.ID, staking.StakeClaim("claim")) + err = RemoveStakeClaim(ctx, addr, staking.StakeClaim("claim")) require.NoError(err, "RemoveStakeClaim") - err = CheckStakeClaims(ctx, ent.ID) + err = CheckStakeClaims(ctx, addr) require.NoError(err, "CheckStakeClaims") } diff --git a/go/consensus/tendermint/apps/staking/state/gas.go b/go/consensus/tendermint/apps/staking/state/gas.go index bba9f8e61d8..40ec836e4ee 100644 --- a/go/consensus/tendermint/apps/staking/state/gas.go +++ b/go/consensus/tendermint/apps/staking/state/gas.go @@ -32,7 +32,7 @@ type feeAccumulator struct { // persisted at the end of the block. func AuthenticateAndPayFees( ctx *abciAPI.Context, - id signature.PublicKey, + signer signature.PublicKey, nonce uint64, fee *transaction.Fee, ) error { @@ -46,14 +46,17 @@ func AuthenticateAndPayFees( return nil } + // Convert signer's public key to account address. + addr := staking.NewFromPublicKey(signer) + // Fetch account and make sure the nonce is correct. - account, err := state.Account(ctx, id) + account, err := state.Account(ctx, addr) if err != nil { return fmt.Errorf("failed to fetch account state: %w", err) } if account.General.Nonce != nonce { logger.Error("invalid account nonce", - "account_id", id, + "account_addr", addr, "account_nonce", account.General.Nonce, "nonce", nonce, ) @@ -77,7 +80,8 @@ func AuthenticateAndPayFees( // Check fee against minimum gas price if in CheckTx. Always accept own transactions. // NOTE: This is non-deterministic as it is derived from the local validator // configuration, but as long as it is only done in CheckTx, this is ok. - if !ctx.AppState().OwnTxSigner().Equal(id) { + ownAddr := staking.NewFromPublicKey(ctx.AppState().OwnTxSigner()) + if !ownAddr.Equal(addr) { callerGasPrice := fee.GasPrice() if fee.Gas > 0 && callerGasPrice.Cmp(ctx.AppState().MinGasPrice()) < 0 { return transaction.ErrGasPriceTooLow @@ -94,14 +98,14 @@ func AuthenticateAndPayFees( } account.General.Nonce++ - if err := state.SetAccount(ctx, id, account); err != nil { + if err := state.SetAccount(ctx, addr, account); err != nil { return fmt.Errorf("failed to set account: %w", err) } // Emit transfer event. ev := cbor.Marshal(&staking.TransferEvent{ - From: id, - To: staking.FeeAccumulatorAccountID, + From: addr, + To: staking.FeeAccumulatorAddress, Tokens: fee.Amount, }) ctx.EmitEvent(abciAPI.NewEventBuilder(AppName).Attribute(KeyTransfer, ev)) diff --git a/go/consensus/tendermint/apps/staking/state/state.go b/go/consensus/tendermint/apps/staking/state/state.go index e15a90791e6..9f022cafb90 100644 --- a/go/consensus/tendermint/apps/staking/state/state.go +++ b/go/consensus/tendermint/apps/staking/state/state.go @@ -35,7 +35,7 @@ var ( // accountKeyFmt is the key format used for accounts (account id). // // Value is a CBOR-serialized account. - accountKeyFmt = keyformat.New(0x50, &signature.PublicKey{}) + accountKeyFmt = keyformat.New(0x50, &staking.Address{}) // totalSupplyKeyFmt is the key format used for the total supply. // // Value is a CBOR-serialized quantity. @@ -47,17 +47,17 @@ var ( // delegationKeyFmt is the key format used for delegations (escrow id, delegator id). // // Value is CBOR-serialized delegation. - delegationKeyFmt = keyformat.New(0x53, &signature.PublicKey{}, &signature.PublicKey{}) + delegationKeyFmt = keyformat.New(0x53, &staking.Address{}, &staking.Address{}) // debondingDelegationKeyFmt is the key format used for debonding delegations // (delegator id, escrow id, seq no). // // Value is CBOR-serialized debonding delegation. - debondingDelegationKeyFmt = keyformat.New(0x54, &signature.PublicKey{}, &signature.PublicKey{}, uint64(0)) + debondingDelegationKeyFmt = keyformat.New(0x54, &staking.Address{}, &staking.Address{}, uint64(0)) // debondingQueueKeyFmt is the debonding queue key format (epoch, delegator id, // escrow id, seq no). // // Value is empty. - debondingQueueKeyFmt = keyformat.New(0x55, uint64(0), &signature.PublicKey{}, &signature.PublicKey{}, uint64(0)) + debondingQueueKeyFmt = keyformat.New(0x55, uint64(0), &staking.Address{}, &staking.Address{}, uint64(0)) // parametersKeyFmt is the key format used for consensus parameters. // // Value is CBOR-serialized staking.ConsensusParameters. @@ -165,18 +165,18 @@ func (s *ImmutableState) Thresholds(ctx context.Context) (map[staking.ThresholdK return params.Thresholds, nil } -func (s *ImmutableState) Accounts(ctx context.Context) ([]signature.PublicKey, error) { +func (s *ImmutableState) Accounts(ctx context.Context) ([]staking.Address, error) { it := s.is.NewIterator(ctx) defer it.Close() - var accounts []signature.PublicKey + var accounts []staking.Address for it.Seek(accountKeyFmt.Encode()); it.Valid(); it.Next() { - var id signature.PublicKey - if !accountKeyFmt.Decode(it.Key(), &id) { + var addr staking.Address + if !accountKeyFmt.Decode(it.Key(), &addr) { break } - accounts = append(accounts, id) + accounts = append(accounts, addr) } if it.Err() != nil { return nil, abciAPI.UnavailableStateError(it.Err()) @@ -184,7 +184,7 @@ func (s *ImmutableState) Accounts(ctx context.Context) ([]signature.PublicKey, e return accounts, nil } -func (s *ImmutableState) Account(ctx context.Context, id signature.PublicKey) (*staking.Account, error) { +func (s *ImmutableState) Account(ctx context.Context, id staking.Address) (*staking.Account, error) { if !id.IsValid() { return nil, fmt.Errorf("tendermint/staking: invalid account ID") } @@ -205,7 +205,7 @@ func (s *ImmutableState) Account(ctx context.Context, id signature.PublicKey) (* } // EscrowBalance returns the escrow balance for the ID. -func (s *ImmutableState) EscrowBalance(ctx context.Context, id signature.PublicKey) (*quantity.Quantity, error) { +func (s *ImmutableState) EscrowBalance(ctx context.Context, id staking.Address) (*quantity.Quantity, error) { account, err := s.Account(ctx, id) if err != nil { return nil, err @@ -213,15 +213,17 @@ func (s *ImmutableState) EscrowBalance(ctx context.Context, id signature.PublicK return &account.Escrow.Active.Balance, nil } -func (s *ImmutableState) Delegations(ctx context.Context) (map[signature.PublicKey]map[signature.PublicKey]*staking.Delegation, error) { +func (s *ImmutableState) Delegations( + ctx context.Context, +) (map[staking.Address]map[staking.Address]*staking.Delegation, error) { it := s.is.NewIterator(ctx) defer it.Close() - delegations := make(map[signature.PublicKey]map[signature.PublicKey]*staking.Delegation) + delegations := make(map[staking.Address]map[staking.Address]*staking.Delegation) for it.Seek(delegationKeyFmt.Encode()); it.Valid(); it.Next() { - var escrowID signature.PublicKey - var delegatorID signature.PublicKey - if !delegationKeyFmt.Decode(it.Key(), &escrowID, &delegatorID) { + var escrowAddr staking.Address + var delegatorAddr staking.Address + if !delegationKeyFmt.Decode(it.Key(), &escrowAddr, &delegatorAddr) { break } @@ -230,10 +232,10 @@ func (s *ImmutableState) Delegations(ctx context.Context) (map[signature.PublicK return nil, abciAPI.UnavailableStateError(err) } - if delegations[escrowID] == nil { - delegations[escrowID] = make(map[signature.PublicKey]*staking.Delegation) + if delegations[escrowAddr] == nil { + delegations[escrowAddr] = make(map[staking.Address]*staking.Delegation) } - delegations[escrowID][delegatorID] = &del + delegations[escrowAddr][delegatorAddr] = &del } if it.Err() != nil { return nil, abciAPI.UnavailableStateError(it.Err()) @@ -241,8 +243,11 @@ func (s *ImmutableState) Delegations(ctx context.Context) (map[signature.PublicK return delegations, nil } -func (s *ImmutableState) Delegation(ctx context.Context, delegatorID, escrowID signature.PublicKey) (*staking.Delegation, error) { - value, err := s.is.Get(ctx, delegationKeyFmt.Encode(&escrowID, &delegatorID)) +func (s *ImmutableState) Delegation( + ctx context.Context, + delegatorAddr, escrowAddr staking.Address, +) (*staking.Delegation, error) { + value, err := s.is.Get(ctx, delegationKeyFmt.Encode(&escrowAddr, &delegatorAddr)) if err != nil { return nil, abciAPI.UnavailableStateError(err) } @@ -257,18 +262,21 @@ func (s *ImmutableState) Delegation(ctx context.Context, delegatorID, escrowID s return &del, nil } -func (s *ImmutableState) DelegationsFor(ctx context.Context, delegatorID signature.PublicKey) (map[signature.PublicKey]*staking.Delegation, error) { +func (s *ImmutableState) DelegationsFor( + ctx context.Context, + delegatorAddr staking.Address, +) (map[staking.Address]*staking.Delegation, error) { it := s.is.NewIterator(ctx) defer it.Close() - delegations := make(map[signature.PublicKey]*staking.Delegation) + delegations := make(map[staking.Address]*staking.Delegation) for it.Seek(delegationKeyFmt.Encode()); it.Valid(); it.Next() { - var escrowID signature.PublicKey - var decDelegatorID signature.PublicKey - if !delegationKeyFmt.Decode(it.Key(), &escrowID, &decDelegatorID) { + var escrowAddr staking.Address + var decDelegatorAddr staking.Address + if !delegationKeyFmt.Decode(it.Key(), &escrowAddr, &decDelegatorAddr) { break } - if !decDelegatorID.Equal(delegatorID) { + if !decDelegatorAddr.Equal(delegatorAddr) { continue } @@ -277,7 +285,7 @@ func (s *ImmutableState) DelegationsFor(ctx context.Context, delegatorID signatu return nil, abciAPI.UnavailableStateError(err) } - delegations[escrowID] = &del + delegations[escrowAddr] = &del } if it.Err() != nil { return nil, abciAPI.UnavailableStateError(it.Err()) @@ -287,15 +295,15 @@ func (s *ImmutableState) DelegationsFor(ctx context.Context, delegatorID signatu func (s *ImmutableState) DebondingDelegations( ctx context.Context, -) (map[signature.PublicKey]map[signature.PublicKey][]*staking.DebondingDelegation, error) { +) (map[staking.Address]map[staking.Address][]*staking.DebondingDelegation, error) { it := s.is.NewIterator(ctx) defer it.Close() - delegations := make(map[signature.PublicKey]map[signature.PublicKey][]*staking.DebondingDelegation) + delegations := make(map[staking.Address]map[staking.Address][]*staking.DebondingDelegation) for it.Seek(debondingDelegationKeyFmt.Encode()); it.Valid(); it.Next() { - var escrowID signature.PublicKey - var delegatorID signature.PublicKey - if !debondingDelegationKeyFmt.Decode(it.Key(), &delegatorID, &escrowID) { + var escrowAddr staking.Address + var delegatorAddr staking.Address + if !debondingDelegationKeyFmt.Decode(it.Key(), &delegatorAddr, &escrowAddr) { break } @@ -304,10 +312,10 @@ func (s *ImmutableState) DebondingDelegations( return nil, abciAPI.UnavailableStateError(err) } - if delegations[escrowID] == nil { - delegations[escrowID] = make(map[signature.PublicKey][]*staking.DebondingDelegation) + if delegations[escrowAddr] == nil { + delegations[escrowAddr] = make(map[staking.Address][]*staking.DebondingDelegation) } - delegations[escrowID][delegatorID] = append(delegations[escrowID][delegatorID], &deb) + delegations[escrowAddr][delegatorAddr] = append(delegations[escrowAddr][delegatorAddr], &deb) } if it.Err() != nil { return nil, abciAPI.UnavailableStateError(it.Err()) @@ -317,19 +325,19 @@ func (s *ImmutableState) DebondingDelegations( func (s *ImmutableState) DebondingDelegationsFor( ctx context.Context, - delegatorID signature.PublicKey, -) (map[signature.PublicKey][]*staking.DebondingDelegation, error) { + delegatorAddr staking.Address, +) (map[staking.Address][]*staking.DebondingDelegation, error) { it := s.is.NewIterator(ctx) defer it.Close() - delegations := make(map[signature.PublicKey][]*staking.DebondingDelegation) - for it.Seek(debondingDelegationKeyFmt.Encode(&delegatorID)); it.Valid(); it.Next() { - var escrowID signature.PublicKey - var decDelegatorID signature.PublicKey - if !debondingDelegationKeyFmt.Decode(it.Key(), &decDelegatorID, &escrowID) { + delegations := make(map[staking.Address][]*staking.DebondingDelegation) + for it.Seek(debondingDelegationKeyFmt.Encode(&delegatorAddr)); it.Valid(); it.Next() { + var escrowAddr staking.Address + var decDelegatorAddr staking.Address + if !debondingDelegationKeyFmt.Decode(it.Key(), &decDelegatorAddr, &escrowAddr) { break } - if !decDelegatorID.Equal(delegatorID) { + if !decDelegatorAddr.Equal(delegatorAddr) { continue } @@ -338,7 +346,7 @@ func (s *ImmutableState) DebondingDelegationsFor( return nil, abciAPI.UnavailableStateError(err) } - delegations[escrowID] = append(delegations[escrowID], &deb) + delegations[escrowAddr] = append(delegations[escrowAddr], &deb) } if it.Err() != nil { return nil, abciAPI.UnavailableStateError(it.Err()) @@ -348,10 +356,10 @@ func (s *ImmutableState) DebondingDelegationsFor( func (s *ImmutableState) DebondingDelegation( ctx context.Context, - delegatorID, escrowID signature.PublicKey, + delegatorAddr, escrowAddr staking.Address, seq uint64, ) (*staking.DebondingDelegation, error) { - value, err := s.is.Get(ctx, debondingDelegationKeyFmt.Encode(&delegatorID, &escrowID, seq)) + value, err := s.is.Get(ctx, debondingDelegationKeyFmt.Encode(&delegatorAddr, &escrowAddr, seq)) if err != nil { return nil, abciAPI.UnavailableStateError(err) } @@ -367,11 +375,11 @@ func (s *ImmutableState) DebondingDelegation( } type DebondingQueueEntry struct { - Epoch epochtime.EpochTime - DelegatorID signature.PublicKey - EscrowID signature.PublicKey - Seq uint64 - Delegation *staking.DebondingDelegation + Epoch epochtime.EpochTime + DelegatorAddr staking.Address + EscrowAddr staking.Address + Seq uint64 + Delegation *staking.DebondingDelegation } func (s *ImmutableState) ExpiredDebondingQueue(ctx context.Context, epoch epochtime.EpochTime) ([]*DebondingQueueEntry, error) { @@ -381,22 +389,22 @@ func (s *ImmutableState) ExpiredDebondingQueue(ctx context.Context, epoch epocht var entries []*DebondingQueueEntry for it.Seek(debondingQueueKeyFmt.Encode()); it.Valid(); it.Next() { var decEpoch, seq uint64 - var escrowID signature.PublicKey - var delegatorID signature.PublicKey - if !debondingQueueKeyFmt.Decode(it.Key(), &decEpoch, &delegatorID, &escrowID, &seq) || decEpoch > uint64(epoch) { + var escrowAddr staking.Address + var delegatorAddr staking.Address + if !debondingQueueKeyFmt.Decode(it.Key(), &decEpoch, &delegatorAddr, &escrowAddr, &seq) || decEpoch > uint64(epoch) { break } - deb, err := s.DebondingDelegation(ctx, delegatorID, escrowID, seq) + deb, err := s.DebondingDelegation(ctx, delegatorAddr, escrowAddr, seq) if err != nil { return nil, err } entries = append(entries, &DebondingQueueEntry{ - Epoch: epochtime.EpochTime(decEpoch), - DelegatorID: delegatorID, - EscrowID: escrowID, - Seq: seq, - Delegation: deb, + Epoch: epochtime.EpochTime(decEpoch), + DelegatorAddr: delegatorAddr, + EscrowAddr: escrowAddr, + Seq: seq, + Delegation: deb, }) } if it.Err() != nil { @@ -509,8 +517,8 @@ type MutableState struct { ms mkvs.KeyValueTree } -func (s *MutableState) SetAccount(ctx context.Context, id signature.PublicKey, account *staking.Account) error { - err := s.ms.Insert(ctx, accountKeyFmt.Encode(&id), cbor.Marshal(account)) +func (s *MutableState) SetAccount(ctx context.Context, addr staking.Address, account *staking.Account) error { + err := s.ms.Insert(ctx, accountKeyFmt.Encode(&addr), cbor.Marshal(account)) return abciAPI.UnavailableStateError(err) } @@ -529,24 +537,28 @@ func (s *MutableState) SetConsensusParameters(ctx context.Context, params *staki return abciAPI.UnavailableStateError(err) } -func (s *MutableState) SetDelegation(ctx context.Context, delegatorID, escrowID signature.PublicKey, d *staking.Delegation) error { +func (s *MutableState) SetDelegation( + ctx context.Context, + delegatorAddr, escrowAddr staking.Address, + d *staking.Delegation, +) error { // Remove delegation if there are no more shares in it. if d.Shares.IsZero() { - err := s.ms.Remove(ctx, delegationKeyFmt.Encode(&escrowID, &delegatorID)) + err := s.ms.Remove(ctx, delegationKeyFmt.Encode(&escrowAddr, &delegatorAddr)) return abciAPI.UnavailableStateError(err) } - err := s.ms.Insert(ctx, delegationKeyFmt.Encode(&escrowID, &delegatorID), cbor.Marshal(d)) + err := s.ms.Insert(ctx, delegationKeyFmt.Encode(&escrowAddr, &delegatorAddr), cbor.Marshal(d)) return abciAPI.UnavailableStateError(err) } func (s *MutableState) SetDebondingDelegation( ctx context.Context, - delegatorID, escrowID signature.PublicKey, + delegatorAddr, escrowAddr staking.Address, seq uint64, d *staking.DebondingDelegation, ) error { - key := debondingDelegationKeyFmt.Encode(&delegatorID, &escrowID, seq) + key := debondingDelegationKeyFmt.Encode(&delegatorAddr, &escrowAddr, seq) if d == nil { // Remove descriptor. @@ -555,7 +567,15 @@ func (s *MutableState) SetDebondingDelegation( } // Add to debonding queue. - if err := s.ms.Insert(ctx, debondingQueueKeyFmt.Encode(uint64(d.DebondEndTime), &delegatorID, &escrowID, seq), []byte{}); err != nil { + if err := s.ms.Insert( + ctx, + debondingQueueKeyFmt.Encode(uint64(d.DebondEndTime), + &delegatorAddr, + &escrowAddr, + seq, + ), + []byte{}, + ); err != nil { return abciAPI.UnavailableStateError(err) } // Add descriptor. @@ -568,10 +588,10 @@ func (s *MutableState) SetDebondingDelegation( func (s *MutableState) RemoveFromDebondingQueue( ctx context.Context, epoch epochtime.EpochTime, - delegatorID, escrowID signature.PublicKey, + delegatorAddr, escrowAddr staking.Address, seq uint64, ) error { - err := s.ms.Remove(ctx, debondingQueueKeyFmt.Encode(uint64(epoch), &delegatorID, &escrowID, seq)) + err := s.ms.Remove(ctx, debondingQueueKeyFmt.Encode(uint64(epoch), &delegatorAddr, &escrowAddr, seq)) return abciAPI.UnavailableStateError(err) } @@ -613,15 +633,19 @@ func slashPool(dst *quantity.Quantity, p *staking.SharePool, amount, total *quan // // WARNING: This is an internal routine to be used to implement staking policy, // and MUST NOT be exposed outside of backend implementations. -func (s *MutableState) SlashEscrow(ctx *abciAPI.Context, fromID signature.PublicKey, amount *quantity.Quantity) (bool, error) { +func (s *MutableState) SlashEscrow( + ctx *abciAPI.Context, + fromAddr staking.Address, + amount *quantity.Quantity, +) (bool, error) { commonPool, err := s.CommonPool(ctx) if err != nil { return false, fmt.Errorf("tendermint/staking: failed to query common pool for slash: %w", err) } - from, err := s.Account(ctx, fromID) + from, err := s.Account(ctx, fromAddr) if err != nil { - return false, fmt.Errorf("tendermint/staking: failed to query account %s: %w", fromID, err) + return false, fmt.Errorf("tendermint/staking: failed to query account %s: %w", fromAddr, err) } // Compute the amount we need to slash each pool. The amount is split @@ -652,13 +676,13 @@ func (s *MutableState) SlashEscrow(ctx *abciAPI.Context, fromID signature.Public if err = s.SetCommonPool(ctx, commonPool); err != nil { return false, fmt.Errorf("tendermint/staking: failed to set common pool: %w", err) } - if err = s.SetAccount(ctx, fromID, from); err != nil { + if err = s.SetAccount(ctx, fromAddr, from); err != nil { return false, fmt.Errorf("tendermint/staking: failed to set account. %w", err) } if !ctx.IsCheckOnly() { ev := cbor.Marshal(&staking.TakeEscrowEvent{ - Owner: fromID, + Owner: fromAddr, Tokens: *totalSlashed, }) ctx.EmitEvent(api.NewEventBuilder(AppName).Attribute(KeyTakeEscrow, ev)) @@ -673,15 +697,19 @@ func (s *MutableState) SlashEscrow(ctx *abciAPI.Context, fromID signature.Public // // WARNING: This is an internal routine to be used to implement incentivization // policy, and MUST NOT be exposed outside of backend implementations. -func (s *MutableState) TransferFromCommon(ctx *abciAPI.Context, toID signature.PublicKey, amount *quantity.Quantity) (bool, error) { +func (s *MutableState) TransferFromCommon( + ctx *abciAPI.Context, + toAddr staking.Address, + amount *quantity.Quantity, +) (bool, error) { commonPool, err := s.CommonPool(ctx) if err != nil { return false, fmt.Errorf("tendermint/staking: failed to query common pool for transfer: %w", err) } - to, err := s.Account(ctx, toID) + to, err := s.Account(ctx, toAddr) if err != nil { - return false, fmt.Errorf("tendermint/staking: failed to query account %s: %w", toID, err) + return false, fmt.Errorf("tendermint/staking: failed to query account %s: %w", toAddr, err) } transfered, err := quantity.MoveUpTo(&to.General.Balance, commonPool, amount) if err != nil { @@ -693,14 +721,14 @@ func (s *MutableState) TransferFromCommon(ctx *abciAPI.Context, toID signature.P if err = s.SetCommonPool(ctx, commonPool); err != nil { return false, fmt.Errorf("tendermint/staking: failed to set common pool: %w", err) } - if err = s.SetAccount(ctx, toID, to); err != nil { - return false, fmt.Errorf("tendermint/staking: failed to set account %s: %w", toID, err) + if err = s.SetAccount(ctx, toAddr, to); err != nil { + return false, fmt.Errorf("tendermint/staking: failed to set account %s: %w", toAddr, err) } if !ctx.IsCheckOnly() { ev := cbor.Marshal(&staking.TransferEvent{ - From: staking.CommonPoolAccountID, - To: toID, + From: staking.CommonPoolAddress, + To: toAddr, Tokens: *transfered, }) ctx.EmitEvent(api.NewEventBuilder(AppName).Attribute(KeyTransfer, ev)) @@ -720,7 +748,7 @@ func (s *MutableState) AddRewards( ctx *abciAPI.Context, time epochtime.EpochTime, factor *quantity.Quantity, - accounts []signature.PublicKey, + addresses []staking.Address, ) error { steps, err := s.RewardSchedule(ctx) if err != nil { @@ -743,11 +771,11 @@ func (s *MutableState) AddRewards( return fmt.Errorf("tendermint/staking: loading common pool: %w", err) } - for _, id := range accounts { + for _, addr := range addresses { var ent *staking.Account - ent, err = s.Account(ctx, id) + ent, err = s.Account(ctx, addr) if err != nil { - return fmt.Errorf("tendermint/staking: failed to fetch account %s: %w", id, err) + return fmt.Errorf("tendermint/staking: failed to fetch account %s: %w", addr, err) } q := ent.Escrow.Active.Balance.Clone() @@ -788,8 +816,8 @@ func (s *MutableState) AddRewards( return fmt.Errorf("tendermint/staking: failed transferring to active escrow balance from common pool: %w", err) } ev := cbor.Marshal(&staking.AddEscrowEvent{ - Owner: staking.CommonPoolAccountID, - Escrow: id, + Owner: staking.CommonPoolAddress, + Escrow: addr, Tokens: *q, }) ctx.EmitEvent(api.NewEventBuilder(AppName).Attribute(KeyAddEscrow, ev)) @@ -797,7 +825,7 @@ func (s *MutableState) AddRewards( if com != nil && !com.IsZero() { var delegation *staking.Delegation - delegation, err = s.Delegation(ctx, id, id) + delegation, err = s.Delegation(ctx, addr, addr) if err != nil { return fmt.Errorf("tendermint/staking: failed to query delegation: %w", err) } @@ -806,19 +834,19 @@ func (s *MutableState) AddRewards( return fmt.Errorf("tendermint/staking: depositing commission: %w", err) } - if err = s.SetDelegation(ctx, id, id, delegation); err != nil { + if err = s.SetDelegation(ctx, addr, addr, delegation); err != nil { return fmt.Errorf("tendermint/staking: failed to set delegation: %w", err) } ev := cbor.Marshal(&staking.AddEscrowEvent{ - Owner: staking.CommonPoolAccountID, - Escrow: id, + Owner: staking.CommonPoolAddress, + Escrow: addr, Tokens: *com, }) ctx.EmitEvent(api.NewEventBuilder(AppName).Attribute(KeyAddEscrow, ev)) } - if err = s.SetAccount(ctx, id, ent); err != nil { + if err = s.SetAccount(ctx, addr, ent); err != nil { return fmt.Errorf("tendermint/staking: failed to set account: %w", err) } } @@ -836,7 +864,7 @@ func (s *MutableState) AddRewardSingleAttenuated( time epochtime.EpochTime, factor *quantity.Quantity, attenuationNumerator, attenuationDenominator int, - account signature.PublicKey, + address staking.Address, ) error { steps, err := s.RewardSchedule(ctx) if err != nil { @@ -867,12 +895,12 @@ func (s *MutableState) AddRewardSingleAttenuated( return fmt.Errorf("tendermint/staking: failed loading common pool: %w", err) } - ent, err := s.Account(ctx, account) + acct, err := s.Account(ctx, address) if err != nil { - return fmt.Errorf("tendermint/staking: failed to query account %s: %w", account, err) + return fmt.Errorf("tendermint/staking: failed to query account %s: %w", address, err) } - q := ent.Escrow.Active.Balance.Clone() + q := acct.Escrow.Active.Balance.Clone() // Multiply first. if err = q.Mul(factor); err != nil { return fmt.Errorf("tendermint/staking: failed multiplying by reward factor: %w", err) @@ -895,7 +923,7 @@ func (s *MutableState) AddRewardSingleAttenuated( } var com *quantity.Quantity - rate := ent.Escrow.CommissionSchedule.CurrentRate(time) + rate := acct.Escrow.CommissionSchedule.CurrentRate(time) if rate != nil { com = q.Clone() // Multiply first. @@ -912,12 +940,12 @@ func (s *MutableState) AddRewardSingleAttenuated( } if !q.IsZero() { - if err = quantity.Move(&ent.Escrow.Active.Balance, commonPool, q); err != nil { + if err = quantity.Move(&acct.Escrow.Active.Balance, commonPool, q); err != nil { return fmt.Errorf("tendermint/staking: failed transferring to active escrow balance from common pool: %w", err) } ev := cbor.Marshal(&staking.AddEscrowEvent{ - Owner: staking.CommonPoolAccountID, - Escrow: account, + Owner: staking.CommonPoolAddress, + Escrow: address, Tokens: *q, }) ctx.EmitEvent(api.NewEventBuilder(AppName).Attribute(KeyAddEscrow, ev)) @@ -925,28 +953,28 @@ func (s *MutableState) AddRewardSingleAttenuated( if com != nil && !com.IsZero() { var delegation *staking.Delegation - delegation, err = s.Delegation(ctx, account, account) + delegation, err = s.Delegation(ctx, address, address) if err != nil { return fmt.Errorf("tendermint/staking: failed to query delegation: %w", err) } - if err = ent.Escrow.Active.Deposit(&delegation.Shares, commonPool, com); err != nil { + if err = acct.Escrow.Active.Deposit(&delegation.Shares, commonPool, com); err != nil { return fmt.Errorf("tendermint/staking: failed depositing commission: %w", err) } - if err = s.SetDelegation(ctx, account, account, delegation); err != nil { + if err = s.SetDelegation(ctx, address, address, delegation); err != nil { return fmt.Errorf("tendermint/staking: failed to set delegation: %w", err) } ev := cbor.Marshal(&staking.AddEscrowEvent{ - Owner: staking.CommonPoolAccountID, - Escrow: account, + Owner: staking.CommonPoolAddress, + Escrow: address, Tokens: *com, }) ctx.EmitEvent(api.NewEventBuilder(AppName).Attribute(KeyAddEscrow, ev)) } - if err = s.SetAccount(ctx, account, ent); err != nil { + if err = s.SetAccount(ctx, address, acct); err != nil { return fmt.Errorf("tendermint/staking: failed to set account: %w", err) } diff --git a/go/consensus/tendermint/apps/staking/state/state_test.go b/go/consensus/tendermint/apps/staking/state/state_test.go index 23a3f270971..92b727cc49b 100644 --- a/go/consensus/tendermint/apps/staking/state/state_test.go +++ b/go/consensus/tendermint/apps/staking/state/state_test.go @@ -44,26 +44,26 @@ func TestDelegationQueries(t *testing.T) { // Generate escrow account. escrowSigner, err := fac.Generate(signature.SignerEntity, rand.Reader) require.NoError(err, "generating escrow signer") - escrowID := escrowSigner.Public() + escrowAddr := staking.NewFromPublicKey(escrowSigner.Public()) var escrowAccount staking.Account - err = s.SetAccount(ctx, escrowID, &escrowAccount) + err = s.SetAccount(ctx, escrowAddr, &escrowAccount) require.NoError(err, "SetAccount") // Generate delegator accounts. - var delegatorIDs []signature.PublicKey + var delegatorAddrs []staking.Address // Store expected delegations. - expectedDelegations := make(map[signature.PublicKey]map[signature.PublicKey]*staking.Delegation) - expectedDelegations[escrowID] = map[signature.PublicKey]*staking.Delegation{} - expectedDebDelegations := make(map[signature.PublicKey]map[signature.PublicKey][]*staking.DebondingDelegation) - expectedDebDelegations[escrowID] = map[signature.PublicKey][]*staking.DebondingDelegation{} + expectedDelegations := make(map[staking.Address]map[staking.Address]*staking.Delegation) + expectedDelegations[escrowAddr] = map[staking.Address]*staking.Delegation{} + expectedDebDelegations := make(map[staking.Address]map[staking.Address][]*staking.DebondingDelegation) + expectedDebDelegations[escrowAddr] = map[staking.Address][]*staking.DebondingDelegation{} for i := int64(1); i <= int64(numDelegatorAccounts); i++ { signer, serr := fac.Generate(signature.SignerEntity, rand.Reader) require.NoError(serr, "memory signer factory Generate account") - id := signer.Public() + addr := staking.NewFromPublicKey(signer.Public()) - delegatorIDs = append(delegatorIDs, id) + delegatorAddrs = append(delegatorAddrs, addr) // Init account. var account staking.Account @@ -75,30 +75,30 @@ func TestDelegationQueries(t *testing.T) { var del staking.Delegation err = escrowAccount.Escrow.Active.Deposit(&del.Shares, &account.General.Balance, mustInitQuantityP(t, i*100)) require.NoError(err, "active escrow deposit") - expectedDelegations[escrowID][id] = &del + expectedDelegations[escrowAddr][addr] = &del // Init debonding delegation. var deb staking.DebondingDelegation deb.DebondEndTime = epochtime.EpochTime(i) err = escrowAccount.Escrow.Debonding.Deposit(&deb.Shares, &account.General.Balance, mustInitQuantityP(t, i*100)) require.NoError(err, "debonding escrow deposit") - expectedDebDelegations[escrowID][id] = []*staking.DebondingDelegation{&deb} + expectedDebDelegations[escrowAddr][addr] = []*staking.DebondingDelegation{&deb} // Update state. - err = s.SetAccount(ctx, id, &account) + err = s.SetAccount(ctx, addr, &account) require.NoError(err, "SetAccount") - err = s.SetDelegation(ctx, id, escrowID, &del) + err = s.SetDelegation(ctx, addr, escrowAddr, &del) require.NoError(err, "SetDelegation") - err = s.SetDebondingDelegation(ctx, id, escrowID, uint64(i), &deb) + err = s.SetDebondingDelegation(ctx, addr, escrowAddr, uint64(i), &deb) require.NoError(err, "SetDebondingDelegation") } // Test delegation queries. - for _, id := range delegatorIDs { - accDelegations, derr := s.DelegationsFor(ctx, id) + for _, addr := range delegatorAddrs { + accDelegations, derr := s.DelegationsFor(ctx, addr) require.NoError(derr, "DelegationsFor") - expectedDelegation := map[signature.PublicKey]*staking.Delegation{ - escrowID: expectedDelegations[escrowID][id], + expectedDelegation := map[staking.Address]*staking.Delegation{ + escrowAddr: expectedDelegations[escrowAddr][addr], } require.EqualValues(expectedDelegation, accDelegations, "DelegationsFor account should match expected delegations") } @@ -107,11 +107,11 @@ func TestDelegationQueries(t *testing.T) { require.EqualValues(expectedDelegations, delegations, "Delegations should match expected delegations") // Test debonding delegation queries. - for _, id := range delegatorIDs { - accDebDelegations, derr := s.DebondingDelegationsFor(ctx, id) + for _, addr := range delegatorAddrs { + accDebDelegations, derr := s.DebondingDelegationsFor(ctx, addr) require.NoError(derr, "DebondingDelegationsFor") - expectedDebDelegation := map[signature.PublicKey][]*staking.DebondingDelegation{ - escrowID: expectedDebDelegations[escrowID][id], + expectedDebDelegation := map[staking.Address][]*staking.DebondingDelegation{ + escrowAddr: expectedDebDelegations[escrowAddr][addr], } require.EqualValues(expectedDebDelegation, accDebDelegations, "DebondingDelegationsFor account should match expected") } @@ -125,7 +125,7 @@ func TestRewardAndSlash(t *testing.T) { delegatorSigner, err := memorySigner.NewSigner(rand.Reader) require.NoError(err, "generating delegator signer") - delegatorID := delegatorSigner.Public() + delegatorAddr := staking.NewFromPublicKey(delegatorSigner.Public()) delegatorAccount := &staking.Account{} delegatorAccount.General.Nonce = 10 err = delegatorAccount.General.Balance.FromBigInt(big.NewInt(300)) @@ -133,8 +133,8 @@ func TestRewardAndSlash(t *testing.T) { escrowSigner, err := memorySigner.NewSigner(rand.Reader) require.NoError(err, "generating escrow signer") - escrowID := escrowSigner.Public() - escrowAccountOnly := []signature.PublicKey{escrowID} + escrowAddr := staking.NewFromPublicKey(escrowSigner.Public()) + escrowAddrAsList := []staking.Address{escrowAddr} escrowAccount := &staking.Account{} escrowAccount.Escrow.CommissionSchedule = staking.CommissionSchedule{ Rates: []staking.CommissionRateStep{ @@ -199,33 +199,33 @@ func TestRewardAndSlash(t *testing.T) { err = s.SetCommonPool(ctx, mustInitQuantityP(t, 10000)) require.NoError(err, "SetCommonPool") - err = s.SetAccount(ctx, delegatorID, delegatorAccount) + err = s.SetAccount(ctx, delegatorAddr, delegatorAccount) require.NoError(err, "SetAccount") - err = s.SetAccount(ctx, escrowID, escrowAccount) + err = s.SetAccount(ctx, escrowAddr, escrowAccount) require.NoError(err, "SetAccount") - err = s.SetDelegation(ctx, delegatorID, escrowID, del) + err = s.SetDelegation(ctx, delegatorAddr, escrowAddr, del) require.NoError(err, "SetDelegation") - err = s.SetDebondingDelegation(ctx, delegatorID, escrowID, 1, &deb) + err = s.SetDebondingDelegation(ctx, delegatorAddr, escrowAddr, 1, &deb) require.NoError(err, "SetDebondingDelegation") // Epoch 10 is during the first step. - require.NoError(s.AddRewards(ctx, 10, mustInitQuantityP(t, 100), escrowAccountOnly), "add rewards epoch 10") + require.NoError(s.AddRewards(ctx, 10, mustInitQuantityP(t, 100), escrowAddrAsList), "add rewards epoch 10") // 100% gain. - delegatorAccount, err = s.Account(ctx, delegatorID) + delegatorAccount, err = s.Account(ctx, delegatorAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 100), delegatorAccount.General.Balance, "reward first step - delegator general") - escrowAccount, err = s.Account(ctx, escrowID) + escrowAccount, err = s.Account(ctx, escrowAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 200), escrowAccount.Escrow.Active.Balance, "reward first step - escrow active escrow") require.Equal(mustInitQuantity(t, 100), escrowAccount.Escrow.Debonding.Balance, "reward first step - escrow debonding escrow") // Reward is 100 tokens, with 80 added to the pool and 20 deposited as commission. // We add to the pool first, so the delegation becomes 100 shares : 180 tokens. // Then we deposit the 20 for commission, which comes out to 11 shares. - del, err = s.Delegation(ctx, delegatorID, escrowID) + del, err = s.Delegation(ctx, delegatorAddr, escrowAddr) require.NoError(err, "Delegation") require.Equal(mustInitQuantity(t, 100), del.Shares, "reward first step - delegation shares") - escrowSelfDel, err := s.Delegation(ctx, escrowID, escrowID) + escrowSelfDel, err := s.Delegation(ctx, escrowAddr, escrowAddr) require.NoError(err, "Delegation") require.Equal(mustInitQuantity(t, 11), escrowSelfDel.Shares, "reward first step - escrow self delegation shares") commonPool, err := s.CommonPool(ctx) @@ -233,10 +233,10 @@ func TestRewardAndSlash(t *testing.T) { require.Equal(mustInitQuantityP(t, 9900), commonPool, "reward first step - common pool") // Epoch 30 is in the second step. - require.NoError(s.AddRewards(ctx, 30, mustInitQuantityP(t, 100), escrowAccountOnly), "add rewards epoch 30") + require.NoError(s.AddRewards(ctx, 30, mustInitQuantityP(t, 100), escrowAddrAsList), "add rewards epoch 30") // 50% gain. - escrowAccount, err = s.Account(ctx, escrowID) + escrowAccount, err = s.Account(ctx, escrowAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 300), escrowAccount.Escrow.Active.Balance, "reward boundary epoch - escrow active escrow") commonPool, err = s.CommonPool(ctx) @@ -244,22 +244,22 @@ func TestRewardAndSlash(t *testing.T) { require.Equal(mustInitQuantityP(t, 9800), commonPool, "reward first step - common pool") // Epoch 99 is after the end of the schedule - require.NoError(s.AddRewards(ctx, 99, mustInitQuantityP(t, 100), escrowAccountOnly), "add rewards epoch 99") + require.NoError(s.AddRewards(ctx, 99, mustInitQuantityP(t, 100), escrowAddrAsList), "add rewards epoch 99") // No change. - escrowAccount, err = s.Account(ctx, escrowID) + escrowAccount, err = s.Account(ctx, escrowAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 300), escrowAccount.Escrow.Active.Balance, "reward late epoch - escrow active escrow") - slashedNonzero, err := s.SlashEscrow(ctx, escrowID, mustInitQuantityP(t, 40)) + slashedNonzero, err := s.SlashEscrow(ctx, escrowAddr, mustInitQuantityP(t, 40)) require.NoError(err, "slash escrow") require.True(slashedNonzero, "slashed nonzero") // 40 token loss. - delegatorAccount, err = s.Account(ctx, delegatorID) + delegatorAccount, err = s.Account(ctx, delegatorAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 100), delegatorAccount.General.Balance, "slash - delegator general") - escrowAccount, err = s.Account(ctx, escrowID) + escrowAccount, err = s.Account(ctx, escrowAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 270), escrowAccount.Escrow.Active.Balance, "slash - escrow active escrow") require.Equal(mustInitQuantity(t, 90), escrowAccount.Escrow.Debonding.Balance, "slash - escrow debonding escrow") @@ -268,10 +268,10 @@ func TestRewardAndSlash(t *testing.T) { require.Equal(mustInitQuantityP(t, 9840), commonPool, "slash - common pool") // Epoch 10 is during the first step. - require.NoError(s.AddRewardSingleAttenuated(ctx, 10, mustInitQuantityP(t, 10), 5, 10, escrowID), "add attenuated rewards epoch 30") + require.NoError(s.AddRewardSingleAttenuated(ctx, 10, mustInitQuantityP(t, 10), 5, 10, escrowAddr), "add attenuated rewards epoch 30") // 5% gain. - escrowAccount, err = s.Account(ctx, escrowID) + escrowAccount, err = s.Account(ctx, escrowAddr) require.NoError(err, "Account") require.Equal(mustInitQuantity(t, 283), escrowAccount.Escrow.Active.Balance, "attenuated reward - escrow active escrow") commonPool, err = s.CommonPool(ctx) diff --git a/go/consensus/tendermint/apps/staking/transactions.go b/go/consensus/tendermint/apps/staking/transactions.go index c098a4d4aed..c1f36c5a43b 100644 --- a/go/consensus/tendermint/apps/staking/transactions.go +++ b/go/consensus/tendermint/apps/staking/transactions.go @@ -4,18 +4,17 @@ import ( "fmt" "github.com/oasisprotocol/oasis-core/go/common/cbor" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/quantity" "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" stakingState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/staking/state" staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) -func isTransferPermitted(params *staking.ConsensusParameters, fromID signature.PublicKey) (permitted bool) { +func isTransferPermitted(params *staking.ConsensusParameters, from staking.Address) (permitted bool) { permitted = true if params.DisableTransfers { permitted = false - if params.UndisableTransfersFrom != nil && params.UndisableTransfersFrom[fromID] { + if params.UndisableTransfersFrom != nil && params.UndisableTransfersFrom[from] { permitted = true } } @@ -36,23 +35,23 @@ func (app *stakingApplication) transfer(ctx *api.Context, state *stakingState.Mu return err } - fromID := ctx.TxSigner() - if !isTransferPermitted(params, fromID) { + fromAddr := staking.NewFromPublicKey(ctx.TxSigner()) + if !isTransferPermitted(params, fromAddr) { return staking.ErrForbidden } - from, err := state.Account(ctx, fromID) + from, err := state.Account(ctx, fromAddr) if err != nil { return fmt.Errorf("failed to fetch account: %w", err) } - if fromID.Equal(xfer.To) { + if fromAddr.Equal(xfer.To) { // Handle transfer to self as just a balance check. if from.General.Balance.Cmp(&xfer.Tokens) < 0 { err = staking.ErrInsufficientBalance ctx.Logger().Error("Transfer: self-transfer greater than balance", "err", err, - "from", fromID, + "from", fromAddr, "to", xfer.To, "amount", xfer.Tokens, ) @@ -69,7 +68,7 @@ func (app *stakingApplication) transfer(ctx *api.Context, state *stakingState.Mu if err = quantity.Move(&to.General.Balance, &from.General.Balance, &xfer.Tokens); err != nil { ctx.Logger().Error("Transfer: failed to move balance", "err", err, - "from", fromID, + "from", fromAddr, "to", xfer.To, "amount", xfer.Tokens, ) @@ -81,18 +80,18 @@ func (app *stakingApplication) transfer(ctx *api.Context, state *stakingState.Mu } } - if err = state.SetAccount(ctx, fromID, from); err != nil { + if err = state.SetAccount(ctx, fromAddr, from); err != nil { return fmt.Errorf("failed to fetch account: %w", err) } ctx.Logger().Debug("Transfer: executed transfer", - "from", fromID, + "from", fromAddr, "to", xfer.To, "amount", xfer.Tokens, ) evt := &staking.TransferEvent{ - From: fromID, + From: fromAddr, To: xfer.To, Tokens: xfer.Tokens, } @@ -115,8 +114,8 @@ func (app *stakingApplication) burn(ctx *api.Context, state *stakingState.Mutabl return err } - id := ctx.TxSigner() - from, err := state.Account(ctx, id) + fromAddr := staking.NewFromPublicKey(ctx.TxSigner()) + from, err := state.Account(ctx, fromAddr) if err != nil { return fmt.Errorf("failed to fetch account: %w", err) } @@ -124,7 +123,8 @@ func (app *stakingApplication) burn(ctx *api.Context, state *stakingState.Mutabl if err = from.General.Balance.Sub(&burn.Tokens); err != nil { ctx.Logger().Error("Burn: failed to burn tokens", "err", err, - "from", id, "amount", burn.Tokens, + "from", fromAddr, + "amount", burn.Tokens, ) return err } @@ -136,7 +136,7 @@ func (app *stakingApplication) burn(ctx *api.Context, state *stakingState.Mutabl _ = totalSupply.Sub(&burn.Tokens) - if err = state.SetAccount(ctx, id, from); err != nil { + if err = state.SetAccount(ctx, fromAddr, from); err != nil { return fmt.Errorf("failed to set account: %w", err) } if err = state.SetTotalSupply(ctx, totalSupply); err != nil { @@ -144,12 +144,12 @@ func (app *stakingApplication) burn(ctx *api.Context, state *stakingState.Mutabl } ctx.Logger().Debug("Burn: burnt tokens", - "from", id, + "from", fromAddr, "amount", burn.Tokens, ) evt := &staking.BurnEvent{ - Owner: id, + Owner: fromAddr, Tokens: burn.Tokens, } ctx.EmitEvent(api.NewEventBuilder(app.Name()).Attribute(KeyBurn, cbor.Marshal(evt))) @@ -176,8 +176,8 @@ func (app *stakingApplication) addEscrow(ctx *api.Context, state *stakingState.M return staking.ErrInvalidArgument } - id := ctx.TxSigner() - from, err := state.Account(ctx, id) + fromAddr := staking.NewFromPublicKey(ctx.TxSigner()) + from, err := state.Account(ctx, fromAddr) if err != nil { return fmt.Errorf("failed to fetch account: %w", err) } @@ -187,7 +187,7 @@ func (app *stakingApplication) addEscrow(ctx *api.Context, state *stakingState.M // NOTE: Could be the same account, so make sure to not have two duplicate // copies of it and overwrite it later. var to *staking.Account - if id.Equal(escrow.Account) { + if fromAddr.Equal(escrow.Account) { to = from } else { if params.DisableDelegation { @@ -200,7 +200,7 @@ func (app *stakingApplication) addEscrow(ctx *api.Context, state *stakingState.M } // Fetch delegation. - delegation, err := state.Delegation(ctx, id, escrow.Account) + delegation, err := state.Delegation(ctx, fromAddr, escrow.Account) if err != nil { return fmt.Errorf("failed to fetch delegation: %w", err) } @@ -208,7 +208,7 @@ func (app *stakingApplication) addEscrow(ctx *api.Context, state *stakingState.M if err = to.Escrow.Active.Deposit(&delegation.Shares, &from.General.Balance, &escrow.Tokens); err != nil { ctx.Logger().Error("AddEscrow: failed to escrow tokens", "err", err, - "from", id, + "from", fromAddr, "to", escrow.Account, "amount", escrow.Tokens, ) @@ -216,27 +216,27 @@ func (app *stakingApplication) addEscrow(ctx *api.Context, state *stakingState.M } // Commit accounts. - if err = state.SetAccount(ctx, id, from); err != nil { + if err = state.SetAccount(ctx, fromAddr, from); err != nil { return fmt.Errorf("failed to set account: %w", err) } - if !id.Equal(escrow.Account) { + if !fromAddr.Equal(escrow.Account) { if err = state.SetAccount(ctx, escrow.Account, to); err != nil { return fmt.Errorf("failed to set account: %w", err) } } // Commit delegation descriptor. - if err = state.SetDelegation(ctx, id, escrow.Account, delegation); err != nil { + if err = state.SetDelegation(ctx, fromAddr, escrow.Account, delegation); err != nil { return fmt.Errorf("failed to set delegation: %w", err) } ctx.Logger().Debug("AddEscrow: escrowed tokens", - "from", id, + "from", fromAddr, "to", escrow.Account, "amount", escrow.Tokens, ) evt := &staking.AddEscrowEvent{ - Owner: id, + Owner: fromAddr, Escrow: escrow.Account, Tokens: escrow.Tokens, } @@ -264,8 +264,8 @@ func (app *stakingApplication) reclaimEscrow(ctx *api.Context, state *stakingSta return err } - id := ctx.TxSigner() - to, err := state.Account(ctx, id) + toAddr := staking.NewFromPublicKey(ctx.TxSigner()) + to, err := state.Account(ctx, toAddr) if err != nil { return fmt.Errorf("failed to fetch account: %w", err) } @@ -275,7 +275,7 @@ func (app *stakingApplication) reclaimEscrow(ctx *api.Context, state *stakingSta // NOTE: Could be the same account, so make sure to not have two duplicate // copies of it and overwrite it later. var from *staking.Account - if id.Equal(reclaim.Account) { + if toAddr.Equal(reclaim.Account) { from = to } else { if params.DisableDelegation { @@ -288,7 +288,7 @@ func (app *stakingApplication) reclaimEscrow(ctx *api.Context, state *stakingSta } // Fetch delegation. - delegation, err := state.Delegation(ctx, id, reclaim.Account) + delegation, err := state.Delegation(ctx, toAddr, reclaim.Account) if err != nil { return fmt.Errorf("failed to fetch delegation: %w", err) } @@ -315,7 +315,7 @@ func (app *stakingApplication) reclaimEscrow(ctx *api.Context, state *stakingSta if err = from.Escrow.Active.Withdraw(&tokens, &delegation.Shares, &reclaim.Shares); err != nil { ctx.Logger().Error("ReclaimEscrow: failed to redeem escrow shares", "err", err, - "to", id, + "to", toAddr, "from", reclaim.Account, "shares", reclaim.Shares, ) @@ -326,7 +326,7 @@ func (app *stakingApplication) reclaimEscrow(ctx *api.Context, state *stakingSta if err = from.Escrow.Debonding.Deposit(&deb.Shares, &tokens, tokenAmount); err != nil { ctx.Logger().Error("ReclaimEscrow: failed to debond shares", "err", err, - "to", id, + "to", toAddr, "from", reclaim.Account, "shares", reclaim.Shares, ) @@ -341,17 +341,17 @@ func (app *stakingApplication) reclaimEscrow(ctx *api.Context, state *stakingSta } // Include the nonce as the final disambiguator to prevent overwriting debonding delegations. - if err = state.SetDebondingDelegation(ctx, id, reclaim.Account, to.General.Nonce, &deb); err != nil { + if err = state.SetDebondingDelegation(ctx, toAddr, reclaim.Account, to.General.Nonce, &deb); err != nil { return fmt.Errorf("failed to set debonding delegation: %w", err) } - if err = state.SetDelegation(ctx, id, reclaim.Account, delegation); err != nil { + if err = state.SetDelegation(ctx, toAddr, reclaim.Account, delegation); err != nil { return fmt.Errorf("failed to set delegation: %w", err) } - if err = state.SetAccount(ctx, id, to); err != nil { + if err = state.SetAccount(ctx, toAddr, to); err != nil { return fmt.Errorf("failed to set account: %w", err) } - if !id.Equal(reclaim.Account) { + if !toAddr.Equal(reclaim.Account) { if err = state.SetAccount(ctx, reclaim.Account, from); err != nil { return fmt.Errorf("failed to set account: %w", err) } @@ -383,8 +383,8 @@ func (app *stakingApplication) amendCommissionSchedule( return err } - id := ctx.TxSigner() - from, err := state.Account(ctx, id) + fromAddr := staking.NewFromPublicKey(ctx.TxSigner()) + from, err := state.Account(ctx, fromAddr) if err != nil { return fmt.Errorf("failed to fetch account: %w", err) } @@ -392,12 +392,12 @@ func (app *stakingApplication) amendCommissionSchedule( if err = from.Escrow.CommissionSchedule.AmendAndPruneAndValidate(&amendCommissionSchedule.Amendment, ¶ms.CommissionScheduleRules, epoch); err != nil { ctx.Logger().Error("AmendCommissionSchedule: amendment not acceptable", "err", err, - "from", id, + "from", fromAddr, ) return err } - if err = state.SetAccount(ctx, id, from); err != nil { + if err = state.SetAccount(ctx, fromAddr, from); err != nil { return fmt.Errorf("failed to set account: %w", err) } diff --git a/go/consensus/tendermint/apps/staking/transactions_test.go b/go/consensus/tendermint/apps/staking/transactions_test.go index 3e3e1683801..899751b42ee 100644 --- a/go/consensus/tendermint/apps/staking/transactions_test.go +++ b/go/consensus/tendermint/apps/staking/transactions_test.go @@ -5,7 +5,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" staking "github.com/oasisprotocol/oasis-core/go/staking/api" ) @@ -13,13 +12,13 @@ func TestIsTransferPermitted(t *testing.T) { for _, tt := range []struct { msg string params *staking.ConsensusParameters - fromID signature.PublicKey + fromAddr staking.Address permitted bool }{ { "no disablement", &staking.ConsensusParameters{}, - signature.PublicKey{}, + staking.Address{}, true, }, { @@ -27,32 +26,32 @@ func TestIsTransferPermitted(t *testing.T) { &staking.ConsensusParameters{ DisableTransfers: true, }, - signature.PublicKey{}, + staking.Address{}, false, }, { "not whitelisted", &staking.ConsensusParameters{ DisableTransfers: true, - UndisableTransfersFrom: map[signature.PublicKey]bool{ - signature.PublicKey{1}: true, + UndisableTransfersFrom: map[staking.Address]bool{ + staking.Address{1}: true, }, }, - signature.PublicKey{}, + staking.Address{}, false, }, { "whitelisted", &staking.ConsensusParameters{ DisableTransfers: true, - UndisableTransfersFrom: map[signature.PublicKey]bool{ - signature.PublicKey{}: true, + UndisableTransfersFrom: map[staking.Address]bool{ + staking.Address{}: true, }, }, - signature.PublicKey{}, + staking.Address{}, true, }, } { - require.Equal(t, tt.permitted, isTransferPermitted(tt.params, tt.fromID), tt.msg) + require.Equal(t, tt.permitted, isTransferPermitted(tt.params, tt.fromAddr), tt.msg) } } diff --git a/go/consensus/tendermint/apps/supplementarysanity/checks.go b/go/consensus/tendermint/apps/supplementarysanity/checks.go index 758844406cd..174aca1da07 100644 --- a/go/consensus/tendermint/apps/supplementarysanity/checks.go +++ b/go/consensus/tendermint/apps/supplementarysanity/checks.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/oasisprotocol/oasis-core/go/common" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/quantity" abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api" keymanagerState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/keymanager/state" @@ -266,15 +265,15 @@ func checkStakeClaims(ctx *abciAPI.Context, now epochtime.EpochTime) error { return fmt.Errorf("failed to get runtime registrations: %w", err) } // Get staking accounts. - accounts := make(map[signature.PublicKey]*staking.Account) - accountIDs, err := stakingSt.Accounts(ctx) + accounts := make(map[staking.Address]*staking.Account) + addresses, err := stakingSt.Accounts(ctx) if err != nil { return fmt.Errorf("failed to get staking accounts: %w", err) } - for _, id := range accountIDs { - accounts[id], err = stakingSt.Account(ctx, id) + for _, addr := range addresses { + accounts[addr], err = stakingSt.Account(ctx, addr) if err != nil { - return fmt.Errorf("failed to get staking account with id %s: %w", id, err) + return fmt.Errorf("failed to get staking account %s: %w", addr, err) } } diff --git a/go/consensus/tendermint/staking/staking.go b/go/consensus/tendermint/staking/staking.go index c975356990f..452fd1a5cf3 100644 --- a/go/consensus/tendermint/staking/staking.go +++ b/go/consensus/tendermint/staking/staking.go @@ -12,7 +12,6 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/cbor" "github.com/oasisprotocol/oasis-core/go/common/crypto/hash" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/logging" "github.com/oasisprotocol/oasis-core/go/common/pubsub" "github.com/oasisprotocol/oasis-core/go/common/quantity" @@ -83,7 +82,7 @@ func (tb *tendermintBackend) Threshold(ctx context.Context, query *api.Threshold return q.Threshold(ctx, query.Kind) } -func (tb *tendermintBackend) Accounts(ctx context.Context, height int64) ([]signature.PublicKey, error) { +func (tb *tendermintBackend) Accounts(ctx context.Context, height int64) ([]api.Address, error) { q, err := tb.querier.QueryAt(ctx, height) if err != nil { return nil, err @@ -101,7 +100,7 @@ func (tb *tendermintBackend) AccountInfo(ctx context.Context, query *api.OwnerQu return q.AccountInfo(ctx, query.Owner) } -func (tb *tendermintBackend) Delegations(ctx context.Context, query *api.OwnerQuery) (map[signature.PublicKey]*api.Delegation, error) { +func (tb *tendermintBackend) Delegations(ctx context.Context, query *api.OwnerQuery) (map[api.Address]*api.Delegation, error) { q, err := tb.querier.QueryAt(ctx, query.Height) if err != nil { return nil, err @@ -110,7 +109,7 @@ func (tb *tendermintBackend) Delegations(ctx context.Context, query *api.OwnerQu return q.Delegations(ctx, query.Owner) } -func (tb *tendermintBackend) DebondingDelegations(ctx context.Context, query *api.OwnerQuery) (map[signature.PublicKey][]*api.DebondingDelegation, error) { +func (tb *tendermintBackend) DebondingDelegations(ctx context.Context, query *api.OwnerQuery) (map[api.Address][]*api.DebondingDelegation, error) { q, err := tb.querier.QueryAt(ctx, query.Height) if err != nil { return nil, err diff --git a/go/consensus/tendermint/tendermint.go b/go/consensus/tendermint/tendermint.go index 1c0b0f23f58..b54b98bc1c2 100644 --- a/go/consensus/tendermint/tendermint.go +++ b/go/consensus/tendermint/tendermint.go @@ -1203,7 +1203,8 @@ func genesisToTendermint(d *genesisAPI.Document) (*tmtypes.GenesisDoc, error) { power = 1 } else { var stake *quantity.Quantity - if account, ok := d.Staking.Ledger[openedNode.EntityID]; ok { + acctAddr := stakingAPI.NewFromPublicKey(openedNode.EntityID) + if account, ok := d.Staking.Ledger[acctAddr]; ok { stake = account.Escrow.Active.Balance.Clone() } else { // If all balances and stuff are zero, it's permitted not to have an account in the ledger at all. @@ -1211,8 +1212,9 @@ func genesisToTendermint(d *genesisAPI.Document) (*tmtypes.GenesisDoc, error) { } power, err = schedulerAPI.VotingPowerFromTokens(stake) if err != nil { - return nil, fmt.Errorf("tendermint: computing voting power for entity %s with stake %v: %w", + return nil, fmt.Errorf("tendermint: computing voting power for entity %s with account %s and stake %v: %w", openedNode.EntityID, + acctAddr, stake, err, ) diff --git a/go/genesis/genesis_test.go b/go/genesis/genesis_test.go index 73b096d43ec..7fe17162ed4 100644 --- a/go/genesis/genesis_test.go +++ b/go/genesis/genesis_test.go @@ -655,29 +655,29 @@ func TestGenesisSanityCheck(t *testing.T) { require.Error(d.SanityCheck(), "invalid last block fees should be rejected") d = *testDoc - d.Staking.Ledger[stakingTests.DebugStateSrcID].General.Balance = stakingTests.QtyFromInt(100) + d.Staking.Ledger[stakingTests.DebugStateSrcAddress].General.Balance = stakingTests.QtyFromInt(100) require.Error(d.SanityCheck(), "invalid general balance should be rejected") d = *testDoc - d.Staking.Ledger[stakingTests.DebugStateSrcID].Escrow.Active.Balance = stakingTests.QtyFromInt(100) + d.Staking.Ledger[stakingTests.DebugStateSrcAddress].Escrow.Active.Balance = stakingTests.QtyFromInt(100) require.Error(d.SanityCheck(), "invalid escrow active balance should be rejected") d = *testDoc - d.Staking.Ledger[stakingTests.DebugStateSrcID].Escrow.Debonding.Balance = stakingTests.QtyFromInt(100) + d.Staking.Ledger[stakingTests.DebugStateSrcAddress].Escrow.Debonding.Balance = stakingTests.QtyFromInt(100) require.Error(d.SanityCheck(), "invalid escrow debonding balance should be rejected") d = *testDoc - d.Staking.Ledger[stakingTests.DebugStateSrcID].Escrow.Active.TotalShares = stakingTests.QtyFromInt(1) + d.Staking.Ledger[stakingTests.DebugStateSrcAddress].Escrow.Active.TotalShares = stakingTests.QtyFromInt(1) require.Error(d.SanityCheck(), "invalid escrow active total shares should be rejected") d = *testDoc - d.Staking.Ledger[stakingTests.DebugStateSrcID].Escrow.Debonding.TotalShares = stakingTests.QtyFromInt(1) + d.Staking.Ledger[stakingTests.DebugStateSrcAddress].Escrow.Debonding.TotalShares = stakingTests.QtyFromInt(1) require.Error(d.SanityCheck(), "invalid escrow debonding total shares should be rejected") d = *testDoc - d.Staking.Delegations = map[signature.PublicKey]map[signature.PublicKey]*staking.Delegation{ - stakingTests.DebugStateSrcID: map[signature.PublicKey]*staking.Delegation{ - stakingTests.DebugStateDestID: &staking.Delegation{ + d.Staking.Delegations = map[staking.Address]map[staking.Address]*staking.Delegation{ + stakingTests.DebugStateSrcAddress: map[staking.Address]*staking.Delegation{ + stakingTests.DebugStateDestAddress: &staking.Delegation{ Shares: stakingTests.QtyFromInt(1), }, }, @@ -685,9 +685,9 @@ func TestGenesisSanityCheck(t *testing.T) { require.Error(d.SanityCheck(), "invalid delegation should be rejected") d = *testDoc - d.Staking.DebondingDelegations = map[signature.PublicKey]map[signature.PublicKey][]*staking.DebondingDelegation{ - stakingTests.DebugStateSrcID: map[signature.PublicKey][]*staking.DebondingDelegation{ - stakingTests.DebugStateDestID: []*staking.DebondingDelegation{ + d.Staking.DebondingDelegations = map[staking.Address]map[staking.Address][]*staking.DebondingDelegation{ + stakingTests.DebugStateSrcAddress: map[staking.Address][]*staking.DebondingDelegation{ + stakingTests.DebugStateDestAddress: []*staking.DebondingDelegation{ &staking.DebondingDelegation{ Shares: stakingTests.QtyFromInt(1), DebondEndTime: 10, diff --git a/go/oasis-node/cmd/debug/consim/xfer_workload.go b/go/oasis-node/cmd/debug/consim/xfer_workload.go index 5bef0c05d63..c18d4510930 100644 --- a/go/oasis-node/cmd/debug/consim/xfer_workload.go +++ b/go/oasis-node/cmd/debug/consim/xfer_workload.go @@ -42,6 +42,7 @@ type xferWorkload struct { type xferAccount struct { signer signature.Signer + address staking.Address nonce uint64 balance quantity.Quantity } @@ -65,7 +66,7 @@ func (w *xferWorkload) Init(doc *genesis.Document) error { // Ensure the genesis doc has the debug test entity to be used to // fund the accounts. testEntity, _, _ := entity.TestEntity() - testAccount := doc.Staking.Ledger[testEntity.ID] + testAccount := doc.Staking.Ledger[staking.NewFromPublicKey(testEntity.ID)] if testAccount == nil { return fmt.Errorf("consim/workload/xfer: test entity not present in genesis") } @@ -79,9 +80,11 @@ func (w *xferWorkload) Init(doc *genesis.Document) error { func (w *xferWorkload) Start(initialState *genesis.Document, cancelCh <-chan struct{}, errCh chan<- error) (<-chan []BlockTx, error) { // Initialize the funding account. testEntity, testSigner, _ := entity.TestEntity() - testAccount := initialState.Staking.Ledger[testEntity.ID] + testAccountID := staking.NewFromPublicKey(testEntity.ID) + testAccount := initialState.Staking.Ledger[testAccountID] w.fundingAccount = &xferAccount{ signer: testSigner, + address: testAccountID, nonce: testAccount.General.Nonce, balance: testAccount.General.Balance, } @@ -94,9 +97,10 @@ func (w *xferWorkload) Start(initialState *genesis.Document, cancelCh <-chan str } acc := &xferAccount{ - signer: accSigner, + signer: accSigner, + address: staking.NewFromPublicKey(accSigner.Public()), } - if lacc := initialState.Staking.Ledger[accSigner.Public()]; lacc != nil { + if lacc := initialState.Staking.Ledger[acc.address]; lacc != nil { acc.nonce = lacc.General.Nonce acc.balance = lacc.General.Balance } @@ -112,16 +116,21 @@ func (w *xferWorkload) Start(initialState *genesis.Document, cancelCh <-chan str func (w *xferWorkload) Finalize(finalState *genesis.Document) error { for _, acc := range w.accounts { - id := acc.signer.Public() - lacc := finalState.Staking.Ledger[id] + lacc := finalState.Staking.Ledger[acc.address] if lacc == nil { - return fmt.Errorf("consim/workload/xfer: account missing: %v", id) + return fmt.Errorf("consim/workload/xfer: account missing: %v", acc.address) } if lacc.General.Nonce != acc.nonce { - return fmt.Errorf("consim/workload/xfer: nonce mismatch: %v (expected: %v, actual: %v)", id, acc.nonce, lacc.General.Nonce) + return fmt.Errorf( + "consim/workload/xfer: nonce mismatch: %v (expected: %v, actual: %v)", + acc.address, acc.nonce, lacc.General.Nonce, + ) } if lacc.General.Balance.Cmp(&acc.balance) != 0 { - return fmt.Errorf("consim/workload/xfer: balance mismatch: %v (expected: %v, actual: %v)", id, acc.balance, lacc.General.Balance) + return fmt.Errorf( + "consim/workload/xfer: balance mismatch: %v (expected: %v, actual: %v)", + acc.address, acc.balance, lacc.General.Balance, + ) } } return nil @@ -188,7 +197,7 @@ func xferGenTx(from, to *xferAccount, amount uint64) ([]byte, error) { // TODO: At some point this should pay gas, for now don't under // the assumption that transactions are free. xfer := &staking.Transfer{ - To: to.signer.Public(), + To: to.address, } if err := xfer.Tokens.FromUint64(amount); err != nil { return nil, err @@ -202,8 +211,8 @@ func xferGenTx(from, to *xferAccount, amount uint64) ([]byte, error) { } logger.Debug("TX", - "from", from.signer.Public(), - "to", to.signer.Public(), + "from", from.address, + "to", to.address, "nonce", from.nonce, ) diff --git a/go/oasis-node/cmd/debug/txsource/txsource.go b/go/oasis-node/cmd/debug/txsource/txsource.go index ac53f834fc7..c4976e4a8b7 100644 --- a/go/oasis-node/cmd/debug/txsource/txsource.go +++ b/go/oasis-node/cmd/debug/txsource/txsource.go @@ -111,7 +111,7 @@ func doRun(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("memory signer factory generate funding account %w", err) } - if err = workload.FundAccountFromTestEntity(ctx, logger, cnsc, fundingAccount.Public()); err != nil { + if err = workload.FundAccountFromTestEntity(ctx, logger, cnsc, fundingAccount); err != nil { return fmt.Errorf("test entity account funding failure: %w", err) } diff --git a/go/oasis-node/cmd/debug/txsource/workload/commission.go b/go/oasis-node/cmd/debug/txsource/workload/commission.go index e92921e41d2..5fb021ea6ec 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/commission.go +++ b/go/oasis-node/cmd/debug/txsource/workload/commission.go @@ -32,7 +32,8 @@ type commission struct { logger *logging.Logger rules staking.CommissionScheduleRules - account signature.Signer + signer signature.Signer + address staking.Address reckonedNonce uint64 fundingAccount signature.Signer } @@ -136,10 +137,10 @@ func (c *commission) doAmendCommissionSchedule(ctx context.Context, rng *rand.Ra var account *staking.Account account, err = stakingClient.AccountInfo(ctx, &staking.OwnerQuery{ Height: consensus.HeightLatest, - Owner: c.account.Public(), + Owner: c.address, }) if err != nil { - return fmt.Errorf("stakingClient.AccountInfo %s: %w", c.account.Public(), err) + return fmt.Errorf("stakingClient.AccountInfo %s: %w", c.address, err) } existingCommissionSchedule := account.Escrow.CommissionSchedule existingCommissionSchedule.Prune(currentEpoch) @@ -317,7 +318,7 @@ func (c *commission) doAmendCommissionSchedule(ctx context.Context, rng *rand.Ra // Estimate gas. gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{ - Caller: c.account.Public(), + Caller: c.signer.Public(), Transaction: tx, }) if err != nil { @@ -331,18 +332,19 @@ func (c *commission) doAmendCommissionSchedule(ctx context.Context, rng *rand.Ra // Fund account to cover AmendCommissionSchedule transaction fees. fundAmount := int64(gas) * gasPrice // transaction costs - if err = transferFunds(ctx, c.logger, cnsc, c.fundingAccount, c.account.Public(), fundAmount); err != nil { + if err = transferFunds(ctx, c.logger, cnsc, c.fundingAccount, c.address, fundAmount); err != nil { return fmt.Errorf("account funding failure: %w", err) } // Sign transaction. - signedTx, err := transaction.Sign(c.account, tx) + signedTx, err := transaction.Sign(c.signer, tx) if err != nil { return fmt.Errorf("transaction.Sign: %w", err) } c.logger.Debug("submitting amend commission schedule transaction", - "account", c.account.Public(), + "signer", c.signer.Public(), + "account", c.address, "amendment", amendSchedule, "existing", existingCommissionSchedule, ) @@ -363,10 +365,11 @@ func (c *commission) Run(gracefulExit context.Context, rng *rand.Rand, conn *grp c.fundingAccount = fundingAccount fac := memorySigner.NewFactory() - c.account, err = fac.Generate(signature.SignerEntity, rng) + c.signer, err = fac.Generate(signature.SignerEntity, rng) if err != nil { return fmt.Errorf("memory signer factory Generate account: %w", err) } + c.address = staking.NewFromPublicKey(c.signer.Public()) stakingClient := staking.NewStakingClient(conn) diff --git a/go/oasis-node/cmd/debug/txsource/workload/delegation.go b/go/oasis-node/cmd/debug/txsource/workload/delegation.go index 4dab006935d..16731ac1211 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/delegation.go +++ b/go/oasis-node/cmd/debug/txsource/workload/delegation.go @@ -30,8 +30,9 @@ type delegation struct { accounts []struct { signer signature.Signer reckonedNonce uint64 - delegatedTo signature.PublicKey debondEndTime uint64 + address staking.Address + delegatedTo staking.Address } fundingAccount signature.Signer } @@ -48,7 +49,7 @@ func (d *delegation) doEscrowTx(ctx context.Context, rng *rand.Rand, cnsc consen // Select an account that has no active delegations nor debonding funds. perm := rng.Perm(delegationNumAccounts) fromPermIdx := -1 - var empty signature.PublicKey + var empty staking.Address for i := range d.accounts { if d.accounts[perm[i]].delegatedTo == empty && d.accounts[perm[i]].debondEndTime < uint64(epoch) { fromPermIdx = i @@ -67,7 +68,7 @@ func (d *delegation) doEscrowTx(ctx context.Context, rng *rand.Rand, cnsc consen selectedIdx := perm[fromPermIdx] // Update local state. - d.accounts[selectedIdx].delegatedTo = d.accounts[perm[toPermIdx]].signer.Public() + d.accounts[selectedIdx].delegatedTo = d.accounts[perm[toPermIdx]].address // Create escrow tx. escrow := &staking.Escrow{ @@ -98,7 +99,7 @@ func (d *delegation) doReclaimEscrowTx(ctx context.Context, rng *rand.Rand, cnsc // Select an account that has active delegation. perm := rng.Perm(delegationNumAccounts) fromPermIdx := -1 - var empty signature.PublicKey + var empty staking.Address for i := range d.accounts { if d.accounts[perm[i]].delegatedTo != empty { fromPermIdx = i @@ -114,7 +115,7 @@ func (d *delegation) doReclaimEscrowTx(ctx context.Context, rng *rand.Rand, cnsc // Query amount of delegated shares for the account. delegations, err := stakingClient.Delegations(ctx, &staking.OwnerQuery{ Height: consensus.HeightLatest, - Owner: d.accounts[selectedIdx].signer.Public(), + Owner: d.accounts[selectedIdx].address, }) if err != nil { return fmt.Errorf("stakingClient.Delegations %s: %w", d.accounts[selectedIdx].signer.Public(), err) @@ -146,10 +147,10 @@ func (d *delegation) doReclaimEscrowTx(ctx context.Context, rng *rand.Rand, cnsc } // Query debonding end epoch for the account. - var debondingDelegations map[signature.PublicKey][]*staking.DebondingDelegation + var debondingDelegations map[staking.Address][]*staking.DebondingDelegation debondingDelegations, err = stakingClient.DebondingDelegations(ctx, &staking.OwnerQuery{ Height: consensus.HeightLatest, - Owner: d.accounts[selectedIdx].signer.Public(), + Owner: d.accounts[selectedIdx].address, }) if err != nil { return fmt.Errorf("stakingClient.Delegations %s: %w", d.accounts[selectedIdx].signer.Public(), err) @@ -179,7 +180,6 @@ func (d *delegation) Run( cnsc consensus.ClientBackend, fundingAccount signature.Signer, ) error { - var err error ctx := context.Background() d.logger = logging.GetLogger("cmd/txsource/workload/delegation") @@ -189,19 +189,22 @@ func (d *delegation) Run( d.accounts = make([]struct { signer signature.Signer reckonedNonce uint64 - delegatedTo signature.PublicKey debondEndTime uint64 + address staking.Address + delegatedTo staking.Address }, delegationNumAccounts) for i := range d.accounts { - d.accounts[i].signer, err = fac.Generate(signature.SignerEntity, rng) + signer, err := fac.Generate(signature.SignerEntity, rng) if err != nil { return fmt.Errorf("memory signer factory Generate account %d: %w", i, err) } + d.accounts[i].signer = signer + d.accounts[i].address = staking.NewFromPublicKey(signer.Public()) // Fund the account with delegation amount. - // Funds for fee's will be transferred before making transactions. - if err = transferFunds(ctx, d.logger, cnsc, fundingAccount, d.accounts[i].signer.Public(), delegateAmount); err != nil { + // Funds for fees will be transferred before making transactions. + if err = transferFunds(ctx, d.logger, cnsc, fundingAccount, d.accounts[i].address, delegateAmount); err != nil { return fmt.Errorf("account funding failure: %w", err) } } @@ -211,11 +214,11 @@ func (d *delegation) Run( for { switch rng.Intn(2) { case 0: - if err = d.doEscrowTx(ctx, rng, cnsc); err != nil { + if err := d.doEscrowTx(ctx, rng, cnsc); err != nil { return err } case 1: - if err = d.doReclaimEscrowTx(ctx, rng, cnsc, stakingClient); err != nil { + if err := d.doReclaimEscrowTx(ctx, rng, cnsc, stakingClient); err != nil { return err } default: diff --git a/go/oasis-node/cmd/debug/txsource/workload/oversized.go b/go/oasis-node/cmd/debug/txsource/workload/oversized.go index d637c66fe89..a7fb0c6f4ad 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/oversized.go +++ b/go/oasis-node/cmd/debug/txsource/workload/oversized.go @@ -40,6 +40,7 @@ func (oversized) Run( if err != nil { return fmt.Errorf("failed to generate signer key: %w", err) } + txSignerAddr := staking.NewFromPublicKey(txSigner.Public()) ctx := context.Background() @@ -62,12 +63,12 @@ func (oversized) Run( for { // Generate a big transfer transaction which is valid, but oversized. type customTransfer struct { - To signature.PublicKey `json:"xfer_to"` - Data []byte `json:"xfer_data"` + To staking.Address `json:"xfer_to"` + Data []byte `json:"xfer_data"` } xfer := customTransfer{ // Send zero tokens to self, so the transaction will be valid. - To: txSigner.Public(), + To: txSignerAddr, // Include some extra random data so we are over the MaxTxSize limit. Data: make([]byte, genesisDoc.Consensus.Parameters.MaxTxSize), } @@ -75,7 +76,14 @@ func (oversized) Run( return fmt.Errorf("failed to generate bogus transaction: %w", err) } - if err = transferFunds(ctx, oversizedLogger, cnsc, fundingAccount, txSigner.Public(), int64(oversizedTxGasAmount*gasPrice)); err != nil { + if err = transferFunds( + ctx, + oversizedLogger, + cnsc, + fundingAccount, + txSignerAddr, + int64(oversizedTxGasAmount*gasPrice), + ); err != nil { return fmt.Errorf("workload/oversized: account funding failure: %w", err) } diff --git a/go/oasis-node/cmd/debug/txsource/workload/parallel.go b/go/oasis-node/cmd/debug/txsource/workload/parallel.go index a1fe153a6b6..6f99a16d2b8 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/parallel.go +++ b/go/oasis-node/cmd/debug/txsource/workload/parallel.go @@ -45,7 +45,7 @@ func (parallel) Run( // Estimate gas needed for the used transfer transaction. var txGasAmount transaction.Gas xfer := &staking.Transfer{ - To: fundingAccount.Public(), + To: staking.NewFromPublicKey(fundingAccount.Public()), } if err = xfer.Tokens.FromInt64(parallelTxTransferAmount); err != nil { return fmt.Errorf("transfer tokens FromInt64 %d: %w", parallelTxTransferAmount, err) @@ -69,7 +69,8 @@ func (parallel) Run( // Initial funding of accounts. fundAmount := parallelTxTransferAmount + // self transfer amount parallelTxFundInterval*txGasAmount*gasPrice // gas for `parallelTxFundInterval` transfers. - if err = transferFunds(ctx, parallelLogger, cnsc, fundingAccount, accounts[i].Public(), int64(fundAmount)); err != nil { + addr := staking.NewFromPublicKey(accounts[i].Public()) + if err = transferFunds(ctx, parallelLogger, cnsc, fundingAccount, addr, int64(fundAmount)); err != nil { return fmt.Errorf("account funding failure: %w", err) } } @@ -93,9 +94,11 @@ func (parallel) Run( go func(txSigner signature.Signer, nonce uint64) { defer wg.Done() + addr := staking.NewFromPublicKey(txSigner.Public()) + // Transfer tx. transfer := staking.Transfer{ - To: txSigner.Public(), + To: addr, } if err = transfer.Tokens.FromInt64(parallelTxTransferAmount); err != nil { errCh <- fmt.Errorf("transfer tokens FromInt64 %d: %w", parallelTxTransferAmount, err) @@ -112,7 +115,7 @@ func (parallel) Run( } parallelLogger.Debug("submitting self transfer", - "account", txSigner.Public(), + "account", addr, ) if err = cnsc.SubmitTx(ctx, signedTx); err != nil { parallelLogger.Error("SubmitTx error", "err", err) @@ -152,7 +155,8 @@ func (parallel) Run( // Re-fund accounts for next `parallelTxFundInterval` transfers. for i := range accounts { fundAmount := parallelTxFundInterval * txGasAmount * gasPrice // gas for `parallelTxFundInterval` transfers. - if err = transferFunds(ctx, parallelLogger, cnsc, fundingAccount, accounts[i].Public(), int64(fundAmount)); err != nil { + addr := staking.NewFromPublicKey(accounts[i].Public()) + if err = transferFunds(ctx, parallelLogger, cnsc, fundingAccount, addr, int64(fundAmount)); err != nil { return fmt.Errorf("account funding failure: %w", err) } } diff --git a/go/oasis-node/cmd/debug/txsource/workload/transfer.go b/go/oasis-node/cmd/debug/txsource/workload/transfer.go index 960b2a59ff8..affe6d62003 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/transfer.go +++ b/go/oasis-node/cmd/debug/txsource/workload/transfer.go @@ -34,6 +34,7 @@ type transfer struct { accounts []struct { signer signature.Signer + address staking.Address reckonedNonce uint64 reckonedBalance quantity.Quantity } @@ -44,7 +45,7 @@ func (t *transfer) doTransferTx(ctx context.Context, fromIdx int, toIdx int) err from := &t.accounts[fromIdx] to := &t.accounts[toIdx] - transfer := staking.Transfer{To: to.signer.Public()} + transfer := staking.Transfer{To: to.address} if err := transfer.Tokens.FromInt64(transferAmount); err != nil { return fmt.Errorf("transfer tokens FromInt64 %d: %w", transferAmount, err) } @@ -52,8 +53,8 @@ func (t *transfer) doTransferTx(ctx context.Context, fromIdx int, toIdx int) err from.reckonedNonce++ t.logger.Debug("transfering tokens", - "from", from.signer.Public(), - "to", to.signer.Public(), + "from", from.address, + "to", to.address, "amount", transferAmount, ) if err := fundSignAndSubmitTx(ctx, t.logger, t.consensus, from.signer, tx, t.fundingAccount); err != nil { @@ -79,7 +80,7 @@ func (t *transfer) doBurnTx(ctx context.Context, idx int) error { acc := &t.accounts[idx] // Fund account with tokens that will be burned. - if err := transferFunds(ctx, t.logger, t.consensus, t.fundingAccount, acc.signer.Public(), int64(transferBurnAmount)); err != nil { + if err := transferFunds(ctx, t.logger, t.consensus, t.fundingAccount, acc.address, int64(transferBurnAmount)); err != nil { return fmt.Errorf("workload/transfer: account funding failure: %w", err) } @@ -91,7 +92,7 @@ func (t *transfer) doBurnTx(ctx context.Context, idx int) error { acc.reckonedNonce++ t.logger.Debug("Burning tokens", - "account", acc.signer.Public(), + "account", acc.address, "amount", transferBurnAmount, ) if err := fundSignAndSubmitTx(ctx, t.logger, t.consensus, acc.signer, tx, t.fundingAccount); err != nil { @@ -112,13 +113,13 @@ func (t *transfer) Run( cnsc consensus.ClientBackend, fundingAccount signature.Signer, ) error { - var err error ctx := context.Background() t.logger = logging.GetLogger("cmd/txsource/workload/transfer") t.consensus = cnsc t.accounts = make([]struct { signer signature.Signer + address staking.Address reckonedNonce uint64 reckonedBalance quantity.Quantity }, transferNumAccounts) @@ -128,30 +129,32 @@ func (t *transfer) Run( // Load all the keys up front. Like, how annoyed would you be if down the line one of them turned out to be // corrupted or something, ya know? for i := range t.accounts { - t.accounts[i].signer, err = fac.Generate(signature.SignerEntity, rng) + signer, err := fac.Generate(signature.SignerEntity, rng) if err != nil { return fmt.Errorf("memory signer factory Generate account %d: %w", i, err) } + t.accounts[i].signer = signer + t.accounts[i].address = staking.NewFromPublicKey(signer.Public()) } // Read all the account info up front. stakingClient := staking.NewStakingClient(conn) for i := range t.accounts { fundAmount := transferAmount // funds for for a transfer - if err = transferFunds(ctx, t.logger, cnsc, t.fundingAccount, t.accounts[i].signer.Public(), int64(fundAmount)); err != nil { + if err := transferFunds(ctx, t.logger, cnsc, t.fundingAccount, t.accounts[i].address, int64(fundAmount)); err != nil { return fmt.Errorf("workload/transfer: account funding failure: %w", err) } var account *staking.Account - account, err = stakingClient.AccountInfo(ctx, &staking.OwnerQuery{ + account, err := stakingClient.AccountInfo(ctx, &staking.OwnerQuery{ Height: consensus.HeightLatest, - Owner: t.accounts[i].signer.Public(), + Owner: t.accounts[i].address, }) if err != nil { - return fmt.Errorf("stakingClient.AccountInfo %s: %w", t.accounts[i].signer.Public(), err) + return fmt.Errorf("stakingClient.AccountInfo %s: %w", t.accounts[i].address, err) } t.logger.Debug("account info", "i", i, - "pub", t.accounts[i].signer.Public(), + "address", t.accounts[i].address, "info", account, ) t.accounts[i].reckonedNonce = account.General.Nonce @@ -159,7 +162,7 @@ func (t *transfer) Run( } var minBalance quantity.Quantity - if err = minBalance.FromInt64(transferAmount); err != nil { + if err := minBalance.FromInt64(transferAmount); err != nil { return fmt.Errorf("min balance FromInt64 %d: %w", transferAmount, err) } for { @@ -180,12 +183,12 @@ func (t *transfer) Run( } toPermIdx := (fromPermIdx + 1) % transferNumAccounts - if err = t.doTransferTx(ctx, perm[fromPermIdx], perm[toPermIdx]); err != nil { + if err := t.doTransferTx(ctx, perm[fromPermIdx], perm[toPermIdx]); err != nil { return fmt.Errorf("transfer tx failure: %w", err) } case 1: // Burn tx. - if err = t.doBurnTx(ctx, rng.Intn(transferNumAccounts)); err != nil { + if err := t.doBurnTx(ctx, rng.Intn(transferNumAccounts)); err != nil { return fmt.Errorf("burn tx failure: %w", err) } diff --git a/go/oasis-node/cmd/debug/txsource/workload/workload.go b/go/oasis-node/cmd/debug/txsource/workload/workload.go index 578ab919a87..64919c64d5a 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/workload.go +++ b/go/oasis-node/cmd/debug/txsource/workload/workload.go @@ -28,12 +28,25 @@ const ( ) // FundAccountFromTestEntity funds an account from test entity. -func FundAccountFromTestEntity(ctx context.Context, logger *logging.Logger, cnsc consensus.ClientBackend, to signature.PublicKey) error { +func FundAccountFromTestEntity( + ctx context.Context, + logger *logging.Logger, + cnsc consensus.ClientBackend, + to signature.Signer, +) error { _, testEntitySigner, _ := entity.TestEntity() - return transferFunds(ctx, logger, cnsc, testEntitySigner, to, fundAccountAmount) + toAddr := staking.NewFromPublicKey(to.Public()) + return transferFunds(ctx, logger, cnsc, testEntitySigner, toAddr, fundAccountAmount) } -func fundSignAndSubmitTx(ctx context.Context, logger *logging.Logger, cnsc consensus.ClientBackend, caller signature.Signer, tx *transaction.Transaction, fundingAccount signature.Signer) error { +func fundSignAndSubmitTx( + ctx context.Context, + logger *logging.Logger, + cnsc consensus.ClientBackend, + caller signature.Signer, + tx *transaction.Transaction, + fundingAccount signature.Signer, +) error { // Estimate gas needed if not set. if tx.Fee.Gas == 0 { gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{ @@ -51,7 +64,8 @@ func fundSignAndSubmitTx(ctx context.Context, logger *logging.Logger, cnsc conse if err := tx.Fee.Amount.FromInt64(feeAmount); err != nil { return fmt.Errorf("fee amount from int64: %w", err) } - if err := transferFunds(ctx, logger, cnsc, fundingAccount, caller.Public(), feeAmount); err != nil { + callerAddr := staking.NewFromPublicKey(caller.Public()) + if err := transferFunds(ctx, logger, cnsc, fundingAccount, callerAddr, feeAmount); err != nil { return fmt.Errorf("account funding failure: %w", err) } @@ -88,7 +102,14 @@ func fundSignAndSubmitTx(ctx context.Context, logger *logging.Logger, cnsc conse } // transferFunds transfer funds between accounts. -func transferFunds(ctx context.Context, logger *logging.Logger, cnsc consensus.ClientBackend, from signature.Signer, to signature.PublicKey, transferAmount int64) error { +func transferFunds( + ctx context.Context, + logger *logging.Logger, + cnsc consensus.ClientBackend, + from signature.Signer, + to staking.Address, + transferAmount int64, +) error { sched := backoff.NewExponentialBackOff() sched.MaxInterval = maxSubmissionRetryInterval sched.MaxElapsedTime = maxSubmissionRetryElapsedTime diff --git a/go/oasis-node/cmd/genesis/genesis.go b/go/oasis-node/cmd/genesis/genesis.go index 5b600972fbf..f90abee5629 100644 --- a/go/oasis-node/cmd/genesis/genesis.go +++ b/go/oasis-node/cmd/genesis/genesis.go @@ -493,7 +493,7 @@ func AppendKeyManagerState(doc *genesis.Document, statuses []string, l *logging. // AppendStakingState appends the staking genesis state given a state file name. func AppendStakingState(doc *genesis.Document, state string, l *logging.Logger) error { stakingSt := staking.Genesis{ - Ledger: make(map[signature.PublicKey]*staking.Account), + Ledger: make(map[staking.Address]*staking.Account), } if err := stakingSt.Parameters.FeeSplitWeightVote.FromInt64(1); err != nil { return fmt.Errorf("couldn't set default fee split: %w", err) @@ -527,6 +527,7 @@ func AppendStakingState(doc *genesis.Document, state string, l *logging.Logger) ) return err } + entAddr := staking.NewFromPublicKey(ent.ID) // Ok then, we hold the world ransom for One Hundred Billion Dollars. var q quantity.Quantity @@ -537,7 +538,7 @@ func AppendStakingState(doc *genesis.Document, state string, l *logging.Logger) return err } - stakingSt.Ledger[ent.ID] = &staking.Account{ + stakingSt.Ledger[entAddr] = &staking.Account{ General: staking.GeneralAccount{ Balance: q, Nonce: 0, @@ -549,9 +550,9 @@ func AppendStakingState(doc *genesis.Document, state string, l *logging.Logger) }, }, } - stakingSt.Delegations = map[signature.PublicKey]map[signature.PublicKey]*staking.Delegation{ - ent.ID: map[signature.PublicKey]*staking.Delegation{ - ent.ID: &staking.Delegation{ + stakingSt.Delegations = map[staking.Address]map[staking.Address]*staking.Delegation{ + entAddr: map[staking.Address]*staking.Delegation{ + entAddr: &staking.Delegation{ Shares: stakingTests.QtyFromInt(1), }, }, diff --git a/go/oasis-node/cmd/stake/account.go b/go/oasis-node/cmd/stake/account.go index b6714be0619..952e6349a8f 100644 --- a/go/oasis-node/cmd/stake/account.go +++ b/go/oasis-node/cmd/stake/account.go @@ -11,7 +11,6 @@ import ( flag "github.com/spf13/pflag" "github.com/spf13/viper" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" cmdCommon "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common" cmdConsensus "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/consensus" cmdFlags "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/flags" @@ -20,8 +19,8 @@ import ( ) const ( - // CfgAccountID configures the account address. - CfgAccountID = "stake.account.id" + // CfgAccountAddr configures the account address. + CfgAccountAddr = "stake.account.address" // CfgAmount configures the amount of tokens. CfgAmount = "stake.amount" @@ -97,9 +96,9 @@ func doAccountInfo(cmd *cobra.Command, args []string) { cmdCommon.EarlyLogAndExit(err) } - var id signature.PublicKey - if err := id.UnmarshalText([]byte(viper.GetString(CfgAccountID))); err != nil { - logger.Error("failed to parse account ID", + var addr staking.Address + if err := addr.UnmarshalText([]byte(viper.GetString(CfgAccountAddr))); err != nil { + logger.Error("failed to parse account address", "err", err, ) os.Exit(1) @@ -109,7 +108,7 @@ func doAccountInfo(cmd *cobra.Command, args []string) { defer conn.Close() ctx := context.Background() - ai := getAccountInfo(ctx, cmd, id, client) + ai := getAccountInfo(ctx, cmd, addr, client) b, _ := json.Marshal(ai) fmt.Printf("%v\n", string(b)) } @@ -124,7 +123,7 @@ func doAccountTransfer(cmd *cobra.Command, args []string) { var xfer staking.Transfer if err := xfer.To.UnmarshalText([]byte(viper.GetString(CfgTransferDestination))); err != nil { - logger.Error("failed to parse transfer destination ID", + logger.Error("failed to parse transfer destination account address", "err", err, ) os.Exit(1) @@ -322,7 +321,7 @@ func registerAccountCmd() { } func init() { - accountInfoFlags.String(CfgAccountID, "", "ID of the account") + accountInfoFlags.String(CfgAccountAddr, "", "Address of the account") _ = viper.BindPFlags(accountInfoFlags) accountInfoFlags.AddFlagSet(cmdFlags.RetriesFlags) accountInfoFlags.AddFlagSet(cmdGrpc.ClientFlags) @@ -333,12 +332,12 @@ func init() { sharesFlags.String(CfgShares, "0", "amount of shares for the transaction") _ = viper.BindPFlags(sharesFlags) - accountTransferFlags.String(CfgTransferDestination, "", "transfer destination account ID") + accountTransferFlags.String(CfgTransferDestination, "", "transfer destination account address") _ = viper.BindPFlags(accountTransferFlags) accountTransferFlags.AddFlagSet(cmdConsensus.TxFlags) accountTransferFlags.AddFlagSet(amountFlags) - commonEscrowFlags.String(CfgEscrowAccount, "", "ID of the escrow account") + commonEscrowFlags.String(CfgEscrowAccount, "", "address of the escrow account") _ = viper.BindPFlags(commonEscrowFlags) commonEscrowFlags.AddFlagSet(cmdConsensus.TxFlags) diff --git a/go/oasis-node/cmd/stake/stake.go b/go/oasis-node/cmd/stake/stake.go index cdb5a05bcd0..781e77ad33c 100644 --- a/go/oasis-node/cmd/stake/stake.go +++ b/go/oasis-node/cmd/stake/stake.go @@ -11,7 +11,6 @@ import ( flag "github.com/spf13/pflag" "google.golang.org/grpc" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/errors" "github.com/oasisprotocol/oasis-core/go/common/logging" "github.com/oasisprotocol/oasis-core/go/common/quantity" @@ -172,32 +171,32 @@ func doList(cmd *cobra.Command, args []string) { ctx := context.Background() - var ids []signature.PublicKey + var addrs []api.Address doWithRetries(cmd, "query accounts", func() error { var err error - ids, err = client.Accounts(ctx, consensus.HeightLatest) + addrs, err = client.Accounts(ctx, consensus.HeightLatest) return err }) if cmdFlags.Verbose() { - accts := make(map[signature.PublicKey]*api.Account) - for _, v := range ids { + accts := make(map[api.Address]*api.Account) + for _, v := range addrs { accts[v] = getAccountInfo(ctx, cmd, v, client) } b, _ := json.Marshal(accts) fmt.Printf("%v\n", string(b)) } else { - for _, v := range ids { + for _, v := range addrs { fmt.Printf("%v\n", v) } } } -func getAccountInfo(ctx context.Context, cmd *cobra.Command, id signature.PublicKey, client api.Backend) *api.Account { +func getAccountInfo(ctx context.Context, cmd *cobra.Command, addr api.Address, client api.Backend) *api.Account { var acct *api.Account - doWithRetries(cmd, "query account "+id.String(), func() error { + doWithRetries(cmd, "query account "+addr.String(), func() error { var err error - acct, err = client.AccountInfo(ctx, &api.OwnerQuery{Owner: id, Height: consensus.HeightLatest}) + acct, err = client.AccountInfo(ctx, &api.OwnerQuery{Owner: addr, Height: consensus.HeightLatest}) return err }) diff --git a/go/oasis-test-runner/scenario/e2e/gas_fees_staking.go b/go/oasis-test-runner/scenario/e2e/gas_fees_staking.go index 29339d0cc05..0de9176febb 100644 --- a/go/oasis-test-runner/scenario/e2e/gas_fees_staking.go +++ b/go/oasis-test-runner/scenario/e2e/gas_fees_staking.go @@ -43,6 +43,8 @@ var ( // fixture used in this scenario. srcSigner = memorySigner.NewTestSigner("oasis gas fees e2e test signer: src") escrowSigner = memorySigner.NewTestSigner("oasis gas fees e2e test signer: escrow") + // TODO: Unify this with escrowAddress in stake_cli.go. + escrowAddr = staking.NewFromPublicKey(escrowSigner.Public()) ) type gasFeesImpl struct { @@ -265,14 +267,16 @@ func (sc *gasFeesImpl) getTotalEntityBalance(ctx context.Context) (*quantity.Qua var total quantity.Quantity for _, e := range sc.net.Entities()[1:] { // Only count entities with validators. ent, _ := e.Inner() + addr := staking.NewFromPublicKey(ent.ID) - acct, err := st.AccountInfo(ctx, &staking.OwnerQuery{Owner: ent.ID, Height: consensus.HeightLatest}) + acct, err := st.AccountInfo(ctx, &staking.OwnerQuery{Owner: addr, Height: consensus.HeightLatest}) if err != nil { - return nil, fmt.Errorf("failed to get account info: %w", err) + return nil, fmt.Errorf("failed to get account info for %s: %w", addr, err) } sc.logger.Debug("fetched balance", - "entity_id", ent.ID, + "entity", ent.ID, + "address", addr, "balance", acct.General.Balance, ) @@ -289,9 +293,10 @@ func (sc *gasFeesImpl) testTransfer(ctx context.Context, signer signature.Signer if err != nil { return fmt.Errorf("failed to generate destination account: %w", err) } + dstAddr := staking.NewFromPublicKey(dstSigner.Public()) transfer := staking.Transfer{ - To: dstSigner.Public(), + To: dstAddr, } _ = transfer.Tokens.FromInt64(amount) @@ -321,7 +326,7 @@ func (sc *gasFeesImpl) testBurn(ctx context.Context, signer signature.Signer) (* func (sc *gasFeesImpl) testAddEscrow(ctx context.Context, signer signature.Signer) (*quantity.Quantity, error) { return sc.testStakingGas(ctx, signer, true, func(acct *staking.Account, fee transaction.Fee, amount int64) error { escrow := staking.Escrow{ - Account: escrowSigner.Public(), + Account: escrowAddr, } _ = escrow.Tokens.FromInt64(amount) @@ -337,7 +342,7 @@ func (sc *gasFeesImpl) testAddEscrow(ctx context.Context, signer signature.Signe func (sc *gasFeesImpl) testReclaimEscrow(ctx context.Context, signer signature.Signer) (*quantity.Quantity, error) { return sc.testStakingGas(ctx, signer, false, func(acct *staking.Account, fee transaction.Fee, shares int64) error { escrow := staking.ReclaimEscrow{ - Account: escrowSigner.Public(), + Account: escrowAddr, } _ = escrow.Shares.FromInt64(shares) @@ -440,7 +445,8 @@ func (sc *gasFeesImpl) testStakingGasOp( st := sc.net.Controller().Staking // Fetch initial account info. - acct, err := st.AccountInfo(ctx, &staking.OwnerQuery{Owner: signer.Public(), Height: consensus.HeightLatest}) + addr := staking.NewFromPublicKey(signer.Public()) + acct, err := st.AccountInfo(ctx, &staking.OwnerQuery{Owner: addr, Height: consensus.HeightLatest}) if err != nil { return fmt.Errorf("failed to get account info: %w", err) } @@ -493,7 +499,7 @@ func (sc *gasFeesImpl) testStakingGasOp( } // Check account after the (failed) operation. - newAcct, err := st.AccountInfo(ctx, &staking.OwnerQuery{Owner: signer.Public(), Height: consensus.HeightLatest}) + newAcct, err := st.AccountInfo(ctx, &staking.OwnerQuery{Owner: addr, Height: consensus.HeightLatest}) if err != nil { return fmt.Errorf("failed to get account info: %w", err) } diff --git a/go/oasis-test-runner/scenario/e2e/runtime_dynamic.go b/go/oasis-test-runner/scenario/e2e/runtime_dynamic.go index 557433e8ad8..9a3288e387e 100644 --- a/go/oasis-test-runner/scenario/e2e/runtime_dynamic.go +++ b/go/oasis-test-runner/scenario/e2e/runtime_dynamic.go @@ -326,10 +326,11 @@ func (sc *runtimeDynamicImpl) Run(childEnv *env.Env) error { // nolint: gocyclo // Now reclaim all stake from the debug entity which owns the runtime. sc.logger.Info("reclaiming stake from entity which owns the runtime") entSigner := sc.net.Entities()[0].Signer() + entAddr := staking.NewFromPublicKey(entSigner.Public()) var oneShare quantity.Quantity _ = oneShare.FromUint64(1) tx := staking.NewReclaimEscrowTx(nonce, &transaction.Fee{Gas: 10000}, &staking.ReclaimEscrow{ - Account: entSigner.Public(), + Account: entAddr, Shares: oneShare, }) nonce++ @@ -424,7 +425,7 @@ func (sc *runtimeDynamicImpl) Run(childEnv *env.Env) error { // nolint: gocyclo var enoughTokens quantity.Quantity _ = enoughTokens.FromUint64(100_000) tx = staking.NewAddEscrowTx(nonce, &transaction.Fee{Gas: 10000}, &staking.Escrow{ - Account: entSigner.Public(), + Account: entAddr, Tokens: enoughTokens, }) nonce++ // nolint: ineffassign diff --git a/go/oasis-test-runner/scenario/e2e/stake_cli.go b/go/oasis-test-runner/scenario/e2e/stake_cli.go index 6846e2af00e..e823609907e 100644 --- a/go/oasis-test-runner/scenario/e2e/stake_cli.go +++ b/go/oasis-test-runner/scenario/e2e/stake_cli.go @@ -394,10 +394,10 @@ func (s *stakeCLIImpl) listAccounts(childEnv *env.Env) ([]signature.PublicKey, e } func (s *stakeCLIImpl) getAccountInfo(childEnv *env.Env, src signature.PublicKey) (*api.Account, error) { - s.logger.Info("checking account balance", stake.CfgAccountID, src.String()) + s.logger.Info("checking account balance", stake.CfgAccountAddr, src.String()) args := []string{ "stake", "account", "info", - "--" + stake.CfgAccountID, src.String(), + "--" + stake.CfgAccountAddr, src.String(), "--" + grpc.CfgAddress, "unix:" + s.runtimeImpl.net.Validators()[0].SocketPath(), } diff --git a/go/registry/api/sanity_check.go b/go/registry/api/sanity_check.go index 4771dd264cd..6eb72479bde 100644 --- a/go/registry/api/sanity_check.go +++ b/go/registry/api/sanity_check.go @@ -19,7 +19,7 @@ import ( // SanityCheck does basic sanity checking on the genesis state. func (g *Genesis) SanityCheck( baseEpoch epochtime.EpochTime, - stakeLedger map[signature.PublicKey]*staking.Account, + stakeLedger map[staking.Address]*staking.Account, stakeThresholds map[staking.ThresholdKind]quantity.Quantity, publicKeyBlacklist map[signature.PublicKey]bool, ) error { @@ -212,19 +212,20 @@ func SanityCheckNodes( // their registered nodes and runtimes. func SanityCheckStake( entities []*entity.Entity, - accounts map[signature.PublicKey]*staking.Account, + accounts map[staking.Address]*staking.Account, nodes []*node.Node, runtimes []*Runtime, stakeThresholds map[staking.ThresholdKind]quantity.Quantity, isGenesis bool, ) error { // Entities' escrow accounts for checking claims and stake. - generatedEscrows := make(map[signature.PublicKey]*staking.EscrowAccount) + generatedEscrows := make(map[staking.Address]*staking.EscrowAccount) // Generate escrow account for all entities. for _, entity := range entities { var escrow *staking.EscrowAccount - acct, ok := accounts[entity.ID] + addr := staking.NewFromPublicKey(entity.ID) + acct, ok := accounts[addr] if ok { // Generate an escrow account with the same active balance and shares number. escrow = &staking.EscrowAccount{ @@ -241,23 +242,26 @@ func SanityCheckStake( // Add entity stake claim. escrow.StakeAccumulator.AddClaimUnchecked(StakeClaimRegisterEntity, []staking.ThresholdKind{staking.KindEntity}) - generatedEscrows[entity.ID] = escrow + generatedEscrows[addr] = escrow } for _, node := range nodes { // Add node stake claims. - generatedEscrows[node.EntityID].StakeAccumulator.AddClaimUnchecked(StakeClaimForNode(node.ID), StakeThresholdsForNode(node)) + addr := staking.NewFromPublicKey(node.EntityID) + generatedEscrows[addr].StakeAccumulator.AddClaimUnchecked(StakeClaimForNode(node.ID), StakeThresholdsForNode(node)) } for _, rt := range runtimes { // Add runtime stake claims. - generatedEscrows[rt.EntityID].StakeAccumulator.AddClaimUnchecked(StakeClaimForRuntime(rt.ID), StakeThresholdsForRuntime(rt)) + addr := staking.NewFromPublicKey(rt.EntityID) + generatedEscrows[addr].StakeAccumulator.AddClaimUnchecked(StakeClaimForRuntime(rt.ID), StakeThresholdsForRuntime(rt)) } // Compare entities' generated escrow accounts with actual ones. for _, entity := range entities { var generatedEscrow, actualEscrow *staking.EscrowAccount - generatedEscrow = generatedEscrows[entity.ID] - acct, ok := accounts[entity.ID] + addr := staking.NewFromPublicKey(entity.ID) + generatedEscrow = generatedEscrows[addr] + acct, ok := accounts[addr] if ok { actualEscrow = &acct.Escrow } else { @@ -277,7 +281,7 @@ func SanityCheckStake( expected = expectedQty.String() } return fmt.Errorf("insufficient stake for account %s (expected: %s got: %s): %w", - entity.ID, + addr, expected, generatedEscrow.Active.Balance, err, @@ -287,11 +291,11 @@ func SanityCheckStake( // Otherwise, compare the expected accumulator state with the actual one. // NOTE: We can't perform this check for the Genesis document since it is not allowed to // have non-empty stake accumulators. - expectedClaims := generatedEscrows[entity.ID].StakeAccumulator.Claims + expectedClaims := generatedEscrows[addr].StakeAccumulator.Claims actualClaims := actualEscrow.StakeAccumulator.Claims if len(expectedClaims) != len(actualClaims) { return fmt.Errorf("incorrect number of stake claims for account %s (expected: %d got: %d)", - entity.ID, + addr, len(expectedClaims), len(actualClaims), ) @@ -299,12 +303,12 @@ func SanityCheckStake( for claim, expectedThresholds := range expectedClaims { thresholds, ok := actualClaims[claim] if !ok { - return fmt.Errorf("missing claim %s for account %s", claim, entity.ID) + return fmt.Errorf("missing claim %s for account %s", claim, addr) } if len(thresholds) != len(expectedThresholds) { return fmt.Errorf("incorrect number of thresholds for claim %s for account %s (expected: %d got: %d)", claim, - entity.ID, + addr, len(expectedThresholds), len(thresholds), ) @@ -315,7 +319,7 @@ func SanityCheckStake( return fmt.Errorf("incorrect threshold in position %d for claim %s for account %s (expected: %s got: %s)", i, claim, - entity.ID, + addr, expectedThreshold, threshold, ) diff --git a/go/staking/api/api.go b/go/staking/api/api.go index e69839f76f0..4bb86ac2185 100644 --- a/go/staking/api/api.go +++ b/go/staking/api/api.go @@ -24,16 +24,17 @@ const ( ) var ( - // CommonPoolAccountID signifies the common pool in staking events. - // The ID is invalid to prevent it being accidentally used in the - // actual ledger. - CommonPoolAccountID = signature.NewBlacklistedKey("1abe11edc001ffffffffffffffffffffffffffffffffffffffffffffffffffff") - - // FeeAccumulatorAccountID signifies the staking fee accumulator in - // staking events. - // The ID is invalid to prevent it being accidentally used in the - // actual ledger. - FeeAccumulatorAccountID = signature.NewBlacklistedKey("1abe11edfeeaccffffffffffffffffffffffffffffffffffffffffffffffffff") + // CommonPoolAddress signifies the common pool in staking events. + // The address is invalid to prevent it being accidentally used in the actual ledger. + CommonPoolAddress = NewFromPublicKey( + signature.NewBlacklistedKey("1abe11edc001ffffffffffffffffffffffffffffffffffffffffffffffffffff"), + ) + + // FeeAccumulatorAddress signifies the staking fee accumulator in staking events. + // The address is invalid to prevent it being accidentally used in the actual ledger. + FeeAccumulatorAddress = NewFromPublicKey( + signature.NewBlacklistedKey("1abe11edfeeaccffffffffffffffffffffffffffffffffffffffffffffffffff"), + ) // ErrInvalidArgument is the error returned on malformed arguments. ErrInvalidArgument = errors.New(ModuleName, 1, "staking: invalid argument") @@ -92,20 +93,20 @@ type Backend interface { // Threshold returns the specific staking threshold by kind. Threshold(ctx context.Context, query *ThresholdQuery) (*quantity.Quantity, error) - // Accounts returns the IDs of all accounts with a non-zero general - // or escrow balance. - Accounts(ctx context.Context, height int64) ([]signature.PublicKey, error) + // Accounts returns the addresses of all accounts with a non-zero general or + // escrow balance. + Accounts(ctx context.Context, height int64) ([]Address, error) // AccountInfo returns the account descriptor for the given account. AccountInfo(ctx context.Context, query *OwnerQuery) (*Account, error) // Delegations returns the list of delegations for the given owner // (delegator). - Delegations(ctx context.Context, query *OwnerQuery) (map[signature.PublicKey]*Delegation, error) + Delegations(ctx context.Context, query *OwnerQuery) (map[Address]*Delegation, error) // DebondingDelegations returns the list of debonding delegations for // the given owner (delegator). - DebondingDelegations(ctx context.Context, query *OwnerQuery) (map[signature.PublicKey][]*DebondingDelegation, error) + DebondingDelegations(ctx context.Context, query *OwnerQuery) (map[Address][]*DebondingDelegation, error) // StateToGenesis returns the genesis state at specified block height. StateToGenesis(ctx context.Context, height int64) (*Genesis, error) @@ -144,22 +145,22 @@ type ThresholdQuery struct { // OwnerQuery is an owner query. type OwnerQuery struct { - Height int64 `json:"height"` - Owner signature.PublicKey `json:"owner"` + Height int64 `json:"height"` + Owner Address `json:"owner"` } // TransferEvent is the event emitted when a balance is transfered, either by // a call to Transfer or Withdraw. type TransferEvent struct { - From signature.PublicKey `json:"from"` - To signature.PublicKey `json:"to"` - Tokens quantity.Quantity `json:"tokens"` + From Address `json:"from"` + To Address `json:"to"` + Tokens quantity.Quantity `json:"tokens"` } // BurnEvent is the event emitted when tokens are destroyed via a call to Burn. type BurnEvent struct { - Owner signature.PublicKey `json:"owner"` - Tokens quantity.Quantity `json:"tokens"` + Owner Address `json:"owner"` + Tokens quantity.Quantity `json:"tokens"` } // EscrowEvent is an escrow event. @@ -182,30 +183,30 @@ type Event struct { // AddEscrowEvent is the event emitted when a balance is transfered into // an escrow balance. type AddEscrowEvent struct { - Owner signature.PublicKey `json:"owner"` - Escrow signature.PublicKey `json:"escrow"` - Tokens quantity.Quantity `json:"tokens"` + Owner Address `json:"owner"` + Escrow Address `json:"escrow"` + Tokens quantity.Quantity `json:"tokens"` } // TakeEscrowEvent is the event emitted when balance is deducted from an // escrow balance (stake is slashed). type TakeEscrowEvent struct { - Owner signature.PublicKey `json:"owner"` - Tokens quantity.Quantity `json:"tokens"` + Owner Address `json:"owner"` + Tokens quantity.Quantity `json:"tokens"` } // ReclaimEscrowEvent is the event emitted when tokens are reclaimed from an // escrow balance back into the entity's general balance. type ReclaimEscrowEvent struct { - Owner signature.PublicKey `json:"owner"` - Escrow signature.PublicKey `json:"escrow"` - Tokens quantity.Quantity `json:"tokens"` + Owner Address `json:"owner"` + Escrow Address `json:"escrow"` + Tokens quantity.Quantity `json:"tokens"` } // Transfer is a token transfer. type Transfer struct { - To signature.PublicKey `json:"xfer_to"` - Tokens quantity.Quantity `json:"xfer_tokens"` + To Address `json:"xfer_to"` + Tokens quantity.Quantity `json:"xfer_tokens"` } // NewTransferTx creates a new transfer transaction. @@ -225,8 +226,8 @@ func NewBurnTx(nonce uint64, fee *transaction.Fee, burn *Burn) *transaction.Tran // Escrow is a token escrow. type Escrow struct { - Account signature.PublicKey `json:"escrow_account"` - Tokens quantity.Quantity `json:"escrow_tokens"` + Account Address `json:"escrow_account"` + Tokens quantity.Quantity `json:"escrow_tokens"` } // NewAddEscrowTx creates a new add escrow transaction. @@ -236,8 +237,8 @@ func NewAddEscrowTx(nonce uint64, fee *transaction.Fee, escrow *Escrow) *transac // ReclaimEscrow is a token escrow reclimation. type ReclaimEscrow struct { - Account signature.PublicKey `json:"escrow_account"` - Shares quantity.Quantity `json:"reclaim_shares"` + Account Address `json:"escrow_account"` + Shares quantity.Quantity `json:"reclaim_shares"` } // NewReclaimEscrowTx creates a new reclaim escrow transaction. @@ -541,10 +542,10 @@ type Genesis struct { CommonPool quantity.Quantity `json:"common_pool"` LastBlockFees quantity.Quantity `json:"last_block_fees"` - Ledger map[signature.PublicKey]*Account `json:"ledger,omitempty"` + Ledger map[Address]*Account `json:"ledger,omitempty"` - Delegations map[signature.PublicKey]map[signature.PublicKey]*Delegation `json:"delegations,omitempty"` - DebondingDelegations map[signature.PublicKey]map[signature.PublicKey][]*DebondingDelegation `json:"debonding_delegations,omitempty"` + Delegations map[Address]map[Address]*Delegation `json:"delegations,omitempty"` + DebondingDelegations map[Address]map[Address][]*DebondingDelegation `json:"debonding_delegations,omitempty"` } // ConsensusParameters are the staking consensus parameters. @@ -559,9 +560,9 @@ type ConsensusParameters struct { GasCosts transaction.Costs `json:"gas_costs,omitempty"` MinDelegationAmount quantity.Quantity `json:"min_delegation"` - DisableTransfers bool `json:"disable_transfers,omitempty"` - DisableDelegation bool `json:"disable_delegation,omitempty"` - UndisableTransfersFrom map[signature.PublicKey]bool `json:"undisable_transfers_from,omitempty"` + DisableTransfers bool `json:"disable_transfers,omitempty"` + DisableDelegation bool `json:"disable_delegation,omitempty"` + UndisableTransfersFrom map[Address]bool `json:"undisable_transfers_from,omitempty"` // FeeSplitWeightPropose is the proportion of block fee portions that go to the proposer. FeeSplitWeightPropose quantity.Quantity `json:"fee_split_weight_propose"` diff --git a/go/staking/api/grpc.go b/go/staking/api/grpc.go index f9de1d944d6..a83129d81e5 100644 --- a/go/staking/api/grpc.go +++ b/go/staking/api/grpc.go @@ -5,7 +5,6 @@ import ( "google.golang.org/grpc" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" cmnGrpc "github.com/oasisprotocol/oasis-core/go/common/grpc" "github.com/oasisprotocol/oasis-core/go/common/pubsub" "github.com/oasisprotocol/oasis-core/go/common/quantity" @@ -528,8 +527,8 @@ func (c *stakingClient) Threshold(ctx context.Context, query *ThresholdQuery) (* return &rsp, nil } -func (c *stakingClient) Accounts(ctx context.Context, height int64) ([]signature.PublicKey, error) { - var rsp []signature.PublicKey +func (c *stakingClient) Accounts(ctx context.Context, height int64) ([]Address, error) { + var rsp []Address if err := c.conn.Invoke(ctx, methodAccounts.FullName(), height, &rsp); err != nil { return nil, err } @@ -544,16 +543,16 @@ func (c *stakingClient) AccountInfo(ctx context.Context, query *OwnerQuery) (*Ac return &rsp, nil } -func (c *stakingClient) Delegations(ctx context.Context, query *OwnerQuery) (map[signature.PublicKey]*Delegation, error) { - var rsp map[signature.PublicKey]*Delegation +func (c *stakingClient) Delegations(ctx context.Context, query *OwnerQuery) (map[Address]*Delegation, error) { + var rsp map[Address]*Delegation if err := c.conn.Invoke(ctx, methodDelegations.FullName(), query, &rsp); err != nil { return nil, err } return rsp, nil } -func (c *stakingClient) DebondingDelegations(ctx context.Context, query *OwnerQuery) (map[signature.PublicKey][]*DebondingDelegation, error) { - var rsp map[signature.PublicKey][]*DebondingDelegation +func (c *stakingClient) DebondingDelegations(ctx context.Context, query *OwnerQuery) (map[Address][]*DebondingDelegation, error) { + var rsp map[Address][]*DebondingDelegation if err := c.conn.Invoke(ctx, methodDebondingDelegations.FullName(), query, &rsp); err != nil { return nil, err } diff --git a/go/staking/api/sanity_check.go b/go/staking/api/sanity_check.go index 2baf4b27296..ac496b31088 100644 --- a/go/staking/api/sanity_check.go +++ b/go/staking/api/sanity_check.go @@ -4,7 +4,6 @@ package api import ( "fmt" - "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" "github.com/oasisprotocol/oasis-core/go/common/quantity" epochtime "github.com/oasisprotocol/oasis-core/go/epochtime/api" ) @@ -41,18 +40,31 @@ func (p *ConsensusParameters) SanityCheck() error { // SanityCheckAccount examines an account's balances. // Adds the balances to a running total `total`. -func SanityCheckAccount(total *quantity.Quantity, parameters *ConsensusParameters, now epochtime.EpochTime, id signature.PublicKey, acct *Account) error { - if !id.IsValid() { - return fmt.Errorf("staking: sanity check failed: account has invalid ID: %s", id) +func SanityCheckAccount( + total *quantity.Quantity, + parameters *ConsensusParameters, + now epochtime.EpochTime, + addr Address, + acct *Account, +) error { + if !addr.IsValid() { + return fmt.Errorf("staking: sanity check failed: account has invalid address: %s", addr) } if !acct.General.Balance.IsValid() { - return fmt.Errorf("staking: sanity check failed: general balance is invalid for account with ID: %s", id) + return fmt.Errorf( + "staking: sanity check failed: general balance is invalid for account %s", addr, + ) } if !acct.Escrow.Active.Balance.IsValid() { - return fmt.Errorf("staking: sanity check failed: escrow active balance is invalid for account with ID: %s", id) + return fmt.Errorf( + "staking: sanity check failed: escrow active balance is invalid for account %s", addr, + ) } if !acct.Escrow.Debonding.Balance.IsValid() { - return fmt.Errorf("staking: sanity check failed: escrow debonding balance is invalid for account with ID: %s", id) + return fmt.Errorf( + "staking: sanity check failed: escrow debonding balance is invalid for account %s", + addr, + ) } _ = total.Add(&acct.General.Balance) @@ -61,14 +73,17 @@ func SanityCheckAccount(total *quantity.Quantity, parameters *ConsensusParameter commissionScheduleShallowCopy := acct.Escrow.CommissionSchedule if err := commissionScheduleShallowCopy.PruneAndValidateForGenesis(¶meters.CommissionScheduleRules, now); err != nil { - return fmt.Errorf("staking: sanity check failed: commission schedule for account with ID %s is invalid: %+v", id, err) + return fmt.Errorf( + "staking: sanity check failed: commission schedule for account %s is invalid: %+v", + addr, err, + ) } return nil } // SanityCheckDelegations examines an account's delegations. -func SanityCheckDelegations(id signature.PublicKey, account *Account, delegations map[signature.PublicKey]*Delegation) error { +func SanityCheckDelegations(addr Address, account *Account, delegations map[Address]*Delegation) error { var shares quantity.Quantity var numDelegations uint64 for _, d := range delegations { @@ -79,13 +94,19 @@ func SanityCheckDelegations(id signature.PublicKey, account *Account, delegation sharesExpected := account.Escrow.Active.TotalShares if shares.Cmp(&sharesExpected) != 0 { - return fmt.Errorf("staking: sanity check failed: all shares of all delegations (%s) for account with ID: %s don't add up to account's total active shares in escrow (%s)", shares, id, sharesExpected) + return fmt.Errorf( + "staking: sanity check failed: all shares of all delegations (%s) for account %s don't add up to account's total active shares in escrow (%s)", + shares, addr, sharesExpected, + ) } // Account's Escrow.Active.Balance must be 0 if account has no delegations. if numDelegations == 0 { if !account.Escrow.Active.Balance.IsZero() { - return fmt.Errorf("staking: sanity check failed: account with ID: %s has no delegations, but non-zero active escrow balance", id) + return fmt.Errorf( + "staking: sanity check failed: account %s has no delegations, but non-zero active escrow balance", + addr, + ) } } @@ -93,7 +114,7 @@ func SanityCheckDelegations(id signature.PublicKey, account *Account, delegation } // SanityCheckDebondingDelegations examines an account's debonding delegations. -func SanityCheckDebondingDelegations(id signature.PublicKey, account *Account, delegations map[signature.PublicKey][]*DebondingDelegation) error { +func SanityCheckDebondingDelegations(addr Address, account *Account, delegations map[Address][]*DebondingDelegation) error { var shares quantity.Quantity var numDebondingDelegations uint64 for _, dels := range delegations { @@ -106,20 +127,31 @@ func SanityCheckDebondingDelegations(id signature.PublicKey, account *Account, d sharesExpected := account.Escrow.Debonding.TotalShares if shares.Cmp(&sharesExpected) != 0 { - return fmt.Errorf("staking: sanity check failed: all shares of all debonding delegations (%s) for account with ID: %s don't add up to account's total debonding shares in escrow (%s)", shares, id, sharesExpected) + return fmt.Errorf( + "staking: sanity check failed: all shares of all debonding delegations (%s) for account %s don't add up to account's total debonding shares in escrow (%s)", + shares, addr, sharesExpected, + ) } // Account's Escrow.Debonding.Balance must be 0 if account has no debonding delegations. if numDebondingDelegations == 0 { if !account.Escrow.Debonding.Balance.IsZero() { - return fmt.Errorf("staking: sanity check failed: account with ID: %s has no debonding delegations, but non-zero debonding escrow balance", id) + return fmt.Errorf( + "staking: sanity check failed: account %s has no debonding delegations, but non-zero debonding escrow balance", + addr, + ) } } return nil } // SanityCheckAccountShares examines an account's share pools. -func SanityCheckAccountShares(id signature.PublicKey, acct *Account, delegations map[signature.PublicKey]*Delegation, debondingDelegations map[signature.PublicKey][]*DebondingDelegation) error { +func SanityCheckAccountShares( + addr Address, + acct *Account, + delegations map[Address]*Delegation, + debondingDelegations map[Address][]*DebondingDelegation, +) error { // Count the delegations for this account and add up the total shares. var shares quantity.Quantity var numDelegations uint64 @@ -129,12 +161,18 @@ func SanityCheckAccountShares(id signature.PublicKey, acct *Account, delegations } // Account's total active shares in escrow should match delegations. if shares.Cmp(&acct.Escrow.Active.TotalShares) != 0 { - return fmt.Errorf("staking: sanity check failed: delegations (%s) for account with ID: %s don't match account's total active shares in escrow (%s)", shares, id, acct.Escrow.Active.TotalShares) + return fmt.Errorf( + "staking: sanity check failed: delegations (%s) for account %s don't match account's total active shares in escrow (%s)", + shares, addr, acct.Escrow.Active.TotalShares, + ) } // If there are no delegations, the active escrow balance should be 0. if numDelegations == 0 { if !acct.Escrow.Active.Balance.IsZero() { - return fmt.Errorf("staking: sanity check failed: account with ID: %s has no delegations, but non-zero active escrow balance", id) + return fmt.Errorf( + "staking: sanity check failed: account %s has no delegations, but non-zero active escrow balance", + addr, + ) } } @@ -149,12 +187,18 @@ func SanityCheckAccountShares(id signature.PublicKey, acct *Account, delegations } // Account's total debonding shares in escrow should match debonding delegations. if debondingShares.Cmp(&acct.Escrow.Debonding.TotalShares) != 0 { - return fmt.Errorf("staking: sanity check failed: debonding delegations (%s) for account with ID: %s don't match account's total debonding shares in escrow (%s)", debondingShares, id, acct.Escrow.Debonding.TotalShares) + return fmt.Errorf( + "staking: sanity check failed: debonding delegations (%s) for account %s don't match account's total debonding shares in escrow (%s)", + debondingShares, addr, acct.Escrow.Debonding.TotalShares, + ) } // If there are no debonding delegations, the debonding escrow balance should be 0. if numDebondingDelegations == 0 { if !acct.Escrow.Debonding.Balance.IsZero() { - return fmt.Errorf("staking: sanity check failed: account with ID: %s has no debonding delegations, but non-zero debonding escrow balance", id) + return fmt.Errorf( + "staking: sanity check failed: account %s has no debonding delegations, but non-zero debonding escrow balance", + addr, + ) } } return nil @@ -182,8 +226,8 @@ func (g *Genesis) SanityCheck(now epochtime.EpochTime) error { // nolint: gocycl // common pool + last block fees + all balances in the ledger. // Check all commission schedules. var total quantity.Quantity - for id, acct := range g.Ledger { - err := SanityCheckAccount(&total, &g.Parameters, now, id, acct) + for addr, acct := range g.Ledger { + err := SanityCheckAccount(&total, &g.Parameters, now, addr, acct) if err != nil { return err } @@ -197,34 +241,42 @@ func (g *Genesis) SanityCheck(now epochtime.EpochTime) error { // nolint: gocycl _ = total.Add(&g.CommonPool) _ = total.Add(&g.LastBlockFees) if total.Cmp(&g.TotalSupply) != 0 { - return fmt.Errorf("staking: sanity check failed: balances in accounts plus common pool (%s) does not add up to total supply (%s)", total.String(), g.TotalSupply.String()) + return fmt.Errorf( + "staking: sanity check failed: balances in accounts plus common pool (%s) does not add up to total supply (%s)", + total.String(), g.TotalSupply.String(), + ) } // All shares of all delegations for a given account must add up to account's Escrow.Active.TotalShares. - for id, delegations := range g.Delegations { - acct := g.Ledger[id] + for addr, delegations := range g.Delegations { + acct := g.Ledger[addr] if acct == nil { - return fmt.Errorf("staking: sanity check failed: delegation specified for a nonexisting account with ID: %v", id) + return fmt.Errorf( + "staking: sanity check failed: delegation specified for a nonexisting account: %v", + addr, + ) } - if err := SanityCheckDelegations(id, acct, delegations); err != nil { + if err := SanityCheckDelegations(addr, acct, delegations); err != nil { return err } } // All shares of all debonding delegations for a given account must add up to account's Escrow.Debonding.TotalShares. - for id, delegations := range g.DebondingDelegations { - acct := g.Ledger[id] + for addr, delegations := range g.DebondingDelegations { + acct := g.Ledger[addr] if acct == nil { - return fmt.Errorf("staking: sanity check failed: debonding delegation specified for a nonexisting account with ID: %v", id) + return fmt.Errorf( + "staking: sanity check failed: debonding delegation specified for a nonexisting account: %v", addr, + ) } - if err := SanityCheckDebondingDelegations(id, acct, delegations); err != nil { + if err := SanityCheckDebondingDelegations(addr, acct, delegations); err != nil { return err } } // Check the above two invariants for each account as well. - for id, acct := range g.Ledger { - if err := SanityCheckAccountShares(id, acct, g.Delegations[id], g.DebondingDelegations[id]); err != nil { + for addr, acct := range g.Ledger { + if err := SanityCheckAccountShares(addr, acct, g.Delegations[addr], g.DebondingDelegations[addr]); err != nil { return err } } diff --git a/go/staking/gen_vectors/main.go b/go/staking/gen_vectors/main.go index 1194ce9ee54..dc778d9981b 100644 --- a/go/staking/gen_vectors/main.go +++ b/go/staking/gen_vectors/main.go @@ -42,10 +42,11 @@ func main() { for _, nonce := range []uint64{0, 1, 10, 42, 1000, 1_000_000, 10_000_000, math.MaxUint64} { // Valid transfer transactions. transferDst := memorySigner.NewTestSigner("oasis-core staking test vectors: Transfer dst") + transferDstAddr := staking.NewFromPublicKey(transferDst.Public()) for _, amt := range []int64{0, 1000, 10_000_000} { for _, tx := range []*transaction.Transaction{ staking.NewTransferTx(nonce, fee, &staking.Transfer{ - To: transferDst.Public(), + To: transferDstAddr, Tokens: quantityInt64(amt), }), } { @@ -66,10 +67,11 @@ func main() { // Valid escrow transactions. escrowDst := memorySigner.NewTestSigner("oasis-core staking test vectors: Escrow dst") + escrowDstAddr := staking.NewFromPublicKey(escrowDst.Public()) for _, amt := range []int64{0, 1000, 10_000_000} { for _, tx := range []*transaction.Transaction{ staking.NewAddEscrowTx(nonce, fee, &staking.Escrow{ - Account: escrowDst.Public(), + Account: escrowDstAddr, Tokens: quantityInt64(amt), }), } { @@ -79,10 +81,11 @@ func main() { // Valid reclaim escrow transactions. escrowSrc := memorySigner.NewTestSigner("oasis-core staking test vectors: ReclaimEscrow src") + escrowSrcAddr := staking.NewFromPublicKey(escrowSrc.Public()) for _, amt := range []int64{0, 1000, 10_000_000} { for _, tx := range []*transaction.Transaction{ staking.NewReclaimEscrowTx(nonce, fee, &staking.ReclaimEscrow{ - Account: escrowSrc.Public(), + Account: escrowSrcAddr, Shares: quantityInt64(amt), }), } { diff --git a/go/staking/tests/debug/debug_stake.go b/go/staking/tests/debug/debug_stake.go index 4937580731d..8162e3c1008 100644 --- a/go/staking/tests/debug/debug_stake.go +++ b/go/staking/tests/debug/debug_stake.go @@ -41,8 +41,8 @@ var ( // Zero RewardFactorBlockProposed is normal. }, TotalSupply: DebugStateTotalSupply, - Ledger: map[signature.PublicKey]*api.Account{ - DebugStateSrcID: &api.Account{ + Ledger: map[api.Address]*api.Account{ + DebugStateSrcAddress: &api.Account{ General: api.GeneralAccount{ Balance: DebugStateSrcGeneralBalance, }, @@ -54,19 +54,19 @@ var ( }, }, }, - Delegations: map[signature.PublicKey]map[signature.PublicKey]*api.Delegation{ - DebugStateSrcID: map[signature.PublicKey]*api.Delegation{ - DebugStateSrcID: &api.Delegation{ + Delegations: map[api.Address]map[api.Address]*api.Delegation{ + DebugStateSrcAddress: map[api.Address]*api.Delegation{ + DebugStateSrcAddress: &api.Delegation{ Shares: DebugStateSrcEscrowActiveShares, }, }, }, } - DebugStateSrcSigner = mustGenerateSigner() - DebugStateSrcID = DebugStateSrcSigner.Public() - destSigner = mustGenerateSigner() - DebugStateDestID = destSigner.Public() + DebugStateSrcSigner = mustGenerateSigner() + DebugStateSrcAddress = api.NewFromPublicKey(DebugStateSrcSigner.Public()) + destSigner = mustGenerateSigner() + DebugStateDestAddress = api.NewFromPublicKey(destSigner.Public()) ) func QtyFromInt(n int) quantity.Quantity { diff --git a/go/staking/tests/tester.go b/go/staking/tests/tester.go index 62fe286e5c0..f288bf855f6 100644 --- a/go/staking/tests/tester.go +++ b/go/staking/tests/tester.go @@ -50,14 +50,14 @@ func (s *stakingTestsState) update(t *testing.T, backend api.Backend, consensus require.NoError(err, "update: CommonPool") s.commonPool = commonPool - srcAccount, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + srcAccount, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "update: src: AccountInfo") s.srcAccountGeneralBalance = srcAccount.General.Balance s.srcAccountNonce = srcAccount.General.Nonce s.srcAccountEscrowActiveBalance = srcAccount.Escrow.Active.Balance s.srcAccountEscrowActiveShares = srcAccount.Escrow.Active.TotalShares - destAccount, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: DestID, Height: consensusAPI.HeightLatest}) + destAccount, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: DestAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "update: dest: AccountInfo") s.destAccountGeneralBalance = destAccount.General.Balance } @@ -74,8 +74,8 @@ var ( qtyOne = debug.QtyFromInt(1) srcSigner = debug.DebugStateSrcSigner - SrcID = debug.DebugStateSrcID - DestID = debug.DebugStateDestID + SrcAddr = debug.DebugStateSrcAddress + DestAddr = debug.DebugStateDestAddress ) // StakingImplementationTests exercises the basic functionality of a @@ -163,10 +163,10 @@ func testLastBlockFees(t *testing.T, state *stakingTestsState, backend api.Backe func testTransfer(t *testing.T, state *stakingTestsState, backend api.Backend, consensus consensusAPI.Backend) { require := require.New(t) - dstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: DestID, Height: consensusAPI.HeightLatest}) + dstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: DestAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "dest: AccountInfo") - srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - before") ch, sub, err := backend.WatchTransfers(context.Background()) @@ -174,7 +174,7 @@ func testTransfer(t *testing.T, state *stakingTestsState, backend api.Backend, c defer sub.Close() xfer := &api.Transfer{ - To: DestID, + To: DestAddr, Tokens: debug.QtyFromInt(math.MaxUint8), } tx := api.NewTransferTx(srcAcc.General.Nonce, nil, xfer) @@ -189,18 +189,18 @@ TransferWaitLoop: for { select { case ev := <-ch: - if ev.From.Equal(api.CommonPoolAccountID) || ev.To.Equal(api.CommonPoolAccountID) { + if ev.From.Equal(api.CommonPoolAddress) || ev.To.Equal(api.CommonPoolAddress) { gotCommon = true continue } - if ev.From.Equal(api.FeeAccumulatorAccountID) || ev.To.Equal(api.FeeAccumulatorAccountID) { + if ev.From.Equal(api.FeeAccumulatorAddress) || ev.To.Equal(api.FeeAccumulatorAddress) { gotFeeAcc = true continue } if !gotTransfer { - require.Equal(SrcID, ev.From, "Event: from") - require.Equal(DestID, ev.To, "Event: to") + require.Equal(SrcAddr, ev.From, "Event: from") + require.Equal(DestAddr, ev.To, "Event: to") require.Equal(xfer.Tokens, ev.Tokens, "Event: tokens") // Make sure that GetEvents also returns the transfer event. @@ -229,13 +229,13 @@ TransferWaitLoop: require.True(gotCommon || gotFeeAcc, "WatchTransfers should also return transfers related to the common pool and/or the fee accumulator") _ = srcAcc.General.Balance.Sub(&xfer.Tokens) - newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - after") require.Equal(srcAcc.General.Balance, newSrcAcc.General.Balance, "src: general balance - after") require.Equal(tx.Nonce+1, newSrcAcc.General.Nonce, "src: nonce - after") _ = dstAcc.General.Balance.Add(&xfer.Tokens) - newDstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: DestID, Height: consensusAPI.HeightLatest}) + newDstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: DestAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "dest: AccountInfo - after") require.Equal(dstAcc.General.Balance, newDstAcc.General.Balance, "dest: general balance - after") require.EqualValues(dstAcc.General.Nonce, newDstAcc.General.Nonce, "dest: nonce - after") @@ -252,7 +252,7 @@ TransferWaitLoop: func testTransferWatchEvents(t *testing.T, state *stakingTestsState, backend api.Backend, consensus consensusAPI.Backend) { require := require.New(t) - srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "AccountInfo") ch, sub, err := backend.WatchEvents(context.Background()) @@ -260,7 +260,7 @@ func testTransferWatchEvents(t *testing.T, state *stakingTestsState, backend api defer sub.Close() xfer := &api.Transfer{ - To: DestID, + To: DestAddr, Tokens: debug.QtyFromInt(math.MaxUint8), } tx := api.NewTransferTx(srcAcc.General.Nonce, nil, xfer) @@ -284,18 +284,18 @@ TransferWaitLoop: to := ev.TransferEvent.To // We should also get some traffic to/from the common pool and fee accumulator. - if from.Equal(api.CommonPoolAccountID) || to.Equal(api.CommonPoolAccountID) { + if from.Equal(api.CommonPoolAddress) || to.Equal(api.CommonPoolAddress) { gotCommon = true continue } - if from.Equal(api.FeeAccumulatorAccountID) || to.Equal(api.FeeAccumulatorAccountID) { + if from.Equal(api.FeeAccumulatorAddress) || to.Equal(api.FeeAccumulatorAddress) { gotFeeAcc = true continue } if !gotTransfer { - require.Equal(SrcID, from, "Event: from") - require.Equal(DestID, to, "Event: to") + require.Equal(SrcAddr, from, "Event: from") + require.Equal(DestAddr, to, "Event: to") require.Equal(xfer.Tokens, ev.TransferEvent.Tokens, "Event: tokens") // Height must be valid. @@ -321,7 +321,7 @@ TransferWaitLoop: func testSelfTransfer(t *testing.T, state *stakingTestsState, backend api.Backend, consensus consensusAPI.Backend) { require := require.New(t) - srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - before") ch, sub, err := backend.WatchTransfers(context.Background()) @@ -329,7 +329,7 @@ func testSelfTransfer(t *testing.T, state *stakingTestsState, backend api.Backen defer sub.Close() xfer := &api.Transfer{ - To: SrcID, + To: SrcAddr, Tokens: debug.QtyFromInt(math.MaxUint8), } tx := api.NewTransferTx(srcAcc.General.Nonce, nil, xfer) @@ -344,18 +344,18 @@ TransferWaitLoop: for { select { case ev := <-ch: - if ev.From.Equal(api.CommonPoolAccountID) || ev.To.Equal(api.CommonPoolAccountID) { + if ev.From.Equal(api.CommonPoolAddress) || ev.To.Equal(api.CommonPoolAddress) { gotCommon = true continue } - if ev.From.Equal(api.FeeAccumulatorAccountID) || ev.To.Equal(api.FeeAccumulatorAccountID) { + if ev.From.Equal(api.FeeAccumulatorAddress) || ev.To.Equal(api.FeeAccumulatorAddress) { gotFeeAcc = true continue } if !gotTransfer { - require.Equal(SrcID, ev.From, "Event: from") - require.Equal(SrcID, ev.To, "Event: to") + require.Equal(SrcAddr, ev.From, "Event: from") + require.Equal(SrcAddr, ev.To, "Event: to") require.Equal(xfer.Tokens, ev.Tokens, "Event: tokens") gotTransfer = true } @@ -370,7 +370,7 @@ TransferWaitLoop: require.True(gotCommon || gotFeeAcc, "WatchTransfers should also return transfers related to the common pool and/or the fee accumulator") - newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - after") require.Equal(srcAcc.General.Balance, newSrcAcc.General.Balance, "src: general balance - after") require.Equal(tx.Nonce+1, newSrcAcc.General.Nonce, "src: nonce - after") @@ -390,7 +390,7 @@ func testBurn(t *testing.T, state *stakingTestsState, backend api.Backend, conse totalSupply, err := backend.TotalSupply(context.Background(), consensusAPI.HeightLatest) require.NoError(err, "TotalSupply - before") - srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo") ch, sub, err := backend.WatchBurns(context.Background()) @@ -406,7 +406,7 @@ func testBurn(t *testing.T, state *stakingTestsState, backend api.Backend, conse select { case ev := <-ch: - require.Equal(SrcID, ev.Owner, "Event: owner") + require.Equal(SrcAddr, ev.Owner, "Event: owner") require.Equal(burn.Tokens, ev.Tokens, "Event: tokens") // Make sure that GetEvents also returns the burn event. @@ -432,18 +432,18 @@ func testBurn(t *testing.T, state *stakingTestsState, backend api.Backend, conse require.Equal(totalSupply, newTotalSupply, "totalSupply is reduced by burn") _ = srcAcc.General.Balance.Sub(&burn.Tokens) - newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo") require.Equal(srcAcc.General.Balance, newSrcAcc.General.Balance, "src: general balance - after") require.EqualValues(tx.Nonce+1, newSrcAcc.General.Nonce, "src: nonce - after") } func testEscrow(t *testing.T, state *stakingTestsState, backend api.Backend, consensus consensusAPI.Backend) { - testEscrowEx(t, state, backend, consensus, SrcID, srcSigner, DestID) + testEscrowEx(t, state, backend, consensus, SrcAddr, srcSigner, DestAddr) } func testSelfEscrow(t *testing.T, state *stakingTestsState, backend api.Backend, consensus consensusAPI.Backend) { - testEscrowEx(t, state, backend, consensus, SrcID, srcSigner, SrcID) + testEscrowEx(t, state, backend, consensus, SrcAddr, srcSigner, SrcAddr) } func testEscrowEx( // nolint: gocyclo @@ -451,13 +451,13 @@ func testEscrowEx( // nolint: gocyclo state *stakingTestsState, backend api.Backend, consensus consensusAPI.Backend, - srcID signature.PublicKey, + srcAddr api.Address, srcSigner signature.Signer, - dstID signature.PublicKey, + dstAddr api.Address, ) { require := require.New(t) - srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - before") require.False(srcAcc.General.Balance.IsZero(), "src: general balance != 0") require.Equal(state.srcAccountEscrowActiveBalance, srcAcc.Escrow.Active.Balance, "src: active escrow balance") @@ -465,9 +465,9 @@ func testEscrowEx( // nolint: gocyclo require.True(srcAcc.Escrow.Debonding.Balance.IsZero(), "src: debonding escrow balance == 0") require.True(srcAcc.Escrow.Debonding.TotalShares.IsZero(), "src: debonding escrow total shares == 0") - dstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstID, Height: consensusAPI.HeightLatest}) + dstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "dst: AccountInfo - before") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.True(dstAcc.Escrow.Active.Balance.IsZero(), "dst: active escrow balance == 0") require.True(dstAcc.Escrow.Active.TotalShares.IsZero(), "dst: active escrow total shares == 0") } @@ -482,7 +482,7 @@ func testEscrowEx( // nolint: gocyclo // Escrow. escrow := &api.Escrow{ - Account: dstID, + Account: dstAddr, Tokens: debug.QtyFromInt(math.MaxUint32), } tx := api.NewAddEscrowTx(srcAcc.General.Nonce, nil, escrow) @@ -494,8 +494,8 @@ func testEscrowEx( // nolint: gocyclo case rawEv := <-ch: ev := rawEv.Add require.NotNil(ev) - require.Equal(srcID, ev.Owner, "Event: owner") - require.Equal(dstID, ev.Escrow, "Event: escrow") + require.Equal(srcAddr, ev.Owner, "Event: owner") + require.Equal(dstAddr, ev.Escrow, "Event: escrow") require.Equal(escrow.Tokens, ev.Tokens, "Event: tokens") // Make sure that GetEvents also returns the add escrow event. @@ -518,18 +518,18 @@ func testEscrowEx( // nolint: gocyclo currentTotalShares := dstAcc.Escrow.Active.TotalShares.Clone() _ = dstAcc.Escrow.Active.Deposit(currentTotalShares, &srcAcc.General.Balance, &escrow.Tokens) - newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + newSrcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - after") require.Equal(srcAcc.General.Balance, newSrcAcc.General.Balance, "src: general balance - after") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.Equal(state.srcAccountEscrowActiveBalance, newSrcAcc.Escrow.Active.Balance, "src: active escrow balance unchanged - after") require.True(newSrcAcc.Escrow.Debonding.Balance.IsZero(), "src: debonding escrow balance == 0 - after") } require.Equal(tx.Nonce+1, newSrcAcc.General.Nonce, "src: nonce - after") - newDstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstID, Height: consensusAPI.HeightLatest}) + newDstAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "dst: AccountInfo - after") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.Equal(dstAcc.General.Balance, newDstAcc.General.Balance, "dst: general balance - after") require.Equal(dstAcc.General.Nonce, newDstAcc.General.Nonce, "dst: nonce - after") } @@ -545,7 +545,7 @@ func testEscrowEx( // nolint: gocyclo // Escrow some more. escrow = &api.Escrow{ - Account: dstID, + Account: dstAddr, Tokens: debug.QtyFromInt(math.MaxUint32), } tx = api.NewAddEscrowTx(srcAcc.General.Nonce, nil, escrow) @@ -557,8 +557,8 @@ func testEscrowEx( // nolint: gocyclo case rawEv := <-ch: ev := rawEv.Add require.NotNil(ev) - require.Equal(srcID, ev.Owner, "Event: owner") - require.Equal(dstID, ev.Escrow, "Event: escrow") + require.Equal(srcAddr, ev.Owner, "Event: owner") + require.Equal(dstAddr, ev.Escrow, "Event: escrow") require.Equal(escrow.Tokens, ev.Tokens, "Event: tokens") // Make sure that GetEvents also returns the add escrow event. @@ -581,18 +581,18 @@ func testEscrowEx( // nolint: gocyclo currentTotalShares = dstAcc.Escrow.Active.TotalShares.Clone() _ = dstAcc.Escrow.Active.Deposit(currentTotalShares, &srcAcc.General.Balance, &escrow.Tokens) - newSrcAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + newSrcAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - after 2nd") require.Equal(srcAcc.General.Balance, newSrcAcc.General.Balance, "src: general balance - after 2nd") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.Equal(state.srcAccountEscrowActiveBalance, newSrcAcc.Escrow.Active.Balance, "src: active escrow balance unchanged - after 2nd") require.True(newSrcAcc.Escrow.Debonding.Balance.IsZero(), "src: debonding escrow balance == 0 - after 2nd") } require.Equal(tx.Nonce+1, newSrcAcc.General.Nonce, "src: nonce - after 2nd") - newDstAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstID, Height: consensusAPI.HeightLatest}) + newDstAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "dst: AccountInfo - after 2nd") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.Equal(dstAcc.General.Balance, newDstAcc.General.Balance, "dst: general balance - after 2nd") require.Equal(dstAcc.General.Nonce, newDstAcc.General.Nonce, "dst: nonce - after 2nd") } @@ -607,12 +607,12 @@ func testEscrowEx( // nolint: gocyclo newDstAcc = nil // Reclaim escrow (subject to debonding). - debs, err := backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + debs, err := backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "DebondingDelegations - before") require.Len(debs, 0, "no debonding delegations before reclaiming escrow") reclaim := &api.ReclaimEscrow{ - Account: dstID, + Account: dstAddr, Shares: dstAcc.Escrow.Active.TotalShares, } tx = api.NewReclaimEscrowTx(srcAcc.General.Nonce, nil, reclaim) @@ -620,10 +620,10 @@ func testEscrowEx( // nolint: gocyclo require.NoError(err, "ReclaimEscrow") // Query debonding delegations. - debs, err = backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + debs, err = backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "DebondingDelegations - after (in debonding)") require.Len(debs, 1, "one debonding delegation after reclaiming escrow") - require.Len(debs[dstID], 1, "one debonding delegation after reclaiming escrow") + require.Len(debs[dstAddr], 1, "one debonding delegation after reclaiming escrow") // Advance epoch to trigger debonding. timeSource := consensus.EpochTime().(epochtime.SetableBackend) @@ -634,8 +634,8 @@ func testEscrowEx( // nolint: gocyclo case rawEv := <-ch: ev := rawEv.Reclaim require.NotNil(ev) - require.Equal(srcID, ev.Owner, "Event: owner") - require.Equal(dstID, ev.Escrow, "Event: escrow") + require.Equal(srcAddr, ev.Owner, "Event: owner") + require.Equal(dstAddr, ev.Escrow, "Event: escrow") require.Equal(totalEscrowed, &ev.Tokens, "Event: tokens") // Make sure that GetEvents also returns the reclaim escrow event. @@ -656,18 +656,18 @@ func testEscrowEx( // nolint: gocyclo } _ = srcAcc.General.Balance.Add(totalEscrowed) - newSrcAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + newSrcAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "src: AccountInfo - after debond") require.Equal(srcAcc.General.Balance, newSrcAcc.General.Balance, "src: general balance - after debond") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.Equal(state.srcAccountEscrowActiveBalance, srcAcc.Escrow.Active.Balance, "src: active escrow balance unchanged - after debond") require.True(srcAcc.Escrow.Debonding.Balance.IsZero(), "src: debonding escrow balance == 0 - after debond") } require.Equal(tx.Nonce+1, newSrcAcc.General.Nonce, "src: nonce - after debond") - newDstAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstID, Height: consensusAPI.HeightLatest}) + newDstAcc, err = backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: dstAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "dst: AccountInfo - after debond") - if !srcID.Equal(dstID) { + if !srcAddr.Equal(dstAddr) { require.Equal(dstAcc.General.Balance, newDstAcc.General.Balance, "dst: general balance - after debond") require.Equal(dstAcc.General.Nonce, newDstAcc.General.Nonce, "dst: nonce - after debond") } @@ -676,26 +676,26 @@ func testEscrowEx( // nolint: gocyclo require.True(newDstAcc.Escrow.Debonding.Balance.IsZero(), "dst: debonding escrow balance == 0 - after debond") require.True(newDstAcc.Escrow.Debonding.TotalShares.IsZero(), "dst: debonding escrow total shares == 0 - after debond") - debs, err = backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + debs, err = backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "DebondingDelegations - after (debonding completed)") require.Len(debs, 0, "no debonding delegations after debonding has completed") // Reclaim escrow (without enough shares). reclaim = &api.ReclaimEscrow{ - Account: dstID, + Account: dstAddr, Shares: reclaim.Shares, } tx = api.NewReclaimEscrowTx(newSrcAcc.General.Nonce, nil, reclaim) err = consensusAPI.SignAndSubmitTx(context.Background(), consensus, srcSigner, tx) require.Error(err, "ReclaimEscrow") - debs, err = backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcID, Height: consensusAPI.HeightLatest}) + debs, err = backend.DebondingDelegations(context.Background(), &api.OwnerQuery{Owner: srcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "DebondingDelegations") require.Len(debs, 0, "no debonding delegations after failed reclaim") // Escrow less than the minimum amount. escrow = &api.Escrow{ - Account: dstID, + Account: dstAddr, Tokens: debug.QtyFromInt(1), // Minimum is 10. } tx = api.NewAddEscrowTx(srcAcc.General.Nonce, nil, escrow) @@ -716,15 +716,17 @@ func testSlashDoubleSigning( require := require.New(t) // Delegate some stake to the validator so we can check if slashing works. - srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcID, Height: consensusAPI.HeightLatest}) + srcAcc, err := backend.AccountInfo(context.Background(), &api.OwnerQuery{Owner: SrcAddr, Height: consensusAPI.HeightLatest}) require.NoError(err, "AccountInfo") escrowCh, escrowSub, err := backend.WatchEscrows(context.Background()) require.NoError(err, "WatchEscrows") defer escrowSub.Close() + entAddr := api.NewFromPublicKey(ent.ID) + escrow := &api.Escrow{ - Account: ent.ID, + Account: entAddr, Tokens: debug.QtyFromInt(math.MaxUint32), } tx := api.NewAddEscrowTx(srcAcc.General.Nonce, nil, escrow) @@ -735,8 +737,8 @@ func testSlashDoubleSigning( case rawEv := <-escrowCh: ev := rawEv.Add require.NotNil(ev) - require.Equal(SrcID, ev.Owner, "Event: owner") - require.Equal(ent.ID, ev.Escrow, "Event: escrow") + require.Equal(SrcAddr, ev.Owner, "Event: owner") + require.Equal(entAddr, ev.Escrow, "Event: escrow") require.Equal(escrow.Tokens, ev.Tokens, "Event: tokens") case <-time.After(recvTimeout): t.Fatalf("failed to receive escrow event") @@ -763,7 +765,7 @@ WaitLoop: select { case ev := <-slashCh: if e := ev.Take; e != nil { - require.Equal(ent.ID, e.Owner, "TakeEscrowEvent - owner must be entity") + require.Equal(entAddr, e.Owner, "TakeEscrowEvent - owner must be entity's address") // All tokens must be slashed as defined in debugGenesisState. require.Equal(escrow.Tokens, e.Tokens, "TakeEscrowEvent - all tokens slashed") break WaitLoop diff --git a/go/upgrade/migrations/dummy.go b/go/upgrade/migrations/dummy.go index dee1bad9343..cc3bcead268 100644 --- a/go/upgrade/migrations/dummy.go +++ b/go/upgrade/migrations/dummy.go @@ -57,7 +57,8 @@ func (th *dummyMigrationHandler) ConsensusUpgrade(ctx *Context, privateCtx inter } // Set this entity's staking properly. - err = stakeState.SetAccount(abciCtx, TestEntity.ID, &staking.Account{ + testEntityAddr := staking.NewFromPublicKey(TestEntity.ID) + err = stakeState.SetAccount(abciCtx, testEntityAddr, &staking.Account{ Escrow: staking.EscrowAccount{ StakeAccumulator: staking.StakeAccumulator{ Claims: map[staking.StakeClaim][]staking.ThresholdKind{