geth的启动之区块链的生成

作者: 古则 | 来源:发表于2018-04-13 17:17 被阅读15次

    区块链的生成

    //go-ethereum/cmd/geth/main.go
    func init() {
        // Initialize the CLI app and start Geth
        app.Action = geth
        app.HideVersion = true // we have a command to print the version
        app.Copyright = "Copyright 2013-2017 The go-ethereum Authors"
        app.Commands = []cli.Command{
            // See chaincmd.go:
            initCommand,
            importCommand,
            exportCommand,
            copydbCommand,
            removedbCommand,
            dumpCommand,
            // See monitorcmd.go:
            monitorCommand,
            // See accountcmd.go:
            accountCommand,
            walletCommand,
            // See consolecmd.go:
            consoleCommand,
            attachCommand,
            javascriptCommand,
            // See misccmd.go:
            makecacheCommand,
            makedagCommand,
            versionCommand,
            bugCommand,
            licenseCommand,
            // See config.go
            dumpConfigCommand,
        }
        sort.Sort(cli.CommandsByName(app.Commands))
    
        app.Flags = append(app.Flags, nodeFlags...)
        app.Flags = append(app.Flags, rpcFlags...)
        app.Flags = append(app.Flags, consoleFlags...)
        app.Flags = append(app.Flags, debug.Flags...)
        app.Flags = append(app.Flags, whisperFlags...)
    
        app.Before = func(ctx *cli.Context) error {
            runtime.GOMAXPROCS(runtime.NumCPU())
            if err := debug.Setup(ctx); err != nil {
                return err
            }
            // Start system runtime metrics collection
            go metrics.CollectProcessMetrics(3 * time.Second)
    
            utils.SetupNetwork(ctx)
            return nil
        }
    
        app.After = func(ctx *cli.Context) error {
            debug.Exit()
            console.Stdin.Close() // Resets terminal mode.
            return nil
        }
    }
    
    

    init()调用来源待深入
    init()方法注册了多个命令,这些命令如initCommand会调用区块链的创建

    //go-ethereum/cmd/geth/chaincmd.go
    func importChain(ctx *cli.Context) error {
        if len(ctx.Args()) < 1 {
            utils.Fatalf("This command requires an argument.")
        }
        stack := makeFullNode(ctx)
        chain, chainDb := utils.MakeChain(ctx, stack)
        defer chainDb.Close()
    .......
    
    //go-ethereum/cmd/utils/flags.go
    func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) {
        var err error
        chainDb = MakeChainDatabase(ctx, stack)
    
        config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
        if err != nil {
            Fatalf("%v", err)
        }
        var engine consensus.Engine
        if config.Clique != nil {
            engine = clique.New(config.Clique, chainDb)
        } else {
            engine = ethash.NewFaker()
            if !ctx.GlobalBool(FakePoWFlag.Name) {
                engine = ethash.New(ethash.Config{
                    CacheDir:       stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir),
                    CachesInMem:    eth.DefaultConfig.Ethash.CachesInMem,
                    CachesOnDisk:   eth.DefaultConfig.Ethash.CachesOnDisk,
                    DatasetDir:     stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir),
                    DatasetsInMem:  eth.DefaultConfig.Ethash.DatasetsInMem,
                    DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
                })
            }
        }
        if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
            Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
        }
        cache := &core.CacheConfig{
            Disabled:      ctx.GlobalString(GCModeFlag.Name) == "archive",
            TrieNodeLimit: eth.DefaultConfig.TrieCache,
            TrieTimeLimit: eth.DefaultConfig.TrieTimeout,
        }
        if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
            cache.TrieNodeLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
        }
        vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
        chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg)
        if err != nil {
            Fatalf("Can't create BlockChain: %v", err)
        }
        return chain, chainDb
    }
    
    

    最后blockchain的创建来到了

    //go-ethereum/core/blockchain.go中

    func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
        if cacheConfig == nil {
            cacheConfig = &CacheConfig{
                TrieNodeLimit: 256 * 1024 * 1024,
                TrieTimeLimit: 5 * time.Minute,
            }
        }
        bodyCache, _ := lru.New(bodyCacheLimit)
        bodyRLPCache, _ := lru.New(bodyCacheLimit)
        blockCache, _ := lru.New(blockCacheLimit)
        futureBlocks, _ := lru.New(maxFutureBlocks)
        badBlocks, _ := lru.New(badBlockLimit)
    
        bc := &BlockChain{
            chainConfig:  chainConfig,
            cacheConfig:  cacheConfig,
            db:           db,
            triegc:       prque.New(),
            stateCache:   state.NewDatabase(db),
            quit:         make(chan struct{}),
            bodyCache:    bodyCache,
            bodyRLPCache: bodyRLPCache,
            blockCache:   blockCache,
            futureBlocks: futureBlocks,
            engine:       engine,
            vmConfig:     vmConfig,
            badBlocks:    badBlocks,
        }
        bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
        bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
    
        var err error
        bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt)
        if err != nil {
            return nil, err
        }
        bc.genesisBlock = bc.GetBlockByNumber(0)
        if bc.genesisBlock == nil {
            return nil, ErrNoGenesis
        }
        if err := bc.loadLastState(); err != nil {
            return nil, err
        }
        // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
        for hash := range BadHashes {
            if header := bc.GetHeaderByHash(hash); header != nil {
                // get the canonical block corresponding to the offending header's number
                headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64())
                // make sure the headerByNumber (if present) is in our current canonical chain
                if headerByNumber != nil && headerByNumber.Hash() == header.Hash() {
                    log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash)
                    bc.SetHead(header.Number.Uint64() - 1)
                    log.Error("Chain rewind was successful, resuming normal operation")
                }
            }
        }
        // Take ownership of this particular state
        go bc.update()
        return bc, nil
    }
    

    相关文章

      网友评论

        本文标题:geth的启动之区块链的生成

        本文链接:https://www.haomeiwen.com/subject/maqhkftx.html