Skip to content

Commit

Permalink
fast node verification
Browse files Browse the repository at this point in the history
Signed-off-by: kyrie-yl <yl.on.the.way@gmail.com>
  • Loading branch information
kyrie-yl committed Jan 25, 2022
1 parent 80fd4dd commit 62b3390
Show file tree
Hide file tree
Showing 18 changed files with 515 additions and 38 deletions.
4 changes: 3 additions & 1 deletion cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ var (
utils.NoUSBFlag,
utils.DirectBroadcastFlag,
utils.DisableSnapProtocolFlag,
utils.DisableDiffProtocolFlag,
utils.EnableTrustProtocolFlag,
utils.DiffSyncFlag,
utils.RangeLimitFlag,
utils.USBFlag,
Expand All @@ -97,6 +99,7 @@ var (
utils.TxPoolLifetimeFlag,
utils.TxPoolReannounceTimeFlag,
utils.SyncModeFlag,
utils.TriesVerifyModeFlag,
utils.ExitWhenSyncedFlag,
utils.GCModeFlag,
utils.SnapshotFlag,
Expand All @@ -114,7 +117,6 @@ var (
utils.WhitelistFlag,
utils.BloomFilterSizeFlag,
utils.TriesInMemoryFlag,
utils.AllowInsecureNoTriesFlag,
utils.CacheFlag,
utils.CacheDatabaseFlag,
utils.CacheTrieFlag,
Expand Down
3 changes: 3 additions & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.NoUSBFlag,
utils.DirectBroadcastFlag,
utils.DisableSnapProtocolFlag,
utils.DisableDiffProtocolFlag,
utils.EnableTrustProtocolFlag,
utils.RangeLimitFlag,
utils.SmartCardDaemonPathFlag,
utils.NetworkIdFlag,
Expand All @@ -50,6 +52,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.YoloV3Flag,
utils.RopstenFlag,
utils.SyncModeFlag,
utils.TriesVerifyModeFlag,
utils.ExitWhenSyncedFlag,
utils.GCModeFlag,
utils.TxLookupLimitFlag,
Expand Down
36 changes: 31 additions & 5 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ var (
Name: "disablesnapprotocol",
Usage: "Disable snap protocol",
}
DisableDiffProtocolFlag = cli.BoolFlag{
Name: "disablediffprotocol",
Usage: "Disable diff protocol",
}
EnableTrustProtocolFlag = cli.BoolFlag{
Name: "enabletrustprotocol",
Usage: "Enable trust protocol",
}
DiffSyncFlag = cli.BoolFlag{
Name: "diffsync",
Usage: "Enable diffy sync, Please note that enable diffsync will improve the syncing speed, " +
Expand Down Expand Up @@ -259,9 +267,11 @@ var (
Usage: "The layer of tries trees that keep in memory",
Value: 128,
}
AllowInsecureNoTriesFlag = cli.BoolTFlag{
Name: "allow-insecure-no-tries",
Usage: `Disable the tries state root verification, the state consistency is no longer 100% guaranteed, diffsync is not allowed if enabled. Do not enable it unless you know exactly what the consequence it will cause.`,
defaultVerifyMode = ethconfig.Defaults.TriesVerifyMode
TriesVerifyModeFlag = TextMarshalerFlag{
Name: "tries-verify-mode",
Usage: `tries verify mode: "local", "full", "light", "insecure"`,
Value: &defaultVerifyMode,
}
OverrideBerlinFlag = cli.Uint64Flag{
Name: "override.berlin",
Expand Down Expand Up @@ -1622,6 +1632,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if ctx.GlobalIsSet(DisableSnapProtocolFlag.Name) {
cfg.DisableSnapProtocol = ctx.GlobalBool(DisableSnapProtocolFlag.Name)
}
if ctx.GlobalIsSet(DisableDiffProtocolFlag.Name) {
cfg.DisableDiffProtocol = ctx.GlobalIsSet(DisableDiffProtocolFlag.Name)
}
if ctx.GlobalIsSet(EnableTrustProtocolFlag.Name) {
cfg.EnableTrustProtocol = ctx.GlobalIsSet(EnableTrustProtocolFlag.Name)
}
if ctx.GlobalIsSet(DiffSyncFlag.Name) {
cfg.DiffSync = ctx.GlobalBool(DiffSyncFlag.Name)
}
Expand Down Expand Up @@ -1652,8 +1668,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if ctx.GlobalIsSet(TriesInMemoryFlag.Name) {
cfg.TriesInMemory = ctx.GlobalUint64(TriesInMemoryFlag.Name)
}
if ctx.GlobalIsSet(AllowInsecureNoTriesFlag.Name) {
cfg.NoTries = ctx.GlobalBool(AllowInsecureNoTriesFlag.Name)
if ctx.GlobalIsSet(TriesVerifyModeFlag.Name) {
cfg.TriesVerifyMode = *GlobalTextMarshaler(ctx, TriesVerifyModeFlag.Name).(*core.VerifyMode)
//If a node sets verify mode to full or light, it's a fast node and need
//to verify blocks from verify nodes, then it should enable trust protocol.
if cfg.TriesVerifyMode == core.FullVerify || cfg.TriesVerifyMode == core.LightVerify {
cfg.EnableTrustProtocol = true
}
//If a node sets verify node but not local, it's a fast node whose difflayer is not integral.
//So fast node should disable diff protocol.
if cfg.TriesVerifyMode != core.LocalVerify {
cfg.DisableDiffProtocol = true
}
}
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheSnapshotFlag.Name) {
cfg.SnapshotCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheSnapshotFlag.Name) / 100
Expand Down
40 changes: 38 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ type BlockChain struct {
engine consensus.Engine
validator Validator // Block and state validator interface
processor Processor // Block transaction processor interface
verifyManager *VerifyManager
vmConfig vm.Config

shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
Expand Down Expand Up @@ -462,6 +463,16 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
return bc, nil
}

func (bc *BlockChain) StartVerify(peers VerifyPeers, allowUntrustedVerify bool) {
bc.verifyManager.peers = peers
bc.verifyManager.allowUntrustedVerify = allowUntrustedVerify
bc.verifyManager.Start()
}

func (bc *BlockChain) VerifyManger() *VerifyManager {
return bc.verifyManager
}

// GetVMConfig returns the block chain VM config.
func (bc *BlockChain) GetVMConfig() *vm.Config {
return &bc.vmConfig
Expand Down Expand Up @@ -1191,6 +1202,9 @@ func (bc *BlockChain) Stop() {
close(bc.quit)
bc.StopInsert()
bc.wg.Wait()
if bc.verifyManager != nil {
bc.verifyManager.Stop()
}

// Ensure that the entirety of the state snapshot is journalled to disk.
var snapBase common.Hash
Expand Down Expand Up @@ -2009,6 +2023,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
log.Debug("Abort during block processing")
break
}
//For fast node, if the H-11 block has not been verified, stop processing blocks.
if bc.verifyManager != nil && bc.verifyManager.CheckAncestorVerified(block.Header()) {
log.Debug("Block ancestor has not been verified", "hash", block.Hash(), "number", block.Number())
break
}
// If the header is a banned one, straight out abort
if BadHashes[block.Hash()] {
bc.reportBlock(block, nil, ErrBlacklistedHash)
Expand Down Expand Up @@ -2052,6 +2071,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
lastCanon = block
continue
}

// Retrieve the parent block and it's state to execute on top
start := time.Now()

Expand Down Expand Up @@ -2122,6 +2142,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
blockWriteTimer.Update(time.Since(substart))
blockInsertTimer.UpdateSince(start)

//Start a routine to verify this block.
if bc.verifyManager != nil {
bc.verifyManager.NewBlockVerifyTask(block.Header())
}

switch status {
case CanonStatTy:
log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(),
Expand Down Expand Up @@ -3020,8 +3045,15 @@ func EnablePersistDiff(limit uint64) BlockChainOption {
}
}

func (bc *BlockChain) GetRootByDiffHash(blockNumber uint64, blockHash common.Hash, diffHash common.Hash) (*types.VerifyResult, error) {
var res types.VerifyResult
func EnableVerifyManager() BlockChainOption {
return func(chain *BlockChain) *BlockChain {
chain.verifyManager = NewVerifyManager(chain)
return chain
}
}

func (bc *BlockChain) GetRootByDiffHash(blockNumber uint64, blockHash common.Hash, diffHash common.Hash) (*VerifyResult, error) {
var res VerifyResult
res.BlockNumber = blockNumber
res.BlockHash = blockHash

Expand Down Expand Up @@ -3076,6 +3108,10 @@ func (bc *BlockChain) GetRootByDiffHash(blockNumber uint64, blockHash common.Has
return &res, nil
}

func (bc *BlockChain) GenerateDiffLayer(blockHash common.Hash) (*types.DiffLayer, error) {

}

func (bc *BlockChain) GetTrustedDiffLayer(blockHash common.Hash) *types.DiffLayer {
var diff *types.DiffLayer
if cached, ok := bc.diffLayerCache.Get(blockHash); ok {
Expand Down
20 changes: 20 additions & 0 deletions core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) {
}
}

func ReadTrustBlockHash(db ethdb.Reader, hash common.Hash) bool {
data, _ := db.Get(trustBlockHashKey(hash))
if len(data) == 0 {
return false
}
return bytes.Equal(data,[]byte{0x01})
}

func WriteTrustBlockHash(db ethdb.KeyValueWriter, hashkey common.Hash) {
if err := db.Put(trustBlockHashKey(hashkey),[]byte{0x01}); err != nil {
log.Crit("Failed to store trust block hash")
}
}

func DeleteTrustBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
if err := db.Delete(trustBlockHashKey(hash)); err != nil {
log.Crit("Failed to delete trust block hash")
}
}

// ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
// both canonical and reorged forks included.
func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
Expand Down
7 changes: 7 additions & 0 deletions core/rawdb/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ var (
// difflayer database
diffLayerPrefix = []byte("d") // diffLayerPrefix + hash -> diffLayer

// trust block database
trustBlockPrefix = []byte("tb") // trustBlockPrefix + hash -> verify result

preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
configPrefix = []byte("ethereum-config-") // config prefix for the db

Expand Down Expand Up @@ -164,6 +167,10 @@ func headerTDKey(number uint64, hash common.Hash) []byte {
func headerHashKey(number uint64) []byte {
return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...)
}
// trustBlockHashKey = trustBlockPrefix + hash
func trustBlockHashKey(hash common.Hash) []byte {
return append(append(trustBlockPrefix, hash.Bytes()...))
}

// headerNumberKey = headerNumberPrefix + hash
func headerNumberKey(hash common.Hash) []byte {
Expand Down
7 changes: 0 additions & 7 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@ var (
StatusUnexpectedError = VerifyStatus{Code: 0x400, Msg: "can’t verify because of unexpected internal error"}
)

type VerifyResult struct {
Status VerifyStatus
BlockNumber uint64
BlockHash common.Hash
Root common.Hash
}

// A BlockNonce is a 64-bit hash which proves (combined with the
// mix-hash) that a sufficient amount of computation has been carried
// out on a block.
Expand Down
Loading

0 comments on commit 62b3390

Please sign in to comment.