handler tests pass woot

...
This commit is contained in:
rigelrozanski 2018-04-03 22:26:39 -04:00
parent b8541c8174
commit 6b995ac701
3 changed files with 149 additions and 118 deletions

View File

@ -78,6 +78,9 @@ func ErrBadDelegatorAddr() sdk.Error {
func ErrCandidateExistsAddr() sdk.Error {
return newError(CodeInvalidValidator, "Candidate already exist, cannot re-declare candidacy")
}
func ErrCandidateRevoked() sdk.Error {
return newError(CodeInvalidValidator, "Candidacy for this address is currently revoked")
}
func ErrMissingSignature() sdk.Error {
return newError(CodeInvalidValidator, "Missing signature")
}

View File

@ -15,40 +15,6 @@ const (
GasUnbond int64 = 20
)
//XXX fix initstater
// separated for testing
//func InitState(ctx sdk.Context, k Keeper, key, value string) sdk.Error {
//params := k.GetParams(ctx)
//switch key {
//case "allowed_bond_denom":
//params.BondDenom = value
//case "max_vals", "gas_bond", "gas_unbond":
//i, err := strconv.Atoi(value)
//if err != nil {
//return sdk.ErrUnknownRequest(fmt.Sprintf("input must be integer, Error: %v", err.Error()))
//}
//switch key {
//case "max_vals":
//if i < 0 {
//return sdk.ErrUnknownRequest("cannot designate negative max validators")
//}
//params.MaxValidators = uint16(i)
//case "gas_bond":
//GasDelegate = int64(i)
//case "gas_unbound":
//GasUnbond = int64(i)
//}
//default:
//return sdk.ErrUnknownRequest(key)
//}
//k.setParams(params)
//return nil
//}
//_______________________________________________________________________
func NewHandler(k Keeper, ck bank.CoinKeeper) sdk.Handler {
@ -138,6 +104,9 @@ func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result {
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
return ErrBadBondingDenom().Result()
}
if candidate.Status == Revoked {
return ErrCandidateRevoked().Result()
}
if ctx.IsCheckTx() {
return sdk.Result{
GasUsed: GasDelegate,
@ -150,17 +119,14 @@ func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result {
return sdk.Result{}
}
// common functionality between handlers
func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
bondAmt sdk.Coin, candidate Candidate) sdk.Error {
if candidate.Status == Revoked { //candidate has been withdrawn
return ErrBondNotNominated()
}
// Get or create the delegator bond
existingBond, found := k.getDelegatorBond(ctx, delegatorAddr, candidate.Address)
bond, found := k.getDelegatorBond(ctx, delegatorAddr, candidate.Address)
if !found {
existingBond = DelegatorBond{
bond = DelegatorBond{
DelegatorAddr: delegatorAddr,
CandidateAddr: candidate.Address,
Shares: sdk.ZeroRat,
@ -168,28 +134,17 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address,
}
// Account new shares, save
err := BondCoins(ctx, k, existingBond, candidate, bondAmt)
pool := k.GetPool(ctx)
_, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{bondAmt})
if err != nil {
return err
}
k.setDelegatorBond(ctx, existingBond)
k.setCandidate(ctx, candidate)
return nil
}
// Perform all the actions required to bond tokens to a delegator bond from their account
func BondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond, candidate Candidate, amount sdk.Coin) sdk.Error {
_, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{amount})
if err != nil {
return err
}
p := k.GetPool(ctx)
p, candidate, newShares := p.candidateAddTokens(candidate, amount.Amount)
pool, candidate, newShares := pool.candidateAddTokens(candidate, bondAmt.Amount)
bond.Shares = bond.Shares.Add(newShares)
k.setPool(ctx, p)
k.setCandidate(ctx, candidate)
k.setDelegatorBond(ctx, bond)
k.setCandidate(ctx, candidate)
k.setPool(ctx, pool)
return nil
}
@ -216,7 +171,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
return ErrNotEnoughBondShares(msg.Shares).Result()
}
} else {
if !bond.Shares.GT(shares) {
if bond.Shares.LT(shares) {
return ErrNotEnoughBondShares(msg.Shares).Result()
}
}
@ -259,11 +214,12 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
// Add the coins
p := k.GetPool(ctx)
var returnAmount int64
p, candidate, returnAmount = p.candidateRemoveShares(candidate, shares)
p, candidate, returnAmount := p.candidateRemoveShares(candidate, shares)
returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
k.coinKeeper.AddCoins(ctx, bond.DelegatorAddr, returnCoins)
/////////////////////////////////////
// revoke candidate if necessary
if revokeCandidacy {
@ -286,26 +242,39 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
return sdk.Result{}
}
// XXX where this used
// Perform all the actions required to bond tokens to a delegator bond from their account
func UnbondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond, candidate Candidate, shares sdk.Rat) sdk.Error {
// TODO use or remove
//// Perform all the actions required to bond tokens to a delegator bond from their account
//func BondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond,
//candidate Candidate, amount sdk.Coin) (DelegatorBond, Candidate, Pool, sdk.Error) {
// subtract bond tokens from delegator bond
if bond.Shares.LT(shares) {
return sdk.ErrInsufficientFunds("") //XXX variables inside
}
bond.Shares = bond.Shares.Sub(shares)
//pool := k.GetPool(ctx)
//_, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{amount})
//if err != nil {
//return bond, candidate, pool, err
//}
//pool, candidate, newShares := pool.candidateAddTokens(candidate, amount.Amount)
//bond.Shares = bond.Shares.Add(newShares)
//return bond, candidate, pool, nil
//}
//// Perform all the actions required to bond tokens to a delegator bond from their account
//func UnbondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond,
//candidate Candidate, shares sdk.Rat) (DelegatorBond, Candidate, Pool, sdk.Error) {
p := k.GetPool(ctx)
var returnAmount int64
p, candidate, returnAmount = p.candidateRemoveShares(candidate, shares)
returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
//pool := k.GetPool(ctx)
_, err := k.coinKeeper.AddCoins(ctx, candidate.Address, returnCoins)
if err != nil {
return err
}
k.setPool(ctx, p)
k.setCandidate(ctx, candidate)
return nil
}
//// subtract bond tokens from delegator bond
//if bond.Shares.LT(shares) {
//errMsg := fmt.Sprintf("cannot unbond %v shares, only have %v shares available", shares, bond.Shares)
//return bond, candidate, pool, sdk.ErrInsufficientFunds(errMsg)
//}
//bond.Shares = bond.Shares.Sub(shares)
//pool, candidate, returnAmount := p.candidateRemoveShares(candidate, shares)
//returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}}
//_, err := k.coinKeeper.AddCoins(ctx, candidate.Address, returnCoins)
//if err != nil {
//return err
//}
//return bond, candidate, pool, nil
//}

View File

@ -23,7 +23,7 @@ func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt i
}
}
func newTestMsgDelegate(amt int64, delegatorAddr, candidateAddr sdk.Address) MsgDelegate {
func newTestMsgDelegate(delegatorAddr, candidateAddr sdk.Address, amt int64) MsgDelegate {
return MsgDelegate{
DelegatorAddr: delegatorAddr,
CandidateAddr: candidateAddr,
@ -31,12 +31,24 @@ func newTestMsgDelegate(amt int64, delegatorAddr, candidateAddr sdk.Address) Msg
}
}
//______________________________________________________________________
func TestDuplicatesMsgDeclareCandidacy(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 1000)
msgDeclareCandidacy := newTestMsgDeclareCandidacy(addrs[0], pks[0], 10)
candidateAddr := addrs[0]
pk := pks[0]
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pk, 10)
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
assert.True(t, got.IsOK(), "%v", got)
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
assert.Equal(t, Unbonded, candidate.Status)
assert.Equal(t, candidateAddr, candidate.Address)
assert.Equal(t, pk, candidate.PubKey)
assert.Equal(t, sdk.NewRat(10), candidate.Assets)
assert.Equal(t, sdk.NewRat(10), candidate.Liabilities)
assert.Equal(t, Description{}, candidate.Description)
// one candidate cannot bond twice
msgDeclareCandidacy.PubKey = pks[1]
@ -56,22 +68,41 @@ func TestIncrementsMsgDelegate(t *testing.T) {
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], bondAmount)
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
assert.True(t, got.IsOK(), "expected declare candidacy msg to be ok, got %v", got)
expectedBond := bondAmount
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
assert.Equal(t, bondAmount, candidate.Liabilities.Evaluate())
assert.Equal(t, bondAmount, candidate.Assets.Evaluate())
// just send the same msgbond multiple times
msgDelegate := newTestMsgDelegate(bondAmount, delegatorAddr, candidateAddr)
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, bondAmount)
for i := 0; i < 5; i++ {
got := handleMsgDelegate(ctx, msgDelegate, keeper)
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
//Check that the accounts and the bond account have the appropriate values
candidates := keeper.GetCandidates(ctx, 100)
expectedBond += bondAmount
expectedDelegator := initBond - expectedBond
gotBonded := candidates[0].Liabilities.Evaluate()
gotDelegator := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
require.Equal(t, expectedBond, gotBonded, "i: %v, %v, %v", i, expectedBond, gotBonded)
require.Equal(t, expectedDelegator, gotDelegator, "i: %v, %v, %v", i, expectedDelegator, gotDelegator) // XXX fix
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr)
require.True(t, found)
expBond := int64(i+1) * bondAmount
expLiabilities := int64(i+2) * bondAmount // (1 self delegation)
expDelegatorAcc := initBond - expBond
gotBond := bond.Shares.Evaluate()
gotLiabilities := candidate.Liabilities.Evaluate()
gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
require.Equal(t, expBond, gotBond,
"i: %v\nexpBond: %v\ngotBond: %v\ncandidate: %v\nbond: %v\n",
i, expBond, gotBond, candidate, bond)
require.Equal(t, expLiabilities, gotLiabilities,
"i: %v\nexpLiabilities: %v\ngotLiabilities: %v\ncandidate: %v\nbond: %v\n",
i, expLiabilities, gotLiabilities, candidate, bond)
require.Equal(t, expDelegatorAcc, gotDelegatorAcc,
"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\ncandidate: %v\nbond: %v\n",
i, expDelegatorAcc, gotDelegatorAcc, candidate, bond)
}
}
@ -82,13 +113,20 @@ func TestIncrementsMsgUnbond(t *testing.T) {
// declare candidacy, delegate
candidateAddr, delegatorAddr := addrs[0], addrs[1]
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], initBond)
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
assert.True(t, got.IsOK(), "expected declare-candidacy to be ok, got %v", got)
msgDelegate := newTestMsgDelegate(initBond, delegatorAddr, candidateAddr)
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, initBond)
got = handleMsgDelegate(ctx, msgDelegate, keeper)
assert.True(t, got.IsOK(), "expected delegation to be ok, got %v", got)
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
assert.Equal(t, initBond*2, candidate.Liabilities.Evaluate())
assert.Equal(t, initBond*2, candidate.Assets.Evaluate())
// just send the same msgUnbond multiple times
// TODO use decimals here
unbondShares, unbondSharesStr := int64(10), "10"
@ -99,15 +137,28 @@ func TestIncrementsMsgUnbond(t *testing.T) {
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
//Check that the accounts and the bond account have the appropriate values
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
candidate, found = keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr)
require.True(t, found)
expectedBond := initBond - int64(i+1)*unbondShares
expectedDelegator := initBond - expectedBond
gotBonded := candidate.Liabilities.Evaluate()
gotDelegator := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
require.Equal(t, expectedBond, gotBonded, "%v, %v", expectedBond, gotBonded)
require.Equal(t, expectedDelegator, gotDelegator, "%v, %v", expectedDelegator, gotDelegator)
expBond := initBond - int64(i+1)*unbondShares
expLiabilities := 2*initBond - int64(i+1)*unbondShares
expDelegatorAcc := initBond - expBond
gotBond := bond.Shares.Evaluate()
gotLiabilities := candidate.Liabilities.Evaluate()
gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
require.Equal(t, expBond, gotBond,
"i: %v\nexpBond: %v\ngotBond: %v\ncandidate: %v\nbond: %v\n",
i, expBond, gotBond, candidate, bond)
require.Equal(t, expLiabilities, gotLiabilities,
"i: %v\nexpLiabilities: %v\ngotLiabilities: %v\ncandidate: %v\nbond: %v\n",
i, expLiabilities, gotLiabilities, candidate, bond)
require.Equal(t, expDelegatorAcc, gotDelegatorAcc,
"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\ncandidate: %v\nbond: %v\n",
i, expDelegatorAcc, gotDelegatorAcc, candidate, bond)
}
// these are more than we have bonded now
@ -128,14 +179,18 @@ func TestIncrementsMsgUnbond(t *testing.T) {
leftBonded := initBond - unbondShares*int64(numUnbonds)
// should be unable to unbond one more than we have
msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, strconv.Itoa(int(leftBonded)+1))
unbondSharesStr = strconv.Itoa(int(leftBonded) + 1)
msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr)
got = handleMsgUnbond(ctx, msgUnbond, keeper)
assert.False(t, got.IsOK(), "expected unbond msg to fail")
assert.False(t, got.IsOK(),
"got: %v\nmsgUnbond: %v\nshares: %v\nleftBonded: %v\n", got, msgUnbond, unbondSharesStr, leftBonded)
// should be able to unbond just what we have
msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, strconv.Itoa(int(leftBonded)))
unbondSharesStr = strconv.Itoa(int(leftBonded))
msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr)
got = handleMsgUnbond(ctx, msgUnbond, keeper)
assert.True(t, got.IsOK(), "expected unbond msg to pass")
assert.True(t, got.IsOK(),
"got: %v\nmsgUnbond: %v\nshares: %v\nleftBonded: %v\n", got, msgUnbond, unbondSharesStr, leftBonded)
}
func TestMultipleMsgDeclareCandidacy(t *testing.T) {
@ -152,7 +207,7 @@ func TestMultipleMsgDeclareCandidacy(t *testing.T) {
//Check that the account is bonded
candidates := keeper.GetCandidates(ctx, 100)
require.Equal(t, i, len(candidates))
require.Equal(t, (i + 1), len(candidates))
val := candidates[i]
balanceExpd := initBond - 10
balanceGot := accMapper.GetAccount(ctx, val.Address).GetCoins().AmountOf(params.BondDenom)
@ -174,17 +229,17 @@ func TestMultipleMsgDeclareCandidacy(t *testing.T) {
require.Equal(t, len(candidateAddrs)-(i+1), len(candidates),
"expected %d candidates got %d", len(candidateAddrs)-(i+1), len(candidates))
candidatePost, found := keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
balanceExpd := initBond
balanceGot := accMapper.GetAccount(ctx, candidatePre.Address).GetCoins().AmountOf(params.BondDenom)
require.Nil(t, candidatePost, "expected nil candidate retrieve, got %d", 0, candidatePost)
require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot)
_, found = keeper.GetCandidate(ctx, candidateAddr)
require.False(t, found)
expBalance := initBond
gotBalance := accMapper.GetAccount(ctx, candidatePre.Address).GetCoins().AmountOf(params.BondDenom)
require.Equal(t, expBalance, gotBalance, "expected account to have %d, got %d", expBalance, gotBalance)
}
}
func TestMultipleMsgDelegate(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 0)
ctx, _, keeper := createTestInput(t, false, 1000)
candidateAddr, delegatorAddrs := addrs[0], addrs[1:]
//first make a candidate
@ -194,7 +249,7 @@ func TestMultipleMsgDelegate(t *testing.T) {
// delegate multiple parties
for i, delegatorAddr := range delegatorAddrs {
msgDelegate := newTestMsgDelegate(10, delegatorAddr, candidateAddr)
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, 10)
got := handleMsgDelegate(ctx, msgDelegate, keeper)
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
@ -217,8 +272,8 @@ func TestMultipleMsgDelegate(t *testing.T) {
}
func TestVoidCandidacy(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, 1000)
candidateAddr, delegatorAddr := addrs[0], addrs[1]
ctx, _, keeper := createTestInput(t, false, 0)
// create the candidate
msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], 10)
@ -226,21 +281,25 @@ func TestVoidCandidacy(t *testing.T) {
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
// bond a delegator
msgDelegate := newTestMsgDelegate(10, delegatorAddr, candidateAddr)
msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, 10)
got = handleMsgDelegate(ctx, msgDelegate, keeper)
require.True(t, got.IsOK(), "expected ok, got %v", got)
// unbond the candidates bond portion
msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, "10")
got = handleMsgUnbond(ctx, msgUnbond, keeper)
msgUnbondCandidate := NewMsgUnbond(candidateAddr, candidateAddr, "10")
got = handleMsgUnbond(ctx, msgUnbondCandidate, keeper)
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
candidate, found := keeper.GetCandidate(ctx, candidateAddr)
require.True(t, found)
require.Equal(t, Revoked, candidate.Status)
// test that this pubkey cannot yet be bonded too
// test that this address cannot yet be bonded too because is revoked
got = handleMsgDelegate(ctx, msgDelegate, keeper)
assert.False(t, got.IsOK(), "expected error, got %v", got)
// test that the delegator can still withdraw their bonds
got = handleMsgUnbond(ctx, msgUnbond, keeper)
msgUnbondDelegator := NewMsgUnbond(delegatorAddr, candidateAddr, "10")
got = handleMsgUnbond(ctx, msgUnbondDelegator, keeper)
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
// verify that the pubkey can now be reused