github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/consensus/abci/execute_tx.go (about) 1 package abci 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hyperledger/burrow/consensus/tendermint/codes" 8 "github.com/hyperledger/burrow/execution" 9 "github.com/hyperledger/burrow/execution/errors" 10 "github.com/hyperledger/burrow/logging" 11 "github.com/hyperledger/burrow/logging/structure" 12 "github.com/hyperledger/burrow/txs" 13 "github.com/tendermint/tendermint/abci/types" 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 txe, err := executor.Execute(txEnv) 30 if err != nil { 31 ex := errors.AsException(err) 32 return types.ResponseCheckTx{ 33 Code: codes.TxExecutionErrorCode, 34 Log: logf("Could not execute transaction: %s, error: %v", txEnv, ex.Exception), 35 } 36 } 37 38 tags := []types.EventAttribute{{Key: []byte(structure.TxHashKey), Value: []byte(txEnv.Tx.Hash().String())}} 39 if txe.Receipt.CreatesContract { 40 tags = append(tags, types.EventAttribute{ 41 Key: []byte("created_contract_address"), 42 Value: []byte(txe.Receipt.ContractAddress.String()), 43 }) 44 } 45 46 events := []types.Event{{Type: "ExecuteTx", Attributes: tags}} 47 bs, err := txe.Receipt.Encode() 48 if err != nil { 49 return types.ResponseCheckTx{ 50 Code: codes.EncodingErrorCode, 51 Events: events, 52 Log: logf("Could not serialise receipt: %s", err), 53 } 54 } 55 return types.ResponseCheckTx{ 56 Code: codes.TxExecutionSuccessCode, 57 Events: events, 58 Log: logf("Execution success - TxExecution in data"), 59 Data: bs, 60 } 61 } 62 63 // Some ABCI type helpers 64 65 func WithEvents(logger *logging.Logger, events []types.Event) *logging.Logger { 66 for _, e := range events { 67 values := make([]string, 0, len(e.Attributes)) 68 for _, kvp := range e.Attributes { 69 values = append(values, fmt.Sprintf("%s:%s", string(kvp.Key), string(kvp.Value))) 70 } 71 logger = logger.With(e.Type, strings.Join(values, ",")) 72 } 73 return logger 74 } 75 76 func DeliverTxFromCheckTx(ctr types.ResponseCheckTx) types.ResponseDeliverTx { 77 return types.ResponseDeliverTx{ 78 Code: ctr.Code, 79 Log: ctr.Log, 80 Data: ctr.Data, 81 Events: ctr.Events, 82 GasUsed: ctr.GasUsed, 83 GasWanted: ctr.GasWanted, 84 Info: ctr.Info, 85 } 86 }