From f9a13ef0874aaa84c109fbf9cfec63df05dc5498 Mon Sep 17 00:00:00 2001 From: Silas Davis <silas@monax.io> Date: Thu, 1 Feb 2018 18:29:01 +0000 Subject: [PATCH] Updated ABCI app for latest Tendermint Signed-off-by: Silas Davis <silas@monax.io> --- consensus/tendermint/abci/app.go | 88 ++++++++++++++++++++--------- consensus/tendermint/codes/codes.go | 18 ++++++ 2 files changed, 78 insertions(+), 28 deletions(-) create mode 100644 consensus/tendermint/codes/codes.go diff --git a/consensus/tendermint/abci/app.go b/consensus/tendermint/abci/app.go index 119b3349..2142e90c 100644 --- a/consensus/tendermint/abci/app.go +++ b/consensus/tendermint/abci/app.go @@ -6,6 +6,7 @@ import ( "time" bcm "github.com/hyperledger/burrow/blockchain" + "github.com/hyperledger/burrow/consensus/tendermint/codes" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" @@ -50,29 +51,34 @@ func (app *abciApp) Info(info abci_types.RequestInfo) abci_types.ResponseInfo { return abci_types.ResponseInfo{ Data: responseInfoName, Version: version.GetSemanticVersionString(), - LastBlockHeight: tip.LastBlockHeight(), + LastBlockHeight: int64(tip.LastBlockHeight()), LastBlockAppHash: tip.AppHashAfterLastBlock(), } } -func (app *abciApp) SetOption(key string, value string) string { - return "No options available" +func (app *abciApp) SetOption(option abci_types.RequestSetOption) (respSetOption abci_types.ResponseSetOption) { + respSetOption.Log = "SetOption not supported" + respSetOption.Code = codes.UnsupportedRequestCode + return } func (app *abciApp) Query(reqQuery abci_types.RequestQuery) (respQuery abci_types.ResponseQuery) { - respQuery.Log = "Query not support" - respQuery.Code = abci_types.CodeType_UnknownRequest - return respQuery + respQuery.Log = "Query not supported" + respQuery.Code = codes.UnsupportedRequestCode + return } -func (app *abciApp) CheckTx(txBytes []byte) abci_types.Result { +func (app *abciApp) CheckTx(txBytes []byte) abci_types.ResponseCheckTx { app.mtx.Lock() defer app.mtx.Unlock() tx, err := app.txDecoder.DecodeTx(txBytes) if err != nil { logging.TraceMsg(app.logger, "CheckTx decoding error", structure.ErrorKey, err) - return abci_types.NewError(abci_types.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err)) + return abci_types.ResponseCheckTx{ + Code: codes.EncodingErrorCode, + Log: fmt.Sprintf("Encoding error: %s", err), + } } // TODO: map ExecTx errors to sensible ABCI error codes receipt := txs.GenerateReceipt(app.blockchain.ChainID(), tx) @@ -83,33 +89,44 @@ func (app *abciApp) CheckTx(txBytes []byte) abci_types.Result { structure.ErrorKey, err, "tx_hash", receipt.TxHash, "creates_contract", receipt.CreatesContract) - return abci_types.NewError(abci_types.CodeType_InternalError, - fmt.Sprintf("Could not execute transaction: %s, error: %v", tx, err)) + return abci_types.ResponseCheckTx{ + Code: codes.EncodingErrorCode, + Log: fmt.Sprintf("Could not execute transaction: %s, error: %v", tx, err), + } } receiptBytes := wire.BinaryBytes(receipt) logging.TraceMsg(app.logger, "CheckTx success", "tx_hash", receipt.TxHash, "creates_contract", receipt.CreatesContract) - return abci_types.NewResultOK(receiptBytes, "Success") + return abci_types.ResponseCheckTx{ + Code: codes.TxExecutionSuccessCode, + Log: "CheckTx success - receipt in data", + Data: receiptBytes, + } } -func (app *abciApp) InitChain(chain abci_types.RequestInitChain) { +func (app *abciApp) InitChain(chain abci_types.RequestInitChain) (respInitChain abci_types.ResponseInitChain) { // Could verify agreement on initial validator set here + return } -func (app *abciApp) BeginBlock(block abci_types.RequestBeginBlock) { +func (app *abciApp) BeginBlock(block abci_types.RequestBeginBlock) (respBeginBlock abci_types.ResponseBeginBlock) { app.block = &block + return } -func (app *abciApp) DeliverTx(txBytes []byte) abci_types.Result { +func (app *abciApp) DeliverTx(txBytes []byte) abci_types.ResponseDeliverTx { app.mtx.Lock() defer app.mtx.Unlock() tx, err := app.txDecoder.DecodeTx(txBytes) if err != nil { logging.TraceMsg(app.logger, "DeliverTx decoding error", structure.ErrorKey, err) - return abci_types.NewError(abci_types.CodeType_EncodingError, fmt.Sprintf("Encoding error: %s", err)) + return abci_types.ResponseDeliverTx{ + Code: codes.EncodingErrorCode, + Log: fmt.Sprintf("Encoding error: %s", err), + } } receipt := txs.GenerateReceipt(app.blockchain.ChainID(), tx) @@ -119,22 +136,29 @@ func (app *abciApp) DeliverTx(txBytes []byte) abci_types.Result { structure.ErrorKey, err, "tx_hash", receipt.TxHash, "creates_contract", receipt.CreatesContract) - return abci_types.NewError(abci_types.CodeType_InternalError, - fmt.Sprintf("Could not execute transaction: %s, error: %s", tx, err)) + return abci_types.ResponseDeliverTx{ + Code: codes.TxExecutionErrorCode, + Log: fmt.Sprintf("Could not execute transaction: %s, error: %s", tx, err), + } } logging.TraceMsg(app.logger, "DeliverTx success", "tx_hash", receipt.TxHash, "creates_contract", receipt.CreatesContract) receiptBytes := wire.BinaryBytes(receipt) - return abci_types.NewResultOK(receiptBytes, "Success") + return abci_types.ResponseDeliverTx{ + Code: codes.TxExecutionSuccessCode, + Log: "DeliverTx success - receipt in data", + Data: receiptBytes, + } } -func (app *abciApp) EndBlock(height uint64) (respEndBlock abci_types.ResponseEndBlock) { - return respEndBlock +func (app *abciApp) EndBlock(reqEndBlock abci_types.RequestEndBlock) (respEndBlock abci_types.ResponseEndBlock) { + // Validator mutation goes here + return } -func (app *abciApp) Commit() abci_types.Result { +func (app *abciApp) Commit() abci_types.ResponseCommit { app.mtx.Lock() defer app.mtx.Unlock() tip := app.blockchain.Tip() @@ -149,8 +173,10 @@ func (app *abciApp) Commit() abci_types.Result { appHash, err := app.committer.Commit() if err != nil { - return abci_types.NewError(abci_types.CodeType_InternalError, - fmt.Sprintf("Could not commit block: %s", err)) + return abci_types.ResponseCommit{ + Code: codes.CommitErrorCode, + Log: fmt.Sprintf("Could not commit block: %s", err), + } } logging.InfoMsg(app.logger, "Resetting transaction check cache") @@ -160,15 +186,21 @@ func (app *abciApp) Commit() abci_types.Result { app.blockchain.CommitBlock(time.Unix(int64(app.block.Header.Time), 0), app.block.Hash, appHash) // Perform a sanity check our block height - if app.blockchain.LastBlockHeight() != app.block.Header.Height { + if app.blockchain.LastBlockHeight() != uint64(app.block.Header.Height) { logging.InfoMsg(app.logger, "Burrow block height disagrees with Tendermint block height", structure.ScopeKey, "Commit()", "burrow_height", app.blockchain.LastBlockHeight(), "tendermint_height", app.block.Header.Height) - return abci_types.NewError(abci_types.CodeType_InternalError, - fmt.Sprintf("Burrow has recorded a block height of %v, "+ + return abci_types.ResponseCommit{ + Code: codes.CommitErrorCode, + Log: fmt.Sprintf("Burrow has recorded a block height of %v, "+ "but Tendermint reports a block height of %v, and the two should agree.", - app.blockchain.LastBlockHeight(), app.block.Header.Height)) + app.blockchain.LastBlockHeight(), app.block.Header.Height), + } + } + return abci_types.ResponseCommit{ + Code: codes.TxExecutionSuccessCode, + Data: appHash, + Log: "Success - AppHash in data", } - return abci_types.NewResultOK(appHash, "Success") } diff --git a/consensus/tendermint/codes/codes.go b/consensus/tendermint/codes/codes.go new file mode 100644 index 00000000..9fe76ea6 --- /dev/null +++ b/consensus/tendermint/codes/codes.go @@ -0,0 +1,18 @@ +package codes + +import ( + abci_types "github.com/tendermint/abci/types" +) + +const ( + // Success + TxExecutionSuccessCode uint32 = abci_types.CodeTypeOK + + // Informational + UnsupportedRequestCode uint32 = 400 + + // Internal errors + EncodingErrorCode uint32 = 500 + TxExecutionErrorCode uint32 = 501 + CommitErrorCode uint32 = 502 +) -- GitLab