update sites of DeliverTx

This commit is contained in:
William Banfield
2022-03-01 14:46:11 -05:00
parent 1aa5dda364
commit a341046b28
27 changed files with 325 additions and 104 deletions
+1 -1
View File
@@ -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,
+4 -4
View File
@@ -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")
}
}
+8 -8
View File
@@ -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)
+229 -8
View File
@@ -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,
+1 -1
View File
@@ -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")
+2 -2
View File
@@ -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,
@@ -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},
+4 -4
View File
@@ -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}
}
+1 -1
View File
@@ -32,7 +32,7 @@ func (emptyMempool) Update(
_ context.Context,
_ int64,
_ types.Txs,
_ []*abci.ResponseDeliverTx,
_ []*abci.ExecTxResult,
_ mempool.PreCheckFunc,
_ mempool.PostCheckFunc,
) error {
+4 -4
View File
@@ -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 {
+2 -2
View File
@@ -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 {
+12 -12
View File
@@ -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()
+1 -1
View File
@@ -27,7 +27,7 @@ func (Mempool) Update(
_ context.Context,
_ int64,
_ types.Txs,
_ []*abci.ResponseDeliverTx,
_ []*abci.ExecTxResult,
_ mempool.PreCheckFunc,
_ mempool.PostCheckFunc,
) error {
+3 -3
View File
@@ -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)
}()
}
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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{
+4 -4
View File
@@ -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
}
}
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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
}
}
+10 -10
View File
@@ -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,
},
}
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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
}
+5 -5
View File
@@ -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
+10 -10
View File
@@ -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
+2 -2
View File
@@ -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))
+4 -4
View File
@@ -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,
+6 -6
View File
@@ -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()