兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx

上传人:b****2 文档编号:2309542 上传时间:2022-10-28 格式:DOCX 页数:19 大小:24.77KB
下载 相关 举报
兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx_第1页
第1页 / 共19页
兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx_第2页
第2页 / 共19页
兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx_第3页
第3页 / 共19页
兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx_第4页
第4页 / 共19页
兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx

《兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx》由会员分享,可在线阅读,更多相关《兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx(19页珍藏版)》请在冰豆网上搜索。

兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析.docx

兄弟连Go语言+区块链技术培训以太坊源码分析49p2ptablego源码分析

兄弟连Go语言+区块链技术培训以太坊源码分析(49)p2p-table.go源码分析

table.go主要实现了p2p的Kademlia协议。

###Kademlia协议简介(建议阅读references里面的pdf文档)

Kademlia协议(以下简称Kad)是美国纽约大学的PetarP.Maymounkov和DavidMazieres.

在2002年发布的一项研究结果《Kademlia:

Apeerto-peerinformationsystembasedon

theXORmetric》。

简单的说,Kad是一种分布式哈希表(DHT)技术,不过和其他DHT实现技术比较,如

Chord、CAN、Pastry等,Kad通过独特的以异或算法(XOR)为距离度量基础,建立了一种

全新的DHT拓扑结构,相比于其他算法,大大提高了路由查询速度。

###table的结构和字段

    const(

        alpha=3//Kademliaconcurrencyfactor

        bucketSize=16//Kademliabucketsize

        hashBits=len(common.Hash{})*8

        nBuckets=hashBits+1//Numberofbuckets

    

        maxBondingPingPongs=16

        maxFindnodeFailures=5

    

        autoRefreshInterval=1*time.Hour

        seedCount=30

        seedMaxAge=5*24*time.Hour

    )

    

    typeTablestruct{

        mutexsync.Mutex//protectsbuckets,theircontent,andnursery

        buckets[nBuckets]*bucket//indexofknownnodesbydistance

        nursery[]*Node//bootstrapnodes

        db*nodeDB//databaseofknownnodes

    

        refreshReqchanchanstruct{}

        closeReqchanstruct{}

        closedchanstruct{}

    

        bondmusync.Mutex

        bondingmap[NodeID]*bondproc

        bondslotschanstruct{}//limitstotalnumberofactivebondingprocesses

    

        nodeAddedHookfunc(*Node)//fortesting

    

        nettransport

        self*Node//metadataofthelocalnode

    }

###初始化

    funcnewTable(ttransport,ourIDNodeID,ourAddr*net.UDPAddr,nodeDBPathstring)(*Table,error){

        //Ifnonodedatabasewasgiven,useanin-memoryone

        //这个在之前的database.go里面有介绍。

打开leveldb。

如果path为空。

那么打开一个基于内存的db

        db,err:

=newNodeDB(nodeDBPath,Version,ourID)

        iferr!

=nil{

            returnnil,err

        }

        tab:

=&Table{

            net:

t,

            db:

db,

            self:

NewNode(ourID,ourAddr.IP,uint16(ourAddr.Port),uint16(ourAddr.Port)),

            bonding:

make(map[NodeID]*bondproc),

            bondslots:

make(chanstruct{},maxBondingPingPongs),

            refreshReq:

make(chanchanstruct{}),

            closeReq:

make(chanstruct{}),

            closed:

make(chanstruct{}),

        }

        fori:

=0;i

            tab.bondslots<-struct{}{}

        }

        fori:

=rangetab.buckets{

            tab.buckets[i]=new(bucket)

        }

        gotab.refreshLoop()

        returntab,nil

    }

上面的初始化启动了一个goroutinerefreshLoop(),这个函数主要完成以下的工作。

1. 每一个小时进行一次刷新工作(autoRefreshInterval)

2. 如果接收到refreshReq请求。

那么进行刷新工作。

3. 如果接收到关闭消息。

那么进行关闭。

所以函数主要的工作就是启动刷新工作。

doRefresh

    //refreshLoopschedulesdoRefreshrunsandcoordinatesshutdown.

    func(tab*Table)refreshLoop(){

        var(

            timer=time.NewTicker(autoRefreshInterval)

            waiting[]chanstruct{}//accumulateswaitingcallerswhiledoRefreshruns

            donechanstruct{}//wheredoRefreshreportscompletion

        )

    loop:

        for{

            select{

            case<-timer.C:

                ifdone==nil{

                    done=make(chanstruct{})

                    gotab.doRefresh(done)

                }

            casereq:

=<-tab.refreshReq:

                waiting=append(waiting,req)

                ifdone==nil{

                    done=make(chanstruct{})

                    gotab.doRefresh(done)

                }

            case<-done:

                for_,ch:

=rangewaiting{

                    close(ch)

                }

                waiting=nil

                done=nil

            case<-tab.closeReq:

                breakloop

            }

        }

    

        if!

=nil{

            .close()

        }

        ifdone!

=nil{

            <-done

        }

        for_,ch:

=rangewaiting{

            close(ch)

        }

        tab.db.close()

        close(tab.closed)

    }

doRefresh函数

    //doRefreshperformsalookupforarandomtargettokeepbuckets

    //full.seednodesareinsertedifthetableisempty(initial

    //bootstrapordiscardedfaultypeers).

    //doRefresh随机查找一个目标,以便保持buckets是满的。

如果table是空的,那么种子节点会插入。

(比如最开始的启动或者是删除错误的节点之后)

    func(tab*Table)doRefresh(donechanstruct{}){

        deferclose(done)

    

        //TheKademliapaperspecifiesthatthebucketrefreshshould

        //performalookupintheleastrecentlyusedbucket.Wecannot

        //adheretothisbecausethefindnodetargetisa512bitvalue

        //(nothash-sized)anditisnoteasilypossibletogeneratea

        //sha3preimagethatfallsintoachosenbucket.

        //Weperformalookupwitharandomtargetinstead.

        //这里暂时没看懂

        vartargetNodeID

        rand.Read(target[:

])

        result:

=tab.lookup(targ

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1