diff --git a/core/state_processor.go b/core/state_processor.go index 09bc9a165..d1c0d576c 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -89,9 +89,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.DB, cfg vm.C // indicating the block was invalid. func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, uint64, error) { msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) - if err != nil { + // skip signer err for additiononly tx + if err != nil && msg.TxType() != types.AdditionOnly { return nil, nil, 0, err } + // Create a new context to be used in the EVM environment context := NewEVMContext(msg, header, bc, author) // Create a new environment which holds all relevant information diff --git a/core/state_transition.go b/core/state_transition.go index 613514d5d..9df329f35 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -172,7 +172,7 @@ func (st *StateTransition) buyGas() error { func (st *StateTransition) preCheck() error { // Make sure this transaction's nonce is correct. - if st.msg.CheckNonce() { + if st.msg.CheckNonce() && st.txType != types.AdditionOnly { nonce := st.state.GetNonce(st.msg.From()) if nonce < st.msg.Nonce() { return ErrNonceTooHigh @@ -223,8 +223,13 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo // The only possible consensus-error would be if there wasn't // sufficient balance to make the transfer happen. The first // balance transfer may never fail. + if vmerr == vm.ErrInsufficientBalance { - return nil, 0, false, vmerr + if st.txType != types.AdditionOnly { + return nil, 0, false, vmerr + } else { + vmerr = nil + } } } st.refundGas() diff --git a/core/vm/evm.go b/core/vm/evm.go index 0355507bd..83b46a2d5 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -195,7 +195,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas return nil, gas, ErrDepth } // Fail if we're trying to transfer more than the available balance - if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { + if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) && txType != types.AdditionOnly { return nil, gas, ErrInsufficientBalance } diff --git a/node/node_cross_shard.go b/node/node_cross_shard.go index 1414b89b6..90e7cf9f3 100644 --- a/node/node_cross_shard.go +++ b/node/node_cross_shard.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" proto_node "github.com/harmony-one/harmony/api/proto/node" + "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" ) @@ -73,9 +74,14 @@ func (node *Node) ProcessReceiptMessage(msgPayload []byte) { txs := types.Transactions{} inputData, _ := base64.StdEncoding.DecodeString("") + gas, err := core.IntrinsicGas(inputData, false, true) + if err != nil { + utils.Logger().Warn().Err(err).Msg("cannot calculate required gas") + return + } for _, cx := range cxReceipts { // TODO chao: add gas fee to incentivize - tx := types.NewCrossShardTransaction(0, cx.To, cx.ShardID, cx.ToShardID, cx.Amount, 0, nil, inputData, types.AdditionOnly) + tx := types.NewCrossShardTransaction(0, cx.To, cx.ToShardID, cx.ToShardID, cx.Amount, gas, nil, inputData, types.AdditionOnly) txs = append(txs, tx) } node.addPendingTransactions(txs) diff --git a/node/worker/worker.go b/node/worker/worker.go index 449d7ed9b..34054a33b 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -1,6 +1,7 @@ package worker import ( + "fmt" "math/big" "time" @@ -75,10 +76,14 @@ func (w *Worker) commitTransaction(tx *types.Transaction, coinbase common.Addres snap := w.current.state.Snapshot() receipt, cx, _, err := core.ApplyTransaction(w.config, w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &w.current.header.GasUsed, vm.Config{}) - if err != nil { + if err != nil && tx.TxType() != types.AdditionOnly { w.current.state.RevertToSnapshot(snap) return nil, err } + if receipt == nil { + utils.Logger().Warn().Interface("tx", tx).Interface("cx", cx).Interface("txType", tx.TxType()).Msg("Receipt is Nil!") + return nil, fmt.Errorf("Receipt is Nil, txType=%v", tx.TxType()) + } w.current.txs = append(w.current.txs, tx) w.current.receipts = append(w.current.receipts, receipt) w.current.cxs = append(w.current.cxs, cx)