Skip to content

Commit

Permalink
Fixed mining system contract txn lost (erigontech#5212)
Browse files Browse the repository at this point in the history
* fix mining exec error

* fix invalid memory

* remove logs

Co-authored-by: Jeff Rossiter <jeffrey.rossiter@me.com>
  • Loading branch information
fynnss and JSRossiter authored Aug 30, 2022
1 parent 7e0f6e0 commit 9c713d8
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 15 deletions.
4 changes: 3 additions & 1 deletion consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,14 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx
} else {
txs = append(txs, tx)
receipts = append(receipts, receipt)
log.Debug("slash successful", "txns", txs.Len(), "receipts", len(receipts), "gasUsed", header.GasUsed)
}
}
}
if txs, systemTxs, receipts, err = p.distributeIncoming(header.Coinbase, state, header, txs, receipts, systemTxs, &header.GasUsed, mining); err != nil {
return nil, nil, err
}
log.Debug("distribute successful", "txns", txs.Len(), "receipts", len(receipts), "gasUsed", header.GasUsed)
if len(systemTxs) > 0 {
return nil, nil, fmt.Errorf("the length of systemTxs is still %d", len(systemTxs))
}
Expand Down Expand Up @@ -833,7 +835,7 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
// Sweet, the protocol permits us to sign the block, wait for our time
delay := p.delayForRamanujanFork(snap, header)

log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex())
log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex(), "headerHash", header.Hash().Hex(), "gasUsed", header.GasUsed, "block txn number", block.Transactions().Len(), "State Root", header.Root)

// Sign all the things!
sig, err := signFn(val, crypto.Keccak256(parliaRLP(header, p.chainConfig.ChainID)), p.chainConfig.ChainID)
Expand Down
20 changes: 10 additions & 10 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func ExecuteBlockEphemerallyForBSC(
}
}
if !statelessExec && newBlock.GasUsed() != header.GasUsed {
return nil, fmt.Errorf("gas used by execution: %d, in header: %d", *usedGas, header.GasUsed)
return nil, fmt.Errorf("gas used by execution: %d, in header: %d, in new Block: %v", *usedGas, header.GasUsed, newBlock.GasUsed())
}

var bloom types.Bloom
Expand Down Expand Up @@ -312,7 +312,7 @@ func ExecuteBlockEphemerally(
}
if !vmConfig.ReadOnly {
txs := block.Transactions()
if _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, epochReader, chainReader, false); err != nil {
if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, epochReader, chainReader, false); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -451,17 +451,17 @@ func CallContractTx(contract common.Address, data []byte, ibs *state.IntraBlockS
func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateReader, header *types.Header,
txs types.Transactions, uncles []*types.Header, stateWriter state.WriterWithChangeSets, cc *params.ChainConfig, ibs *state.IntraBlockState,
receipts types.Receipts, e consensus.EpochReader, headerReader consensus.ChainHeaderReader, isMining bool,
) (newBlock *types.Block, err error) {
) (newBlock *types.Block, newTxs types.Transactions, newReceipt types.Receipts, err error) {
syscall := func(contract common.Address, data []byte) ([]byte, error) {
return SysCallContract(contract, data, *cc, ibs, header, engine)
}
if isMining {
newBlock, _, _, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, e, headerReader, syscall, nil)
newBlock, newTxs, newReceipt, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, e, headerReader, syscall, nil)
} else {
_, _, err = engine.Finalize(cc, header, ibs, txs, uncles, receipts, e, headerReader, syscall)
}
if err != nil {
return nil, err
return nil, nil, nil, err
}

var originalSystemAcc *accounts.Account
Expand All @@ -471,27 +471,27 @@ func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateRead
var err error
originalSystemAcc, err = stateReader.ReadAccountData(state.SystemAddress)
if err != nil {
return nil, err
return nil, nil, nil, err
}
}
}

if err := ibs.CommitBlock(cc.Rules(header.Number.Uint64()), stateWriter); err != nil {
return nil, fmt.Errorf("committing block %d failed: %w", header.Number.Uint64(), err)
return nil, nil, nil, fmt.Errorf("committing block %d failed: %w", header.Number.Uint64(), err)
}

if originalSystemAcc != nil { // hack for Sokol - don't understand why eip158 is enabled, but OE still save SystemAddress with nonce=0
acc := accounts.NewAccount()
acc.Nonce = 0
if err := stateWriter.UpdateAccountData(state.SystemAddress, originalSystemAcc, &acc); err != nil {
return nil, err
return nil, nil, nil, err
}
}

if err := stateWriter.WriteChangeSets(); err != nil {
return nil, fmt.Errorf("writing changesets for block %d failed: %w", header.Number.Uint64(), err)
return nil, nil, nil, fmt.Errorf("writing changesets for block %d failed: %w", header.Number.Uint64(), err)
}
return newBlock, nil
return newBlock, newTxs, newReceipt, nil
}

func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, epochReader consensus.EpochReader, header *types.Header, txs types.Transactions, uncles []*types.Header, cc *params.ChainConfig, ibs *state.IntraBlockState) error {
Expand Down
3 changes: 2 additions & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere
if err := miningRPC.(*privateapi.MiningServer).BroadcastMinedBlock(b); err != nil {
log.Error("txpool rpc mined block broadcast", "err", err)
}
log.Trace("BroadcastMinedBlock successful", "number", b.Number(), "GasUsed", b.GasUsed(), "txn count", b.Transactions().Len())
backend.sentriesClient.PropagateNewBlockHashes(ctx, []headerdownload.Announce{
{
Number: b.NumberU64(),
Expand Down Expand Up @@ -745,7 +746,7 @@ func (s *Ethereum) StartMining(ctx context.Context, db kv.RwDB, mining *stagedsy
mineEvery.Reset(3 * time.Second)
select {
case <-s.notifyMiningAboutNewTxs:
hasWork = true
hasWork = false
case <-mineEvery.C:
hasWork = true
case err := <-errc:
Expand Down
4 changes: 3 additions & 1 deletion eth/stagedsync/stage_mining_create_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc
return err
}

var skipByChainIDMismatch uint64 = 0
for i := range txSlots.Txs {
s := rlp.NewStream(bytes.NewReader(txSlots.Txs[i]), uint64(len(txSlots.Txs[i])))

Expand All @@ -144,7 +145,8 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc
if err != nil {
return err
}
if transaction.GetChainID().ToBig().Cmp(cfg.chainConfig.ChainID) != 0 {
if transaction.GetChainID().ToBig().Uint64() != 0 && transaction.GetChainID().ToBig().Cmp(cfg.chainConfig.ChainID) != 0 {
skipByChainIDMismatch++
continue
}
var sender common.Address
Expand Down
7 changes: 6 additions & 1 deletion eth/stagedsync/stage_mining_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c
}
}

log.Debug("SpawnMiningExecStage", "block txn", current.Txs.Len(), "remote txn", current.RemoteTxs.Empty())
if current.Uncles == nil {
current.Uncles = []*types.Header{}
}
Expand All @@ -129,11 +130,13 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c
current.Receipts = types.Receipts{}
}

_, err := core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txs, current.Uncles, stateWriter,
var err error
_, current.Txs, current.Receipts, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txs, current.Uncles, stateWriter,
&cfg.chainConfig, ibs, current.Receipts, epochReader{tx: tx}, chainReader{config: &cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, true)
if err != nil {
return err
}
log.Debug("FinalizeBlockExecution", "current txn", current.Txs.Len(), "current receipt", current.Receipts.Len())

/*
if w.isRunning() {
Expand Down Expand Up @@ -183,6 +186,7 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC
ibs.Prepare(txn.Hash(), common.Hash{}, tcount)
gasSnap := gasPool.Gas()
snap := ibs.Snapshot()
log.Info("addTransactionsToMiningBlock", "txn hash", txn.Hash())
receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig, contractHasTEVM)
if err != nil {
ibs.RevertToSnapshot(snap)
Expand Down Expand Up @@ -249,6 +253,7 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC
txs.Pop()
} else if err == nil {
// Everything ok, collect the logs and shift in the next transaction from the same account
log.Debug(fmt.Sprintf("[%s] addTransactionsToMiningBlock Successful", logPrefix), "sender", from, "nonce", txn.GetNonce())
coalescedLogs = append(coalescedLogs, logs...)
tcount++
txs.Shift()
Expand Down
1 change: 1 addition & 0 deletions ethdb/privateapi/mining.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func (s *MiningServer) OnMinedBlock(req *proto_txpool.OnMinedBlockRequest, reply
}

func (s *MiningServer) BroadcastMinedBlock(block *types.Block) error {
log.Debug("BroadcastMinedBlock", "block hash", block.Hash(), "block number", block.Number(), "root", block.Root(), "gas", block.GasUsed())
var buf bytes.Buffer
if err := block.EncodeRLP(&buf); err != nil {
return err
Expand Down
1 change: 0 additions & 1 deletion turbo/trie/trie_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str
if err := l.receiver.Receive(CutoffStreamItem, nil, nil, nil, nil, nil, false, len(prefix)); err != nil {
return EmptyRoot, err
}

return l.receiver.Root(), nil
}

Expand Down

0 comments on commit 9c713d8

Please sign in to comment.