github.com/klaytn/klaytn@v1.10.2/blockchain/blockchain.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from core/blockchain.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package blockchain 22 23 import ( 24 "errors" 25 "fmt" 26 "io" 27 "math/big" 28 mrand "math/rand" 29 "reflect" 30 "runtime" 31 "strconv" 32 "sync" 33 "sync/atomic" 34 "time" 35 36 "github.com/klaytn/klaytn/snapshot" 37 38 "github.com/go-redis/redis/v7" 39 lru "github.com/hashicorp/golang-lru" 40 "github.com/klaytn/klaytn/blockchain/state" 41 "github.com/klaytn/klaytn/blockchain/types" 42 "github.com/klaytn/klaytn/blockchain/vm" 43 "github.com/klaytn/klaytn/common" 44 "github.com/klaytn/klaytn/common/hexutil" 45 "github.com/klaytn/klaytn/common/mclock" 46 "github.com/klaytn/klaytn/common/prque" 47 "github.com/klaytn/klaytn/consensus" 48 "github.com/klaytn/klaytn/crypto" 49 "github.com/klaytn/klaytn/event" 50 "github.com/klaytn/klaytn/fork" 51 "github.com/klaytn/klaytn/log" 52 klaytnmetrics "github.com/klaytn/klaytn/metrics" 53 "github.com/klaytn/klaytn/params" 54 "github.com/klaytn/klaytn/rlp" 55 "github.com/klaytn/klaytn/storage/database" 56 "github.com/klaytn/klaytn/storage/statedb" 57 "github.com/rcrowley/go-metrics" 58 ) 59 60 // If total insertion time of a block exceeds insertTimeLimit, 61 // that time will be logged by blockLongInsertTimeGauge. 62 const insertTimeLimit = common.PrettyDuration(time.Second) 63 64 var ( 65 accountReadTimer = klaytnmetrics.NewRegisteredHybridTimer("state/account/reads", nil) 66 accountHashTimer = klaytnmetrics.NewRegisteredHybridTimer("state/account/hashes", nil) 67 accountUpdateTimer = klaytnmetrics.NewRegisteredHybridTimer("state/account/updates", nil) 68 accountCommitTimer = klaytnmetrics.NewRegisteredHybridTimer("state/account/commits", nil) 69 70 storageReadTimer = klaytnmetrics.NewRegisteredHybridTimer("state/storage/reads", nil) 71 storageHashTimer = klaytnmetrics.NewRegisteredHybridTimer("state/storage/hashes", nil) 72 storageUpdateTimer = klaytnmetrics.NewRegisteredHybridTimer("state/storage/updates", nil) 73 storageCommitTimer = klaytnmetrics.NewRegisteredHybridTimer("state/storage/commits", nil) 74 75 snapshotAccountReadTimer = metrics.NewRegisteredTimer("state/snapshot/account/reads", nil) 76 snapshotStorageReadTimer = metrics.NewRegisteredTimer("state/snapshot/storage/reads", nil) 77 snapshotCommitTimer = metrics.NewRegisteredTimer("state/snapshot/commits", nil) 78 79 blockBaseFee = metrics.NewRegisteredGauge("chain/basefee", nil) 80 blockInsertTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/inserts", nil) 81 blockProcessTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/process", nil) 82 blockExecutionTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/execution", nil) 83 blockFinalizeTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/finalize", nil) 84 blockValidateTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/validate", nil) 85 blockAgeTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/age", nil) 86 87 blockPrefetchExecuteTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/prefetch/executes", nil) 88 blockPrefetchInterruptMeter = metrics.NewRegisteredMeter("chain/prefetch/interrupts", nil) 89 90 ErrNoGenesis = errors.New("genesis not found in chain") 91 ErrNotExistNode = errors.New("the node does not exist in cached node") 92 ErrQuitBySignal = errors.New("quit by signal") 93 ErrNotInWarmUp = errors.New("not in warm up") 94 logger = log.NewModuleLogger(log.Blockchain) 95 kesCachePrefixBlockLogs = []byte("blockLogs") 96 ) 97 98 // Below is the list of the constants for cache size. 99 // TODO-Klaytn: Below should be handled by ini or other configurations. 100 const ( 101 maxFutureBlocks = 256 102 maxTimeFutureBlocks = 30 103 // TODO-Klaytn-Issue1911 This flag needs to be adjusted to the appropriate value. 104 // Currently, this value is taken to cache all 10 million accounts 105 // and should be optimized considering memory size and performance. 106 maxAccountForCache = 10000000 107 ) 108 109 const ( 110 DefaultTriesInMemory = 128 111 DefaultBlockInterval = 128 112 MaxPrefetchTxs = 20000 113 114 // BlockChainVersion ensures that an incompatible database forces a resync from scratch. 115 // Changelog: 116 // - Version 4 117 // The following incompatible database changes were added: 118 // * New scheme for contract code in order to separate the codes and trie nodes 119 BlockChainVersion = 4 120 ) 121 122 // CacheConfig contains the configuration values for the 1) stateDB caching and 123 // 2) trie caching/pruning resident in a blockchain. 124 type CacheConfig struct { 125 // TODO-Klaytn-Issue1666 Need to check the benefit of trie caching. 126 ArchiveMode bool // If true, state trie is not pruned and always written to database 127 CacheSize int // Size of in-memory cache of a trie (MiB) to flush matured singleton trie nodes to disk 128 BlockInterval uint // Block interval to flush the trie. Each interval state trie will be flushed into disk 129 TriesInMemory uint64 // Maximum number of recent state tries according to its block number 130 SenderTxHashIndexing bool // Enables saving senderTxHash to txHash mapping information to database and cache 131 TrieNodeCacheConfig *statedb.TrieNodeCacheConfig // Configures trie node cache 132 SnapshotCacheSize int // Memory allowance (MB) to use for caching snapshot entries in memory 133 SnapshotAsyncGen bool // Enables snapshot data generation asynchronously 134 } 135 136 // gcBlock is used for priority queue for GC. 137 type gcBlock struct { 138 root common.Hash 139 blockNum uint64 140 } 141 142 // BlockChain represents the canonical chain given a database with a genesis 143 // block. The Blockchain manages chain imports, reverts, chain reorganisations. 144 // 145 // Importing blocks in to the block chain happens according to the set of rules 146 // defined by the two stage Validator. Processing of blocks is done using the 147 // Processor which processes the included transaction. The validation of the state 148 // is done in the second part of the Validator. Failing results in aborting of 149 // the import. 150 // 151 // The BlockChain also helps in returning blocks from **any** chain included 152 // in the database as well as blocks that represents the canonical chain. It's 153 // important to note that GetBlock can return any block and does not need to be 154 // included in the canonical one where as GetBlockByNumber always represents the 155 // canonical chain. 156 type BlockChain struct { 157 chainConfig *params.ChainConfig // Chain & network configuration 158 cacheConfig *CacheConfig // stateDB caching and trie caching/pruning configuration 159 160 db database.DBManager // Low level persistent database to store final content in 161 snaps *snapshot.Tree // Snapshot tree for fast trie leaf access 162 triegc *prque.Prque // Priority queue mapping block numbers to tries to gc 163 chBlock chan gcBlock // chPushBlockGCPrque is a channel for delivering the gc item to gc loop. 164 165 hc *HeaderChain 166 rmLogsFeed event.Feed 167 chainFeed event.Feed 168 chainSideFeed event.Feed 169 chainHeadFeed event.Feed 170 logsFeed event.Feed 171 scope event.SubscriptionScope 172 genesisBlock *types.Block 173 174 mu sync.RWMutex // global mutex for locking chain operations 175 176 checkpoint int // checkpoint counts towards the new checkpoint 177 currentBlock atomic.Value // Current head of the block chain 178 currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!) 179 180 stateCache state.Database // State database to reuse between imports (contains state cache) 181 futureBlocks *lru.Cache // future blocks are blocks added for later processing 182 183 quit chan struct{} // blockchain quit channel 184 running int32 // running must be called atomically 185 // procInterrupt must be atomically called 186 procInterrupt int32 // interrupt signaler for block processing 187 wg sync.WaitGroup // chain processing wait group for shutting down 188 189 engine consensus.Engine 190 processor Processor // block processor interface 191 prefetcher Prefetcher // Block state prefetcher interface 192 validator Validator // block and state validator interface 193 vmConfig vm.Config 194 195 parallelDBWrite bool // TODO-Klaytn-Storage parallelDBWrite will be replaced by number of goroutines when worker pool pattern is introduced. 196 197 // State migration 198 prepareStateMigration bool 199 stopStateMigration chan struct{} 200 readCnt int 201 committedCnt int 202 pendingCnt int 203 progress float64 204 migrationErr error 205 testMigrationHook func() 206 207 // Warm up 208 lastCommittedBlock uint64 209 quitWarmUp chan struct{} 210 211 prefetchTxCh chan prefetchTx 212 } 213 214 // prefetchTx is used to prefetch transactions, when fetcher works. 215 type prefetchTx struct { 216 ti int 217 block *types.Block 218 followupInterrupt *uint32 219 } 220 221 // NewBlockChain returns a fully initialised block chain using information 222 // available in the database. It initialises the default Klaytn validator and 223 // Processor. 224 func NewBlockChain(db database.DBManager, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) { 225 if cacheConfig == nil { 226 cacheConfig = &CacheConfig{ 227 ArchiveMode: false, 228 CacheSize: 512, 229 BlockInterval: DefaultBlockInterval, 230 TriesInMemory: DefaultTriesInMemory, 231 TrieNodeCacheConfig: statedb.GetEmptyTrieNodeCacheConfig(), 232 SnapshotCacheSize: 512, 233 SnapshotAsyncGen: true, 234 } 235 } 236 237 if cacheConfig.TrieNodeCacheConfig == nil { 238 cacheConfig.TrieNodeCacheConfig = statedb.GetEmptyTrieNodeCacheConfig() 239 } 240 241 state.EnabledExpensive = db.GetDBConfig().EnableDBPerfMetrics 242 243 futureBlocks, _ := lru.New(maxFutureBlocks) 244 245 bc := &BlockChain{ 246 chainConfig: chainConfig, 247 cacheConfig: cacheConfig, 248 db: db, 249 triegc: prque.New(), 250 chBlock: make(chan gcBlock, 1000), 251 stateCache: state.NewDatabaseWithNewCache(db, cacheConfig.TrieNodeCacheConfig), 252 quit: make(chan struct{}), 253 futureBlocks: futureBlocks, 254 engine: engine, 255 vmConfig: vmConfig, 256 parallelDBWrite: db.IsParallelDBWrite(), 257 stopStateMigration: make(chan struct{}), 258 prefetchTxCh: make(chan prefetchTx, MaxPrefetchTxs), 259 } 260 261 // set hardForkBlockNumberConfig which will be used as a global variable 262 if err := fork.SetHardForkBlockNumberConfig(bc.chainConfig); err != nil { 263 return nil, err 264 } 265 266 bc.validator = NewBlockValidator(chainConfig, bc, engine) 267 bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine) 268 bc.processor = NewStateProcessor(chainConfig, bc, engine) 269 270 var err error 271 bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt) 272 if err != nil { 273 return nil, err 274 } 275 bc.genesisBlock = bc.GetBlockByNumber(0) 276 if bc.genesisBlock == nil { 277 return nil, ErrNoGenesis 278 } 279 var nilBlock *types.Block 280 bc.currentBlock.Store(nilBlock) 281 bc.currentFastBlock.Store(nilBlock) 282 283 if err := bc.loadLastState(); err != nil { 284 return nil, err 285 } 286 // Make sure the state associated with the block is available 287 head := bc.CurrentBlock() 288 if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil { 289 // Head state is missing, before the state recovery, find out the 290 // disk layer point of snapshot(if it's enabled). Make sure the 291 // rewound point is lower than disk layer. 292 var diskRoot common.Hash 293 if bc.cacheConfig.SnapshotCacheSize > 0 { 294 diskRoot = bc.db.ReadSnapshotRoot() 295 } 296 if diskRoot != (common.Hash{}) { 297 logger.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot) 298 299 snapDisk, err := bc.setHeadBeyondRoot(head.NumberU64(), diskRoot, true) 300 if err != nil { 301 return nil, err 302 } 303 304 // Chain rewound, persist old snapshot number to indicate recovery procedure 305 if snapDisk != 0 { 306 bc.db.WriteSnapshotRecoveryNumber(snapDisk) 307 } 308 } else { 309 // Dangling block without a state associated, init from scratch 310 logger.Warn("Head state missing, repairing chain", 311 "number", head.NumberU64(), "hash", head.Hash().String()) 312 if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil { 313 return nil, err 314 } 315 } 316 } 317 // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain 318 for hash := range BadHashes { 319 if header := bc.GetHeaderByHash(hash); header != nil { 320 // get the canonical block corresponding to the offending header's number 321 headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) 322 // make sure the headerByNumber (if present) is in our current canonical chain 323 if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { 324 logger.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) 325 bc.SetHead(header.Number.Uint64() - 1) 326 logger.Error("Chain rewind was successful, resuming normal operation") 327 } 328 } 329 } 330 331 // Load any existing snapshot, regenerating it if loading failed 332 if bc.cacheConfig.SnapshotCacheSize > 0 { 333 // If the chain was rewound past the snapshot persistent layer (causing 334 // a recovery block number to be persisted to disk), check if we're still 335 // in recovery mode and in that case, don't invalidate the snapshot on a 336 // head mismatch. 337 var recover bool 338 339 head := bc.CurrentBlock() 340 if layer := bc.db.ReadSnapshotRecoveryNumber(); layer != nil && *layer > head.NumberU64() { 341 logger.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer) 342 recover = true 343 } 344 bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotCacheSize, head.Root(), bc.cacheConfig.SnapshotAsyncGen, true, recover) 345 } 346 347 for i := 1; i <= bc.cacheConfig.TrieNodeCacheConfig.NumFetcherPrefetchWorker; i++ { 348 bc.wg.Add(1) 349 go bc.prefetchTxWorker(i) 350 } 351 logger.Info("prefetchTxWorkers are started", "num", bc.cacheConfig.TrieNodeCacheConfig.NumFetcherPrefetchWorker) 352 353 // Take ownership of this particular state 354 go bc.update() 355 bc.gcCachedNodeLoop() 356 bc.restartStateMigration() 357 358 if cacheConfig.TrieNodeCacheConfig.DumpPeriodically() { 359 logger.Info("LocalCache is used for trie node cache, start saving cache to file periodically", 360 "dir", bc.cacheConfig.TrieNodeCacheConfig.FastCacheFileDir, 361 "period", bc.cacheConfig.TrieNodeCacheConfig.FastCacheSavePeriod) 362 trieDB := bc.stateCache.TrieDB() 363 bc.wg.Add(1) 364 go func() { 365 defer bc.wg.Done() 366 trieDB.SaveCachePeriodically(bc.cacheConfig.TrieNodeCacheConfig, bc.quit) 367 }() 368 } 369 370 return bc, nil 371 } 372 373 // prefetchTxWorker receives a block and a transaction index, which it pre-executes 374 // to retrieve and cache the data for the actual block processing. 375 func (bc *BlockChain) prefetchTxWorker(index int) { 376 defer bc.wg.Done() 377 378 logger.Debug("prefetchTxWorker is started", "index", index) 379 var snaps *snapshot.Tree 380 if bc.cacheConfig.TrieNodeCacheConfig.UseSnapshotForPrefetch { 381 snaps = bc.snaps 382 } 383 for followup := range bc.prefetchTxCh { 384 stateDB, err := state.NewForPrefetching(bc.CurrentBlock().Root(), bc.stateCache, snaps) 385 if err != nil { 386 logger.Debug("failed to retrieve stateDB for prefetchTxWorker", "err", err) 387 continue 388 } 389 vmCfg := bc.vmConfig 390 vmCfg.Prefetching = true 391 bc.prefetcher.PrefetchTx(followup.block, followup.ti, stateDB, vmCfg, followup.followupInterrupt) 392 } 393 logger.Debug("prefetchTxWorker is terminated", "index", index) 394 } 395 396 // SetCanonicalBlock resets the canonical as the block with the given block number. 397 // It works as rewinding the head block to the previous one, but does not delete the data. 398 func (bc *BlockChain) SetCanonicalBlock(blockNum uint64) { 399 // If the given block number is zero (it is zero by default), it does nothing 400 if blockNum == 0 { 401 return 402 } 403 // Read the block with the given block number and set it as canonical block 404 targetBlock := bc.db.ReadBlockByNumber(blockNum) 405 if targetBlock == nil { 406 logger.Error("failed to retrieve the block", "blockNum", blockNum) 407 return 408 } 409 bc.insert(targetBlock) 410 if err := bc.loadLastState(); err != nil { 411 logger.Error("failed to load last state after setting the canonical block", "err", err) 412 return 413 } 414 // Make sure the state associated with the block is available 415 head := bc.CurrentBlock() 416 if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil { 417 // Dangling block without a state associated, init from scratch 418 logger.Warn("Head state missing, repairing chain", 419 "number", head.NumberU64(), "hash", head.Hash().String()) 420 if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil { 421 logger.Error("Repairing chain is failed", "number", head.NumberU64(), "hash", head.Hash().String(), "err", err) 422 return 423 } 424 } 425 logger.Info("successfully set the canonical block", "blockNum", blockNum) 426 } 427 428 func (bc *BlockChain) UseGiniCoeff() bool { 429 return bc.chainConfig.Governance.Reward.UseGiniCoeff 430 } 431 432 func (bc *BlockChain) ProposerPolicy() uint64 { 433 return bc.chainConfig.Istanbul.ProposerPolicy 434 } 435 436 func (bc *BlockChain) getProcInterrupt() bool { 437 return atomic.LoadInt32(&bc.procInterrupt) == 1 438 } 439 440 // loadLastState loads the last known chain state from the database. This method 441 // assumes that the chain manager mutex is held. 442 func (bc *BlockChain) loadLastState() error { 443 // Restore the last known head block 444 head := bc.db.ReadHeadBlockHash() 445 if head == (common.Hash{}) { 446 // Corrupt or empty database, init from scratch 447 logger.Info("Empty database, resetting chain") 448 return bc.Reset() 449 } 450 // Make sure the entire head block is available 451 currentBlock := bc.GetBlockByHash(head) 452 if currentBlock == nil { 453 head = bc.db.ReadHeadBlockBackupHash() 454 if head == (common.Hash{}) { 455 // Corrupt or empty database, init from scratch 456 logger.Info("Empty database, resetting chain") 457 return bc.Reset() 458 } 459 460 currentBlock = bc.GetBlockByHash(head) 461 if currentBlock == nil { 462 // Corrupt or empty database, init from scratch 463 logger.Error("Head block missing, resetting chain", "hash", head.String()) 464 return bc.Reset() 465 } 466 } 467 // Everything seems to be fine, set as the head block 468 bc.currentBlock.Store(currentBlock) 469 bc.lastCommittedBlock = currentBlock.NumberU64() 470 471 // Restore the last known head header 472 currentHeader := currentBlock.Header() 473 if head := bc.db.ReadHeadHeaderHash(); head != (common.Hash{}) { 474 if header := bc.GetHeaderByHash(head); header != nil { 475 currentHeader = header 476 } 477 } 478 bc.hc.SetCurrentHeader(currentHeader) 479 480 // Restore the last known head fast block 481 bc.currentFastBlock.Store(currentBlock) 482 if head := bc.db.ReadHeadFastBlockHash(); head != (common.Hash{}) { 483 if block := bc.GetBlockByHash(head); block != nil { 484 bc.currentFastBlock.Store(block) 485 } else if head := bc.db.ReadHeadFastBlockBackupHash(); head != (common.Hash{}) { 486 if block := bc.GetBlockByHash(head); block != nil { 487 bc.currentFastBlock.Store(block) 488 } 489 } 490 } 491 492 // Issue a status log for the user 493 currentFastBlock := bc.CurrentFastBlock() 494 495 headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) 496 blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 497 fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()) 498 499 logger.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time.Uint64()), 0))) 500 logger.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time.Uint64()), 0))) 501 logger.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time.Uint64()), 0))) 502 503 return nil 504 } 505 506 // SetHead rewinds the local chain to a new head with the extra condition 507 // that the rewind must pass the specified state root. The method will try to 508 // delete minimal data from disk whilst retaining chain consistency. 509 func (bc *BlockChain) SetHead(head uint64) error { 510 _, err := bc.setHeadBeyondRoot(head, common.Hash{}, false) 511 return err 512 } 513 514 // setHeadBeyondRoot rewinds the local chain to a new head with the extra condition 515 // that the rewind must pass the specified state root. This method is meant to be 516 // used when rewinding with snapshots enabled to ensure that we go back further than 517 // persistent disk layer. Depending on whether the node was fast synced or full, and 518 // in which state, the method will try to delete minimal data from disk whilst 519 // retaining chain consistency. 520 // 521 // The method returns the block number where the requested root cap was found. 522 func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bool) (uint64, error) { 523 bc.mu.Lock() 524 defer bc.mu.Unlock() 525 526 // Track the block number of the requested root hash 527 var rootNumber uint64 // (no root == always 0) 528 529 updateFn := func(header *types.Header) error { 530 // Rewind the block chain, ensuring we don't end up with a stateless head block 531 if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() { 532 newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) 533 if newHeadBlock == nil { 534 logger.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash()) 535 newHeadBlock = bc.genesisBlock 536 } else { 537 // Block exists, keep rewinding until we find one with state, 538 // keeping rewinding until we exceed the optional threshold 539 // root hash 540 beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true) 541 542 for { 543 // If a root threshold was requested but not yet crossed, check 544 if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root { 545 beyondRoot, rootNumber = true, newHeadBlock.NumberU64() 546 } 547 if _, err := state.New(newHeadBlock.Root(), bc.stateCache, bc.snaps); err != nil { 548 // Rewound state missing, rolled back to the parent block, reset to genesis 549 logger.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash()) 550 parent := bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) 551 if parent != nil { 552 newHeadBlock = parent 553 continue 554 } 555 logger.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash()) 556 newHeadBlock = bc.genesisBlock 557 } 558 if beyondRoot || newHeadBlock.NumberU64() == 0 { 559 logger.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash().String()) 560 break 561 } 562 // if newHeadBlock has state, then rewind first 563 logger.Debug("Skipping block with threshold state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash().String(), "root", newHeadBlock.Root().String()) 564 newHeadBlock = bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) // Keep rewinding 565 } 566 567 } 568 if newHeadBlock.NumberU64() == 0 { 569 return errors.New("rewound to block number 0, but repair failed") 570 } 571 bc.db.WriteHeadBlockHash(newHeadBlock.Hash()) 572 573 // Degrade the chain markers if they are explicitly reverted. 574 // In theory we should update all in-memory markers in the 575 // last step, however the direction of SetHead is from high 576 // to low, so it's safe the update in-memory markers directly. 577 bc.currentBlock.Store(newHeadBlock) 578 headBlockNumberGauge.Update(int64(newHeadBlock.NumberU64())) 579 } 580 581 // Rewind the fast block in a simpleton way to the target head 582 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() { 583 newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) 584 // If either blocks reached nil, reset to the genesis state 585 if newHeadFastBlock == nil { 586 newHeadFastBlock = bc.genesisBlock 587 } 588 bc.db.WriteHeadFastBlockHash(newHeadFastBlock.Hash()) 589 590 // Degrade the chain markers if they are explicitly reverted. 591 // In theory we should update all in-memory markers in the 592 // last step, however the direction of SetHead is from high 593 // to low, so it's safe the update in-memory markers directly. 594 bc.currentFastBlock.Store(newHeadFastBlock) 595 } 596 return nil 597 } 598 599 // Rewind the header chain, deleting all block bodies until then 600 delFn := func(hash common.Hash, num uint64) { 601 // Remove relative body and receipts from the active store. 602 // The header, total difficulty and canonical hash will be 603 // removed in the hc.SetHead function. 604 bc.db.DeleteBody(hash, num) 605 bc.db.DeleteReceipts(hash, num) 606 } 607 608 // If SetHead was only called as a chain reparation method, try to skip 609 // touching the header chain altogether 610 if repair { 611 if err := updateFn(bc.CurrentBlock().Header()); err != nil { 612 return 0, err 613 } 614 } else { 615 // Rewind the chain to the requested head and keep going backwards until a 616 // block with a state is found 617 logger.Warn("Rewinding blockchain", "target", head) 618 if err := bc.hc.SetHead(head, updateFn, delFn); err != nil { 619 return 0, err 620 } 621 } 622 623 // Clear out any stale content from the caches 624 bc.futureBlocks.Purge() 625 bc.db.ClearBlockChainCache() 626 // TODO-Klaytn add governance DB deletion logic. 627 628 return rootNumber, bc.loadLastState() 629 } 630 631 // FastSyncCommitHead sets the current head block to the one defined by the hash 632 // irrelevant what the chain contents were prior. 633 func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { 634 // Make sure that both the block as well at its state trie exists 635 block := bc.GetBlockByHash(hash) 636 if block == nil { 637 return fmt.Errorf("non existent block [%x…]", hash[:4]) 638 } 639 if _, err := statedb.NewSecureTrie(block.Root(), bc.stateCache.TrieDB()); err != nil { 640 return err 641 } 642 // If all checks out, manually set the head block 643 bc.mu.Lock() 644 bc.currentBlock.Store(block) 645 bc.lastCommittedBlock = block.NumberU64() 646 bc.mu.Unlock() 647 648 // Destroy any existing state snapshot and regenerate it in the background, 649 // also resuming the normal maintenance of any previously paused snapshot. 650 if bc.snaps != nil { 651 bc.snaps.Rebuild(block.Root()) 652 } 653 logger.Info("Committed new head block", "number", block.Number(), "hash", hash) 654 return nil 655 } 656 657 // CurrentBlock retrieves the current head block of the canonical chain. The 658 // block is retrieved from the blockchain's internal cache. 659 func (bc *BlockChain) CurrentBlock() *types.Block { 660 return bc.currentBlock.Load().(*types.Block) 661 } 662 663 // CurrentFastBlock retrieves the current fast-sync head block of the canonical 664 // chain. The block is retrieved from the blockchain's internal cache. 665 func (bc *BlockChain) CurrentFastBlock() *types.Block { 666 return bc.currentFastBlock.Load().(*types.Block) 667 } 668 669 // Validator returns the current validator. 670 func (bc *BlockChain) Validator() Validator { 671 return bc.validator 672 } 673 674 // Processor returns the current processor. 675 func (bc *BlockChain) Processor() Processor { 676 return bc.processor 677 } 678 679 // State returns a new mutable state based on the current HEAD block. 680 func (bc *BlockChain) State() (*state.StateDB, error) { 681 return bc.StateAt(bc.CurrentBlock().Root()) 682 } 683 684 // StateAt returns a new mutable state based on a particular point in time. 685 func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { 686 return state.New(root, bc.stateCache, bc.snaps) 687 } 688 689 // StateAtWithPersistent returns a new mutable state based on a particular point in time with persistent trie nodes. 690 func (bc *BlockChain) StateAtWithPersistent(root common.Hash) (*state.StateDB, error) { 691 exist := bc.stateCache.TrieDB().DoesExistNodeInPersistent(root) 692 if !exist { 693 return nil, ErrNotExistNode 694 } 695 return state.New(root, bc.stateCache, bc.snaps) 696 } 697 698 // StateAtWithGCLock returns a new mutable state based on a particular point in time with read lock of the state nodes. 699 func (bc *BlockChain) StateAtWithGCLock(root common.Hash) (*state.StateDB, error) { 700 bc.RLockGCCachedNode() 701 702 exist := bc.stateCache.TrieDB().DoesExistCachedNode(root) 703 if !exist { 704 bc.RUnlockGCCachedNode() 705 return nil, ErrNotExistNode 706 } 707 708 stateDB, err := state.New(root, bc.stateCache, bc.snaps) 709 if err != nil { 710 bc.RUnlockGCCachedNode() 711 return nil, err 712 } 713 714 return stateDB, nil 715 } 716 717 // StateCache returns the caching database underpinning the blockchain instance. 718 func (bc *BlockChain) StateCache() state.Database { 719 return bc.stateCache 720 } 721 722 // Reset purges the entire blockchain, restoring it to its genesis state. 723 func (bc *BlockChain) Reset() error { 724 return bc.ResetWithGenesisBlock(bc.genesisBlock) 725 } 726 727 // ResetWithGenesisBlock purges the entire blockchain, restoring it to the 728 // specified genesis state. 729 func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { 730 // Dump the entire block chain and purge the caches 731 if err := bc.SetHead(0); err != nil { 732 return err 733 } 734 bc.mu.Lock() 735 defer bc.mu.Unlock() 736 737 // Prepare the genesis block and reinitialise the chain 738 bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.BlockScore()) 739 bc.db.WriteBlock(genesis) 740 741 bc.genesisBlock = genesis 742 bc.insert(bc.genesisBlock) 743 bc.currentBlock.Store(bc.genesisBlock) 744 bc.hc.SetGenesis(bc.genesisBlock.Header()) 745 bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) 746 bc.currentFastBlock.Store(bc.genesisBlock) 747 748 return nil 749 } 750 751 // repair tries to repair the current blockchain by rolling back the current block 752 // until one with associated state is found. This is needed to fix incomplete db 753 // writes caused either by crashes/power outages, or simply non-committed tries. 754 // 755 // This method only rolls back the current block. The current header and current 756 // fast block are left intact. 757 // Deprecated: in order to repair chain, please use SetHead or setHeadBeyondRoot methods 758 func (bc *BlockChain) repair(head **types.Block) error { 759 for { 760 // Abort if we've rewound to a head block that does have associated state 761 if _, err := state.New((*head).Root(), bc.stateCache, bc.snaps); err == nil { 762 logger.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash()) 763 return nil 764 } else { 765 // Should abort and return error, otherwise it will fall into infinite loop 766 if (*head).NumberU64() == 0 { 767 return errors.New("rewound to block number 0, but repair failed") 768 } else { 769 // If headBlockNumber > 0, rewind one block and recheck state availability there 770 block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1) 771 if block == nil { 772 return fmt.Errorf("missing block %d [%x]", (*head).NumberU64()-1, (*head).ParentHash()) 773 } 774 *head = block 775 } 776 } 777 } 778 } 779 780 // Export writes the active chain to the given writer. 781 func (bc *BlockChain) Export(w io.Writer) error { 782 return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64()) 783 } 784 785 // ExportN writes a subset of the active chain to the given writer. 786 func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { 787 bc.mu.RLock() 788 defer bc.mu.RUnlock() 789 790 if first > last { 791 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 792 } 793 logger.Info("Exporting batch of blocks", "count", last-first+1) 794 795 start, reported := time.Now(), time.Now() 796 for nr := first; nr <= last; nr++ { 797 block := bc.GetBlockByNumber(nr) 798 if block == nil { 799 return fmt.Errorf("export failed on #%d: not found", nr) 800 } 801 if err := block.EncodeRLP(w); err != nil { 802 return err 803 } 804 if time.Since(reported) >= log.StatsReportLimit { 805 logger.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start))) 806 reported = time.Now() 807 } 808 } 809 810 return nil 811 } 812 813 // insert injects a new head block into the current block chain. This method 814 // assumes that the block is indeed a true head. It will also reset the head 815 // header and the head fast sync block to this very same block if they are older 816 // or if they are on a different side chain. 817 // 818 // Note, this function assumes that the `mu` mutex is held! 819 func (bc *BlockChain) insert(block *types.Block) { 820 // If the block is on a side chain or an unknown one, force other heads onto it too 821 updateHeads := bc.db.ReadCanonicalHash(block.NumberU64()) != block.Hash() 822 823 // Add the block to the canonical chain number scheme and mark as the head 824 bc.db.WriteCanonicalHash(block.Hash(), block.NumberU64()) 825 bc.db.WriteHeadBlockHash(block.Hash()) 826 827 bc.currentBlock.Store(block) 828 829 // If the block is better than our head or is on a different chain, force update heads 830 if updateHeads { 831 bc.hc.SetCurrentHeader(block.Header()) 832 bc.db.WriteHeadFastBlockHash(block.Hash()) 833 834 bc.currentFastBlock.Store(block) 835 } 836 } 837 838 // Genesis retrieves the chain's genesis block. 839 func (bc *BlockChain) Genesis() *types.Block { 840 return bc.genesisBlock 841 } 842 843 // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, 844 // caching it if found. 845 func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 846 return bc.db.ReadBodyRLPByHash(hash) 847 } 848 849 // HasBlock checks if a block is fully present in the database or not. 850 func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { 851 return bc.db.HasBlock(hash, number) 852 } 853 854 // HasState checks if state trie is fully present in the database or not. 855 func (bc *BlockChain) HasState(hash common.Hash) bool { 856 _, err := bc.stateCache.OpenTrie(hash) 857 return err == nil 858 } 859 860 // HasBlockAndState checks if a block and associated state trie is fully present 861 // in the database or not, caching it if present. 862 func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool { 863 // Check first that the block itself is known 864 block := bc.GetBlock(hash, number) 865 if block == nil { 866 return false 867 } 868 return bc.HasState(block.Root()) 869 } 870 871 // ShouldTryInserting returns the state whether the block should be inserted. 872 // If a node doesn't have the given block or the block number of given block is higher than the node's head block, it can try inserting the block. 873 func (bc *BlockChain) ShouldTryInserting(block *types.Block) bool { 874 return !bc.HasBlockAndState(block.Hash(), block.NumberU64()) || bc.CurrentBlock().NumberU64() < block.NumberU64() 875 } 876 877 // GetBlock retrieves a block from the database by hash and number, 878 // caching it if found. 879 func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 880 return bc.db.ReadBlock(hash, number) 881 } 882 883 // GetBlockByHash retrieves a block from the database by hash, caching it if found. 884 func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { 885 return bc.db.ReadBlockByHash(hash) 886 } 887 888 // GetBlockNumber retrieves a blockNumber from the database by hash, caching it if found. 889 func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 { 890 return bc.hc.GetBlockNumber(hash) 891 } 892 893 // GetBlockByNumber retrieves a block from the database by number, caching it 894 // (associated with its hash) if found. 895 func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { 896 return bc.db.ReadBlockByNumber(number) 897 } 898 899 // GetTxAndLookupInfo retrieves a tx and lookup info for a given transaction hash. 900 func (bc *BlockChain) GetTxAndLookupInfo(txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { 901 tx, blockHash, blockNumber, index := bc.GetTxAndLookupInfoInCache(txHash) 902 if tx == nil { 903 tx, blockHash, blockNumber, index = bc.db.ReadTxAndLookupInfo(txHash) 904 } 905 return tx, blockHash, blockNumber, index 906 } 907 908 // GetTxLookupInfoAndReceipt retrieves a tx and lookup info and receipt for a given transaction hash. 909 func (bc *BlockChain) GetTxLookupInfoAndReceipt(txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, *types.Receipt) { 910 tx, blockHash, blockNumber, index := bc.GetTxAndLookupInfo(txHash) 911 if tx == nil { 912 return nil, common.Hash{}, 0, 0, nil 913 } 914 915 receipt := bc.GetReceiptByTxHash(txHash) 916 if receipt == nil { 917 return nil, common.Hash{}, 0, 0, nil 918 } 919 920 return tx, blockHash, blockNumber, index, receipt 921 } 922 923 // GetTxLookupInfoAndReceiptInCache retrieves a tx and lookup info and receipt for a given transaction hash in cache. 924 func (bc *BlockChain) GetTxLookupInfoAndReceiptInCache(txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, *types.Receipt) { 925 tx, blockHash, blockNumber, index := bc.GetTxAndLookupInfoInCache(txHash) 926 if tx == nil { 927 return nil, common.Hash{}, 0, 0, nil 928 } 929 930 receipt := bc.GetTxReceiptInCache(txHash) 931 if receipt == nil { 932 return nil, common.Hash{}, 0, 0, nil 933 } 934 935 return tx, blockHash, blockNumber, index, receipt 936 } 937 938 // GetReceiptsByBlockHash retrieves the receipts for all transactions with given block hash. 939 func (bc *BlockChain) GetReceiptsByBlockHash(blockHash common.Hash) types.Receipts { 940 return bc.db.ReadReceiptsByBlockHash(blockHash) 941 } 942 943 // GetReceiptByTxHash retrieves a receipt for a given transaction hash. 944 func (bc *BlockChain) GetReceiptByTxHash(txHash common.Hash) *types.Receipt { 945 receipt := bc.GetTxReceiptInCache(txHash) 946 if receipt != nil { 947 return receipt 948 } 949 950 tx, blockHash, _, index := bc.GetTxAndLookupInfo(txHash) 951 if tx == nil { 952 return nil 953 } 954 955 receipts := bc.GetReceiptsByBlockHash(blockHash) 956 if len(receipts) <= int(index) { 957 logger.Error("receipt index exceeds the size of receipts", "receiptIndex", index, "receiptsSize", len(receipts)) 958 return nil 959 } 960 return receipts[index] 961 } 962 963 // GetLogsByHash retrieves the logs for all receipts in a given block. 964 func (bc *BlockChain) GetLogsByHash(hash common.Hash) [][]*types.Log { 965 receipts := bc.GetReceiptsByBlockHash(hash) 966 if receipts == nil { 967 return nil 968 } 969 970 logs := make([][]*types.Log, len(receipts)) 971 for i, receipt := range receipts { 972 logs[i] = receipt.Logs 973 } 974 return logs 975 } 976 977 // TrieNode retrieves a blob of data associated with a trie node 978 // either from ephemeral in-memory cache, or from persistent storage. 979 func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) { 980 return bc.stateCache.TrieDB().Node(hash) 981 } 982 983 // ContractCode retrieves a blob of data associated with a contract hash 984 // either from ephemeral in-memory cache, or from persistent storage. 985 func (bc *BlockChain) ContractCode(hash common.Hash) ([]byte, error) { 986 return bc.stateCache.ContractCode(hash) 987 } 988 989 // ContractCodeWithPrefix retrieves a blob of data associated with a contract 990 // hash either from ephemeral in-memory cache, or from persistent storage. 991 // 992 // If the code doesn't exist in the in-memory cache, check the storage with 993 // new code scheme. 994 func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) { 995 type codeReader interface { 996 ContractCodeWithPrefix(codeHash common.Hash) ([]byte, error) 997 } 998 return bc.stateCache.(codeReader).ContractCodeWithPrefix(hash) 999 } 1000 1001 // Stop stops the blockchain service. If any imports are currently in progress 1002 // it will abort them using the procInterrupt. 1003 func (bc *BlockChain) Stop() { 1004 if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { 1005 return 1006 } 1007 // Unsubscribe all subscriptions registered from blockchain 1008 bc.scope.Close() 1009 if bc.cacheConfig.TrieNodeCacheConfig.RedisSubscribeBlockEnable { 1010 bc.CloseBlockSubscriptionLoop() 1011 } 1012 1013 close(bc.prefetchTxCh) 1014 close(bc.quit) 1015 atomic.StoreInt32(&bc.procInterrupt, 1) 1016 1017 bc.wg.Wait() 1018 1019 // Ensure that the entirety of the state snapshot is journalled to disk. 1020 var snapBase common.Hash 1021 if bc.snaps != nil { 1022 var err error 1023 if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root()); err != nil { 1024 logger.Error("Failed to journal state snapshot", "err", err) 1025 } 1026 } 1027 1028 triedb := bc.stateCache.TrieDB() 1029 if !bc.isArchiveMode() { 1030 number := bc.CurrentBlock().NumberU64() 1031 recent := bc.GetBlockByNumber(number) 1032 if recent == nil { 1033 logger.Error("Failed to find recent block from persistent", "blockNumber", number) 1034 return 1035 } 1036 1037 logger.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) 1038 if err := triedb.Commit(recent.Root(), true, number); err != nil { 1039 logger.Error("Failed to commit recent state trie", "err", err) 1040 } 1041 if snapBase != (common.Hash{}) { 1042 logger.Info("Writing snapshot state to disk", "root", snapBase) 1043 if err := triedb.Commit(snapBase, true, number); err != nil { 1044 logger.Error("Failed to commit recent state trie", "err", err) 1045 } 1046 } 1047 for !bc.triegc.Empty() { 1048 triedb.Dereference(bc.triegc.PopItem().(common.Hash)) 1049 } 1050 if size, _, _ := triedb.Size(); size != 0 { 1051 logger.Error("Dangling trie nodes after full cleanup") 1052 } 1053 } 1054 if triedb.TrieNodeCache() != nil { 1055 _ = triedb.TrieNodeCache().Close() 1056 } 1057 1058 logger.Info("Blockchain manager stopped") 1059 } 1060 1061 func (bc *BlockChain) procFutureBlocks() { 1062 blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) 1063 for _, hash := range bc.futureBlocks.Keys() { 1064 hashKey, ok := hash.(common.CacheKey) 1065 if !ok { 1066 logger.Error("invalid key type", "expect", "common.CacheKey", "actual", reflect.TypeOf(hash)) 1067 continue 1068 } 1069 1070 if block, exist := bc.futureBlocks.Peek(hashKey); exist { 1071 cacheGetFutureBlockHitMeter.Mark(1) 1072 blocks = append(blocks, block.(*types.Block)) 1073 } else { 1074 cacheGetFutureBlockMissMeter.Mark(1) 1075 } 1076 } 1077 if len(blocks) > 0 { 1078 types.BlockBy(types.Number).Sort(blocks) 1079 1080 // Insert one by one as chain insertion needs contiguous ancestry between blocks 1081 for i := range blocks { 1082 bc.InsertChain(blocks[i : i+1]) 1083 } 1084 } 1085 } 1086 1087 // WriteStatus status of write 1088 type WriteStatus byte 1089 1090 // TODO-Klaytn-Issue264 If we are using istanbul BFT, then we always have a canonical chain. 1091 // 1092 // Later we may be able to remove SideStatTy. 1093 const ( 1094 NonStatTy WriteStatus = iota 1095 CanonStatTy 1096 SideStatTy 1097 ) 1098 1099 // WriteResult includes the block write status and related statistics. 1100 type WriteResult struct { 1101 Status WriteStatus 1102 TotalWriteTime time.Duration 1103 TrieWriteTime time.Duration 1104 } 1105 1106 // Rollback is designed to remove a chain of links from the database that aren't 1107 // certain enough to be valid. 1108 func (bc *BlockChain) Rollback(chain []common.Hash) { 1109 bc.mu.Lock() 1110 defer bc.mu.Unlock() 1111 1112 for i := len(chain) - 1; i >= 0; i-- { 1113 hash := chain[i] 1114 1115 currentHeader := bc.CurrentHeader() 1116 if currentHeader.Hash() == hash { 1117 bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) 1118 } 1119 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash { 1120 newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1) 1121 bc.currentFastBlock.Store(newFastBlock) 1122 bc.db.WriteHeadFastBlockHash(newFastBlock.Hash()) 1123 } 1124 if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash { 1125 newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1) 1126 bc.currentBlock.Store(newBlock) 1127 bc.db.WriteHeadBlockHash(newBlock.Hash()) 1128 } 1129 } 1130 } 1131 1132 // SetReceiptsData computes all the non-consensus fields of the receipts 1133 func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error { 1134 signer := types.MakeSigner(config, block.Number()) 1135 1136 transactions, logIndex := block.Transactions(), uint(0) 1137 if len(transactions) != len(receipts) { 1138 return errors.New("transaction and receipt count mismatch") 1139 } 1140 1141 for j := 0; j < len(receipts); j++ { 1142 // The transaction hash can be retrieved from the transaction itself 1143 receipts[j].TxHash = transactions[j].Hash() 1144 1145 // The contract address can be derived from the transaction itself 1146 if transactions[j].To() == nil { 1147 // Deriving the signer is expensive, only do if it's actually needed 1148 from, _ := types.Sender(signer, transactions[j]) 1149 receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce()) 1150 } 1151 // The derived log fields can simply be set from the block and transaction 1152 for k := 0; k < len(receipts[j].Logs); k++ { 1153 receipts[j].Logs[k].BlockNumber = block.NumberU64() 1154 receipts[j].Logs[k].BlockHash = block.Hash() 1155 receipts[j].Logs[k].TxHash = receipts[j].TxHash 1156 receipts[j].Logs[k].TxIndex = uint(j) 1157 receipts[j].Logs[k].Index = logIndex 1158 logIndex++ 1159 } 1160 } 1161 return nil 1162 } 1163 1164 // InsertReceiptChain attempts to complete an already existing header chain with 1165 // transaction and receipt data. 1166 func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { 1167 bc.wg.Add(1) 1168 defer bc.wg.Done() 1169 1170 // Do a sanity check that the provided chain is actually ordered and linked 1171 for i := 1; i < len(blockChain); i++ { 1172 if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { 1173 logger.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(), 1174 "prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash()) 1175 return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, blockChain[i-1].NumberU64(), 1176 blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4]) 1177 } 1178 } 1179 1180 var ( 1181 stats = struct{ processed, ignored int32 }{} 1182 start = time.Now() 1183 bytes = 0 1184 1185 // TODO-Klaytn Needs to roll back if any one of batches fails 1186 bodyBatch = bc.db.NewBatch(database.BodyDB) 1187 receiptsBatch = bc.db.NewBatch(database.ReceiptsDB) 1188 txLookupEntriesBatch = bc.db.NewBatch(database.TxLookUpEntryDB) 1189 ) 1190 for i, block := range blockChain { 1191 receipts := receiptChain[i] 1192 // Short circuit insertion if shutting down or processing failed 1193 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1194 return 0, nil 1195 } 1196 // Short circuit if the owner header is unknown 1197 if !bc.HasHeader(block.Hash(), block.NumberU64()) { 1198 return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) 1199 } 1200 // Skip if the entire data is already known 1201 if bc.HasBlock(block.Hash(), block.NumberU64()) { 1202 stats.ignored++ 1203 continue 1204 } 1205 // Compute all the non-consensus fields of the receipts 1206 if err := SetReceiptsData(bc.chainConfig, block, receipts); err != nil { 1207 return i, fmt.Errorf("failed to set receipts data: %v", err) 1208 } 1209 // Write all the data out into the database 1210 bc.db.PutBodyToBatch(bodyBatch, block.Hash(), block.NumberU64(), block.Body()) 1211 bc.db.PutReceiptsToBatch(receiptsBatch, block.Hash(), block.NumberU64(), receipts) 1212 bc.db.PutTxLookupEntriesToBatch(txLookupEntriesBatch, block) 1213 1214 stats.processed++ 1215 1216 totalBytes, err := database.WriteBatchesOverThreshold(bodyBatch, receiptsBatch, txLookupEntriesBatch) 1217 if err != nil { 1218 return 0, err 1219 } else { 1220 bytes += totalBytes 1221 } 1222 } 1223 1224 totalBytes, err := database.WriteBatches(bodyBatch, receiptsBatch, txLookupEntriesBatch) 1225 if err != nil { 1226 return 0, err 1227 } else { 1228 bytes += totalBytes 1229 } 1230 1231 // Update the head fast sync block if better 1232 bc.mu.Lock() 1233 head := blockChain[len(blockChain)-1] 1234 if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case 1235 currentFastBlock := bc.CurrentFastBlock() 1236 if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 { 1237 bc.db.WriteHeadFastBlockHash(head.Hash()) 1238 bc.currentFastBlock.Store(head) 1239 } 1240 } 1241 bc.mu.Unlock() 1242 1243 logger.Info("Imported new block receipts", 1244 "count", stats.processed, 1245 "elapsed", common.PrettyDuration(time.Since(start)), 1246 "number", head.Number(), 1247 "hash", head.Hash(), 1248 "size", common.StorageSize(bytes), 1249 "ignored", stats.ignored) 1250 return 0, nil 1251 } 1252 1253 // WriteBlockWithoutState writes only the block and its metadata to the database, 1254 // but does not write any state. This is used to construct competing side forks 1255 // up to the point where they exceed the canonical total blockscore. 1256 func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) { 1257 bc.wg.Add(1) 1258 defer bc.wg.Done() 1259 1260 bc.hc.WriteTd(block.Hash(), block.NumberU64(), td) 1261 bc.writeBlock(block) 1262 } 1263 1264 type TransactionLookup struct { 1265 Tx *types.Transaction 1266 *database.TxLookupEntry 1267 } 1268 1269 // writeBlock writes block to persistent database. 1270 // If write through caching is enabled, it also writes block to the cache. 1271 func (bc *BlockChain) writeBlock(block *types.Block) { 1272 bc.db.WriteBlock(block) 1273 } 1274 1275 // writeReceipts writes receipts to persistent database. 1276 // If write through caching is enabled, it also writes blockReceipts to the cache. 1277 func (bc *BlockChain) writeReceipts(hash common.Hash, number uint64, receipts types.Receipts) { 1278 bc.db.WriteReceipts(hash, number, receipts) 1279 } 1280 1281 // writeStateTrie writes state trie to database if possible. 1282 // If an archiving node is running, it always flushes state trie to DB. 1283 // If not, it flushes state trie to DB periodically. (period = bc.cacheConfig.BlockInterval) 1284 func (bc *BlockChain) writeStateTrie(block *types.Block, state *state.StateDB) error { 1285 state.LockGCCachedNode() 1286 defer state.UnlockGCCachedNode() 1287 1288 root, err := state.Commit(true) 1289 if err != nil { 1290 return err 1291 } 1292 trieDB := bc.stateCache.TrieDB() 1293 trieDB.UpdateMetricNodes() 1294 1295 // If we're running an archive node, always flush 1296 if bc.isArchiveMode() { 1297 if err := trieDB.Commit(root, false, block.NumberU64()); err != nil { 1298 return err 1299 } 1300 1301 bc.checkStartStateMigration(block.NumberU64(), root) 1302 bc.lastCommittedBlock = block.NumberU64() 1303 } else { 1304 // Full but not archive node, do proper garbage collection 1305 trieDB.Reference(root, common.Hash{}) // metadata reference to keep trie alive 1306 1307 // If we exceeded our memory allowance, flush matured singleton nodes to disk 1308 var ( 1309 nodesSize, _, preimagesSize = trieDB.Size() 1310 nodesSizeLimit = common.StorageSize(bc.cacheConfig.CacheSize) * 1024 * 1024 1311 ) 1312 1313 trieDBNodesSizeBytesGauge.Update(int64(nodesSize)) 1314 trieDBPreimagesSizeGauge.Update(int64(preimagesSize)) 1315 1316 if nodesSize > nodesSizeLimit || preimagesSize > 4*1024*1024 { 1317 // NOTE-Klaytn Not to change the original behavior, error is not returned. 1318 // Error should be returned if it is thought to be safe in the future. 1319 if err := trieDB.Cap(nodesSizeLimit - database.IdealBatchSize); err != nil { 1320 logger.Error("Error from trieDB.Cap", "err", err, "limit", nodesSizeLimit-database.IdealBatchSize) 1321 } 1322 } 1323 1324 if isCommitTrieRequired(bc, block.NumberU64()) { 1325 logger.Trace("Commit the state trie into the disk", "blocknum", block.NumberU64()) 1326 if err := trieDB.Commit(block.Header().Root, true, block.NumberU64()); err != nil { 1327 return err 1328 } 1329 1330 if bc.checkStartStateMigration(block.NumberU64(), root) { 1331 // flush referenced trie nodes out to new stateTrieDB 1332 if err := trieDB.Cap(0); err != nil { 1333 logger.Error("Error from trieDB.Cap by state migration", "err", err) 1334 } 1335 } 1336 1337 bc.lastCommittedBlock = block.NumberU64() 1338 } 1339 1340 bc.chBlock <- gcBlock{root, block.NumberU64()} 1341 } 1342 return nil 1343 } 1344 1345 // RLockGCCachedNode locks the GC lock of CachedNode. 1346 func (bc *BlockChain) RLockGCCachedNode() { 1347 bc.stateCache.RLockGCCachedNode() 1348 } 1349 1350 // RUnlockGCCachedNode unlocks the GC lock of CachedNode. 1351 func (bc *BlockChain) RUnlockGCCachedNode() { 1352 bc.stateCache.RUnlockGCCachedNode() 1353 } 1354 1355 // DefaultTriesInMemory returns the number of tries residing in the memory. 1356 func (bc *BlockChain) triesInMemory() uint64 { 1357 return bc.cacheConfig.TriesInMemory 1358 } 1359 1360 // gcCachedNodeLoop runs a loop to gc. 1361 func (bc *BlockChain) gcCachedNodeLoop() { 1362 trieDB := bc.stateCache.TrieDB() 1363 1364 bc.wg.Add(1) 1365 go func() { 1366 defer bc.wg.Done() 1367 for { 1368 select { 1369 case block := <-bc.chBlock: 1370 bc.triegc.Push(block.root, -int64(block.blockNum)) 1371 logger.Trace("Push GC block", "blkNum", block.blockNum, "hash", block.root.String()) 1372 1373 blkNum := block.blockNum 1374 if blkNum <= bc.triesInMemory() { 1375 continue 1376 } 1377 1378 // Garbage collect anything below our required write retention 1379 chosen := blkNum - bc.triesInMemory() 1380 cnt := 0 1381 for !bc.triegc.Empty() { 1382 root, number := bc.triegc.Pop() 1383 if uint64(-number) > chosen { 1384 bc.triegc.Push(root, number) 1385 break 1386 } 1387 trieDB.Dereference(root.(common.Hash)) 1388 cnt++ 1389 } 1390 logger.Debug("GC cached node", "currentBlk", blkNum, "chosenBlk", chosen, "deferenceCnt", cnt) 1391 case <-bc.quit: 1392 return 1393 } 1394 } 1395 }() 1396 } 1397 1398 func isCommitTrieRequired(bc *BlockChain, blockNum uint64) bool { 1399 if bc.prepareStateMigration { 1400 return true 1401 } 1402 1403 // TODO-Klaytn-Issue1602 Introduce a simple and more concise way to determine commit trie requirements from governance 1404 if blockNum%uint64(bc.cacheConfig.BlockInterval) == 0 { 1405 return true 1406 } 1407 1408 if bc.chainConfig.Istanbul != nil { 1409 return bc.ProposerPolicy() == params.WeightedRandom && 1410 params.IsStakingUpdateInterval(blockNum) 1411 } 1412 return false 1413 } 1414 1415 // isReorganizationRequired returns if reorganization is required or not based on total blockscore. 1416 func isReorganizationRequired(localTd, externTd *big.Int, currentBlock, block *types.Block) bool { 1417 reorg := externTd.Cmp(localTd) > 0 1418 if !reorg && externTd.Cmp(localTd) == 0 { 1419 // Split same-blockscore blocks by number, then at random 1420 reorg = block.NumberU64() < currentBlock.NumberU64() || (block.NumberU64() == currentBlock.NumberU64() && mrand.Float64() < 0.5) 1421 } 1422 return reorg 1423 } 1424 1425 // WriteBlockWithState writes the block and all associated state to the database. 1426 // If we are to use writeBlockWithState alone, we should use mutex to protect internal state. 1427 func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, stateDB *state.StateDB) (WriteResult, error) { 1428 bc.mu.Lock() 1429 defer bc.mu.Unlock() 1430 1431 return bc.writeBlockWithState(block, receipts, stateDB) 1432 } 1433 1434 // writeBlockWithState writes the block and all associated state to the database. 1435 // If BlockChain.parallelDBWrite is true, it calls writeBlockWithStateParallel. 1436 // If not, it calls writeBlockWithStateSerial. 1437 func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, stateDB *state.StateDB) (WriteResult, error) { 1438 var status WriteResult 1439 var err error 1440 if bc.parallelDBWrite { 1441 status, err = bc.writeBlockWithStateParallel(block, receipts, stateDB) 1442 } else { 1443 status, err = bc.writeBlockWithStateSerial(block, receipts, stateDB) 1444 } 1445 1446 if err != nil { 1447 return status, err 1448 } 1449 1450 // Publish the committed block to the redis cache of stateDB. 1451 // The cache uses the block to distinguish the latest state. 1452 if bc.cacheConfig.TrieNodeCacheConfig.RedisPublishBlockEnable { 1453 blockLogsKey := append(kesCachePrefixBlockLogs, block.Number().Bytes()...) 1454 bc.writeBlockLogsToRemoteCache(blockLogsKey, receipts) 1455 1456 blockRlp, err := rlp.EncodeToBytes(block) 1457 if err != nil { 1458 logger.Error("failed to encode lastCommittedBlock", "blockNumber", block.NumberU64(), "err", err) 1459 } 1460 1461 pubSub, ok := bc.stateCache.TrieDB().TrieNodeCache().(statedb.BlockPubSub) 1462 if ok { 1463 if err := pubSub.PublishBlock(hexutil.Encode(blockRlp)); err != nil { 1464 logger.Error("failed to publish block to redis", "blockNumber", block.NumberU64(), "err", err) 1465 } 1466 } else { 1467 logger.Error("invalid TrieNodeCache type", "trieNodeCacheConfig", bc.cacheConfig.TrieNodeCacheConfig) 1468 } 1469 } 1470 1471 return status, err 1472 } 1473 1474 // writeBlockLogsToRemoteCache writes block logs to remote cache. 1475 // The stored logs will be used by KES service nodes to subscribe log events. 1476 // This method is only for KES nodes. 1477 func (bc *BlockChain) writeBlockLogsToRemoteCache(blockLogsKey []byte, receipts []*types.Receipt) { 1478 var entireBlockLogs []*types.LogForStorage 1479 for _, receipt := range receipts { 1480 for _, log := range receipt.Logs { 1481 // convert Log to LogForStorage to encode entire data 1482 entireBlockLogs = append(entireBlockLogs, (*types.LogForStorage)(log)) 1483 } 1484 } 1485 encodedBlockLogs, err := rlp.EncodeToBytes(entireBlockLogs) 1486 if err != nil { 1487 logger.Error("rlp encoding error", "err", err) 1488 return 1489 } 1490 // TODO-Klaytn-KES: refine this not to use trieNodeCache 1491 cache, ok := bc.stateCache.TrieDB().TrieNodeCache().(*statedb.HybridCache) 1492 if !ok { 1493 logger.Error("only HybridCache supports block logs writing", 1494 "TrieNodeCacheType", reflect.TypeOf(bc.stateCache.TrieDB().TrieNodeCache())) 1495 } else { 1496 cache.Remote().Set(blockLogsKey, encodedBlockLogs) 1497 } 1498 } 1499 1500 // writeBlockWithStateSerial writes the block and all associated state to the database in serial manner. 1501 func (bc *BlockChain) writeBlockWithStateSerial(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (WriteResult, error) { 1502 start := time.Now() 1503 bc.wg.Add(1) 1504 defer bc.wg.Done() 1505 1506 var status WriteStatus 1507 // Calculate the total blockscore of the block 1508 ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) 1509 if ptd == nil { 1510 logger.Error("unknown ancestor (writeBlockWithStateSerial)", "num", block.NumberU64(), 1511 "hash", block.Hash(), "parentHash", block.ParentHash()) 1512 return WriteResult{Status: NonStatTy}, consensus.ErrUnknownAncestor 1513 } 1514 1515 if !bc.ShouldTryInserting(block) { 1516 return WriteResult{Status: NonStatTy}, ErrKnownBlock 1517 } 1518 1519 currentBlock := bc.CurrentBlock() 1520 localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 1521 externTd := new(big.Int).Add(block.BlockScore(), ptd) 1522 1523 // Irrelevant of the canonical status, write the block itself to the database 1524 bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd) 1525 1526 // Write other block data. 1527 bc.writeBlock(block) 1528 1529 trieWriteStart := time.Now() 1530 if err := bc.writeStateTrie(block, state); err != nil { 1531 return WriteResult{Status: NonStatTy}, err 1532 } 1533 trieWriteTime := time.Since(trieWriteStart) 1534 1535 bc.writeReceipts(block.Hash(), block.NumberU64(), receipts) 1536 1537 // TODO-Klaytn-Issue264 If we are using istanbul BFT, then we always have a canonical chain. 1538 // Later we may be able to refine below code. 1539 1540 // If the total blockscore is higher than our known, add it to the canonical chain 1541 // Second clause in the if statement reduces the vulnerability to selfish mining. 1542 // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf 1543 currentBlock = bc.CurrentBlock() 1544 reorg := isReorganizationRequired(localTd, externTd, currentBlock, block) 1545 if reorg { 1546 // Reorganise the chain if the parent is not the head block 1547 if block.ParentHash() != currentBlock.Hash() { 1548 if err := bc.reorg(currentBlock, block); err != nil { 1549 return WriteResult{Status: NonStatTy}, err 1550 } 1551 } 1552 // Write the positional metadata for transaction/receipt lookups and preimages 1553 if err := bc.writeTxLookupEntries(block); err != nil { 1554 return WriteResult{Status: NonStatTy}, err 1555 } 1556 bc.db.WritePreimages(block.NumberU64(), state.Preimages()) 1557 status = CanonStatTy 1558 } else { 1559 status = SideStatTy 1560 } 1561 1562 return bc.finalizeWriteBlockWithState(block, status, start, trieWriteTime) 1563 } 1564 1565 // writeBlockWithStateParallel writes the block and all associated state to the database using goroutines. 1566 func (bc *BlockChain) writeBlockWithStateParallel(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (WriteResult, error) { 1567 start := time.Now() 1568 bc.wg.Add(1) 1569 defer bc.wg.Done() 1570 1571 var status WriteStatus 1572 // Calculate the total blockscore of the block 1573 ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) 1574 if ptd == nil { 1575 logger.Error("unknown ancestor (writeBlockWithStateParallel)", "num", block.NumberU64(), 1576 "hash", block.Hash(), "parentHash", block.ParentHash()) 1577 return WriteResult{Status: NonStatTy}, consensus.ErrUnknownAncestor 1578 } 1579 1580 if !bc.ShouldTryInserting(block) { 1581 return WriteResult{Status: NonStatTy}, ErrKnownBlock 1582 } 1583 1584 currentBlock := bc.CurrentBlock() 1585 localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 1586 externTd := new(big.Int).Add(block.BlockScore(), ptd) 1587 1588 parallelDBWriteWG := sync.WaitGroup{} 1589 parallelDBWriteErrCh := make(chan error, 2) 1590 // Irrelevant of the canonical status, write the block itself to the database 1591 // TODO-Klaytn-Storage Implementing worker pool pattern instead of generating goroutines every time. 1592 parallelDBWriteWG.Add(4) 1593 go func() { 1594 defer parallelDBWriteWG.Done() 1595 bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd) 1596 }() 1597 1598 // Write other block data. 1599 go func() { 1600 defer parallelDBWriteWG.Done() 1601 bc.writeBlock(block) 1602 }() 1603 1604 var trieWriteTime time.Duration 1605 trieWriteStart := time.Now() 1606 go func() { 1607 defer parallelDBWriteWG.Done() 1608 if err := bc.writeStateTrie(block, state); err != nil { 1609 parallelDBWriteErrCh <- err 1610 } 1611 trieWriteTime = time.Since(trieWriteStart) 1612 }() 1613 1614 go func() { 1615 defer parallelDBWriteWG.Done() 1616 bc.writeReceipts(block.Hash(), block.NumberU64(), receipts) 1617 }() 1618 1619 // Wait until all writing goroutines are terminated. 1620 parallelDBWriteWG.Wait() 1621 select { 1622 case err := <-parallelDBWriteErrCh: 1623 return WriteResult{Status: NonStatTy}, err 1624 default: 1625 } 1626 1627 // TODO-Klaytn-Issue264 If we are using istanbul BFT, then we always have a canonical chain. 1628 // Later we may be able to refine below code. 1629 1630 // If the total blockscore is higher than our known, add it to the canonical chain 1631 // Second clause in the if statement reduces the vulnerability to selfish mining. 1632 // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf 1633 currentBlock = bc.CurrentBlock() 1634 reorg := isReorganizationRequired(localTd, externTd, currentBlock, block) 1635 if reorg { 1636 // Reorganise the chain if the parent is not the head block 1637 if block.ParentHash() != currentBlock.Hash() { 1638 if err := bc.reorg(currentBlock, block); err != nil { 1639 return WriteResult{Status: NonStatTy}, err 1640 } 1641 } 1642 1643 parallelDBWriteWG.Add(2) 1644 1645 go func() { 1646 defer parallelDBWriteWG.Done() 1647 // Write the positional metadata for transaction/receipt lookups 1648 if err := bc.writeTxLookupEntries(block); err != nil { 1649 parallelDBWriteErrCh <- err 1650 } 1651 }() 1652 1653 go func() { 1654 defer parallelDBWriteWG.Done() 1655 bc.db.WritePreimages(block.NumberU64(), state.Preimages()) 1656 }() 1657 1658 // Wait until all writing goroutines are terminated. 1659 parallelDBWriteWG.Wait() 1660 1661 status = CanonStatTy 1662 } else { 1663 status = SideStatTy 1664 } 1665 1666 select { 1667 case err := <-parallelDBWriteErrCh: 1668 return WriteResult{Status: NonStatTy}, err 1669 default: 1670 } 1671 1672 return bc.finalizeWriteBlockWithState(block, status, start, trieWriteTime) 1673 } 1674 1675 // finalizeWriteBlockWithState updates metrics and inserts block when status is CanonStatTy. 1676 func (bc *BlockChain) finalizeWriteBlockWithState(block *types.Block, status WriteStatus, startTime time.Time, trieWriteTime time.Duration) (WriteResult, error) { 1677 // Set new head. 1678 if status == CanonStatTy { 1679 bc.insert(block) 1680 headBlockNumberGauge.Update(block.Number().Int64()) 1681 blockTxCountsGauge.Update(int64(block.Transactions().Len())) 1682 blockTxCountsCounter.Inc(int64(block.Transactions().Len())) 1683 } 1684 bc.futureBlocks.Remove(block.Hash()) 1685 return WriteResult{status, time.Since(startTime), trieWriteTime}, nil 1686 } 1687 1688 func (bc *BlockChain) writeTxLookupEntries(block *types.Block) error { 1689 return bc.db.WriteAndCacheTxLookupEntries(block) 1690 } 1691 1692 // GetTxAndLookupInfoInCache retrieves a tx and lookup info for a given transaction hash in cache. 1693 func (bc *BlockChain) GetTxAndLookupInfoInCache(hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { 1694 return bc.db.ReadTxAndLookupInfoInCache(hash) 1695 } 1696 1697 // GetBlockReceiptsInCache returns receipt of txHash in cache. 1698 func (bc *BlockChain) GetBlockReceiptsInCache(blockHash common.Hash) types.Receipts { 1699 return bc.db.ReadBlockReceiptsInCache(blockHash) 1700 } 1701 1702 // GetTxReceiptInCache returns receipt of txHash in cache. 1703 func (bc *BlockChain) GetTxReceiptInCache(txHash common.Hash) *types.Receipt { 1704 return bc.db.ReadTxReceiptInCache(txHash) 1705 } 1706 1707 // InsertChain attempts to insert the given batch of blocks in to the canonical 1708 // chain or, otherwise, create a fork. If an error is returned it will return 1709 // the index number of the failing block as well an error describing what went 1710 // wrong. 1711 // 1712 // After insertion is done, all accumulated events will be fired. 1713 func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { 1714 n, events, logs, err := bc.insertChain(chain) 1715 bc.PostChainEvents(events, logs) 1716 return n, err 1717 } 1718 1719 // insertChain will execute the actual chain insertion and event aggregation. The 1720 // only reason this method exists as a separate one is to make locking cleaner 1721 // with deferred statements. 1722 func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) { 1723 // Sanity check that we have something meaningful to import 1724 if len(chain) == 0 { 1725 return 0, nil, nil, nil 1726 } 1727 // Do a sanity check that the provided chain is actually ordered and linked 1728 for i := 1; i < len(chain); i++ { 1729 if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { 1730 // Chain broke ancestry, log a messge (programming error) and skip insertion 1731 logger.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(), 1732 "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash()) 1733 1734 return 0, nil, nil, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(), 1735 chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4]) 1736 } 1737 } 1738 1739 // Pre-checks passed, start the full block imports 1740 bc.wg.Add(1) 1741 defer bc.wg.Done() 1742 1743 bc.mu.Lock() 1744 defer bc.mu.Unlock() 1745 1746 // A queued approach to delivering events. This is generally 1747 // faster than direct delivery and requires much less mutex 1748 // acquiring. 1749 var ( 1750 stats = insertStats{startTime: mclock.Now()} 1751 events = make([]interface{}, 0, len(chain)) 1752 lastCanon *types.Block 1753 coalescedLogs []*types.Log 1754 ) 1755 // Start the parallel header verifier 1756 headers := make([]*types.Header, len(chain)) 1757 seals := make([]bool, len(chain)) 1758 1759 for i, block := range chain { 1760 headers[i] = block.Header() 1761 seals[i] = true 1762 } 1763 1764 var ( 1765 abort chan<- struct{} 1766 results <-chan error 1767 ) 1768 if bc.engine.CanVerifyHeadersConcurrently() { 1769 abort, results = bc.engine.VerifyHeaders(bc, headers, seals) 1770 } else { 1771 abort, results = bc.engine.PreprocessHeaderVerification(headers) 1772 } 1773 defer close(abort) 1774 1775 // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) 1776 senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) 1777 1778 // Iterate over the blocks and insert when the verifier permits 1779 for i, block := range chain { 1780 // If the chain is terminating, stop processing blocks 1781 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1782 logger.Debug("Premature abort during blocks processing") 1783 break 1784 } 1785 // Create a new trie using the parent block and report an 1786 // error if it fails. 1787 var parent *types.Block 1788 if i == 0 { 1789 parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 1790 } else { 1791 parent = chain[i-1] 1792 } 1793 1794 // If we have a followup block, run that against the current state to pre-cache 1795 // transactions and probabilistically some of the account/storage trie nodes. 1796 var followupInterrupt uint32 1797 1798 if bc.cacheConfig.TrieNodeCacheConfig.NumFetcherPrefetchWorker > 0 && parent != nil { 1799 var snaps *snapshot.Tree 1800 if bc.cacheConfig.TrieNodeCacheConfig.UseSnapshotForPrefetch { 1801 snaps = bc.snaps 1802 } 1803 1804 // Tx prefetcher is enabled for all cases (both single and multiple block insertion). 1805 for ti := range block.Transactions() { 1806 select { 1807 case bc.prefetchTxCh <- prefetchTx{ti, block, &followupInterrupt}: 1808 default: 1809 } 1810 } 1811 if i < len(chain)-1 { 1812 // current block is not the last one, so prefetch the right next block 1813 followup := chain[i+1] 1814 go func(start time.Time) { 1815 defer func() { 1816 if err := recover(); err != nil { 1817 logger.Error("Got panic and recovered from prefetcher", "err", err) 1818 } 1819 }() 1820 1821 throwaway, err := state.NewForPrefetching(parent.Root(), bc.stateCache, snaps) 1822 if throwaway == nil || err != nil { 1823 logger.Warn("failed to get StateDB for prefetcher", "err", err, 1824 "parentBlockNum", parent.NumberU64(), "currBlockNum", bc.CurrentBlock().NumberU64()) 1825 return 1826 } 1827 1828 vmCfg := bc.vmConfig 1829 vmCfg.Prefetching = true 1830 bc.prefetcher.Prefetch(followup, throwaway, vmCfg, &followupInterrupt) 1831 1832 blockPrefetchExecuteTimer.Update(time.Since(start)) 1833 if atomic.LoadUint32(&followupInterrupt) == 1 { 1834 blockPrefetchInterruptMeter.Mark(1) 1835 } 1836 }(time.Now()) 1837 } 1838 } 1839 // If the header is a banned one, straight out abort 1840 if BadHashes[block.Hash()] { 1841 bc.reportBlock(block, nil, ErrBlacklistedHash) 1842 return i, events, coalescedLogs, ErrBlacklistedHash 1843 } 1844 // Wait for the block's verification to complete 1845 bstart := time.Now() 1846 1847 err := <-results 1848 if !bc.engine.CanVerifyHeadersConcurrently() && err == nil { 1849 err = bc.engine.VerifyHeader(bc, block.Header(), true) 1850 } 1851 1852 if err == nil { 1853 err = bc.validator.ValidateBody(block) 1854 } 1855 1856 switch { 1857 case err == ErrKnownBlock: 1858 // Block and state both already known. However if the current block is below 1859 // this number we did a rollback and we should reimport it nonetheless. 1860 if bc.CurrentBlock().NumberU64() >= block.NumberU64() { 1861 stats.ignored++ 1862 continue 1863 } 1864 1865 case err == consensus.ErrFutureBlock: 1866 // Allow up to MaxFuture second in the future blocks. If this limit is exceeded 1867 // the chain is discarded and processed at a later time if given. 1868 max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks) 1869 if block.Time().Cmp(max) > 0 { 1870 return i, events, coalescedLogs, fmt.Errorf("future block: %v > %v", block.Time(), max) 1871 } 1872 bc.futureBlocks.Add(block.Hash(), block) 1873 stats.queued++ 1874 continue 1875 1876 case err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()): 1877 bc.futureBlocks.Add(block.Hash(), block) 1878 stats.queued++ 1879 continue 1880 1881 case err == consensus.ErrPrunedAncestor: 1882 // Block competing with the canonical chain, store in the db, but don't process 1883 // until the competitor TD goes above the canonical TD 1884 currentBlock := bc.CurrentBlock() 1885 localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 1886 externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.BlockScore()) 1887 if localTd.Cmp(externTd) > 0 { 1888 bc.WriteBlockWithoutState(block, externTd) 1889 continue 1890 } 1891 // Competitor chain beat canonical, gather all blocks from the common ancestor 1892 var winner []*types.Block 1893 1894 parent := bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 1895 for !bc.HasState(parent.Root()) { 1896 winner = append(winner, parent) 1897 parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1) 1898 } 1899 for j := 0; j < len(winner)/2; j++ { 1900 winner[j], winner[len(winner)-1-j] = winner[len(winner)-1-j], winner[j] 1901 } 1902 // Import all the pruned blocks to make the state available 1903 bc.mu.Unlock() 1904 _, evs, logs, err := bc.insertChain(winner) 1905 bc.mu.Lock() 1906 events, coalescedLogs = evs, logs 1907 1908 if err != nil { 1909 return i, events, coalescedLogs, err 1910 } 1911 1912 case err != nil: 1913 bc.futureBlocks.Remove(block.Hash()) 1914 bc.reportBlock(block, nil, err) 1915 return i, events, coalescedLogs, err 1916 } 1917 1918 stateDB, err := bc.StateAt(parent.Root()) 1919 if err != nil { 1920 return i, events, coalescedLogs, err 1921 } 1922 1923 // Process block using the parent state as reference point. 1924 receipts, logs, usedGas, internalTxTraces, procStats, err := bc.processor.Process(block, stateDB, bc.vmConfig) 1925 if err != nil { 1926 bc.reportBlock(block, receipts, err) 1927 atomic.StoreUint32(&followupInterrupt, 1) 1928 return i, events, coalescedLogs, err 1929 } 1930 1931 // Validate the state using the default validator 1932 err = bc.validator.ValidateState(block, parent, stateDB, receipts, usedGas) 1933 if err != nil { 1934 bc.reportBlock(block, receipts, err) 1935 atomic.StoreUint32(&followupInterrupt, 1) 1936 return i, events, coalescedLogs, err 1937 } 1938 afterValidate := time.Now() 1939 1940 // Write the block to the chain and get the writeResult. 1941 writeResult, err := bc.writeBlockWithState(block, receipts, stateDB) 1942 if err != nil { 1943 atomic.StoreUint32(&followupInterrupt, 1) 1944 if err == ErrKnownBlock { 1945 logger.Debug("Tried to insert already known block", "num", block.NumberU64(), "hash", block.Hash().String()) 1946 continue 1947 } 1948 return i, events, coalescedLogs, err 1949 } 1950 atomic.StoreUint32(&followupInterrupt, 1) 1951 1952 // Update to-address based spam throttler when spamThrottler is enabled and a single block is fetched. 1953 spamThrottler := GetSpamThrottler() 1954 if spamThrottler != nil && len(chain) == 1 { 1955 spamThrottler.updateThrottlerState(block.Transactions(), receipts) 1956 } 1957 1958 // Update the metrics subsystem with all the measurements 1959 accountReadTimer.Update(stateDB.AccountReads) 1960 accountHashTimer.Update(stateDB.AccountHashes) 1961 accountUpdateTimer.Update(stateDB.AccountUpdates) 1962 accountCommitTimer.Update(stateDB.AccountCommits) 1963 1964 storageReadTimer.Update(stateDB.StorageReads) 1965 storageHashTimer.Update(stateDB.StorageHashes) 1966 storageUpdateTimer.Update(stateDB.StorageUpdates) 1967 storageCommitTimer.Update(stateDB.StorageCommits) 1968 1969 snapshotAccountReadTimer.Update(stateDB.SnapshotAccountReads) 1970 snapshotStorageReadTimer.Update(stateDB.SnapshotStorageReads) 1971 snapshotCommitTimer.Update(stateDB.SnapshotCommits) 1972 1973 trieAccess := stateDB.AccountReads + stateDB.AccountHashes + stateDB.AccountUpdates + stateDB.AccountCommits 1974 trieAccess += stateDB.StorageReads + stateDB.StorageHashes + stateDB.StorageUpdates + stateDB.StorageCommits 1975 1976 blockAgeTimer.Update(time.Since(time.Unix(int64(block.Time().Uint64()), 0))) 1977 1978 switch writeResult.Status { 1979 case CanonStatTy: 1980 processTxsTime := common.PrettyDuration(procStats.AfterApplyTxs.Sub(procStats.BeforeApplyTxs)) 1981 processFinalizeTime := common.PrettyDuration(procStats.AfterFinalize.Sub(procStats.AfterApplyTxs)) 1982 validateTime := common.PrettyDuration(afterValidate.Sub(procStats.AfterFinalize)) 1983 totalTime := common.PrettyDuration(time.Since(bstart)) 1984 logger.Info("Inserted a new block", "number", block.Number(), "hash", block.Hash(), 1985 "txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", totalTime, 1986 "processTxs", processTxsTime, "finalize", processFinalizeTime, "validateState", validateTime, 1987 "totalWrite", writeResult.TotalWriteTime, "trieWrite", writeResult.TrieWriteTime) 1988 1989 if block.Header().BaseFee != nil { 1990 blockBaseFee.Update(block.Header().BaseFee.Int64() / int64(params.Ston)) 1991 } 1992 blockProcessTimer.Update(time.Duration(processTxsTime)) 1993 blockExecutionTimer.Update(time.Duration(processTxsTime) - trieAccess) 1994 blockFinalizeTimer.Update(time.Duration(processFinalizeTime)) 1995 blockValidateTimer.Update(time.Duration(validateTime)) 1996 blockInsertTimer.Update(time.Duration(totalTime)) 1997 1998 coalescedLogs = append(coalescedLogs, logs...) 1999 events = append(events, ChainEvent{ 2000 Block: block, 2001 Hash: block.Hash(), 2002 Logs: logs, 2003 Receipts: receipts, 2004 InternalTxTraces: internalTxTraces, 2005 }) 2006 lastCanon = block 2007 2008 case SideStatTy: 2009 logger.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "diff", block.BlockScore(), "elapsed", 2010 common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "gas", block.GasUsed()) 2011 2012 events = append(events, ChainSideEvent{block}) 2013 } 2014 stats.processed++ 2015 stats.usedGas += usedGas 2016 2017 cache, _, _ := bc.stateCache.TrieDB().Size() 2018 stats.report(chain, i, cache) 2019 2020 // update governance CurrentSet if it is at an epoch block 2021 if bc.engine.CreateSnapshot(bc, block.NumberU64(), block.Hash(), nil) != nil { 2022 return i, events, coalescedLogs, err 2023 } 2024 } 2025 // Append a single chain head event if we've progressed the chain 2026 if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { 2027 events = append(events, ChainHeadEvent{lastCanon}) 2028 } 2029 return 0, events, coalescedLogs, nil 2030 } 2031 2032 // BlockSubscriptionLoop subscribes blocks from a redis server and processes them. 2033 // This method is only for KES nodes. 2034 func (bc *BlockChain) BlockSubscriptionLoop(pool *TxPool) { 2035 var ch <-chan *redis.Message 2036 logger.Info("subscribe blocks from redis cache") 2037 2038 pubSub, ok := bc.stateCache.TrieDB().TrieNodeCache().(statedb.BlockPubSub) 2039 if !ok || pubSub == nil { 2040 logger.Crit("invalid block pub/sub configure", "trieNodeCacheConfig", 2041 bc.stateCache.TrieDB().GetTrieNodeCacheConfig()) 2042 } 2043 2044 ch = pubSub.SubscribeBlockCh() 2045 if ch == nil { 2046 logger.Crit("failed to create redis subscription channel") 2047 } 2048 2049 for msg := range ch { 2050 logger.Debug("msg from redis subscription channel", "msg", msg.Payload) 2051 2052 blockRlp, err := hexutil.Decode(msg.Payload) 2053 if err != nil { 2054 logger.Error("failed to decode redis subscription msg", "msg", msg.Payload) 2055 continue 2056 } 2057 2058 block := &types.Block{} 2059 if err := rlp.DecodeBytes(blockRlp, block); err != nil { 2060 logger.Error("failed to rlp decode block", "msg", msg.Payload, "block", string(blockRlp)) 2061 continue 2062 } 2063 2064 oldHead := bc.CurrentHeader() 2065 bc.replaceCurrentBlock(block) 2066 pool.lockedReset(oldHead, bc.CurrentHeader()) 2067 2068 // just in case the block number jumps up more than one, iterates all missed blocks 2069 for blockNum := oldHead.Number.Uint64() + 1; blockNum < block.Number().Uint64(); blockNum++ { 2070 retrievedBlock := bc.GetBlockByNumber(blockNum) 2071 bc.sendKESSubscriptionData(retrievedBlock) 2072 } 2073 bc.sendKESSubscriptionData(block) 2074 } 2075 2076 logger.Info("closed the block subscription loop") 2077 } 2078 2079 // sendKESSubscriptionData sends data to chainFeed and logsFeed. 2080 // ChainEvent containing only Block and Hash is sent to chainFeed. 2081 // []*types.Log containing entire logs of a block is set to logsFeed. 2082 // The logs are expected to be delivered from remote cache. 2083 // If it failed to read log data from remote cache, it will read the data from database. 2084 // This method is only for KES nodes. 2085 func (bc *BlockChain) sendKESSubscriptionData(block *types.Block) { 2086 bc.chainFeed.Send(ChainEvent{ 2087 Block: block, 2088 Hash: block.Hash(), 2089 // TODO-Klaytn-KES: fill the following data if needed 2090 Receipts: types.Receipts{}, 2091 Logs: []*types.Log{}, 2092 InternalTxTraces: []*vm.InternalTxTrace{}, 2093 }) 2094 2095 // TODO-Klaytn-KES: refine this not to use trieNodeCache 2096 logKey := append(kesCachePrefixBlockLogs, block.Number().Bytes()...) 2097 encodedLogs := bc.stateCache.TrieDB().TrieNodeCache().Get(logKey) 2098 if encodedLogs == nil { 2099 logger.Warn("cannot get a block log from the remote cache", "blockNum", block.NumberU64()) 2100 2101 // read log data from database and send it 2102 logsList := bc.GetLogsByHash(block.Header().Hash()) 2103 var logs []*types.Log 2104 for _, list := range logsList { 2105 logs = append(logs, list...) 2106 } 2107 bc.logsFeed.Send(logs) 2108 return 2109 } 2110 2111 entireLogs := []*types.LogForStorage{} 2112 if err := rlp.DecodeBytes(encodedLogs, &entireLogs); err != nil { 2113 logger.Warn("failed to decode a block log", "blockNum", block.NumberU64(), "err", err) 2114 2115 // read log data from database and send it 2116 logsList := bc.GetLogsByHash(block.Header().Hash()) 2117 var logs []*types.Log 2118 for _, list := range logsList { 2119 logs = append(logs, list...) 2120 } 2121 bc.logsFeed.Send(logs) 2122 return 2123 } 2124 2125 // convert LogForStorage to Log 2126 logs := make([]*types.Log, len(entireLogs)) 2127 for i, log := range entireLogs { 2128 logs[i] = (*types.Log)(log) 2129 } 2130 bc.logsFeed.Send(logs) 2131 } 2132 2133 // CloseBlockSubscriptionLoop closes BlockSubscriptionLoop. 2134 func (bc *BlockChain) CloseBlockSubscriptionLoop() { 2135 pubSub, ok := bc.stateCache.TrieDB().TrieNodeCache().(statedb.BlockPubSub) 2136 if ok { 2137 if err := pubSub.UnsubscribeBlock(); err != nil { 2138 logger.Error("failed to unsubscribe blocks", "err", err, "trieNodeCacheConfig", 2139 bc.stateCache.TrieDB().GetTrieNodeCacheConfig()) 2140 } 2141 } 2142 } 2143 2144 // replaceCurrentBlock replaces bc.currentBlock to the given block. 2145 func (bc *BlockChain) replaceCurrentBlock(latestBlock *types.Block) { 2146 bc.mu.Lock() 2147 defer bc.mu.Unlock() 2148 2149 if latestBlock == nil { 2150 logger.Error("no latest block") 2151 return 2152 } 2153 2154 // Don't update current block if the latest block is not newer than current block. 2155 currentBlock := bc.CurrentBlock() 2156 if currentBlock.NumberU64() >= latestBlock.NumberU64() { 2157 logger.Debug("ignore an old block", "currentBlockNumber", currentBlock.NumberU64(), "oldBlockNumber", 2158 latestBlock.NumberU64()) 2159 return 2160 } 2161 2162 // Insert a new block and update metrics 2163 bc.insert(latestBlock) 2164 bc.hc.SetCurrentHeader(latestBlock.Header()) 2165 2166 headBlockNumberGauge.Update(latestBlock.Number().Int64()) 2167 blockTxCountsGauge.Update(int64(latestBlock.Transactions().Len())) 2168 blockTxCountsCounter.Inc(int64(latestBlock.Transactions().Len())) 2169 bc.stateCache.TrieDB().UpdateMetricNodes() 2170 2171 logger.Info("Replaced the current block", 2172 "blkNum", latestBlock.NumberU64(), "blkHash", latestBlock.Hash().String()) 2173 } 2174 2175 // insertStats tracks and reports on block insertion. 2176 type insertStats struct { 2177 queued, processed, ignored int 2178 usedGas uint64 2179 lastIndex int 2180 startTime mclock.AbsTime 2181 } 2182 2183 // report prints statistics if some number of blocks have been processed 2184 // or more than a few seconds have passed since the last message. 2185 func (st *insertStats) report(chain []*types.Block, index int, cache common.StorageSize) { 2186 // report will leave a log only if inserting two or more blocks at once 2187 if len(chain) <= 1 { 2188 return 2189 } 2190 // Fetch the timings for the batch 2191 var ( 2192 now = mclock.Now() 2193 elapsed = time.Duration(now) - time.Duration(st.startTime) 2194 ) 2195 // If we're at the last block of the batch or report period reached, log 2196 if index == len(chain)-1 || elapsed >= log.StatsReportLimit { 2197 var ( 2198 end = chain[index] 2199 txs = countTransactions(chain[st.lastIndex : index+1]) 2200 ) 2201 context := []interface{}{ 2202 "number", end.Number(), "hash", end.Hash(), "blocks", st.processed, "txs", txs, "elapsed", common.PrettyDuration(elapsed), 2203 "trieDBSize", cache, "mgas", float64(st.usedGas) / 1000000, "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), 2204 } 2205 2206 timestamp := time.Unix(int64(end.Time().Uint64()), 0) 2207 context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) 2208 2209 if st.queued > 0 { 2210 context = append(context, []interface{}{"queued", st.queued}...) 2211 } 2212 if st.ignored > 0 { 2213 context = append(context, []interface{}{"ignored", st.ignored}...) 2214 } 2215 logger.Info("Imported new chain segment", context...) 2216 2217 *st = insertStats{startTime: now, lastIndex: index + 1} 2218 } 2219 } 2220 2221 func countTransactions(chain []*types.Block) (c int) { 2222 for _, b := range chain { 2223 c += len(b.Transactions()) 2224 } 2225 return c 2226 } 2227 2228 // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them 2229 // to be part of the new canonical chain and accumulates potential missing transactions and post an 2230 // event about them 2231 func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { 2232 var ( 2233 newChain types.Blocks 2234 oldChain types.Blocks 2235 commonBlock *types.Block 2236 deletedTxs types.Transactions 2237 deletedLogs []*types.Log 2238 // collectLogs collects the logs that were generated during the 2239 // processing of the block that corresponds with the given hash. 2240 // These logs are later announced as deleted. 2241 collectLogs = func(hash common.Hash) { 2242 // Coalesce logs and set 'Removed'. 2243 number := bc.GetBlockNumber(hash) 2244 if number == nil { 2245 return 2246 } 2247 receipts := bc.db.ReadReceipts(hash, *number) 2248 for _, receipt := range receipts { 2249 for _, log := range receipt.Logs { 2250 del := *log 2251 del.Removed = true 2252 deletedLogs = append(deletedLogs, &del) 2253 } 2254 } 2255 } 2256 ) 2257 2258 // first reduce whoever is higher bound 2259 if oldBlock.NumberU64() > newBlock.NumberU64() { 2260 // reduce old chain 2261 for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { 2262 oldChain = append(oldChain, oldBlock) 2263 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 2264 2265 collectLogs(oldBlock.Hash()) 2266 } 2267 } else { 2268 // reduce new chain and append new chain blocks for inserting later on 2269 for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { 2270 newChain = append(newChain, newBlock) 2271 } 2272 } 2273 if oldBlock == nil { 2274 return fmt.Errorf("Invalid old chain") 2275 } 2276 if newBlock == nil { 2277 return fmt.Errorf("Invalid new chain") 2278 } 2279 2280 for { 2281 if oldBlock.Hash() == newBlock.Hash() { 2282 commonBlock = oldBlock 2283 break 2284 } 2285 2286 oldChain = append(oldChain, oldBlock) 2287 newChain = append(newChain, newBlock) 2288 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 2289 collectLogs(oldBlock.Hash()) 2290 2291 oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) 2292 if oldBlock == nil { 2293 return fmt.Errorf("Invalid old chain") 2294 } 2295 if newBlock == nil { 2296 return fmt.Errorf("Invalid new chain") 2297 } 2298 } 2299 // Ensure the user sees large reorgs 2300 if len(oldChain) > 0 && len(newChain) > 0 { 2301 logFn := logger.Debug 2302 if len(oldChain) > 63 { 2303 logFn = logger.Warn 2304 } 2305 logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(), 2306 "drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash()) 2307 } else { 2308 logger.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) 2309 } 2310 // Insert the new chain, taking care of the proper incremental order 2311 var addedTxs types.Transactions 2312 for i := len(newChain) - 1; i >= 0; i-- { 2313 // insert the block in the canonical way, re-writing history 2314 bc.insert(newChain[i]) 2315 // write lookup entries for hash based transaction/receipt searches 2316 bc.db.WriteTxLookupEntries(newChain[i]) 2317 addedTxs = append(addedTxs, newChain[i].Transactions()...) 2318 } 2319 // calculate the difference between deleted and added transactions 2320 diff := types.TxDifference(deletedTxs, addedTxs) 2321 // When transactions get deleted from the database that means the 2322 // receipts that were created in the fork must also be deleted 2323 for _, tx := range diff { 2324 bc.db.DeleteTxLookupEntry(tx.Hash()) 2325 } 2326 if len(deletedLogs) > 0 { 2327 go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) 2328 } 2329 if len(oldChain) > 0 { 2330 go func() { 2331 for _, block := range oldChain { 2332 bc.chainSideFeed.Send(ChainSideEvent{Block: block}) 2333 } 2334 }() 2335 } 2336 2337 return nil 2338 } 2339 2340 // PostChainEvents iterates over the events generated by a chain insertion and 2341 // posts them into the event feed. 2342 // TODO: Should not expose PostChainEvents. The chain events should be posted in WriteBlock. 2343 func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) { 2344 // post event logs for further processing 2345 if logs != nil { 2346 bc.logsFeed.Send(logs) 2347 } 2348 for _, event := range events { 2349 switch ev := event.(type) { 2350 case ChainEvent: 2351 bc.chainFeed.Send(ev) 2352 2353 case ChainHeadEvent: 2354 bc.chainHeadFeed.Send(ev) 2355 2356 case ChainSideEvent: 2357 bc.chainSideFeed.Send(ev) 2358 } 2359 } 2360 } 2361 2362 func (bc *BlockChain) update() { 2363 futureTimer := time.NewTicker(5 * time.Second) 2364 defer futureTimer.Stop() 2365 for { 2366 select { 2367 case <-futureTimer.C: 2368 bc.procFutureBlocks() 2369 case <-bc.quit: 2370 return 2371 } 2372 } 2373 } 2374 2375 // BadBlockArgs represents the entries in the list returned when bad blocks are queried. 2376 type BadBlockArgs struct { 2377 Hash common.Hash `json:"hash"` 2378 Block *types.Block `json:"block"` 2379 } 2380 2381 // BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network 2382 func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) { 2383 blocks, err := bc.db.ReadAllBadBlocks() 2384 if err != nil { 2385 return nil, err 2386 } 2387 badBlockArgs := make([]BadBlockArgs, len(blocks)) 2388 for i, block := range blocks { 2389 hash := block.Hash() 2390 badBlockArgs[i] = BadBlockArgs{Hash: hash, Block: block} 2391 } 2392 return badBlockArgs, err 2393 } 2394 2395 // istanbul BFT 2396 func (bc *BlockChain) HasBadBlock(hash common.Hash) bool { 2397 badBlock := bc.db.ReadBadBlock(hash) 2398 if badBlock != nil { 2399 return true 2400 } 2401 return false 2402 } 2403 2404 // reportBlock logs a bad block error. 2405 func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { 2406 badBlockCounter.Inc(1) 2407 bc.db.WriteBadBlock(block) 2408 2409 var receiptString string 2410 for i, receipt := range receipts { 2411 receiptString += fmt.Sprintf("\t %d: tx: %v status: %v gas: %v contract: %v bloom: %x logs: %v\n", 2412 i, receipt.TxHash.Hex(), receipt.Status, receipt.GasUsed, receipt.ContractAddress.Hex(), 2413 receipt.Bloom, receipt.Logs) 2414 } 2415 logger.Error(fmt.Sprintf(`########## BAD BLOCK ######### Chain config: %v Number: %v Hash: 0x%x Receipt: %v Error: %v`, bc.chainConfig, block.Number(), block.Hash(), receiptString, err)) 2416 } 2417 2418 // InsertHeaderChain attempts to insert the given header chain in to the local 2419 // chain, possibly creating a reorg. If an error is returned, it will return the 2420 // index number of the failing header as well an error describing what went wrong. 2421 // 2422 // The verify parameter can be used to fine tune whether nonce verification 2423 // should be done or not. The reason behind the optional check is because some 2424 // of the header retrieval mechanisms already need to verify nonces, as well as 2425 // because nonces can be verified sparsely, not needing to check each. 2426 func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { 2427 start := time.Now() 2428 if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { 2429 return i, err 2430 } 2431 2432 // Make sure only one thread manipulates the chain at once 2433 bc.mu.Lock() 2434 defer bc.mu.Unlock() 2435 2436 bc.wg.Add(1) 2437 defer bc.wg.Done() 2438 2439 whFunc := func(header *types.Header) error { 2440 _, err := bc.hc.WriteHeader(header) 2441 return err 2442 } 2443 2444 return bc.hc.InsertHeaderChain(chain, whFunc, start) 2445 } 2446 2447 // CurrentHeader retrieves the current head header of the canonical chain. The 2448 // header is retrieved from the HeaderChain's internal cache. 2449 func (bc *BlockChain) CurrentHeader() *types.Header { 2450 return bc.hc.CurrentHeader() 2451 } 2452 2453 // GetTd retrieves a block's total blockscore in the canonical chain from the 2454 // database by hash and number, caching it if found. 2455 func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { 2456 return bc.hc.GetTd(hash, number) 2457 } 2458 2459 // GetTdByHash retrieves a block's total blockscore in the canonical chain from the 2460 // database by hash, caching it if found. 2461 func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { 2462 return bc.hc.GetTdByHash(hash) 2463 } 2464 2465 // GetHeader retrieves a block header from the database by hash and number, 2466 // caching it if found. 2467 func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { 2468 return bc.hc.GetHeader(hash, number) 2469 } 2470 2471 // GetHeaderByHash retrieves a block header from the database by hash, caching it if 2472 // found. 2473 func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { 2474 return bc.hc.GetHeaderByHash(hash) 2475 } 2476 2477 // HasHeader checks if a block header is present in the database or not, caching 2478 // it if present. 2479 func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { 2480 return bc.hc.HasHeader(hash, number) 2481 } 2482 2483 // GetBlockHashesFromHash retrieves a number of block hashes starting at a given 2484 // hash, fetching towards the genesis block. 2485 func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 2486 return bc.hc.GetBlockHashesFromHash(hash, max) 2487 } 2488 2489 // GetHeaderByNumber retrieves a block header from the database by number, 2490 // caching it (associated with its hash) if found. 2491 func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { 2492 return bc.hc.GetHeaderByNumber(number) 2493 } 2494 2495 // Config retrieves the blockchain's chain configuration. 2496 func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } 2497 2498 // Engine retrieves the blockchain's consensus engine. 2499 func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } 2500 2501 // Snapshots returns the blockchain snapshot tree. 2502 func (bc *BlockChain) Snapshots() *snapshot.Tree { 2503 return bc.snaps 2504 } 2505 2506 // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. 2507 func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { 2508 return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch)) 2509 } 2510 2511 // SubscribeChainEvent registers a subscription of ChainEvent. 2512 func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription { 2513 return bc.scope.Track(bc.chainFeed.Subscribe(ch)) 2514 } 2515 2516 // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. 2517 func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 2518 return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch)) 2519 } 2520 2521 // SubscribeChainSideEvent registers a subscription of ChainSideEvent. 2522 func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription { 2523 return bc.scope.Track(bc.chainSideFeed.Subscribe(ch)) 2524 } 2525 2526 // SubscribeLogsEvent registers a subscription of []*types.Log. 2527 func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { 2528 return bc.scope.Track(bc.logsFeed.Subscribe(ch)) 2529 } 2530 2531 // isArchiveMode returns whether current blockchain is in archiving mode or not. 2532 // cacheConfig.ArchiveMode means trie caching is disabled. 2533 func (bc *BlockChain) isArchiveMode() bool { 2534 return bc.cacheConfig.ArchiveMode 2535 } 2536 2537 // IsParallelDBWrite returns if parallel write is enabled or not. 2538 // If enabled, data written in WriteBlockWithState is being written in parallel manner. 2539 func (bc *BlockChain) IsParallelDBWrite() bool { 2540 return bc.parallelDBWrite 2541 } 2542 2543 // IsSenderTxHashIndexingEnabled returns if storing senderTxHash to txHash mapping information 2544 // is enabled or not. 2545 func (bc *BlockChain) IsSenderTxHashIndexingEnabled() bool { 2546 return bc.cacheConfig.SenderTxHashIndexing 2547 } 2548 2549 func (bc *BlockChain) SaveTrieNodeCacheToDisk() error { 2550 if err := bc.stateCache.TrieDB().CanSaveTrieNodeCacheToFile(); err != nil { 2551 return err 2552 } 2553 go bc.stateCache.TrieDB().SaveTrieNodeCacheToFile(bc.cacheConfig.TrieNodeCacheConfig.FastCacheFileDir, runtime.NumCPU()/2) 2554 return nil 2555 } 2556 2557 // ApplyTransaction attempts to apply a transaction to the given state database 2558 // and uses the input parameters for its environment. It returns the receipt 2559 // for the transaction, gas used and an error if the transaction failed, 2560 // indicating the block was invalid. 2561 func (bc *BlockChain) ApplyTransaction(chainConfig *params.ChainConfig, author *common.Address, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, vmConfig *vm.Config) (*types.Receipt, *vm.InternalTxTrace, error) { 2562 // TODO-Klaytn We reject transactions with unexpected gasPrice and do not put the transaction into TxPool. 2563 // And we run transactions regardless of gasPrice if we push transactions in the TxPool. 2564 /* 2565 // istanbul BFT 2566 if tx.GasPrice() != nil && tx.GasPrice().Cmp(common.Big0) > 0 { 2567 return nil, uint64(0), ErrInvalidGasPrice 2568 } 2569 */ 2570 2571 blockNumber := header.Number.Uint64() 2572 2573 // validation for each transaction before execution 2574 if err := tx.Validate(statedb, blockNumber); err != nil { 2575 return nil, nil, err 2576 } 2577 2578 msg, err := tx.AsMessageWithAccountKeyPicker(types.MakeSigner(chainConfig, header.Number), statedb, blockNumber) 2579 if err != nil { 2580 return nil, nil, err 2581 } 2582 // Create a new context to be used in the EVM environment 2583 context := NewEVMContext(msg, header, bc, author) 2584 // Create a new environment which holds all relevant information 2585 // about the transaction and calling mechanisms. 2586 vmenv := vm.NewEVM(context, statedb, chainConfig, vmConfig) 2587 // Apply the transaction to the current state (included in the env) 2588 _, gas, kerr := ApplyMessage(vmenv, msg) 2589 err = kerr.ErrTxInvalid 2590 if err != nil { 2591 return nil, nil, err 2592 } 2593 2594 var internalTrace *vm.InternalTxTrace 2595 if vmConfig.EnableInternalTxTracing { 2596 internalTrace, err = GetInternalTxTrace(vmConfig.Tracer) 2597 if err != nil { 2598 logger.Error("failed to get tracing result from a transaction", "txHash", tx.Hash().String(), "err", err) 2599 } 2600 } 2601 // Update the state with pending changes 2602 statedb.Finalise(true, false) 2603 *usedGas += gas 2604 2605 receipt := types.NewReceipt(kerr.Status, tx.Hash(), gas) 2606 // if the transaction created a contract, store the creation address in the receipt. 2607 msg.FillContractAddress(vmenv.Context.Origin, receipt) 2608 // Set the receipt logs and create a bloom for filtering 2609 receipt.Logs = statedb.GetLogs(tx.Hash()) 2610 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 2611 2612 return receipt, internalTrace, err 2613 } 2614 2615 func GetInternalTxTrace(tracer vm.Tracer) (*vm.InternalTxTrace, error) { 2616 var ( 2617 internalTxTrace *vm.InternalTxTrace 2618 err error 2619 ) 2620 switch tracer := tracer.(type) { 2621 case *vm.InternalTxTracer: 2622 internalTxTrace, err = tracer.GetResult() 2623 if err != nil { 2624 return nil, err 2625 } 2626 default: 2627 logger.Error("To trace internal transactions, VM tracer type should be vm.InternalTxTracer", "actualType", reflect.TypeOf(tracer).String()) 2628 return nil, ErrInvalidTracer 2629 } 2630 return internalTxTrace, nil 2631 } 2632 2633 // CheckBlockChainVersion checks the version of the current database and upgrade if possible. 2634 func CheckBlockChainVersion(chainDB database.DBManager) error { 2635 bcVersion := chainDB.ReadDatabaseVersion() 2636 if bcVersion != nil && *bcVersion > BlockChainVersion { 2637 return fmt.Errorf("database version is v%d, Klaytn %s only supports v%d", *bcVersion, params.Version, BlockChainVersion) 2638 } else if bcVersion == nil || *bcVersion < BlockChainVersion { 2639 bcVersionStr := "N/A" 2640 if bcVersion != nil { 2641 bcVersionStr = strconv.Itoa(int(*bcVersion)) 2642 } 2643 logger.Warn("Upgrade database version", "from", bcVersionStr, "to", BlockChainVersion) 2644 chainDB.WriteDatabaseVersion(BlockChainVersion) 2645 } 2646 return nil 2647 }