Skip to content

Commit

Permalink
light: fix txpool causes panic on reorgOnNewHead
Browse files Browse the repository at this point in the history
panic: runtime error: invalid memory address or nil pointer dereference
Mar 04 12:22:51 sf-etclabs sh[26575]: [signal SIGSEGV: segmentation violation code=0x1 addr=0x1c0 pc=0xc5937c]
Mar 04 12:22:51 sf-etclabs sh[26575]: goroutine 57 [running]:
Mar 04 12:22:51 sf-etclabs sh[26575]: github.com/ethereum/go-ethereum/light.(*TxPool).reorgOnNewHead(0xc00038cc60, 0x11a2960, 0xc0204bd920, 0xc0209ec480,
0xc0204bd920, 0xc02096eb00, 0x8)
Mar 04 12:22:51 sf-etclabs sh[26575]:         /root/go/src/github.com/ethereum/go-ethereum/light/txpool.go:230 +0x23c
Mar 04 12:22:51 sf-etclabs sh[26575]: github.com/ethereum/go-ethereum/light.(*TxPool).setNewHead(0xc00038cc60, 0xc0209ec480)
Mar 04 12:22:51 sf-etclabs sh[26575]:         /root/go/src/github.com/ethereum/go-ethereum/light/txpool.go:311 +0x13a
Mar 04 12:22:51 sf-etclabs sh[26575]: github.com/ethereum/go-ethereum/light.(*TxPool).eventLoop(0xc00038cc60)
Mar 04 12:22:51 sf-etclabs sh[26575]:         /root/go/src/github.com/ethereum/go-ethereum/light/txpool.go:292 +0x53
Mar 04 12:22:51 sf-etclabs sh[26575]: created by github.com/ethereum/go-ethereum/light.NewTxPool
Mar 04 12:22:51 sf-etclabs sh[26575]:         /root/go/src/github.com/ethereum/go-ethereum/light/txpool.go:109 +0x3eb

Signed-off-by: meows <b5c6@protonmail.com>
  • Loading branch information
meowsbits committed Mar 4, 2020
1 parent 1100abd commit f6ed5d4
Showing 1 changed file with 28 additions and 20 deletions.
48 changes: 28 additions & 20 deletions light/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,30 +224,38 @@ func (pool *TxPool) reorgOnNewHead(ctx context.Context, newHeader *types.Header)
txc := make(txStateChanges)
oldh := pool.chain.GetHeaderByHash(pool.head)
newh := newHeader
// find common ancestor, create list of rolled back and new block hashes
var oldHashes, newHashes []common.Hash
for oldh.Hash() != newh.Hash() {
if oldh.Number.Uint64() >= newh.Number.Uint64() {
oldHashes = append(oldHashes, oldh.Hash())
oldh = pool.chain.GetHeader(oldh.ParentHash, oldh.Number.Uint64()-1)
}
if oldh.Number.Uint64() < newh.Number.Uint64() {
newHashes = append(newHashes, newh.Hash())
newh = pool.chain.GetHeader(newh.ParentHash, newh.Number.Uint64()-1)
if newh == nil {
// happens when CHT syncing, nothing to do
newh = oldh

if oldh != nil {
// find common ancestor, create list of rolled back and new block hashes
for oldh.Hash() != newh.Hash() {
if oldh.Number.Uint64() >= newh.Number.Uint64() {
oldHashes = append(oldHashes, oldh.Hash())
oldh = pool.chain.GetHeader(oldh.ParentHash, oldh.Number.Uint64()-1)
}
if oldh.Number.Uint64() < newh.Number.Uint64() {
newHashes = append(newHashes, newh.Hash())
newh = pool.chain.GetHeader(newh.ParentHash, newh.Number.Uint64()-1)
if newh == nil {
// happens when CHT syncing, nothing to do
newh = oldh
}
}
}
if oldh.Number.Uint64() < pool.clearIdx {
pool.clearIdx = oldh.Number.Uint64()
}
// roll back old blocks
for _, hash := range oldHashes {
pool.rollbackTxs(hash, txc)
}
pool.head = oldh.Hash()
}
if oldh.Number.Uint64() < pool.clearIdx {
pool.clearIdx = oldh.Number.Uint64()
}
// roll back old blocks
for _, hash := range oldHashes {
pool.rollbackTxs(hash, txc)

if newHeader == nil {
return txc, nil
}
pool.head = oldh.Hash()

// check mined txs of new blocks (array is in reversed order)
for i := len(newHashes) - 1; i >= 0; i-- {
hash := newHashes[i]
Expand Down Expand Up @@ -365,7 +373,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
// Check the transaction doesn't exceed the current
// block limit gas.
header := pool.chain.GetHeaderByHash(pool.head)
if header.GasLimit < tx.Gas() {
if header != nil && header.GasLimit < tx.Gas() {
return core.ErrGasLimit
}

Expand Down

0 comments on commit f6ed5d4

Please sign in to comment.