@@ -18,11 +18,13 @@ package eth
18
18
19
19
import (
20
20
"context"
21
+ "fmt"
21
22
"math/big"
22
23
23
24
"github.com/ethereum/go-ethereum/accounts"
24
25
"github.com/ethereum/go-ethereum/common"
25
26
"github.com/ethereum/go-ethereum/common/math"
27
+ "github.com/ethereum/go-ethereum/consensus/clique"
26
28
"github.com/ethereum/go-ethereum/core"
27
29
"github.com/ethereum/go-ethereum/core/bloombits"
28
30
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -33,6 +35,7 @@ import (
33
35
"github.com/ethereum/go-ethereum/eth/gasprice"
34
36
"github.com/ethereum/go-ethereum/ethdb"
35
37
"github.com/ethereum/go-ethereum/event"
38
+ "github.com/ethereum/go-ethereum/miner"
36
39
"github.com/ethereum/go-ethereum/params"
37
40
"github.com/ethereum/go-ethereum/rpc"
38
41
)
@@ -53,7 +56,28 @@ func (b *EthAPIBackend) CurrentBlock() *types.Block {
53
56
54
57
func (b * EthAPIBackend ) SetHead (number uint64 ) {
55
58
b .eth .protocolManager .downloader .Cancel ()
59
+
60
+ // Note: Suddenly changing the state of the blockchain can break other parts
61
+ // of the codebase that are holding on to some state, in some cases causing
62
+ // crashes. In order to prevent that, we need to stop and reset the miner,
63
+ // txpool, and consensus engine.
64
+ wasMining := b .eth .miner .Mining ()
65
+ if wasMining {
66
+ b .eth .miner .Stop ()
67
+ }
68
+ b .eth .txPool .Stop ()
56
69
b .eth .blockchain .SetHead (number )
70
+ b .eth .txPool = core .NewTxPool (b .eth .config .TxPool , b .eth .chainConfig , b .eth .blockchain )
71
+ if b .eth .chainConfig .Clique != nil {
72
+ b .eth .engine = clique .New (b .eth .chainConfig .Clique , b .eth .chainDb )
73
+ }
74
+ b .eth .miner = miner .New (b .eth , b .eth .chainConfig , b .eth .EventMux (), b .eth .engine )
75
+
76
+ if wasMining {
77
+ if err := b .eth .StartMining (true ); err != nil {
78
+ panic (fmt .Errorf ("could not start miner: %s" , err .Error ()))
79
+ }
80
+ }
57
81
}
58
82
59
83
func (b * EthAPIBackend ) HeaderByNumber (ctx context.Context , blockNr rpc.BlockNumber ) (* types.Header , error ) {
0 commit comments