applyPrivateTx attempts to apply a private transaction to the given state database
(config *configs.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, privateStateDb *state.StateDB, remoteDB database.RemoteDatabase, header *types.Header, tx *types.Transaction, cfg vm.Config, accm *accounts.Manager)
| 177 | |
| 178 | // applyPrivateTx attempts to apply a private transaction to the given state database |
| 179 | func tryApplyPrivateTx(config *configs.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, privateStateDb *state.StateDB, |
| 180 | remoteDB database.RemoteDatabase, header *types.Header, tx *types.Transaction, cfg vm.Config, accm *accounts.Manager) (*types.Receipt, error) { |
| 181 | msg, err := tx.AsMessage(types.MakeSigner(config)) |
| 182 | if err != nil { |
| 183 | return nil, err |
| 184 | } |
| 185 | |
| 186 | if remoteDB == nil { |
| 187 | return nil, RemoteDBAbsenceError |
| 188 | } |
| 189 | |
| 190 | payload, hasPermission, err := private.RetrieveAndDecryptPayload(tx.Data(), tx.Nonce(), remoteDB, accm) |
| 191 | if err != nil { |
| 192 | return nil, err |
| 193 | } |
| 194 | if !hasPermission { |
| 195 | return nil, NoPermissionError |
| 196 | } |
| 197 | |
| 198 | // Replace with the real payload decrypted from remote database. |
| 199 | msg.SetData(payload) |
| 200 | msg.GasPrice().SetUint64(0) |
| 201 | privateStateDb.SetNonce(msg.From(), msg.Nonce()) |
| 202 | |
| 203 | // Create a new context to be used in the EVM environment |
| 204 | context := NewEVMContext(msg, header, bc, author) |
| 205 | // Create a new environment which holds all relevant information |
| 206 | // about the transaction and calling mechanisms. |
| 207 | vmenv := vm.NewEVM(context, privateStateDb, config, cfg) |
| 208 | // Apply the transaction to the current state (included in the env) |
| 209 | _, _, failed, err := ApplyMessage(vmenv, msg, gp) |
| 210 | if err != nil { |
| 211 | return nil, err |
| 212 | } |
| 213 | |
| 214 | root := privateStateDb.IntermediateRoot(true).Bytes() |
| 215 | |
| 216 | // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx |
| 217 | // based on the eip phase, we're passing wether the root touch-delete accounts. |
| 218 | receipt := types.NewReceipt(root, failed, 0) |
| 219 | receipt.TxHash = tx.Hash() |
| 220 | receipt.GasUsed = 0 // for private tx, consume no gas. |
| 221 | // if the transaction created a contract, store the creation address in the receipt. |
| 222 | if msg.To() == nil { |
| 223 | receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) |
| 224 | } |
| 225 | // Set the receipt logs and create a bloom for filtering |
| 226 | receipt.Logs = privateStateDb.GetLogs(tx.Hash()) |
| 227 | receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) |
| 228 | |
| 229 | return receipt, nil |
| 230 | } |
no test coverage detected