Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An overview of Go based on geth (ethereum client)

Avatar for NFM NFM
August 31, 2018

An overview of Go based on geth (ethereum client)

사내 Golang meetup 발표 자료입니다.

Avatar for NFM

NFM

August 31, 2018
Tweet

Other Decks in Technology

Transcript

  1. • ੷ܳ рױ൤ ࣗѐ೤פ׮. • ۄ੉࠳ ࢲ࠺झ ࢲߡѐߊೞҊ ੓যਃ. •

    ੍Ҋ ੿ܻೞח Ѫਸ જই೤פ׮. • Ӓ ؋࠙ী Angular ୐Ѧ਺੉ۆ ଼ب ोणפ׮. • ӝࣿ੸ੋ ஏݶীࢲ ࠶۾୓ੋ ী ҙब੉ ݆णפ׮.
  2. GVODNBJO func main() { if err := app.Run(os.Args); err !=

    nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/geth/main.go#L249-L254
  3. 'VODUJPO ೣࣻח੉ۧѱࢶ঱ func main() { if err := app.Run(os.Args); err

    != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } 001঱য׹ѱ ௿ېझ੄ݫࢲ٘о઺ब੉ۄݶ ೣࣻо઺ब func helloWorld() { fmt.Println("Hello, Go") }
  4. GVODNBJO  䟤୓ੋ٠ೠBQQ਷য٣ࢲա৳ա   NBJOೣࣻоࢶ঱ػ౵ੌ߄۽ਤীj var ( gitCommit =

    "" app = utils.NewApp(gitCommit, "...") ... ) func main() { if err := app.Run(os.Args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } }
  5. var ( gitCommit = "" app = utils.NewApp(gitCommit, "...") ...

    ) 7BSJBCMF%FDMBSBUJPO ߸ࣻ੄ࢶ঱਷WBSఃਕ٘۽ var foo = "bar" ఋੑ਷ఃਕٍ٘ীॄبغ૑݅ ୶ۿೡࣻ੓ਵפࢤۚ೧بػ׮ var foo string = "bar" https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/geth/main.go#L49-L162
  6. var ( gitCommit = "" app = utils.NewApp(gitCommit, "...") ...

    ) 'BDUPSFE7BSJBCMF%FDMBSBUJPO ࣗҚഐ۽ޘযࢲೠߣীࢶ঱بоמ ੉ѤJNQPSUب݃ଲо૑ۄח import ( "fmt" "math" ... ) var ( golang = "" meetup = 1 ) https://tour.golang.org/basics/11
  7. GVOD/FX"QQ HJU$PNNJU VTBHFTUSJOH  DMJ"QQ  DMJ"QQఋੑ੄䟤୓ܳࢤࢿ೧ࢲ߈ജ  DMJ"QQ਷$-*গ೒ܻா੉࣌ѐߊਸب৬઱חۄ੉࠳۞ܻ 

    ఠ޷䠭ী䞵ੋ੗۽߉਷ч਷DMJ$POUFYU䟤୓ী䞵ҙܻ var ( gitCommit = "" app = utils.NewApp(gitCommit, "...") ... ) https://github.com/urfave/cli
  8. 1BDLBHFBOE&YQPSUFE/BNF VUJMTחё୓оইצಁః૑ ೣࣻ੄୐Ӗ੗۽ҕѐৈࠗоѾ੿ػ׮ var ( gitCommit = "" app =

    utils.NewApp(gitCommit, "...") ... ) import "github.com/ethereum/go-ethereum/cmd/utils" func funcPrivate() func FuncPublic()
  9. GVODJOJU  $-*ۄ੉࠳۞ܻоઁҕೞחੋఠಕ੉झীೣࣻ߂ࢸ੿١۾  HFUI੄पઁFOUSZQPJOUੋHFUIೣࣻܳBQQ"DUJPOী١۾  Ӓؘ۠JOJUೣࣻܳഐ୹ೞחҔ਷য٣ীبহ׮j func init() {

    // Initialize the CLI app and start Geth app.Action = geth app.HideVersion = true app.Copyright = "Copyright 2013-2018 …" ... https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/geth/main.go#L164-L247
  10. https://golang.org/ref/spec#Package_initialization 001׹ѱ߸ࣻ੄झ௏೐৬ ୡӝചب௿ېझױਤ۽ 1LH*OJUJBMJ[BUJPO func init() { // Initialize the

    CLI app and start Geth app.Action = geth app.HideVersion = true app.Copyright = "Copyright 2013-2018 …" ... JOJUೣࣻחಁః૑ۨ߰੄ झ௏೐ܳыח߸ࣻܳ ୡӝചद઱۽ॵ׮
  11. GVODHFUI DUY DMJ$POUFYU FSSPS  HFUI੄पઁFOUSZQPJOU  &UIFSFVN௿ۄ੉঱౟֢٘ܳप೯ೞҊઙܐܳ؀ӝೠ׮ func geth(ctx

    *cli.Context) error { if args := ctx.Args(); len(args) > 0 { return fmt.Errorf("invalid command: %q", args[0]) } node := makeFullNode(ctx) startNode(ctx, node) node.Wait() return nil } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/geth/main.go#L259-L267
  12. https://tour.golang.org/basics/10 4IPSU7BSJBCMF%FDMBSBUJPO ೐۽ӈଳ۞ٜਸਤೠࢶޛ ߸ࣻࢶ঱੄୷ডഋ 4ZOUBUJD4VHBS׮ func geth(ctx *cli.Context) error {

    if args := ctx.Args(); len(args) > 0 { return fmt.Errorf("invalid command: %q", args[0]) } node := makeFullNode(ctx) startNode(ctx, node) node.Wait() return nil } ݃ٶೠߑߨ੉
 -PNCPLਵ۽Ӓա݃j
  13. GVODNBLF'VMM/PEF DUY DMJ$POUFYU  OPEF/PEF  ࢎਊ੗оੑ䢁ೠ২䣩ਸ߄ఔਵ۽HFUI੄֢٘੄઱ਃࢲ࠺झ੄ࢸ੿䟐࠺ func makeFullNode(ctx *cli.Context)

    *node.Node { stack, cfg := makeConfigNode(ctx) utils.RegisterEthService(stack, &cfg.Eth) if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { utils.RegisterDashboardService( . . . ) } 
 . . .
 // Add the Ethereum Stats daemon if requested. if cfg.Ethstats.URL != "" { utils.RegisterEthStatsService(. . .) } return stack } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/geth/config.go#L153-L179
  14. func makeFullNode(ctx *cli.Context) *node.Node { stack, cfg := makeConfigNode(ctx) utils.RegisterEthService(stack,

    &cfg.Eth) . . . .VMUJQMF3FUVSO ࠂࣻ੄ܻఢчب૑ਗೠ׮ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig)
  15. GVODNBLF'VMM/PEF DUY DMJ$POUFYU  OPEF/PEF  ࢸ੿ਸ݃஖ݶ/PEFఋੑ੄䟤୓ܳ߈ജೠ׮ func makeFullNode(ctx *cli.Context)

    *node.Node { stack, cfg := makeConfigNode(ctx) utils.RegisterEthService(stack, &cfg.Eth) if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { utils.RegisterDashboardService( . . . ) } 
 . . .
 // Add the Ethereum Stats daemon if requested. if cfg.Ethstats.URL != "" { utils.RegisterEthStatsService(. . .) } return stack }
  16. https://tour.golang.org/moretypes/2 4USVDUVSF // Node is a container on which services

    can be registered. type Node struct { eventmux *event.TypeMux // Event multiplexer used between the services of a config *Config accman *accounts.Manager ephemeralKeystore string // if non-empty, the key directory that wi instanceDirLock flock.Releaser // prevents concurrent use of instance dir serverConfig p2p.Config server *p2p.Server // Currently running P2P networking layer serviceFuncs []ServiceConstructor // Service constructors (in dependenc services map[reflect.Type]Service // Currently running services rpcAPIs []rpc.API // List of APIs currently provided by the node inprocHandler *rpc.Server // In-process RPC request handler to process the ipcEndpoint string // IPC endpoint to listen at (empty = IPC disabled ipcListener net.Listener // IPC RPC listener socket to serve API requests ipcHandler *rpc.Server // IPC RPC request handler to process the API requ httpEndpoint string // HTTP endpoint (interface + port) to listen at httpWhitelist []string // HTTP RPC modules to allow through this endpoi httpListener net.Listener // HTTP RPC listener socket to server API reques httpHandler *rpc.Server // HTTP RPC request handler to process the API r wsEndpoint string // Websocket endpoint (interface + port) to listen wsListener net.Listener // Websocket RPC listener socket to server API requ wsHandler *rpc.Server // Websocket RPC request handler to process the API stop chan struct{} // Channel to wait for termination notifications lock sync.RWMutex log log.Logger } $୊ۢ ҳઑ୓۽ఋੑࢶ঱ ё୓ۄݶࢲjݫࢲ٘חয٣ী ӒѤਫ਼दٍীj
  17. GVODNBLF'VMM/PEF DUY DMJ$POUFYU  OPEF/PEF  ਫ਼दറഐ୹ؼ&UIFSFVNࢲ࠺झ੄ࢤࢿ੗ܳৈӝࢲ١۾ೠ׮ func makeFullNode(ctx *cli.Context)

    *node.Node { stack, cfg := makeConfigNode(ctx) utils.RegisterEthService(stack, &cfg.Eth) if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { utils.RegisterDashboardService( . . . ) } 
 . . .
 // Add the Ethereum Stats daemon if requested. if cfg.Ethstats.URL != "" { utils.RegisterEthStatsService(. . .) } return stack }
  18. GVOD3FHJTUFS&UI4FSWJDF TUBDL OPEF/PEF DGH FUI$POGJH \  TUBDL3FHJTUFS۽١۾݅ೡࡺই૒प೯ೠѪ੉ইפ׮  FUI/FXী䞵&UIFSFVN䟤୓ࢤࢿҗೣԋৈ۞ୡӝച੘সਸೠ׮

    // RegisterEthService adds an Ethereum client to the stack. func RegisterEthService(stack *node.Node, cfg *eth.Config) { var err error if cfg.SyncMode == downloader.LightSync { err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return les.New(ctx, cfg) }) } else { err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { fullNode, err := eth.New(ctx, cfg) if fullNode != nil && cfg.LightServ > 0 { ls, _ := les.NewLesServer(fullNode, cfg) fullNode.AddLesServer(ls) } return fullNode, err }) } if err != nil { Fatalf("Failed to register the Ethereum service: %v", err) } } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/utils/flags.go#L1212-L1231
  19. GVODHFUI DUY DMJ$POUFYU FSSPS  HFUI੄पઁFOUSZQPJOU  &UIFSFVN௿ۄ੉঱౟֢٘ܳप೯ೞҊઙܐܳ؀ӝೠ׮ func geth(ctx

    *cli.Context) error { if args := ctx.Args(); len(args) > 0 { return fmt.Errorf("invalid command: %q", args[0]) } node := makeFullNode(ctx) startNode(ctx, node) node.Wait() return nil }
  20. GVODTUBSU/PEF DUY DMJ$POUFYU TUBDL OPEF/PEF  ࢎਊ੗о੹׳ೠ২䣩чਸ׸਷$POUFYU৬NBLF'VMM/PEFী䞵ୡ ӝചػ/PEFܳо૑Ҋ/PEFܳप೯ func startNode(ctx

    *cli.Context, stack *node.Node) { debug.Memsize.Add("node", stack) // Start up the node itself utils.StartNode(stack) // ؘݽীࢲ ઱૑ ঋ਷ ২࣌ਸ ଵઑ೧ࢲ ҅੿ਸ ৌҊ // ҅੿(૑ц)੄ ߸҃ࢎ೦ਸ subscribe ೞח झۨ٘(Ҋܖ౯) प೯ // Minerܳ ߄۽ द੘ೞח ١੄ ۽૒ . . . https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/geth/main.go#L272-L354
  21. GVOD4UBSU/PEF TUBDL OPEF/PEF func StartNode(stack *node.Node) { if err :=

    stack.Start(); err != nil { Fatalf("Error starting protocol stack: %v", err) } go func() { sigc := make(chan os.Signal, 1) signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) defer signal.Stop(sigc) <-sigc log.Info("Got interrupt, shutting down...") go stack.Stop() for i := 10; i > 0; i-- { <-sigc if i > 1 { log.Warn("ী۞۽Ӓח ૣѱ...", "times", i-1) } } debug.Exit() debug.LoudPanic("boom") }() }  /PEF䟤୓੄प೯߂ࢎਊ੗੄ઙܐदӒօ؀ӝ https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/utils/cmd.go#L66-L86
  22. func StartNode(stack *node.Node) { if err := stack.Start(); err !=

    nil { Fatalf("Error starting protocol stack: %v", err) } . . . &SSPS)BOEMJOH ݃஖$୊ۢ ী۞بܻఢчਵ۽߈ജ &YDFQUJPOਸ؍૑Ѣա੟Ѣաj ߈ജػী۞ё୓ܳഛੋ೧ࢲӒ੗ܻࢲ୊ܻ
  23. 04੄OBUJWFझۨ٘ী؀਽ೞח झۨ٘ܳࢤࢿ೧ࢲزदࢿ୊ܻܳೞ૑ HPSPVUJOF ೣࣻখীHPఃਕ٘݅ࠢ੉ݶزदࢿ୊ܻо (P3VOUJNF੉ҙܻ೧઱૑ func StartNode(stack *node.Node) { if

    err := stack.Start(); err != nil { Fatalf("Error starting protocol stack: %v", err) } go func() { ... }() } go func() { /* ੊ݺೣࣻ */ }() go foo() // ೣࣻ
  24. GVOD4UBSU/PEF TUBDL OPEF/PEF func StartNode(stack *node.Node) { if err :=

    stack.Start(); err != nil { Fatalf("Error starting protocol stack: %v", err) } go func() { sigc := make(chan os.Signal, 1) signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) defer signal.Stop(sigc) <-sigc log.Info("Got interrupt, shutting down...") go stack.Stop() for i := 10; i > 0; i-- { <-sigc if i > 1 { log.Warn("ী۞۽Ӓח ૣѱ...", "times", i-1) } } debug.Exit() debug.LoudPanic("boom") }() }
  25. GVOD O /PEF 4UBSU FSSPS NBLF'VMM/PEFࢲ١۾ೠࢲ࠺झࢤࢿ߂प೯ &UIFSFVN䟤୓੄ࢤࢿҗप೯ // Start create

    a live P2P node and starts running it. func (n *Node) Start() error { n.lock.Lock() defer n.lock.Unlock() // Short circuit if the node's already running if n.server != nil { return ErrNodeRunning } if err := n.openDataDir(); err != nil { return err } // P2P ೐۽ష௒ प೯ೞݶࢲ ׮ܲ ֢٘ ଺ӝ
 // খীࢲ ١۾ೠ ࢲ࠺झ प೯ೞӝ ١ https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/node/node.go#L138-L228
  26. 3FDFJWFSBOE.FUIPE ೣࣻ੉ܴখী߹ب۽߉חੋ੗ 3FDFJWFо੓חೣࣻחݫࢲ٘ 001ܳ૑ਗೞחߑߨ // Start create a live P2P

    node and starts running it. func (n *Node) Start() error { n.lock.Lock() defer n.lock.Unlock() stack.Start() ௿ېझীؘ੉ఠ৬೯ਤоэ੉੓חؘj
 ఋੑীؘ੉ఠܳࢶ঱ೞҊ ߹ب۽ೣࣻо੓ਵפয࢝ೞ׮j
  27. // Start create a live P2P node and starts running

    it. func (n *Node) Start() error { n.lock.Lock() defer n.lock.Unlock() %FGFS EFGFSܳೣࣻখীࠢ੉ݶ प೯ਸೣࣻ੄ઙܐद੼ө૑૑ো ۅ੉աܻࣗझ୊ܻदपࣻߑ૑ ܻࣗझ୊ܻۄݶীࢲࢤӟ 5SZ8JUI3FTPVSDFܳॳѢա ইש'JOBMMZীࢲഛप൤୊ܻೞѢա
  28. GVOD3FHJTUFS&UI4FSWJDF TUBDL OPEF/PEF DGH FUI$POGJH \  TUBDL3FHJTUFS۽١۾݅ೡࡺই૒प೯ೠѪ੉ইפ׮  FUI/FXী䞵&UIFSFVN䟤୓ࢤࢿҗೣԋৈ۞ୡӝച੘সਸೠ׮

    // RegisterEthService adds an Ethereum client to the stack. func RegisterEthService(stack *node.Node, cfg *eth.Config) { var err error if cfg.SyncMode == downloader.LightSync { err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return les.New(ctx, cfg) }) } else { err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { fullNode, err := eth.New(ctx, cfg) if fullNode != nil && cfg.LightServ > 0 { ls, _ := les.NewLesServer(fullNode, cfg) fullNode.AddLesServer(ls) } return fullNode, err }) } if err != nil { Fatalf("Failed to register the Ethereum service: %v", err) } } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/cmd/utils/flags.go#L1212-L1231
  29. GVOD/FX DUY OPEF4FSWJDF$POUFYU DPOGJH $POGJH  &UIFSFVN FSSPS  &UIFSFVN䟤୓੄ࢤࢿ

     ࠶۾%# ࠶ܚGJMUFS ೤੄ূ૓ 1P8 .JOFS١઱ਃ䟤୓ࢤࢿ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { // Ensure configuration values are compatible and sane . . . // Assemble the Ethereum object chainDb, err := CreateDB(ctx, config, "chaindata") . . . chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) . . . eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig) . . . eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit) . . . } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/eth/backend.go#L104-L187
  30. eth := &Ethereum{ config: config, chainDb: chainDb, chainConfig: chainConfig, eventMux:

    ctx.EventMux, accountManager: ctx.AccountManager, engine: CreateConsensusEngine( /* ࢤۚ */ ), shutdownChan: make(chan bool), networkID: config.NetworkId, gasPrice: config.MinerGasPrice, etherbase: config.Etherbase, bloomRequests: make(chan chan *bloombits.Retrieval), bloomIndexer: NewBloomIndexer( /* ࢤۚ */ ), } &UIFSFVNఋੑ https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/eth/backend.go#L62-L95
  31. GVOD/FX DUY OPEF4FSWJDF$POUFYU DPOGJH $POGJH  &UIFSFVN FSSPS func New(ctx

    *node.ServiceContext, config *Config) (*Ethereum, error) { // Ensure configuration values are compatible and sane . . . // Assemble the Ethereum object chainDb, err := CreateDB(ctx, config, "chaindata") . . . chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) . . . eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig) . . . eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit) . . . }
  32. GVOD/FX j  .JOFS  1PX ഑਷1P" ۽.JOJOHೡ䟤୓ࢤࢿ  OFX8PSLFS۽ࢤࢿغחXPSLFSоपઁ݃੉׬੘সࣻ೯

    func New(…) *Miner { miner := &Miner{ eth: eth, mux: mux, engine: engine, exitCh: make(chan struct{}), worker: newWorker(config, engine, eth, mux), canStart: 1, } go miner.update() return miner } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/miner/miner.go#L55-L67
  33. $IBOOFM ؘ੉ఠܳ઱Ҋ߉חా۽ HPSPVUJOFрؘ੉ఠҮജਊ੉ func New(…) *Miner { miner := &Miner{

    eth: eth, mux: mux, engine: engine, exitCh: make(chan struct{}), worker: newWorker(config, engine, eth, mux), canStart: 1, } go miner.update() return miner } type Miner struct { mux *event.TypeMux worker *worker coinbase common.Address eth Backend engine consensus.Engine exitCh chan struct{} canStart int32 shouldStart int32 } ࢶ঱਷੉ۧѱ ࢤࢿ਷੉ۧѱ
  34. GVOD/FX j  .JOFS func New(…) *Miner { miner :=

    &Miner{ eth: eth, mux: mux, engine: engine, exitCh: make(chan struct{}), worker: newWorker(config, engine, eth, mux), canStart: 1, } go miner.update() return miner }
  35. GVOD TFMG .JOFS VQEBUF for { select { case ev

    := <-events.Chan(): if ev == nil { return } switch ev.Data.(type) { case downloader.StartEvent: atomic.StoreInt32(&self.canStart, 0) if self.Mining() { self.Stop() atomic.StoreInt32(&self.shouldStart, 1) log.Info("Mining aborted due to sync") } case downloader.DoneEvent, downloader.FailedEvent: shouldStart := atomic.LoadInt32(&self.shouldStart) == 1 atomic.StoreInt32(&self.canStart, 1) atomic.StoreInt32(&self.shouldStart, 0) if shouldStart { self.Start(self.coinbase) } // stop immediately and ignore all further pending events return } case <-self.exitCh: return } } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/miner/miner.go#L73-L106
  36. $IBOOFMਸ੉ਊೠ&WFOU-PPQ GPS TFMFDUޙਸࢎਊೞݶ &WFOU-PPQэ਷௏٘ܳૢࣻ੓׮ for { select { case ev

    := <-events.Chan(): . . . case <-self.exitCh: return } } https://tour.golang.org/concurrency/5 for (;;) { Runnable task = takeTask(); if (task != null) { task.run(); updateLastExecutionTime(); } if (confirmShutdown()) { break; } } /FUUZ੄%FGBVMU&WFOU-PPQ
  37. GVOD TFMG .JOFS 4UBSU DPJOCBTFDPNNPO"EESFTT HFUI୭ୡप೯द২䣩ਸ઱Ѣա ௑ࣛী䞵NJOFSTUBSU दप೯ func (self

    *Miner) Start(coinbase common.Address) { atomic.StoreInt32(&self.shouldStart, 1) self.SetEtherbase(coinbase) if atomic.LoadInt32(&self.canStart) == 0 { log.Info("Network syncing, will start miner afterwards") return } self.worker.start() } https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/miner/miner.go#L108-L117
  38. GVOD X XPSLFS TUBSU func (w *worker) start() { atomic.StoreInt32(&w.running,

    1) w.startCh <- struct{}{} } दӒօ୊ۢFNQUZҳઑ୓ܳTUBSU$Iী֍਺  TUBSU$I଻䠭ਸా೧ࢲ.JOFSद੘ਸ੹׳  TUBSU$Iਸӝ׮ܻחҔ਷খࢲ.JOFS/FXী䞵ࢤࢿೠXPSLFS https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/miner/worker.go#L257-L260
  39. ଻䠭ਸ੉ਊೠ8PSLFS੄.JOJOH'MPX for { select { case req := <-w.newWorkCh: w.commitNewWork(req.interrupt,

    req.noempty) . . . NBJO-PPQ w.commit(uncles, w.fullTaskHook, true, tstart) DPNNJU/FX8PSLೣࣻ੄݃૑݄ case task := <-w.taskCh: . . . go w.seal(task, stopCh) UBTL-PPQ case w.taskCh <- &task{ . . . }: DPNNJUೣࣻ block, err := w.engine.Seal(w.chain, t.block, stop) TFBMೣࣻ೤੄ূ૓੄1P8ഐ୹ࠗ )BTIܳߊѼೞѱغݶSFTVMU$I۽֍ח׮ ethash.mine(block, id, nonce, abort, ethash.resultCh) &UBTI੄݃੉׬ೣࣻ
  40. GVOD FUIBTI &UIBTI 4FBM  1P8ܳਤ೧OPODFܳےؒೞѱTFFE۽೧ࢲNJOFݫࢲ٘ഐ୹ . . . for

    i := 0; i < threads; i++ { pend.Add(1) go func(id int, nonce uint64) { defer pend.Done() ethash.mine(block, id, nonce, abort, ethash.resultCh) }(i, uint64(ethash.rand.Int63())) } . . . https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/consensus/ethash/sealer.go#L81-L87
  41. GVOD FUIBTI &UIBTI NJOF  1PX੄पઁ௏٘ // We don't have

    to update hash rate on every nonce, so update after after 2^X nonces attempts++ if (attempts % (1 << 15)) == 0 { ethash.hashrate.Mark(attempts) attempts = 0 } // Compute the PoW value of this nonce digest, result := hashimotoFull(dataset.dataset, hash, nonce) if new(big.Int).SetBytes(result).Cmp(target) <= 0 { // Correct nonce found, create a new header with it header = types.CopyHeader(header) header.Nonce = types.EncodeNonce(nonce) header.MixDigest = common.BytesToHash(digest) // Seal and return a block (if still needed) select { case found <- block.WithSeal(header): logger.Trace("Ethash nonce found and reported", "attempts", nonce-seed, "nonce", nonce) case <-abort: logger.Trace("Ethash nonce found but discarded", "attempts", nonce-seed, "nonce", nonce) } break search } nonce++ https://github.com/ethereum/go-ethereum/blob/1acefafe2201ba061a58b51afd7a7edf4aa0f120/consensus/ethash/sealer.go#L110-L165
  42. ଵҊ੗ܐ .BTUFSJOH#JUDPJO IUUQTHJUIVCDPNCJUDPJOCPPLCJUDPJOCPPL  .BTUFSJOH&UIFSFVN IUUQTHJUIVCDPNFUIFSFVNCPPLFUIFSFVNCPPL 
 $PVSTFSB-FDUVSF IUUQTXXXDPVSTFSBPSHMFBSODSZQUPDVSSFODZ 

    #JUDPJOsT"DBEFNJD1FEJHSFF IUUQTRVFVFBDNPSHEFUBJMDGN JE  #JUDPJO8IJUFQBQFS IUUQTCJUDPJOPSHCJUDPJOQEG  ೠӖIUUQTFODPEFOUDPNCJUDPJO  &UIFSFVN8IJUFQBQFS IUUQTHJUIVCDPNFUIFSFVNXJLJXJLJ8IJUF1BQFS  &UIFSFVN:FMMPX1BQFS IUUQTFUIFSFVNHJUIVCJPZFMMPXQBQFSQBQFSQEG  &UIFSFVN#FJHF1BQFS IUUQTHJUIVCDPNDISPOBFPOCFJHFQBQFSCMPCNBTUFSCFJHFQBQFSQEG  $SZQUP;PNCJF IUUQTDSZQUP[PNCJFTJPLP  ҴղӖݽ਺ IUUQTQSPHSBNNFSTDPLSQBHFTCMPDLDIBJO  
 IUUQTHJUIVCDPNFUIFSFVNHPFUIFSFVN IUUQTHPCZFYBNQMFDPN IUUQTUPVSHPMBOHPSH