diff --git a/x/stake/errors.go b/x/stake/errors.go index bd1992959e..e5b3e0cb3c 100644 --- a/x/stake/errors.go +++ b/x/stake/errors.go @@ -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") } diff --git a/x/stake/handler.go b/x/stake/handler.go index 6e3b6ff72d..094d01aeab 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -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 { @@ -95,7 +61,11 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe // move coins from the msg.Address account to a (self-bond) delegator account // the candidate account and global shares are updated within here - return delegateWithCandidate(ctx, k, msg.CandidateAddr, msg.Bond, candidate).Result() + err := delegate(ctx, k, msg.CandidateAddr, msg.Bond, candidate) + if err != nil { + return err.Result() + } + return sdk.Result{} } func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk.Result { @@ -134,25 +104,29 @@ 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, } } - return delegateWithCandidate(ctx, k, msg.DelegatorAddr, msg.Bond, candidate).Result() + err := delegate(ctx, k, msg.DelegatorAddr, msg.Bond, candidate) + if err != nil { + return err.Result() + } + return sdk.Result{} } -func delegateWithCandidate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, +// 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, @@ -160,28 +134,17 @@ func delegateWithCandidate(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 } @@ -208,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() } } @@ -251,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 { @@ -278,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 +//} diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index b435b754d6..1f0bc6415b 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -1,6 +1,5 @@ package stake -/* import ( "strconv" "testing" @@ -24,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, @@ -32,73 +31,134 @@ func newTestMsgDelegate(amt int64, delegatorAddr, candidateAddr sdk.Address) Msg } } -func TestDuplicatesMsgDeclareCandidacy(t *testing.T) { - ctx, _, keeper := createTestInput(t, addrs[0], false, 1000) +//______________________________________________________________________ - msgDeclareCandidacy := newTestMsgDeclareCandidacy(addrs[0], pks[0], 10) +func TestDuplicatesMsgDeclareCandidacy(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 1000) + + 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 sender cannot bond twice + // one candidate cannot bond twice msgDeclareCandidacy.PubKey = pks[1] got = handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper) assert.False(t, got.IsOK(), "%v", got) } func TestIncrementsMsgDelegate(t *testing.T) { - ctx, _, keeper := createTestInput(t, addrs[0], false, 1000) + initBond := int64(1000) + ctx, accMapper, keeper := createTestInput(t, false, initBond) + params := keeper.GetParams(ctx) + + bondAmount := int64(10) + candidateAddr, delegatorAddr := addrs[0], addrs[1] // first declare candidacy - bondAmount := int64(10) - msgDeclareCandidacy := newTestMsgDeclareCandidacy(addrs[0], pks[0], bondAmount) - got := deliverer.declareCandidacy(msgDeclareCandidacy) - assert.NoError(t, got, "expected declare candidacy msg to be ok, got %v", got) - expectedBond := bondAmount // 1 since we send 1 at the start of loop, + 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) + + 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, addrs[0]) + msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, bondAmount) for i := 0; i < 5; i++ { - got := deliverer.delegate(msgDelegate) - assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got) + 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 := mapper.GetCandidates() - expectedBond += bondAmount - //expectedSender := initSender - expectedBond - gotBonded := candidates[0].Liabilities.Evaluate() - //gotSender := accStore[string(deliverer.sender)] //XXX use StoreMapper - assert.Equal(t, expectedBond, gotBonded, "i: %v, %v, %v", i, expectedBond, gotBonded) - //assert.Equal(t, expectedSender, gotSender, "i: %v, %v, %v", i, expectedSender, gotSender) // 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) } } func TestIncrementsMsgUnbond(t *testing.T) { - ctx, _, keeper := createTestInput(t, addrs[0], false, 0) - - // set initial bond initBond := int64(1000) - //accStore[string(deliverer.sender)] = initBond //XXX use StoreMapper - got := deliverer.declareCandidacy(newTestMsgDeclareCandidacy(addrs[0], pks[0], initBond)) - assert.NoError(t, got, "expected initial bond msg to be ok, got %v", got) + ctx, accMapper, keeper := createTestInput(t, false, initBond) + params := keeper.GetParams(ctx) - // just send the same msgunbond multiple times - // XXX use decimals here + // 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(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" - msgUndelegate := NewMsgUnbond(addrs[0], unbondSharesStr) - nUnbonds := 5 - for i := 0; i < nUnbonds; i++ { - got := deliverer.unbond(msgUndelegate) - assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got) + msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr) + numUnbonds := 5 + for i := 0; i < numUnbonds; i++ { + got := handleMsgUnbond(ctx, msgUnbond, 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 := mapper.GetCandidates() - expectedBond := initBond - int64(i+1)*unbondShares // +1 since we send 1 at the start of loop - //expectedSender := initSender + (initBond - expectedBond) - gotBonded := candidates[0].Liabilities.Evaluate() - //gotSender := accStore[string(deliverer.sender)] // XXX use storemapper + candidate, found = keeper.GetCandidate(ctx, candidateAddr) + require.True(t, found) + bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + require.True(t, found) - assert.Equal(t, expectedBond, gotBonded, "%v, %v", expectedBond, gotBonded) - //assert.Equal(t, expectedSender, gotSender, "%v, %v", expectedSender, gotSender) //XXX fix + 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 @@ -111,135 +171,138 @@ func TestIncrementsMsgUnbond(t *testing.T) { } for _, c := range errorCases { unbondShares := strconv.Itoa(int(c)) - msgUndelegate := NewMsgUnbond(addrs[0], unbondShares) - got = deliverer.unbond(msgUndelegate) - assert.Error(t, got, "expected unbond msg to fail") + msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, unbondShares) + got = handleMsgUnbond(ctx, msgUnbond, keeper) + require.False(t, got.IsOK(), "expected unbond msg to fail") } - leftBonded := initBond - unbondShares*int64(nUnbonds) + leftBonded := initBond - unbondShares*int64(numUnbonds) // should be unable to unbond one more than we have - msgUndelegate = NewMsgUnbond(addrs[0], strconv.Itoa(int(leftBonded)+1)) - got = deliverer.unbond(msgUndelegate) - assert.Error(t, got, "expected unbond msg to fail") + unbondSharesStr = strconv.Itoa(int(leftBonded) + 1) + msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr) + got = handleMsgUnbond(ctx, msgUnbond, keeper) + 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 - msgUndelegate = NewMsgUnbond(addrs[0], strconv.Itoa(int(leftBonded))) - got = deliverer.unbond(msgUndelegate) - assert.NoError(t, got, "expected unbond msg to pass") + unbondSharesStr = strconv.Itoa(int(leftBonded)) + msgUnbond = NewMsgUnbond(delegatorAddr, candidateAddr, unbondSharesStr) + got = handleMsgUnbond(ctx, msgUnbond, keeper) + assert.True(t, got.IsOK(), + "got: %v\nmsgUnbond: %v\nshares: %v\nleftBonded: %v\n", got, msgUnbond, unbondSharesStr, leftBonded) } func TestMultipleMsgDeclareCandidacy(t *testing.T) { - initSender := int64(1000) - //ctx, accStore, mapper, deliverer := createTestInput(t, addrs[0], false, initSender) - ctx, mapper, keeper := createTestInput(t, addrs[0], false, initSender) - addrs := []sdk.Address{addrs[0], addrs[1], addrs[2]} + initBond := int64(1000) + ctx, accMapper, keeper := createTestInput(t, false, initBond) + params := keeper.GetParams(ctx) + candidateAddrs := []sdk.Address{addrs[0], addrs[1], addrs[2]} // bond them all - for i, addr := range addrs { - msgDeclareCandidacy := newTestMsgDeclareCandidacy(addrs[i], pks[i], 10) - deliverer.sender = addr - got := deliverer.declareCandidacy(msgDeclareCandidacy) - assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got) + for i, candidateAddr := range candidateAddrs { + msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[i], 10) + got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper) + require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) //Check that the account is bonded - candidates := mapper.GetCandidates() - require.Equal(t, i, len(candidates)) + candidates := keeper.GetCandidates(ctx, 100) + require.Equal(t, (i + 1), len(candidates)) val := candidates[i] - balanceExpd := initSender - 10 - balanceGot := accStore.GetAccount(ctx, val.Address).GetCoins() - assert.Equal(t, i+1, len(candidates), "expected %d candidates got %d, candidates: %v", i+1, len(candidates), candidates) - assert.Equal(t, 10, int(val.Liabilities.Evaluate()), "expected %d shares, got %d", 10, val.Liabilities) - assert.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) + balanceExpd := initBond - 10 + balanceGot := accMapper.GetAccount(ctx, val.Address).GetCoins().AmountOf(params.BondDenom) + require.Equal(t, i+1, len(candidates), "expected %d candidates got %d, candidates: %v", i+1, len(candidates), candidates) + require.Equal(t, 10, int(val.Liabilities.Evaluate()), "expected %d shares, got %d", 10, val.Liabilities) + require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) } // unbond them all - for i, addr := range addrs { - candidatePre := mapper.GetCandidate(addrs[i]) - msgUndelegate := NewMsgUnbond(addrs[i], "10") - deliverer.sender = addr - got := deliverer.unbond(msgUndelegate) - assert.NoError(t, got, "expected msg %d to be ok, got %v", i, got) + for i, candidateAddr := range candidateAddrs { + candidatePre, found := keeper.GetCandidate(ctx, candidateAddr) + require.True(t, found) + msgUnbond := NewMsgUnbond(candidateAddr, candidateAddr, "10") // self-delegation + got := handleMsgUnbond(ctx, msgUnbond, keeper) + require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) //Check that the account is unbonded - candidates := mapper.GetCandidates() - assert.Equal(t, len(addrs)-(i+1), len(candidates), "expected %d candidates got %d", len(addrs)-(i+1), len(candidates)) + candidates := keeper.GetCandidates(ctx, 100) + require.Equal(t, len(candidateAddrs)-(i+1), len(candidates), + "expected %d candidates got %d", len(candidateAddrs)-(i+1), len(candidates)) - candidatePost := mapper.GetCandidate(addrs[i]) - balanceExpd := initSender - balanceGot := accStore.GetAccount(ctx, candidatePre.Address).GetCoins() - assert.Nil(t, candidatePost, "expected nil candidate retrieve, got %d", 0, candidatePost) - assert.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) { - sender, delegators := addrs[0], addrs[1:] - _, _, mapper, deliverer := createTestInput(t, addrs[0], false, 1000) - ctx, _, keeper := createTestInput(t, addrs[0], false, 0) + ctx, _, keeper := createTestInput(t, false, 1000) + candidateAddr, delegatorAddrs := addrs[0], addrs[1:] //first make a candidate - msgDeclareCandidacy := newTestMsgDeclareCandidacy(sender, pks[0], 10) - got := deliverer.declareCandidacy(msgDeclareCandidacy) - require.NoError(t, got, "expected msg to be ok, got %v", got) + msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], 10) + got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper) + require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) // delegate multiple parties - for i, delegator := range delegators { - msgDelegate := newTestMsgDelegate(10, sender) - deliverer.sender = delegator - got := deliverer.delegate(msgDelegate) - require.NoError(t, got, "expected msg %d to be ok, got %v", i, got) + for i, delegatorAddr := range delegatorAddrs { + 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) //Check that the account is bonded - bond := mapper.getDelegatorBond(delegator, sender) - assert.NotNil(t, bond, "expected delegatee bond %d to exist", bond) + bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + require.True(t, found) + require.NotNil(t, bond, "expected delegatee bond %d to exist", bond) } // unbond them all - for i, delegator := range delegators { - msgUndelegate := NewMsgUnbond(sender, "10") - deliverer.sender = delegator - got := deliverer.unbond(msgUndelegate) - require.NoError(t, got, "expected msg %d to be ok, got %v", i, got) + for i, delegatorAddr := range delegatorAddrs { + msgUnbond := NewMsgUnbond(delegatorAddr, candidateAddr, "10") + got := handleMsgUnbond(ctx, msgUnbond, keeper) + require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) //Check that the account is unbonded - bond := mapper.getDelegatorBond(delegator, sender) - assert.Nil(t, bond, "expected delegatee bond %d to be nil", bond) + _, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + require.False(t, found) } } func TestVoidCandidacy(t *testing.T) { - sender, delegator := addrs[0], addrs[1] - _, _, _, deliverer := createTestInput(t, addrs[0], false, 1000) + ctx, _, keeper := createTestInput(t, false, 1000) + candidateAddr, delegatorAddr := addrs[0], addrs[1] // create the candidate - msgDeclareCandidacy := newTestMsgDeclareCandidacy(addrs[0], pks[0], 10) - got := deliverer.declareCandidacy(msgDeclareCandidacy) - require.NoError(t, got, "expected no error on runMsgDeclareCandidacy") + msgDeclareCandidacy := newTestMsgDeclareCandidacy(candidateAddr, pks[0], 10) + got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper) + require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy") // bond a delegator - msgDelegate := newTestMsgDelegate(10, addrs[0]) - deliverer.sender = delegator - got = deliverer.delegate(msgDelegate) - require.NoError(t, got, "expected ok, got %v", got) + 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 - msgUndelegate := NewMsgUnbond(addrs[0], "10") - deliverer.sender = sender - got = deliverer.unbond(msgUndelegate) - require.NoError(t, got, "expected no error on runMsgDeclareCandidacy") + 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 - deliverer.sender = delegator - got = deliverer.delegate(msgDelegate) - assert.Error(t, got, "expected error, got %v", got) + // 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 = deliverer.unbond(msgUndelegate) - require.NoError(t, got, "expected no error on runMsgDeclareCandidacy") + 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 - got = deliverer.declareCandidacy(msgDeclareCandidacy) - assert.NoError(t, got, "expected ok, got %v", got) + got = handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper) + assert.True(t, got.IsOK(), "expected ok, got %v", got) } -*/ diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 9a0d0f30ea..883ffcd177 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -27,7 +27,7 @@ var ( // This function tests GetCandidate, GetCandidates, setCandidate, removeCandidate func TestCandidate(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) //construct the candidates var candidates [3]Candidate @@ -97,7 +97,7 @@ func TestCandidate(t *testing.T) { // tests GetDelegatorBond, GetDelegatorBonds, SetDelegatorBond, removeDelegatorBond func TestBond(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) //construct the candidates amts := []int64{9, 8, 7} @@ -196,7 +196,7 @@ func TestBond(t *testing.T) { // TODO integrate in testing for equal validators, whichever one was a validator // first remains the validator https://github.com/cosmos/cosmos-sdk/issues/582 func TestGetValidators(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) // initialize some candidates into the state amts := []int64{0, 100, 1, 400, 200} @@ -269,7 +269,7 @@ func TestGetValidators(t *testing.T) { // clear the tracked changes to the validator set func TestClearAccUpdateValidators(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) amts := []int64{100, 400, 200} candidates := make([]Candidate, len(amts)) @@ -294,7 +294,7 @@ func TestClearAccUpdateValidators(t *testing.T) { // test the mechanism which keeps track of a validator set change func TestGetAccUpdateValidators(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) params := defaultParams() params.MaxValidators = 4 keeper.setParams(ctx, params) @@ -506,7 +506,7 @@ func TestGetAccUpdateValidators(t *testing.T) { // test if is a validator from the last update func TestIsRecentValidator(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) amts := []int64{9, 8, 7, 10, 6} var candidatesIn [5]Candidate @@ -546,7 +546,7 @@ func TestIsRecentValidator(t *testing.T) { } func TestParams(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) expParams := defaultParams() //check that the empty keeper loads the default @@ -561,7 +561,7 @@ func TestParams(t *testing.T) { } func TestPool(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) expPool := initialPool() //check that the empty keeper loads the default @@ -576,7 +576,7 @@ func TestPool(t *testing.T) { } func TestInitGenesis(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) jsonStr := `{ "params": { "inflation_rate_change": {"num": 13, "denom": 100}, diff --git a/x/stake/pool_test.go b/x/stake/pool_test.go index f8096e0ae2..cf1cd7ca24 100644 --- a/x/stake/pool_test.go +++ b/x/stake/pool_test.go @@ -12,7 +12,7 @@ import ( ) func TestBondedRatio(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) pool.TotalSupply = 3 pool.BondedPool = 2 @@ -26,7 +26,7 @@ func TestBondedRatio(t *testing.T) { } func TestBondedShareExRate(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) pool.BondedPool = 3 pool.BondedShares = sdk.NewRat(10) @@ -40,7 +40,7 @@ func TestBondedShareExRate(t *testing.T) { } func TestUnbondedShareExRate(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) pool.UnbondedPool = 3 pool.UnbondedShares = sdk.NewRat(10) @@ -54,7 +54,7 @@ func TestUnbondedShareExRate(t *testing.T) { } func TestBondedToUnbondedPool(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) @@ -81,7 +81,7 @@ func TestBondedToUnbondedPool(t *testing.T) { } func TestUnbonbedtoBondedPool(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) @@ -109,7 +109,7 @@ func TestUnbonbedtoBondedPool(t *testing.T) { } func TestAddTokensBonded(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) @@ -125,7 +125,7 @@ func TestAddTokensBonded(t *testing.T) { } func TestRemoveSharesBonded(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) @@ -142,7 +142,7 @@ func TestRemoveSharesBonded(t *testing.T) { } func TestAddTokensUnbonded(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) @@ -158,7 +158,7 @@ func TestAddTokensUnbonded(t *testing.T) { } func TestRemoveSharesUnbonded(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) @@ -174,7 +174,7 @@ func TestRemoveSharesUnbonded(t *testing.T) { } func TestCandidateAddTokens(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) candA := Candidate{ @@ -200,7 +200,7 @@ func TestCandidateAddTokens(t *testing.T) { } func TestCandidateRemoveShares(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) candA := Candidate{ diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 71b7454755..285364a5d9 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -11,7 +11,6 @@ import ( oldwire "github.com/tendermint/go-wire" dbm "github.com/tendermint/tmlibs/db" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -108,7 +107,7 @@ func makeTestCodec() *wire.Codec { const accTypeApp = 0x1 var _ = oldwire.RegisterInterface( struct{ sdk.Account }{}, - oldwire.ConcreteType{&types.AppAccount{}, accTypeApp}, + oldwire.ConcreteType{&auth.BaseAccount{}, accTypeApp}, ) cdc := wire.NewCodec() @@ -130,7 +129,7 @@ func paramsNoInflation() Params { } // hogpodge of all sorts of input required for testing -func createTestInput(t *testing.T, sender sdk.Address, isCheckTx bool, initCoins int64) (sdk.Context, sdk.AccountMapper, Keeper) { +func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context, sdk.AccountMapper, Keeper) { db := dbm.NewMemDB() keyStake := sdk.NewKVStoreKey("stake") keyMain := keyStake //sdk.NewKVStoreKey("main") //TODO fix multistore diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 24d95809fb..105ee8981f 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -9,7 +9,7 @@ import ( ) func TestGetInflation(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) params := keeper.GetParams(ctx) hrsPerYrRat := sdk.NewRat(hrsPerYr) @@ -60,7 +60,7 @@ func TestGetInflation(t *testing.T) { } func TestProcessProvisions(t *testing.T) { - ctx, _, keeper := createTestInput(t, nil, false, 0) + ctx, _, keeper := createTestInput(t, false, 0) params := defaultParams() keeper.setParams(ctx, params) pool := keeper.GetPool(ctx)