MCPcopy Create free account
hub / github.com/CPChain/chain / ApplyTransaction

Function ApplyTransaction

core/state_processor.go:113–176  ·  view source on GitHub ↗

ApplyTransaction attempts to apply a transaction to the given state database and uses the input parameters for its environment. It returns the receipt for the transaction, gas used and an error if the transaction failed, indicating the block was invalid.

(config *configs.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, pubStateDb *state.StateDB,
	privateStateDb *state.StateDB, remoteDB database.RemoteDatabase, header *types.Header, tx *types.Transaction, usedGas *uint64,
	cfg vm.Config, accm *accounts.Manager)

Source from the content-addressed store, hash-verified

111// for the transaction, gas used and an error if the transaction failed,
112// indicating the block was invalid.
113func ApplyTransaction(config *configs.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, pubStateDb *state.StateDB,
114 privateStateDb *state.StateDB, remoteDB database.RemoteDatabase, header *types.Header, tx *types.Transaction, usedGas *uint64,
115 cfg vm.Config, accm *accounts.Manager) (*types.Receipt, *types.Receipt, uint64, error) {
116 msg, err := tx.AsMessage(types.MakeSigner(config))
117 if err != nil {
118 return nil, nil, 0, err
119 }
120
121 // if the tx type is not supported, return early
122 if !types.SupportTxType(tx.Type()) {
123 return nil, nil, 0, types.ErrNotSupportedTxType
124 }
125
126 // this is for sanitize, may be useful later. for now, its useless because it already returned
127 if !tx.IsBasic() {
128 msg.SetData([]byte{})
129 }
130
131 // Create a new context to be used in the EVM environment
132 context := NewEVMContext(msg, header, bc, author)
133 // Create a new environment which holds all relevant information
134 // about the transaction and calling mechanisms.
135 vmenv := vm.NewEVM(context, pubStateDb, config, cfg)
136 // Apply the transaction to the current state (included in the env)
137 _, gas, failed, err := ApplyMessage(vmenv, msg, gp)
138 if err != nil {
139 return nil, nil, 0, err
140 }
141 pubStateDb.Finalise(true)
142 *usedGas += gas
143
144 // Create a new pubReceipt for the transaction, storing the intermediate root and gas used by the tx
145 // based on the eip phase, we're passing whether the root touch-delete accounts.
146 pubReceipt := types.NewReceipt([]byte{}, failed, *usedGas)
147 pubReceipt.TxHash = tx.Hash()
148 pubReceipt.GasUsed = gas
149 // if the transaction created a contract, store the creation address in the pubReceipt.
150 if msg.To() == nil {
151 pubReceipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
152 }
153 // Set the pubReceipt logs and create a bloom for filtering
154 pubReceipt.Logs = pubStateDb.GetLogs(tx.Hash())
155 pubReceipt.Bloom = types.CreateBloom(types.Receipts{pubReceipt})
156
157 var privReceipt *types.Receipt
158 // For private tx, it should process its real private tx payload in participant's node. If account manager is nil,
159 // doesn't process private tx. If the node does not support private transaction, skip it.
160 if tx.IsPrivate() && accm != nil && types.SupportTxType(tx.Type()) {
161
162 // for now, it's impossible to enter here
163 privReceipt, err = tryApplyPrivateTx(config, bc, author, gp, privateStateDb, remoteDB, header, tx, cfg, accm)
164 if err != nil {
165 if err == NoPermissionError {
166 log.Info("No permission to process the transaction.")
167 return pubReceipt, privReceipt, gas, nil
168 } else {
169 log.Error("Cannot process the transaction.", err)
170 return pubReceipt, privReceipt, 0, err

Callers 2

AddTxWithChainMethod · 0.85
ProcessMethod · 0.85

Calls 15

NewEVMContextFunction · 0.85
ApplyMessageFunction · 0.85
tryApplyPrivateTxFunction · 0.85
AsMessageMethod · 0.80
TypeMethod · 0.80
IsBasicMethod · 0.80
SetDataMethod · 0.80
FinaliseMethod · 0.80
IsPrivateMethod · 0.80
HashMethod · 0.65
ToMethod · 0.65
NonceMethod · 0.65

Tested by

no test coverage detected