Skip to content

Commit 173ed6a

Browse files
ValarDragoncwgoes
authored andcommitted
Merge PR #2282: simulation: Switch the log method from a single string to string builders
1 parent 8b8028e commit 173ed6a

File tree

14 files changed

+178
-143
lines changed

14 files changed

+178
-143
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ test_sim_gaia_nondeterminism:
157157

158158
test_sim_gaia_fast:
159159
@echo "Running quick Gaia simulation. This may take several minutes..."
160-
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=150 -v -timeout 24h
160+
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -v -timeout 24h
161161

162162
test_sim_gaia_slow:
163163
@echo "Running full Gaia simulation. This may take awhile!"

PENDING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ BREAKING CHANGES
4040
* [x/slashing] [#2122](https://github.com/cosmos/cosmos-sdk/pull/2122) - Implement slashing period
4141
* [types] [\#2119](https://github.com/cosmos/cosmos-sdk/issues/2119) Parsed error messages and ABCI log errors to make them more human readable.
4242
* [simulation] Rename TestAndRunTx to Operation [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
43+
* [simulation] Remove log and testing.TB from Operation and Invariants, in favor of using errors \#2282
4344
* [tools] Removed gocyclo [#2211](https://github.com/cosmos/cosmos-sdk/issues/2211)
4445
* [baseapp] Remove `SetTxDecoder` in favor of requiring the decoder be set in baseapp initialization. [#1441](https://github.com/cosmos/cosmos-sdk/issues/1441)
4546

@@ -104,6 +105,7 @@ IMPROVEMENTS
104105
* [store] Speedup IAVL iteration, and consequently everything that requires IAVL iteration. [#2143](https://github.com/cosmos/cosmos-sdk/issues/2143)
105106
* [store] \#1952, \#2281 Update IAVL dependency to v0.11.0
106107
* [simulation] Make timestamps randomized [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
108+
* [simulation] Make logs not just pure strings, speeding it up by a large factor at greater block heights \#2282
107109

108110
* Tendermint
109111

cmd/gaia/app/sim_test.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
dbm "github.com/tendermint/tendermint/libs/db"
1515
"github.com/tendermint/tendermint/libs/log"
1616

17-
"github.com/cosmos/cosmos-sdk/baseapp"
1817
sdk "github.com/cosmos/cosmos-sdk/types"
1918
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
2019
"github.com/cosmos/cosmos-sdk/x/gov"
@@ -108,12 +107,10 @@ func testAndRunTxs(app *GaiaApp) []simulation.Operation {
108107

109108
func invariants(app *GaiaApp) []simulation.Invariant {
110109
return []simulation.Invariant{
111-
func(t *testing.T, baseapp *baseapp.BaseApp, log string) {
112-
banksim.NonnegativeBalanceInvariant(app.accountMapper)(t, baseapp, log)
113-
govsim.AllInvariants()(t, baseapp, log)
114-
stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, app.accountMapper)(t, baseapp, log)
115-
slashingsim.AllInvariants()(t, baseapp, log)
116-
},
110+
banksim.NonnegativeBalanceInvariant(app.accountMapper),
111+
govsim.AllInvariants(),
112+
stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, app.accountMapper),
113+
slashingsim.AllInvariants(),
117114
}
118115
}
119116

x/bank/simulation/invariants.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package simulation
22

33
import (
4+
"errors"
45
"fmt"
5-
"testing"
6-
7-
"github.com/stretchr/testify/require"
86

97
"github.com/cosmos/cosmos-sdk/baseapp"
108
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -16,25 +14,25 @@ import (
1614

1715
// NonnegativeBalanceInvariant checks that all accounts in the application have non-negative balances
1816
func NonnegativeBalanceInvariant(mapper auth.AccountMapper) simulation.Invariant {
19-
return func(t *testing.T, app *baseapp.BaseApp, log string) {
17+
return func(app *baseapp.BaseApp) error {
2018
ctx := app.NewContext(false, abci.Header{})
2119
accts := mock.GetAllAccounts(mapper, ctx)
2220
for _, acc := range accts {
2321
coins := acc.GetCoins()
24-
require.True(t, coins.IsNotNegative(),
25-
fmt.Sprintf("%s has a negative denomination of %s\n%s",
22+
if !coins.IsNotNegative() {
23+
return fmt.Errorf("%s has a negative denomination of %s",
2624
acc.GetAddress().String(),
27-
coins.String(),
28-
log),
29-
)
25+
coins.String())
26+
}
3027
}
28+
return nil
3129
}
3230
}
3331

3432
// TotalCoinsInvariant checks that the sum of the coins across all accounts
3533
// is what is expected
3634
func TotalCoinsInvariant(mapper auth.AccountMapper, totalSupplyFn func() sdk.Coins) simulation.Invariant {
37-
return func(t *testing.T, app *baseapp.BaseApp, log string) {
35+
return func(app *baseapp.BaseApp) error {
3836
ctx := app.NewContext(false, abci.Header{})
3937
totalCoins := sdk.Coins{}
4038

@@ -45,6 +43,9 @@ func TotalCoinsInvariant(mapper auth.AccountMapper, totalSupplyFn func() sdk.Coi
4543
}
4644

4745
mapper.IterateAccounts(ctx, chkAccount)
48-
require.Equal(t, totalSupplyFn(), totalCoins, log)
46+
if !totalSupplyFn().IsEqual(totalCoins) {
47+
return errors.New("total calculated coins doesn't equal expected coins")
48+
}
49+
return nil
4950
}
5051
}

x/bank/simulation/msgs.go

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ import (
55
"fmt"
66
"math/big"
77
"math/rand"
8-
"testing"
9-
10-
"github.com/stretchr/testify/require"
118

129
"github.com/cosmos/cosmos-sdk/baseapp"
1310
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -21,7 +18,7 @@ import (
2118
// SimulateSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
2219
// accounts already exist.
2320
func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
24-
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
21+
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
2522
fromKey := simulation.RandomKey(r, keys)
2623
fromAddr := sdk.AccAddress(fromKey.PubKey().Address())
2724
toKey := simulation.RandomKey(r, keys)
@@ -51,22 +48,24 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
5148
initFromCoins[denomIndex].Denom,
5249
toAddr.String(),
5350
)
54-
log = fmt.Sprintf("%s\n%s", log, action)
5551

5652
coins := sdk.Coins{{initFromCoins[denomIndex].Denom, amt}}
5753
var msg = bank.MsgSend{
5854
Inputs: []bank.Input{bank.NewInput(fromAddr, coins)},
5955
Outputs: []bank.Output{bank.NewOutput(toAddr, coins)},
6056
}
61-
sendAndVerifyMsgSend(tb, app, mapper, msg, ctx, log, []crypto.PrivKey{fromKey})
57+
goErr = sendAndVerifyMsgSend(app, mapper, msg, ctx, []crypto.PrivKey{fromKey})
58+
if goErr != nil {
59+
return "", nil, goErr
60+
}
6261
event("bank/sendAndVerifyMsgSend/ok")
6362

6463
return action, nil, nil
6564
}
6665
}
6766

6867
// Sends and verifies the transition of a msg send. This fails if there are repeated inputs or outputs
69-
func sendAndVerifyMsgSend(tb testing.TB, app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, log string, privkeys []crypto.PrivKey) {
68+
func sendAndVerifyMsgSend(app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, privkeys []crypto.PrivKey) error {
7069
initialInputAddrCoins := make([]sdk.Coins, len(msg.Inputs))
7170
initialOutputAddrCoins := make([]sdk.Coins, len(msg.Outputs))
7271
AccountNumbers := make([]int64, len(msg.Inputs))
@@ -89,25 +88,22 @@ func sendAndVerifyMsgSend(tb testing.TB, app *baseapp.BaseApp, mapper auth.Accou
8988
res := app.Deliver(tx)
9089
if !res.IsOK() {
9190
// TODO: Do this in a more 'canonical' way
92-
fmt.Println(res)
93-
fmt.Println(log)
94-
tb.FailNow()
91+
return fmt.Errorf("Deliver failed %v", res)
9592
}
9693

9794
for i := 0; i < len(msg.Inputs); i++ {
9895
terminalInputCoins := mapper.GetAccount(ctx, msg.Inputs[i].Address).GetCoins()
99-
require.Equal(tb,
100-
initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins),
101-
terminalInputCoins,
102-
fmt.Sprintf("Input #%d had an incorrect amount of coins\n%s", i, log),
103-
)
96+
if !initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins).IsEqual(terminalInputCoins) {
97+
return fmt.Errorf("input #%d had an incorrect amount of coins", i)
98+
}
10499
}
105100
for i := 0; i < len(msg.Outputs); i++ {
106101
terminalOutputCoins := mapper.GetAccount(ctx, msg.Outputs[i].Address).GetCoins()
107102
if !terminalOutputCoins.IsEqual(initialOutputAddrCoins[i].Plus(msg.Outputs[i].Coins)) {
108-
tb.Fatalf("Output #%d had an incorrect amount of coins\n%s", i, log)
103+
return fmt.Errorf("output #%d had an incorrect amount of coins", i)
109104
}
110105
}
106+
return nil
111107
}
112108

113109
func randPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) {

x/gov/simulation/invariants.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
package simulation
22

33
import (
4-
"testing"
5-
6-
"github.com/stretchr/testify/require"
7-
84
"github.com/cosmos/cosmos-sdk/baseapp"
95
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
106
)
117

128
// AllInvariants tests all governance invariants
139
func AllInvariants() simulation.Invariant {
14-
return func(t *testing.T, app *baseapp.BaseApp, log string) {
10+
return func(app *baseapp.BaseApp) error {
1511
// TODO Add some invariants!
1612
// Checking proposal queues, no passed-but-unexecuted proposals, etc.
17-
require.Nil(t, nil)
13+
return nil
1814
}
1915
}

x/gov/simulation/msgs.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"math"
66
"math/rand"
7-
"testing"
87

98
"github.com/tendermint/tendermint/crypto"
109

@@ -45,10 +44,13 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, sk stake.Keepe
4544
})
4645
statePercentageArray := []float64{1, .9, .75, .4, .15, 0}
4746
curNumVotesState := 1
48-
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
47+
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
4948
// 1) submit proposal now
5049
sender := simulation.RandomKey(r, keys)
51-
msg := simulationCreateMsgSubmitProposal(tb, r, sender, log)
50+
msg, err := simulationCreateMsgSubmitProposal(r, sender)
51+
if err != nil {
52+
return "", nil, err
53+
}
5254
action = simulateHandleMsgSubmitProposal(msg, sk, handler, ctx, event)
5355
proposalID := k.GetLastProposalID(ctx)
5456
// 2) Schedule operations for votes
@@ -77,9 +79,12 @@ func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, sk stake.Keepe
7779
// Note: Currently doesn't ensure that the proposal txt is in JSON form
7880
func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operation {
7981
handler := gov.NewHandler(k)
80-
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
82+
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
8183
sender := simulation.RandomKey(r, keys)
82-
msg := simulationCreateMsgSubmitProposal(tb, r, sender, log)
84+
msg, err := simulationCreateMsgSubmitProposal(r, sender)
85+
if err != nil {
86+
return "", nil, err
87+
}
8388
action = simulateHandleMsgSubmitProposal(msg, sk, handler, ctx, event)
8489
return action, nil, nil
8590
}
@@ -100,25 +105,25 @@ func simulateHandleMsgSubmitProposal(msg gov.MsgSubmitProposal, sk stake.Keeper,
100105
return action
101106
}
102107

103-
func simulationCreateMsgSubmitProposal(tb testing.TB, r *rand.Rand, sender crypto.PrivKey, log string) gov.MsgSubmitProposal {
108+
func simulationCreateMsgSubmitProposal(r *rand.Rand, sender crypto.PrivKey) (msg gov.MsgSubmitProposal, err error) {
104109
addr := sdk.AccAddress(sender.PubKey().Address())
105110
deposit := randomDeposit(r)
106-
msg := gov.NewMsgSubmitProposal(
111+
msg = gov.NewMsgSubmitProposal(
107112
simulation.RandStringOfLength(r, 5),
108113
simulation.RandStringOfLength(r, 5),
109114
gov.ProposalTypeText,
110115
addr,
111116
deposit,
112117
)
113118
if msg.ValidateBasic() != nil {
114-
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
119+
err = fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
115120
}
116-
return msg
121+
return
117122
}
118123

119124
// SimulateMsgDeposit
120125
func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
121-
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
126+
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
122127
key := simulation.RandomKey(r, keys)
123128
addr := sdk.AccAddress(key.PubKey().Address())
124129
proposalID, ok := randomProposalID(r, k, ctx)
@@ -128,7 +133,7 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
128133
deposit := randomDeposit(r)
129134
msg := gov.NewMsgDeposit(addr, proposalID, deposit)
130135
if msg.ValidateBasic() != nil {
131-
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
136+
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
132137
}
133138
ctx, write := ctx.CacheContext()
134139
result := gov.NewHandler(k)(ctx, msg)
@@ -153,7 +158,7 @@ func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
153158

154159
// nolint: unparam
155160
func operationSimulateMsgVote(k gov.Keeper, sk stake.Keeper, key crypto.PrivKey, proposalID int64) simulation.Operation {
156-
return func(tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
161+
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
157162
if key == nil {
158163
key = simulation.RandomKey(r, keys)
159164
}
@@ -168,7 +173,7 @@ func operationSimulateMsgVote(k gov.Keeper, sk stake.Keeper, key crypto.PrivKey,
168173
option := randomVotingOption(r)
169174
msg := gov.NewMsgVote(addr, proposalID, option)
170175
if msg.ValidateBasic() != nil {
171-
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
176+
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
172177
}
173178
ctx, write := ctx.CacheContext()
174179
result := gov.NewHandler(k)(ctx, msg)

0 commit comments

Comments
 (0)