github.com/tri-stone/burrow@v0.25.0/consensus/abci/execute_tx.go (about)

     1  package abci
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hyperledger/burrow/consensus/tendermint/codes"
     7  	"github.com/hyperledger/burrow/execution"
     8  	"github.com/hyperledger/burrow/execution/errors"
     9  	"github.com/hyperledger/burrow/logging"
    10  	"github.com/hyperledger/burrow/logging/structure"
    11  	"github.com/hyperledger/burrow/txs"
    12  	"github.com/tendermint/tendermint/abci/types"
    13  	"github.com/tendermint/tendermint/libs/common"
    14  )
    15  
    16  // Attempt to execute a transaction using ABCI conventions and codes
    17  func ExecuteTx(logHeader string, executor execution.Executor, txDecoder txs.Decoder, txBytes []byte) types.ResponseCheckTx {
    18  	logf := func(format string, args ...interface{}) string {
    19  		return fmt.Sprintf("%s: "+format, append([]interface{}{logHeader}, args...)...)
    20  	}
    21  
    22  	txEnv, err := txDecoder.DecodeTx(txBytes)
    23  	if err != nil {
    24  		return types.ResponseCheckTx{
    25  			Code: codes.EncodingErrorCode,
    26  			Log:  logf("Decoding error: %s", err),
    27  		}
    28  	}
    29  	tags := []common.KVPair{{Key: []byte(structure.TxHashKey), Value: []byte(txEnv.Tx.Hash().String())}}
    30  
    31  	txe, err := executor.Execute(txEnv)
    32  	if err != nil {
    33  		ex := errors.AsException(err)
    34  		return types.ResponseCheckTx{
    35  			Code: codes.TxExecutionErrorCode,
    36  			Tags: tags,
    37  			Log:  logf("Could not execute transaction: %s, error: %v", txEnv, ex.Exception),
    38  		}
    39  	}
    40  
    41  	if txe.Receipt.CreatesContract {
    42  		tags = append(tags, common.KVPair{
    43  			Key:   []byte("created_contract_address"),
    44  			Value: []byte(txe.Receipt.ContractAddress.String()),
    45  		})
    46  	}
    47  
    48  	bs, err := txe.Receipt.Encode()
    49  	if err != nil {
    50  		return types.ResponseCheckTx{
    51  			Code: codes.EncodingErrorCode,
    52  			Tags: tags,
    53  			Log:  logf("Could not serialise receipt: %s", err),
    54  		}
    55  	}
    56  	return types.ResponseCheckTx{
    57  		Code: codes.TxExecutionSuccessCode,
    58  		Tags: tags,
    59  		Log:  logf("Execution success - TxExecution in data"),
    60  		Data: bs,
    61  	}
    62  }
    63  
    64  // Some ABCI type helpers
    65  
    66  func WithTags(logger *logging.Logger, tags []common.KVPair) *logging.Logger {
    67  	keyvals := make([]interface{}, len(tags)*2)
    68  	for i, kvp := range tags {
    69  		keyvals[i] = string(kvp.Key)
    70  		keyvals[i+1] = string(kvp.Value)
    71  	}
    72  	return logger.With(keyvals...)
    73  }
    74  
    75  func DeliverTxFromCheckTx(ctr types.ResponseCheckTx) types.ResponseDeliverTx {
    76  	return types.ResponseDeliverTx{
    77  		Code:      ctr.Code,
    78  		Log:       ctr.Log,
    79  		Data:      ctr.Data,
    80  		Tags:      ctr.Tags,
    81  		GasUsed:   ctr.GasUsed,
    82  		GasWanted: ctr.GasWanted,
    83  		Info:      ctr.Info,
    84  	}
    85  }