Skip to content

Commit

Permalink
Merge pull request #2672 from oasislabs/pro-wh/feature/notbefore
Browse files Browse the repository at this point in the history
go staking: add per-account lockup
  • Loading branch information
pro-wh authored Feb 14, 2020
2 parents ab41005 + b50c11d commit 314bce8
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changelog/2672.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
go staking: Add per-account lockup

With this, we'll be able to set up special accounts in the genesis
document where they're not permitted to transfer staking tokens until
a the specified epoch time.
They can still delegate during that time.
19 changes: 14 additions & 5 deletions go/consensus/tendermint/apps/staking/transactions.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
package staking

import (
"fmt"

"github.com/oasislabs/oasis-core/go/common/cbor"
"github.com/oasislabs/oasis-core/go/common/crypto/signature"
"github.com/oasislabs/oasis-core/go/common/quantity"
"github.com/oasislabs/oasis-core/go/consensus/tendermint/abci"
"github.com/oasislabs/oasis-core/go/consensus/tendermint/api"
stakingState "github.com/oasislabs/oasis-core/go/consensus/tendermint/apps/staking/state"
epochtime "github.com/oasislabs/oasis-core/go/epochtime/api"
staking "github.com/oasislabs/oasis-core/go/staking/api"
)

func isTransferPermitted(params *staking.ConsensusParameters, fromID signature.PublicKey) (permitted bool) {
func isTransferPermitted(params *staking.ConsensusParameters, fromID signature.PublicKey, from *staking.Account, epoch epochtime.EpochTime) (permitted bool) {
permitted = true
if params.DisableTransfers {
permitted = false
if params.UndisableTransfersFrom != nil && params.UndisableTransfersFrom[fromID] {
permitted = true
}
}
if epoch < from.General.TransfersNotBefore {
permitted = false
}
return
}

Expand All @@ -31,16 +37,19 @@ func (app *stakingApplication) transfer(ctx *abci.Context, state *stakingState.M
if err != nil {
return err
}
if err := ctx.Gas().UseGas(1, staking.GasOpTransfer, params.GasCosts); err != nil {
if err = ctx.Gas().UseGas(1, staking.GasOpTransfer, params.GasCosts); err != nil {
return err
}

fromID := ctx.TxSigner()
if !isTransferPermitted(params, fromID) {
return staking.ErrForbidden
epoch, err := app.state.GetCurrentEpoch(ctx.Ctx())
if err != nil {
return fmt.Errorf("getting current epoch: %w", err)
}

from := state.Account(fromID)
if !isTransferPermitted(params, fromID, from, epoch) {
return staking.ErrForbidden
}

if fromID.Equal(xfer.To) {
// Handle transfer to self as just a balance check.
Expand Down
50 changes: 49 additions & 1 deletion go/consensus/tendermint/apps/staking/transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/oasislabs/oasis-core/go/common/crypto/signature"
epochtime "github.com/oasislabs/oasis-core/go/epochtime/api"
staking "github.com/oasislabs/oasis-core/go/staking/api"
)

Expand All @@ -14,12 +15,16 @@ func TestIsTransferPermitted(t *testing.T) {
msg string
params *staking.ConsensusParameters
fromID signature.PublicKey
from *staking.Account
epoch epochtime.EpochTime
permitted bool
}{
{
"no disablement",
&staking.ConsensusParameters{},
signature.PublicKey{},
&staking.Account{},
0,
true,
},
{
Expand All @@ -28,6 +33,8 @@ func TestIsTransferPermitted(t *testing.T) {
DisableTransfers: true,
},
signature.PublicKey{},
&staking.Account{},
0,
false,
},
{
Expand All @@ -39,6 +46,8 @@ func TestIsTransferPermitted(t *testing.T) {
},
},
signature.PublicKey{},
&staking.Account{},
0,
false,
},
{
Expand All @@ -50,9 +59,48 @@ func TestIsTransferPermitted(t *testing.T) {
},
},
signature.PublicKey{},
&staking.Account{},
0,
true,
},
{
"before allowed",
&staking.ConsensusParameters{},
signature.PublicKey{},
&staking.Account{
General: staking.GeneralAccount{
TransfersNotBefore: 1,
},
},
0,
false,
},
{
"after allowed",
&staking.ConsensusParameters{},
signature.PublicKey{},
&staking.Account{},
1,
true,
},
{
"whitelisted before allowed ",
&staking.ConsensusParameters{
DisableTransfers: true,
UndisableTransfersFrom: map[signature.PublicKey]bool{
signature.PublicKey{}: true,
},
},
signature.PublicKey{},
&staking.Account{
General: staking.GeneralAccount{
TransfersNotBefore: 1,
},
},
0,
false,
},
} {
require.Equal(t, tt.permitted, isTransferPermitted(tt.params, tt.fromID), tt.msg)
require.Equal(t, tt.permitted, isTransferPermitted(tt.params, tt.fromID, tt.from, tt.epoch), tt.msg)
}
}
5 changes: 3 additions & 2 deletions go/staking/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,9 @@ func (sa *StakeAccumulator) TotalClaims(thresholds map[ThresholdKind]quantity.Qu

// GeneralAccount is a general-purpose account.
type GeneralAccount struct {
Balance quantity.Quantity `json:"balance"`
Nonce uint64 `json:"nonce"`
Balance quantity.Quantity `json:"balance"`
Nonce uint64 `json:"nonce"`
TransfersNotBefore epochtime.EpochTime `json:"transfers_not_before,omitempty"`
}

// EscrowAccount is an escrow account the balance of which is subject to
Expand Down

0 comments on commit 314bce8

Please sign in to comment.