func (exe *executor) Execute(txEnv *txs.Envelope) (txe *exec.TxExecution, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("recovered from panic in executor.Execute(%s): %v\n%s", txEnv.String(), r,
				debug.Stack())
		}
	}()

	logger := exe.logger.WithScope("executor.Execute(tx txs.Tx)").With(
		"run_call", exe.runCall,
		"tx_hash", txEnv.Tx.Hash())

	logger.InfoMsg("Executing transaction", "tx", txEnv.String())

	// Verify transaction signature against inputs
	err = txEnv.Verify(exe.stateCache, exe.blockchain.ChainID())
	if err != nil {
		logger.InfoMsg("Transaction Verify failed", structure.ErrorKey, err)
		return nil, err
	}

	if txExecutor, ok := exe.contexts[txEnv.Tx.Type()]; ok {
		// Establish new TxExecution
		txe := exe.blockExecution.Tx(txEnv)
		defer func() {
			if r := recover(); r != nil {
				err = fmt.Errorf("recovered from panic in executor.Execute(%s): %v\n%s", txEnv.String(), r,
					debug.Stack())
				// If we recover here we are in a position to promulgate the error to the TxExecution
				txe.PushError(err)
			}
		}()

		// Validate inputs and check sequence numbers
		err = validateInputs(txEnv.Tx, exe.stateCache)
		if err != nil {
			logger.InfoMsg("Transaction validate failed", structure.ErrorKey, err)
			txe.PushError(err)
			return nil, err
		}

		err = txExecutor.Execute(txe, txe.Envelope.Tx.Payload)
		if err != nil {
			logger.InfoMsg("Transaction execution failed", structure.ErrorKey, err)
			txe.PushError(err)
			return nil, err
		}

		// Initialise public keys and increment sequence numbers for Tx inputs
		err = exe.updateSignatories(txEnv)
		if err != nil {
			logger.InfoMsg("Updating signatories failed", structure.ErrorKey, err)
			txe.PushError(err)
			return nil, err
		}
		// Return execution for this tx
		return txe, nil
	}
	return nil, fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type())
}
// If the tx is invalid, an error will be returned.
// Unlike ExecBlock(), state will not be altered.
If the tx is invalid, an error will be returned.
Unlike ExecBlock(), state will not be altered.
// If the tx is invalid an error will be returned . // Unlike ExecBlock () state will not be altered .
func (exe *executor) Execute(txEnv *txs.Envelope) (txe *exec.TxExecution, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("recovered from panic in executor.Execute(%s): %v\n%s", txEnv.String(), r,
				debug.Stack())
		}
	}()
	logger := exe.logger.WithScope("executor.Execute(tx txs.Tx)").With(
		"run_call", exe.runCall,
		"tx_hash", txEnv.Tx.Hash())
	logger.InfoMsg("Executing transaction", "tx", txEnv.String())
	err = txEnv.Verify(exe.stateCache, exe.blockchain.ChainID())
	if err != nil {
		logger.InfoMsg("Transaction Verify failed", structure.ErrorKey, err)
		return nil, err
	}
	if txExecutor, ok := exe.contexts[txEnv.Tx.Type()]; ok {
		txe := exe.blockExecution.Tx(txEnv)
		defer func() {
			if r := recover(); r != nil {
				err = fmt.Errorf("recovered from panic in executor.Execute(%s): %v\n%s", txEnv.String(), r,
					debug.Stack())
				txe.PushError(err)
			}
		}()
		err = validateInputs(txEnv.Tx, exe.stateCache)
		if err != nil {
			logger.InfoMsg("Transaction validate failed", structure.ErrorKey, err)
			txe.PushError(err)
			return nil, err
		}
		err = txExecutor.Execute(txe, txe.Envelope.Tx.Payload)
		if err != nil {
			logger.InfoMsg("Transaction execution failed", structure.ErrorKey, err)
			txe.PushError(err)
			return nil, err
		}
		err = exe.updateSignatories(txEnv)
		if err != nil {
			logger.InfoMsg("Updating signatories failed", structure.ErrorKey, err)
			txe.PushError(err)
			return nil, err
		}
		return txe, nil
	}
	return nil, fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type())
}
func ( exe * executor ) Execute ( txEnv * txs . Envelope ) ( txe * exec . TxExecution , err error ) { defer func ( ) { if r := recover ( ) ; r != nil { err = fmt . Errorf ( " \n " , txEnv . String ( ) , r , debug . Stack ( ) ) } } ( ) logger := exe . logger . WithScope ( " " ) . With ( " " , exe . runCall , " " , txEnv . Tx . Hash ( ) ) logger . InfoMsg ( " " , " " , txEnv . String ( ) ) err = txEnv . Verify ( exe . stateCache , exe . blockchain . ChainID ( ) ) if err != nil { logger . InfoMsg ( " " , structure . ErrorKey , err ) return nil , err } if txExecutor , ok := exe . contexts [ txEnv . Tx . Type ( ) ] ; ok { txe := exe . blockExecution . Tx ( txEnv ) defer func ( ) { if r := recover ( ) ; r != nil { err = fmt . Errorf ( " \n " , txEnv . String ( ) , r , debug . Stack ( ) ) txe . PushError ( err ) } } ( ) err = validateInputs ( txEnv . Tx , exe . stateCache ) if err != nil { logger . InfoMsg ( " " , structure . ErrorKey , err ) txe . PushError ( err ) return nil , err } err = txExecutor . Execute ( txe , txe . Envelope . Tx . Payload ) if err != nil { logger . InfoMsg ( " " , structure . ErrorKey , err ) txe . PushError ( err ) return nil , err } err = exe . updateSignatories ( txEnv ) if err != nil { logger . InfoMsg ( " " , structure . ErrorKey , err ) txe . PushError ( err ) return nil , err } return txe , nil } return nil , fmt . Errorf ( " " , txEnv . Tx . Type ( ) ) }
If the tx is invalid, an error will be returned.
If the tx is invalid an error will be returned .
// Verify transaction signature against inputs // Establish new TxExecution // If we recover here we are in a position to promulgate the error to the TxExecution // Validate inputs and check sequence numbers // Initialise public keys and increment sequence numbers for Tx inputs // Return execution for this tx