diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 5fea32b4e..593329acf 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -512,7 +512,7 @@ func cmdFinalizeBlock(cmd *cobra.Command, args []string) error { if err != nil { return err } - for _, tx := range res.Txs { + for _, tx := range res.TxResults { printResponse(cmd, args, response{ Code: tx.Code, Data: tx.Data, diff --git a/abci/example/example_test.go b/abci/example/example_test.go index bbe28d664..9d9d1548f 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -84,8 +84,8 @@ func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Ap // Send bulk request res, err := client.FinalizeBlock(ctx, rfb) require.NoError(t, err) - require.Equal(t, numDeliverTxs, len(res.Txs), "Number of txs doesn't match") - for _, tx := range res.Txs { + require.Equal(t, numDeliverTxs, len(res.TxResults), "Number of txs doesn't match") + for _, tx := range res.TxResults { require.Equal(t, tx.Code, code.CodeTypeOK, "Tx failed") } @@ -138,8 +138,8 @@ func testGRPCSync(ctx context.Context, t *testing.T, logger log.Logger, app type // Send request response, err := client.FinalizeBlock(ctx, &rfb) require.NoError(t, err, "Error in GRPC FinalizeBlock") - require.Equal(t, numDeliverTxs, len(response.Txs), "Number of txs returned via GRPC doesn't match") - for _, tx := range response.Txs { + require.Equal(t, numDeliverTxs, len(response.TxResults), "Number of txs returned via GRPC doesn't match") + for _, tx := range response.TxResults { require.Equal(t, tx.Code, code.CodeTypeOK, "Tx failed") } } diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 754027e05..0e23c2b4e 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -27,12 +27,12 @@ const ( func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) { req := types.RequestFinalizeBlock{Txs: [][]byte{tx}} ar := app.FinalizeBlock(req) - require.Equal(t, 1, len(ar.Txs)) - require.False(t, ar.Txs[0].IsErr()) + require.Equal(t, 1, len(ar.TxResults)) + require.False(t, ar.TxResults[0].IsErr()) // repeating tx doesn't raise error ar = app.FinalizeBlock(req) - require.Equal(t, 1, len(ar.Txs)) - require.False(t, ar.Txs[0].IsErr()) + require.Equal(t, 1, len(ar.TxResults)) + require.False(t, ar.TxResults[0].IsErr()) // commit app.Commit() @@ -326,13 +326,13 @@ func runClientTests(ctx context.Context, t *testing.T, client abciclient.Client) func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []byte, key, value string) { ar, err := app.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: [][]byte{tx}}) require.NoError(t, err) - require.Equal(t, 1, len(ar.Txs)) - require.False(t, ar.Txs[0].IsErr()) + require.Equal(t, 1, len(ar.TxResults)) + require.False(t, ar.TxResults[0].IsErr()) // repeating FinalizeBlock doesn't raise error ar, err = app.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: [][]byte{tx}}) require.NoError(t, err) - require.Equal(t, 1, len(ar.Txs)) - require.False(t, ar.Txs[0].IsErr()) + require.Equal(t, 1, len(ar.TxResults)) + require.False(t, ar.TxResults[0].IsErr()) // commit _, err = app.Commit(ctx) require.NoError(t, err) diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index 2a6e8aa19..e4247935d 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -2,10 +2,16 @@ package kvstore import ( "bytes" + "encoding/base64" + "fmt" + "strconv" + "strings" dbm "github.com/tendermint/tm-db" + "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" ptypes "github.com/tendermint/tendermint/proto/tendermint/types" @@ -30,15 +36,125 @@ func NewPersistentKVStoreApplication(logger log.Logger, dbDir string) *Persisten } return &PersistentKVStoreApplication{ - Application: &Application{ - valAddrToPubKeyMap: make(map[string]cryptoproto.PublicKey), - state: loadState(db), - logger: logger, - }, + app: &Application{state: state}, + valAddrToPubKeyMap: make(map[string]cryptoproto.PublicKey), + logger: logger, } } -func (app *PersistentKVStoreApplication) OfferSnapshot(req types.RequestOfferSnapshot) types.ResponseOfferSnapshot { +func (app *PersistentKVStoreApplication) Close() error { + return app.app.state.db.Close() +} + +func (app *PersistentKVStoreApplication) Info(req types.RequestInfo) types.ResponseInfo { + res := app.app.Info(req) + res.LastBlockHeight = app.app.state.Height + res.LastBlockAppHash = app.app.state.AppHash + return res +} + +// tx is either "val:pubkey!power" or "key=value" or just arbitrary bytes +func (app *PersistentKVStoreApplication) HandleTx(tx []byte) *types.ExecTxResult { + // if it starts with "val:", update the validator set + // format is "val:pubkey!power" + if isValidatorTx(tx) { + // update validators in the merkle tree + // and in app.ValUpdates + return app.execValidatorTx(tx) + } + + if isPrepareTx(tx) { + return app.execPrepareTx(tx) + } + + // otherwise, update the key-value store + return app.app.HandleTx(tx) +} + +func (app *PersistentKVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { + return app.app.CheckTx(req) +} + +// Commit will panic if InitChain was not called +func (app *PersistentKVStoreApplication) Commit() types.ResponseCommit { + return app.app.Commit() +} + +// When path=/val and data={validator address}, returns the validator update (types.ValidatorUpdate) varint encoded. +// For any other path, returns an associated value or nil if missing. +func (app *PersistentKVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { + switch reqQuery.Path { + case "/val": + key := []byte("val:" + string(reqQuery.Data)) + value, err := app.app.state.db.Get(key) + if err != nil { + panic(err) + } + + resQuery.Key = reqQuery.Data + resQuery.Value = value + return + default: + return app.app.Query(reqQuery) + } +} + +// Save the validators in the merkle tree +func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain { + for _, v := range req.Validators { + r := app.updateValidator(v) + if r.IsErr() { + app.logger.Error("error updating validators", "r", r) + } + } + return types.ResponseInitChain{} +} + +// Track the block hash and header information +// Execute transactions +// Update the validator set +func (app *PersistentKVStoreApplication) FinalizeBlock(req types.RequestFinalizeBlock) types.ResponseFinalizeBlock { + // reset valset changes + app.ValUpdates = make([]types.ValidatorUpdate, 0) + + // Punish validators who committed equivocation. + for _, ev := range req.ByzantineValidators { + if ev.Type == types.EvidenceType_DUPLICATE_VOTE { + addr := string(ev.Validator.Address) + if pubKey, ok := app.valAddrToPubKeyMap[addr]; ok { + app.updateValidator(types.ValidatorUpdate{ + PubKey: pubKey, + Power: ev.Validator.Power - 1, + }) + app.logger.Info("Decreased val power by 1 because of the equivocation", + "val", addr) + } else { + app.logger.Error("Wanted to punish val, but can't find it", + "val", addr) + } + } + } + + respTxs := make([]*types.ExecTxResult, len(req.Txs)) + for i, tx := range req.Txs { + respTxs[i] = app.HandleTx(tx) + } + + return types.ResponseFinalizeBlock{TxResults: respTxs, ValidatorUpdates: app.ValUpdates} +} + +func (app *PersistentKVStoreApplication) ListSnapshots( + req types.RequestListSnapshots) types.ResponseListSnapshots { + return types.ResponseListSnapshots{} +} + +func (app *PersistentKVStoreApplication) LoadSnapshotChunk( + req types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { + return types.ResponseLoadSnapshotChunk{} +} + +func (app *PersistentKVStoreApplication) OfferSnapshot( + req types.RequestOfferSnapshot) types.ResponseOfferSnapshot { return types.ResponseOfferSnapshot{Result: types.ResponseOfferSnapshot_ABORT} } @@ -50,12 +166,117 @@ func (app *PersistentKVStoreApplication) ExtendVote(req types.RequestExtendVote) return types.ResponseExtendVote{VoteExtension: ConstructVoteExtension(req.Vote.ValidatorAddress)} } -func (app *PersistentKVStoreApplication) VerifyVoteExtension(req types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension { - return types.RespondVerifyVoteExtension(app.verifyExtension(req.Vote.ValidatorAddress, req.Vote.VoteExtension)) +func isValidatorTx(tx []byte) bool { + return strings.HasPrefix(string(tx), ValidatorSetChangePrefix) +} + +// format is "val:pubkey!power" +// pubkey is a base64-encoded 32-byte ed25519 key +func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) *types.ExecTxResult { + tx = tx[len(ValidatorSetChangePrefix):] + + // get the pubkey and power + pubKeyAndPower := strings.Split(string(tx), "!") + if len(pubKeyAndPower) != 2 { + return &types.ExecTxResult{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Expected 'pubkey!power'. Got %v", pubKeyAndPower)} + } + pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1] + + // decode the pubkey + pubkey, err := base64.StdEncoding.DecodeString(pubkeyS) + if err != nil { + return &types.ExecTxResult{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Pubkey (%s) is invalid base64", pubkeyS)} + } + + // decode the power + power, err := strconv.ParseInt(powerS, 10, 64) + if err != nil { + return &types.ExecTxResult{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Power (%s) is not an int", powerS)} + } + + // update + return app.updateValidator(types.UpdateValidator(pubkey, power, "")) +} + +// add, update, or remove a validator +func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate) *types.ExecTxResult { + pubkey, err := encoding.PubKeyFromProto(v.PubKey) + if err != nil { + panic(fmt.Errorf("can't decode public key: %w", err)) + } + key := []byte("val:" + string(pubkey.Bytes())) + + if v.Power == 0 { + // remove validator + hasKey, err := app.app.state.db.Has(key) + if err != nil { + panic(err) + } + if !hasKey { + pubStr := base64.StdEncoding.EncodeToString(pubkey.Bytes()) + return &types.ExecTxResult{ + Code: code.CodeTypeUnauthorized, + Log: fmt.Sprintf("Cannot remove non-existent validator %s", pubStr)} + } + if err = app.app.state.db.Delete(key); err != nil { + panic(err) + } + delete(app.valAddrToPubKeyMap, string(pubkey.Address())) + } else { + // add or update validator + value := bytes.NewBuffer(make([]byte, 0)) + if err := types.WriteMessage(&v, value); err != nil { + return &types.ExecTxResult{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("error encoding validator: %v", err)} + } + if err = app.app.state.db.Set(key, value.Bytes()); err != nil { + panic(err) + } + app.valAddrToPubKeyMap[string(pubkey.Address())] = v.PubKey + } + + // we only update the changes array if we successfully updated the tree + app.ValUpdates = append(app.ValUpdates, v) + + return &types.ExecTxResult{Code: code.CodeTypeOK} } // ----------------------------- +const PreparePrefix = "prepare" + +func isPrepareTx(tx []byte) bool { + return strings.HasPrefix(string(tx), PreparePrefix) +} + +// execPrepareTx is noop. tx data is considered as placeholder +// and is substitute at the PrepareProposal. +func (app *PersistentKVStoreApplication) execPrepareTx(tx []byte) *types.ExecTxResult { + // noop + return &types.ExecTxResult{} +} + +// substPrepareTx subst all the preparetx in the blockdata +// to null string(could be any arbitrary string). +func (app *PersistentKVStoreApplication) substPrepareTx(blockData [][]byte) [][]byte { + // TODO: this mechanism will change with the current spec of PrepareProposal + // We now have a special type for marking a tx as changed + for i, tx := range blockData { + if isPrepareTx(tx) { + blockData[i] = make([]byte, len(tx)) + } + } + + return blockData +} + func ConstructVoteExtension(valAddr []byte) *ptypes.VoteExtension { return &ptypes.VoteExtension{ AppDataToSign: valAddr, diff --git a/abci/tests/server/client.go b/abci/tests/server/client.go index 4bdaf5b0e..9273e8046 100644 --- a/abci/tests/server/client.go +++ b/abci/tests/server/client.go @@ -51,7 +51,7 @@ func Commit(ctx context.Context, client abciclient.Client, hashExp []byte) error func FinalizeBlock(ctx context.Context, client abciclient.Client, txBytes [][]byte, codeExp []uint32, dataExp []byte) error { res, _ := client.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: txBytes}) - for i, tx := range res.Txs { + for i, tx := range res.TxResults { code, data, log := tx.Code, tx.Data, tx.Log if code != codeExp[i] { fmt.Println("Failed test: FinalizeBlock") diff --git a/abci/types/application.go b/abci/types/application.go index cf4a1de82..6961ea200 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -103,9 +103,9 @@ func (BaseApplication) ProcessProposal(req RequestProcessProposal) ResponseProce } func (BaseApplication) FinalizeBlock(req RequestFinalizeBlock) ResponseFinalizeBlock { - txs := make([]*ResponseDeliverTx, len(req.Txs)) + txs := make([]*ExecTxResult, len(req.Txs)) for i := range req.Txs { - txs[i] = &ResponseDeliverTx{Code: CodeTypeOK} + txs[i] = &ExecTxResult{Code: CodeTypeOK} } return ResponseFinalizeBlock{ TxResults: txs, diff --git a/cmd/tendermint/commands/reindex_event_test.go b/cmd/tendermint/commands/reindex_event_test.go index 3e7761c20..826fa0233 100644 --- a/cmd/tendermint/commands/reindex_event_test.go +++ b/cmd/tendermint/commands/reindex_event_test.go @@ -153,7 +153,7 @@ func TestReIndexEvent(t *testing.T) { On("IndexTxEvents", mock.AnythingOfType("[]*types.TxResult")).Return(errors.New("")).Once(). On("IndexTxEvents", mock.AnythingOfType("[]*types.TxResult")).Return(nil) - dtx := abcitypes.ResponseDeliverTx{} + dtx := abcitypes.ExecTxResult{} abciResp := &prototmstate.ABCIResponses{ FinalizeBlock: &abcitypes.ResponseFinalizeBlock{ TxResults: []*abcitypes.ExecTxResult{&dtx}, diff --git a/internal/consensus/mempool_test.go b/internal/consensus/mempool_test.go index 5cb977c7a..a0dd542ed 100644 --- a/internal/consensus/mempool_test.go +++ b/internal/consensus/mempool_test.go @@ -193,7 +193,7 @@ func TestMempoolRmBadTx(t *testing.T) { binary.BigEndian.PutUint64(txBytes, uint64(0)) resDeliver := app.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) - assert.False(t, resDeliver.Txs[0].IsErr(), fmt.Sprintf("expected no error. got %v", resDeliver)) + assert.False(t, resDeliver.TxResults[0].IsErr(), fmt.Sprintf("expected no error. got %v", resDeliver)) resCommit := app.Commit() assert.True(t, len(resCommit.Data) > 0) @@ -265,18 +265,18 @@ func (app *CounterApplication) Info(req abci.RequestInfo) abci.ResponseInfo { } func (app *CounterApplication) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { - respTxs := make([]*abci.ResponseDeliverTx, len(req.Txs)) + respTxs := make([]*abci.ExecTxResult, len(req.Txs)) for i, tx := range req.Txs { txValue := txAsUint64(tx) if txValue != uint64(app.txCount) { - respTxs[i] = &abci.ResponseDeliverTx{ + respTxs[i] = &abci.ExecTxResult{ Code: code.CodeTypeBadNonce, Log: fmt.Sprintf("Invalid nonce. Expected %d, got %d", app.txCount, txValue), } continue } app.txCount++ - respTxs[i] = &abci.ResponseDeliverTx{Code: code.CodeTypeOK} + respTxs[i] = &abci.ExecTxResult{Code: code.CodeTypeOK} } return abci.ResponseFinalizeBlock{TxResults: respTxs} } diff --git a/internal/consensus/replay_stubs.go b/internal/consensus/replay_stubs.go index 08eed5d69..721285778 100644 --- a/internal/consensus/replay_stubs.go +++ b/internal/consensus/replay_stubs.go @@ -32,7 +32,7 @@ func (emptyMempool) Update( _ context.Context, _ int64, _ types.Txs, - _ []*abci.ResponseDeliverTx, + _ []*abci.ExecTxResult, _ mempool.PreCheckFunc, _ mempool.PostCheckFunc, ) error { diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index 687932570..80160b380 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -668,8 +668,8 @@ func TestMockProxyApp(t *testing.T) { assert.NotPanics(t, func() { abciResWithEmptyDeliverTx := new(tmstate.ABCIResponses) abciResWithEmptyDeliverTx.FinalizeBlock = new(abci.ResponseFinalizeBlock) - abciResWithEmptyDeliverTx.FinalizeBlock.TxResults = make([]*abci.ResponseDeliverTx, 0) - abciResWithEmptyDeliverTx.FinalizeBlock.TxResults = append(abciResWithEmptyDeliverTx.FinalizeTxResults.Txs, &abci.ResponseDeliverTx{}) + abciResWithEmptyDeliverTx.FinalizeBlock.TxResults = make([]*abci.ExecTxResult, 0) + abciResWithEmptyDeliverTx.FinalizeBlock.TxResults = append(abciResWithEmptyDeliverTx.FinalizeBlock.TxResults, &abci.ExecTxResult{}) // called when saveABCIResponses: bytes, err := proto.Marshal(abciResWithEmptyDeliverTx) @@ -685,7 +685,7 @@ func TestMockProxyApp(t *testing.T) { abciRes := new(tmstate.ABCIResponses) abciRes.FinalizeBlock = new(abci.ResponseFinalizeBlock) - abciRes.FinalizeBlock.TxResults = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.FinalizeBlock.TxResults)) + abciRes.FinalizeBlock.TxResults = make([]*abci.ExecTxResult, len(loadedAbciRes.FinalizeBlock.TxResults)) someTx := []byte("tx") resp, err := mock.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{someTx}}) @@ -693,7 +693,7 @@ func TestMockProxyApp(t *testing.T) { // TODO: make use of res.Log // TODO: make use of this info // Blocks may include invalid txs. - for _, tx := range resp.Txs { + for _, tx := range resp.TxResults { if tx.Code == abci.CodeTypeOK { validTxs++ } else { diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 21429721d..7ab31bfc5 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -418,7 +418,7 @@ func (txmp *TxMempool) Update( ctx context.Context, blockHeight int64, blockTxs types.Txs, - deliverTxResponses []*abci.ResponseDeliverTx, + execTxResult []*abci.ExecTxResult, newPreFn PreCheckFunc, newPostFn PostCheckFunc, ) error { @@ -434,7 +434,7 @@ func (txmp *TxMempool) Update( } for i, tx := range blockTxs { - if deliverTxResponses[i].Code == abci.CodeTypeOK { + if execTxResult[i].Code == abci.CodeTypeOK { // add the valid committed transaction to the cache (if missing) _ = txmp.cache.Push(tx) } else if !txmp.config.KeepInvalidTxsInCache { diff --git a/internal/mempool/mempool_test.go b/internal/mempool/mempool_test.go index e2cf12e07..b9b0a5872 100644 --- a/internal/mempool/mempool_test.go +++ b/internal/mempool/mempool_test.go @@ -172,9 +172,9 @@ func TestTxMempool_TxsAvailable(t *testing.T) { rawTxs[i] = tx.tx } - responses := make([]*abci.ResponseDeliverTx, len(rawTxs[:50])) + responses := make([]*abci.ExecTxResult, len(rawTxs[:50])) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } // commit half the transactions and ensure we fire an event @@ -204,9 +204,9 @@ func TestTxMempool_Size(t *testing.T) { rawTxs[i] = tx.tx } - responses := make([]*abci.ResponseDeliverTx, len(rawTxs[:50])) + responses := make([]*abci.ExecTxResult, len(rawTxs[:50])) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } txmp.Lock() @@ -231,9 +231,9 @@ func TestTxMempool_Flush(t *testing.T) { rawTxs[i] = tx.tx } - responses := make([]*abci.ResponseDeliverTx, len(rawTxs[:50])) + responses := make([]*abci.ExecTxResult, len(rawTxs[:50])) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } txmp.Lock() @@ -446,7 +446,7 @@ func TestTxMempool_ConcurrentTxs(t *testing.T) { for range ticker.C { reapedTxs := txmp.ReapMaxTxs(200) if len(reapedTxs) > 0 { - responses := make([]*abci.ResponseDeliverTx, len(reapedTxs)) + responses := make([]*abci.ExecTxResult, len(reapedTxs)) for i := 0; i < len(responses); i++ { var code uint32 @@ -456,7 +456,7 @@ func TestTxMempool_ConcurrentTxs(t *testing.T) { code = abci.CodeTypeOK } - responses[i] = &abci.ResponseDeliverTx{Code: code} + responses[i] = &abci.ExecTxResult{Code: code} } txmp.Lock() @@ -494,9 +494,9 @@ func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) { // reap 5 txs at the next height -- no txs should expire reapedTxs := txmp.ReapMaxTxs(5) - responses := make([]*abci.ResponseDeliverTx, len(reapedTxs)) + responses := make([]*abci.ExecTxResult, len(reapedTxs)) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } txmp.Lock() @@ -520,9 +520,9 @@ func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) { // removed. However, we do know that that at most 95 txs can be expired and // removed. reapedTxs = txmp.ReapMaxTxs(5) - responses = make([]*abci.ResponseDeliverTx, len(reapedTxs)) + responses = make([]*abci.ExecTxResult, len(reapedTxs)) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } txmp.Lock() diff --git a/internal/mempool/mock/mempool.go b/internal/mempool/mock/mempool.go index e8782c914..1a0cd75ae 100644 --- a/internal/mempool/mock/mempool.go +++ b/internal/mempool/mock/mempool.go @@ -27,7 +27,7 @@ func (Mempool) Update( _ context.Context, _ int64, _ types.Txs, - _ []*abci.ResponseDeliverTx, + _ []*abci.ExecTxResult, _ mempool.PreCheckFunc, _ mempool.PostCheckFunc, ) error { diff --git a/internal/mempool/reactor_test.go b/internal/mempool/reactor_test.go index c073a7356..04e51ca8d 100644 --- a/internal/mempool/reactor_test.go +++ b/internal/mempool/reactor_test.go @@ -242,9 +242,9 @@ func TestReactorConcurrency(t *testing.T) { mempool.Lock() defer mempool.Unlock() - deliverTxResponses := make([]*abci.ResponseDeliverTx, len(txs)) + deliverTxResponses := make([]*abci.ExecTxResult, len(txs)) for i := range txs { - deliverTxResponses[i] = &abci.ResponseDeliverTx{Code: 0} + deliverTxResponses[i] = &abci.ExecTxResult{Code: 0} } require.NoError(t, mempool.Update(ctx, 1, convertTex(txs), deliverTxResponses, nil, nil)) @@ -261,7 +261,7 @@ func TestReactorConcurrency(t *testing.T) { mempool.Lock() defer mempool.Unlock() - err := mempool.Update(ctx, 1, []types.Tx{}, make([]*abci.ResponseDeliverTx, 0), nil, nil) + err := mempool.Update(ctx, 1, []types.Tx{}, make([]*abci.ExecTxResult, 0), nil, nil) require.NoError(t, err) }() } diff --git a/internal/mempool/types.go b/internal/mempool/types.go index d78517372..c2124d538 100644 --- a/internal/mempool/types.go +++ b/internal/mempool/types.go @@ -66,7 +66,7 @@ type Mempool interface { ctx context.Context, blockHeight int64, blockTxs types.Txs, - deliverTxResponses []*abci.ResponseDeliverTx, + txResults []*abci.ExecTxResult, newPreFn PreCheckFunc, newPostFn PostCheckFunc, ) error diff --git a/internal/rpc/core/blocks.go b/internal/rpc/core/blocks.go index dc7947b31..c4f490eae 100644 --- a/internal/rpc/core/blocks.go +++ b/internal/rpc/core/blocks.go @@ -208,8 +208,8 @@ func (env *Environment) BlockResults(ctx context.Context, heightPtr *int64) (*co } var totalGasUsed int64 - for _, tx := range results.FinalizeBlock.GetTxs() { - totalGasUsed += tx.GetGasUsed() + for _, res := range results.FinalizeBlock.GetTxResults() { + totalGasUsed += res.GetGasUsed() } return &coretypes.ResultBlockResults{ diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index 61d36e93a..92df22052 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -114,10 +114,10 @@ func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*co } return &coretypes.ResultBroadcastTxCommit{ - CheckTx: *r, - DeliverTx: txres.TxResult, - Hash: tx.Hash(), - Height: txres.Height, + CheckTx: *r, + TxResult: txres.TxResult, + Hash: tx.Hash(), + Height: txres.Height, }, nil } } diff --git a/internal/state/execution.go b/internal/state/execution.go index 71bdb2ffe..ec32b5f0f 100644 --- a/internal/state/execution.go +++ b/internal/state/execution.go @@ -326,7 +326,7 @@ func (blockExec *BlockExecutor) Commit( ctx context.Context, state State, block *types.Block, - deliverTxResponses []*abci.ResponseDeliverTx, + txResults []*abci.ExecTxResult, ) ([]byte, int64, error) { blockExec.mempool.Lock() defer blockExec.mempool.Unlock() @@ -359,7 +359,7 @@ func (blockExec *BlockExecutor) Commit( ctx, block.Height, block.Txs, - deliverTxResponses, + txResults, TxPreCheck(state), TxPostCheck(state), ) @@ -382,7 +382,7 @@ func execBlockOnProxyApp( ) (*tmstate.ABCIResponses, error) { abciResponses := new(tmstate.ABCIResponses) abciResponses.FinalizeBlock = &abci.ResponseFinalizeBlock{} - dtxs := make([]*abci.ResponseDeliverTx, len(block.Txs)) + dtxs := make([]*abci.ExecTxResult, len(block.Txs)) abciResponses.FinalizeBlock.TxResults = dtxs // Begin block diff --git a/internal/state/helpers_test.go b/internal/state/helpers_test.go index 91ef6285a..49e4aae15 100644 --- a/internal/state/helpers_test.go +++ b/internal/state/helpers_test.go @@ -299,12 +299,12 @@ func (app *testApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFi app.CommitVotes = req.LastCommitInfo.Votes app.ByzantineValidators = req.ByzantineValidators - resTxs := make([]*abci.ResponseDeliverTx, len(req.Txs)) + resTxs := make([]*abci.ExecTxResult, len(req.Txs)) for i, tx := range req.Txs { if len(tx) > 0 { - resTxs[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + resTxs[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } else { - resTxs[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK + 10} // error + resTxs[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK + 10} // error } } diff --git a/internal/state/state_test.go b/internal/state/state_test.go index f737fcdc0..ce14e2659 100644 --- a/internal/state/state_test.go +++ b/internal/state/state_test.go @@ -107,12 +107,12 @@ func TestABCIResponsesSaveLoad1(t *testing.T) { require.NoError(t, err) abciResponses := new(tmstate.ABCIResponses) - dtxs := make([]*abci.ResponseDeliverTx, 2) + dtxs := make([]*abci.ExecTxResult, 2) abciResponses.FinalizeBlock = new(abci.ResponseFinalizeBlock) abciResponses.FinalizeBlock.TxResults = dtxs - abciResponses.FinalizeBlock.TxResults[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil} - abciResponses.FinalizeBlock.TxResults[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil} + abciResponses.FinalizeBlock.TxResults[0] = &abci.ExecTxResult{Data: []byte("foo"), Events: nil} + abciResponses.FinalizeBlock.TxResults[1] = &abci.ExecTxResult{Data: []byte("bar"), Log: "ok", Events: nil} pbpk, err := encoding.PubKeyToProto(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) abciResponses.FinalizeBlock.ValidatorUpdates = []abci.ValidatorUpdate{{PubKey: pbpk, Power: 10}} @@ -136,23 +136,23 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { cases := [...]struct { // Height is implied to equal index+2, // as block 1 is created from genesis. - added []*abci.ResponseDeliverTx - expected []*abci.ResponseDeliverTx + added []*abci.ExecTxResult + expected []*abci.ExecTxResult }{ 0: { nil, nil, }, 1: { - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 32, Data: []byte("Hello"), Log: "Huh?"}, }, - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 32, Data: []byte("Hello")}, }, }, 2: { - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 383}, { Data: []byte("Gotcha!"), @@ -162,7 +162,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { }, }, }, - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 383, Data: nil}, {Code: 0, Data: []byte("Gotcha!"), Events: []abci.Event{ {Type: "type1", Attributes: []abci.EventAttribute{{Key: "a", Value: "1"}}}, @@ -175,7 +175,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { nil, }, 4: { - []*abci.ResponseDeliverTx{nil}, + []*abci.ExecTxResult{nil}, nil, }, } diff --git a/internal/state/store.go b/internal/state/store.go index fd14e35b7..dbde5e0d1 100644 --- a/internal/state/store.go +++ b/internal/state/store.go @@ -442,7 +442,7 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI } func (store dbStore) saveABCIResponses(height int64, abciResponses *tmstate.ABCIResponses) error { - var dtxs []*abci.ResponseDeliverTx + var dtxs []*abci.ExecTxResult // strip nil values, for _, tx := range abciResponses.FinalizeBlock.TxResults { if tx != nil { diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go index 1d04fa4cd..8c652444b 100644 --- a/rpc/client/mock/abci.go +++ b/rpc/client/mock/abci.go @@ -56,7 +56,7 @@ func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes return &res, nil } fb := a.App.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) - res.DeliverTx = *fb.Txs[0] + res.TxResult = *fb.TxResults[0] res.Height = -1 // TODO return &res, nil } diff --git a/rpc/client/mock/abci_test.go b/rpc/client/mock/abci_test.go index 18fbbf6a9..489133a5b 100644 --- a/rpc/client/mock/abci_test.go +++ b/rpc/client/mock/abci_test.go @@ -38,8 +38,8 @@ func TestABCIMock(t *testing.T) { BroadcastCommit: mock.Call{ Args: goodTx, Response: &coretypes.ResultBroadcastTxCommit{ - CheckTx: abci.ResponseCheckTx{Data: bytes.HexBytes("stand")}, - DeliverTx: abci.ResponseDeliverTx{Data: bytes.HexBytes("deliver")}, + CheckTx: abci.ResponseCheckTx{Data: bytes.HexBytes("stand")}, + TxResult: abci.ExecTxResult{Data: bytes.HexBytes("deliver")}, }, Error: errors.New("bad tx"), }, @@ -76,7 +76,7 @@ func TestABCIMock(t *testing.T) { require.NoError(t, err, "%+v", err) assert.EqualValues(t, 0, bres.CheckTx.Code) assert.EqualValues(t, "stand", bres.CheckTx.Data) - assert.EqualValues(t, "deliver", bres.DeliverTx.Data) + assert.EqualValues(t, "deliver", bres.TxResult.Data) } func TestABCIRecorder(t *testing.T) { @@ -179,8 +179,8 @@ func TestABCIApp(t *testing.T) { res, err := m.BroadcastTxCommit(ctx, types.Tx(tx)) require.NoError(t, err) assert.True(t, res.CheckTx.IsOK()) - require.NotNil(t, res.DeliverTx) - assert.True(t, res.DeliverTx.IsOK()) + require.NotNil(t, res.TxResult) + assert.True(t, res.TxResult.IsOK()) // commit // TODO: This may not be necessary in the future diff --git a/rpc/coretypes/responses.go b/rpc/coretypes/responses.go index f9f8c058c..8968f9868 100644 --- a/rpc/coretypes/responses.go +++ b/rpc/coretypes/responses.go @@ -241,10 +241,10 @@ type ResultBroadcastTx struct { // CheckTx and DeliverTx results type ResultBroadcastTxCommit struct { - CheckTx abci.ResponseCheckTx `json:"check_tx"` - DeliverTx abci.ResponseDeliverTx `json:"deliver_tx"` - Hash bytes.HexBytes `json:"hash"` - Height int64 `json:"height,string"` + CheckTx abci.ResponseCheckTx `json:"check_tx"` + TxResult abci.ExecTxResult `json:"tx_result"` + Hash bytes.HexBytes `json:"hash"` + Height int64 `json:"height,string"` } // ResultCheckTx wraps abci.ResponseCheckTx. @@ -254,12 +254,12 @@ type ResultCheckTx struct { // Result of querying for a tx type ResultTx struct { - Hash bytes.HexBytes `json:"hash"` - Height int64 `json:"height,string"` - Index uint32 `json:"index"` - TxResult abci.ResponseDeliverTx `json:"tx_result"` - Tx types.Tx `json:"tx"` - Proof types.TxProof `json:"proof,omitempty"` + Hash bytes.HexBytes `json:"hash"` + Height int64 `json:"height,string"` + Index uint32 `json:"index"` + TxResult abci.ExecTxResult `json:"tx_result"` + Tx types.Tx `json:"tx"` + Proof types.TxProof `json:"proof,omitempty"` } // Result of searching for txs diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index 4052d4e9e..e824682f3 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -155,7 +155,7 @@ func (app *Application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { // FinalizeBlock implements ABCI. func (app *Application) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { - var txs = make([]*abci.ResponseDeliverTx, len(req.Txs)) + var txs = make([]*abci.ExecTxResult, len(req.Txs)) app.mu.Lock() defer app.mu.Unlock() @@ -167,7 +167,7 @@ func (app *Application) FinalizeBlock(req abci.RequestFinalizeBlock) abci.Respon } app.state.Set(key, value) - txs[i] = &abci.ResponseDeliverTx{Code: code.CodeTypeOK} + txs[i] = &abci.ExecTxResult{Code: code.CodeTypeOK} } valUpdates, err := app.validatorUpdates(uint64(req.Height)) diff --git a/types/results.go b/types/results.go index 9181450bc..8b0b8fd26 100644 --- a/types/results.go +++ b/types/results.go @@ -6,11 +6,11 @@ import ( ) // ABCIResults wraps the deliver tx results to return a proof. -type ABCIResults []*abci.ResponseDeliverTx +type ABCIResults []*abci.ExecTxResult // NewResults strips non-deterministic fields from ResponseDeliverTx responses // and returns ABCIResults. -func NewResults(responses []*abci.ResponseDeliverTx) ABCIResults { +func NewResults(responses []*abci.ExecTxResult) ABCIResults { res := make(ABCIResults, len(responses)) for i, d := range responses { res[i] = deterministicResponseDeliverTx(d) @@ -44,8 +44,8 @@ func (a ABCIResults) toByteSlices() [][]byte { // deterministicResponseDeliverTx strips non-deterministic fields from // ResponseDeliverTx and returns another ResponseDeliverTx. -func deterministicResponseDeliverTx(response *abci.ResponseDeliverTx) *abci.ResponseDeliverTx { - return &abci.ResponseDeliverTx{ +func deterministicResponseDeliverTx(response *abci.ExecTxResult) *abci.ExecTxResult { + return &abci.ExecTxResult{ Code: response.Code, Data: response.Data, GasWanted: response.GasWanted, diff --git a/types/results_test.go b/types/results_test.go index 5b1be3466..da7eebed0 100644 --- a/types/results_test.go +++ b/types/results_test.go @@ -10,12 +10,12 @@ import ( ) func TestABCIResults(t *testing.T) { - a := &abci.ResponseDeliverTx{Code: 0, Data: nil} - b := &abci.ResponseDeliverTx{Code: 0, Data: []byte{}} - c := &abci.ResponseDeliverTx{Code: 0, Data: []byte("one")} - d := &abci.ResponseDeliverTx{Code: 14, Data: nil} - e := &abci.ResponseDeliverTx{Code: 14, Data: []byte("foo")} - f := &abci.ResponseDeliverTx{Code: 14, Data: []byte("bar")} + a := &abci.ExecTxResult{Code: 0, Data: nil} + b := &abci.ExecTxResult{Code: 0, Data: []byte{}} + c := &abci.ExecTxResult{Code: 0, Data: []byte("one")} + d := &abci.ExecTxResult{Code: 14, Data: nil} + e := &abci.ExecTxResult{Code: 14, Data: []byte("foo")} + f := &abci.ExecTxResult{Code: 14, Data: []byte("bar")} // Nil and []byte{} should produce the same bytes bzA, err := a.Marshal()