ApplyTransaction() processes the transaction within the state machine, returning the corresponding TxResult.
(index uint64, transaction []byte, txHash string, batchVerifier *crypto.BatchVerifier)
| 15 | |
| 16 | // ApplyTransaction() processes the transaction within the state machine, returning the corresponding TxResult. |
| 17 | func (s *StateMachine) ApplyTransaction(index uint64, transaction []byte, txHash string, batchVerifier *crypto.BatchVerifier) (*lib.TxResult, []*lib.Event, lib.ErrorI) { |
| 18 | s.events.Refer(txHash) |
| 19 | // validate the transaction and get the check result |
| 20 | result, err := s.CheckTx(transaction, txHash, batchVerifier) |
| 21 | if err != nil { |
| 22 | return nil, nil, err |
| 23 | } |
| 24 | // if the transaction is meant for the plugin |
| 25 | if result.plugin && s.Plugin != nil { |
| 26 | // route to plugin |
| 27 | resp, e := s.Plugin.DeliverTx(s, &lib.PluginDeliverRequest{Tx: result.tx}) |
| 28 | // handle error |
| 29 | if e != nil { |
| 30 | return nil, nil, e |
| 31 | } |
| 32 | // if the response contains an error |
| 33 | if err = resp.Error.E(); err != nil { |
| 34 | return nil, nil, err |
| 35 | } |
| 36 | if err = s.addPluginEvents(resp.Events); err != nil { |
| 37 | return nil, nil, err |
| 38 | } |
| 39 | } else { |
| 40 | // faucet mode: ensure "send" txs from the faucet address never fail due to insufficient funds. |
| 41 | if send, ok := result.msg.(*MessageSend); ok { |
| 42 | required := send.Amount |
| 43 | if required > math.MaxUint64-result.tx.Fee { |
| 44 | return nil, nil, ErrInvalidAmount() |
| 45 | } |
| 46 | if err = s.maybeFaucetTopUpForSendTx(result.sender, required+result.tx.Fee); err != nil { |
| 47 | return nil, nil, err |
| 48 | } |
| 49 | } |
| 50 | // deduct fees for the transaction |
| 51 | if err = s.AccountDeductFees(result.sender, result.tx.Fee); err != nil { |
| 52 | return nil, nil, err |
| 53 | } |
| 54 | // handle the message (payload) |
| 55 | if err = s.HandleMessage(result.msg); err != nil { |
| 56 | return nil, nil, err |
| 57 | } |
| 58 | } |
| 59 | // return the tx result |
| 60 | messageType := result.tx.MessageType |
| 61 | if result.msg != nil { |
| 62 | messageType = result.msg.Name() |
| 63 | } |
| 64 | return &lib.TxResult{ |
| 65 | Sender: result.sender.Bytes(), |
| 66 | Recipient: result.recipient, |
| 67 | MessageType: messageType, |
| 68 | Height: s.Height(), |
| 69 | Index: index, |
| 70 | Transaction: result.tx, |
| 71 | TxHash: txHash, |
| 72 | }, s.events.Reset(), nil |
| 73 | } |
| 74 |