Merge pull request #17719 from karalabe/update-chts
les, light, params: update light client CHTs
This commit is contained in:
commit
f55c26ae6d
@ -47,7 +47,7 @@ type NodeInfo struct {
|
|||||||
Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
|
Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
|
||||||
Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
|
Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
|
||||||
Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block
|
Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block
|
||||||
CHT light.TrustedCheckpoint `json:"cht"` // Trused CHT checkpoint for fast catchup
|
CHT params.TrustedCheckpoint `json:"cht"` // Trused CHT checkpoint for fast catchup
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeProtocols creates protocol descriptors for the given LES versions.
|
// makeProtocols creates protocol descriptors for the given LES versions.
|
||||||
@ -76,7 +76,7 @@ func (c *lesCommons) makeProtocols(versions []uint) []p2p.Protocol {
|
|||||||
|
|
||||||
// nodeInfo retrieves some protocol metadata about the running host node.
|
// nodeInfo retrieves some protocol metadata about the running host node.
|
||||||
func (c *lesCommons) nodeInfo() interface{} {
|
func (c *lesCommons) nodeInfo() interface{} {
|
||||||
var cht light.TrustedCheckpoint
|
var cht params.TrustedCheckpoint
|
||||||
sections, _, _ := c.chtIndexer.Sections()
|
sections, _, _ := c.chtIndexer.Sections()
|
||||||
sections2, _, _ := c.bloomTrieIndexer.Sections()
|
sections2, _, _ := c.bloomTrieIndexer.Sections()
|
||||||
|
|
||||||
@ -98,8 +98,8 @@ func (c *lesCommons) nodeInfo() interface{} {
|
|||||||
idxV2 := (sectionIndex+1)*c.iConfig.PairChtSize/c.iConfig.ChtSize - 1
|
idxV2 := (sectionIndex+1)*c.iConfig.PairChtSize/c.iConfig.ChtSize - 1
|
||||||
chtRoot = light.GetChtRoot(c.chainDb, idxV2, sectionHead)
|
chtRoot = light.GetChtRoot(c.chainDb, idxV2, sectionHead)
|
||||||
}
|
}
|
||||||
cht = light.TrustedCheckpoint{
|
cht = params.TrustedCheckpoint{
|
||||||
SectionIdx: sectionIndex,
|
SectionIndex: sectionIndex,
|
||||||
SectionHead: sectionHead,
|
SectionHead: sectionHead,
|
||||||
CHTRoot: chtRoot,
|
CHTRoot: chtRoot,
|
||||||
BloomRoot: light.GetBloomTrieRoot(c.chainDb, sectionIndex, sectionHead),
|
BloomRoot: light.GetBloomTrieRoot(c.chainDb, sectionIndex, sectionHead),
|
||||||
|
@ -478,7 +478,7 @@ func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BloomReq struct {
|
type BloomReq struct {
|
||||||
BloomTrieNum, BitIdx, SectionIdx, FromLevel uint64
|
BloomTrieNum, BitIdx, SectionIndex, FromLevel uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ODR request type for requesting headers by Canonical Hash Trie, see LesOdrRequest interface
|
// ODR request type for requesting headers by Canonical Hash Trie, see LesOdrRequest interface
|
||||||
@ -487,7 +487,7 @@ type BloomRequest light.BloomRequest
|
|||||||
// GetCost returns the cost of the given ODR request according to the serving
|
// GetCost returns the cost of the given ODR request according to the serving
|
||||||
// peer's cost table (implementation of LesOdrRequest)
|
// peer's cost table (implementation of LesOdrRequest)
|
||||||
func (r *BloomRequest) GetCost(peer *peer) uint64 {
|
func (r *BloomRequest) GetCost(peer *peer) uint64 {
|
||||||
return peer.GetRequestCost(GetHelperTrieProofsMsg, len(r.SectionIdxList))
|
return peer.GetRequestCost(GetHelperTrieProofsMsg, len(r.SectionIndexList))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanSend tells if a certain peer is suitable for serving the given request
|
// CanSend tells if a certain peer is suitable for serving the given request
|
||||||
@ -503,13 +503,13 @@ func (r *BloomRequest) CanSend(peer *peer) bool {
|
|||||||
|
|
||||||
// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
|
// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
|
||||||
func (r *BloomRequest) Request(reqID uint64, peer *peer) error {
|
func (r *BloomRequest) Request(reqID uint64, peer *peer) error {
|
||||||
peer.Log().Debug("Requesting BloomBits", "bloomTrie", r.BloomTrieNum, "bitIdx", r.BitIdx, "sections", r.SectionIdxList)
|
peer.Log().Debug("Requesting BloomBits", "bloomTrie", r.BloomTrieNum, "bitIdx", r.BitIdx, "sections", r.SectionIndexList)
|
||||||
reqs := make([]HelperTrieReq, len(r.SectionIdxList))
|
reqs := make([]HelperTrieReq, len(r.SectionIndexList))
|
||||||
|
|
||||||
var encNumber [10]byte
|
var encNumber [10]byte
|
||||||
binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx))
|
binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx))
|
||||||
|
|
||||||
for i, sectionIdx := range r.SectionIdxList {
|
for i, sectionIdx := range r.SectionIndexList {
|
||||||
binary.BigEndian.PutUint64(encNumber[2:], sectionIdx)
|
binary.BigEndian.PutUint64(encNumber[2:], sectionIdx)
|
||||||
reqs[i] = HelperTrieReq{
|
reqs[i] = HelperTrieReq{
|
||||||
Type: htBloomBits,
|
Type: htBloomBits,
|
||||||
@ -524,7 +524,7 @@ func (r *BloomRequest) Request(reqID uint64, peer *peer) error {
|
|||||||
// returns true and stores results in memory if the message was a valid reply
|
// returns true and stores results in memory if the message was a valid reply
|
||||||
// to the request (implementation of LesOdrRequest)
|
// to the request (implementation of LesOdrRequest)
|
||||||
func (r *BloomRequest) Validate(db ethdb.Database, msg *Msg) error {
|
func (r *BloomRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
log.Debug("Validating BloomBits", "bloomTrie", r.BloomTrieNum, "bitIdx", r.BitIdx, "sections", r.SectionIdxList)
|
log.Debug("Validating BloomBits", "bloomTrie", r.BloomTrieNum, "bitIdx", r.BitIdx, "sections", r.SectionIndexList)
|
||||||
|
|
||||||
// Ensure we have a correct message with a single proof element
|
// Ensure we have a correct message with a single proof element
|
||||||
if msg.MsgType != MsgHelperTrieProofs {
|
if msg.MsgType != MsgHelperTrieProofs {
|
||||||
@ -535,13 +535,13 @@ func (r *BloomRequest) Validate(db ethdb.Database, msg *Msg) error {
|
|||||||
nodeSet := proofs.NodeSet()
|
nodeSet := proofs.NodeSet()
|
||||||
reads := &readTraceDB{db: nodeSet}
|
reads := &readTraceDB{db: nodeSet}
|
||||||
|
|
||||||
r.BloomBits = make([][]byte, len(r.SectionIdxList))
|
r.BloomBits = make([][]byte, len(r.SectionIndexList))
|
||||||
|
|
||||||
// Verify the proofs
|
// Verify the proofs
|
||||||
var encNumber [10]byte
|
var encNumber [10]byte
|
||||||
binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx))
|
binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx))
|
||||||
|
|
||||||
for i, idx := range r.SectionIdxList {
|
for i, idx := range r.SectionIndexList {
|
||||||
binary.BigEndian.PutUint64(encNumber[2:], idx)
|
binary.BigEndian.PutUint64(encNumber[2:], idx)
|
||||||
value, _, err := trie.VerifyProof(r.BloomTrieRoot, encNumber[:], reads)
|
value, _, err := trie.VerifyProof(r.BloomTrieRoot, encNumber[:], reads)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -118,19 +118,19 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addTrustedCheckpoint adds a trusted checkpoint to the blockchain
|
// addTrustedCheckpoint adds a trusted checkpoint to the blockchain
|
||||||
func (self *LightChain) addTrustedCheckpoint(cp TrustedCheckpoint) {
|
func (self *LightChain) addTrustedCheckpoint(cp *params.TrustedCheckpoint) {
|
||||||
if self.odr.ChtIndexer() != nil {
|
if self.odr.ChtIndexer() != nil {
|
||||||
StoreChtRoot(self.chainDb, cp.SectionIdx, cp.SectionHead, cp.CHTRoot)
|
StoreChtRoot(self.chainDb, cp.SectionIndex, cp.SectionHead, cp.CHTRoot)
|
||||||
self.odr.ChtIndexer().AddCheckpoint(cp.SectionIdx, cp.SectionHead)
|
self.odr.ChtIndexer().AddCheckpoint(cp.SectionIndex, cp.SectionHead)
|
||||||
}
|
}
|
||||||
if self.odr.BloomTrieIndexer() != nil {
|
if self.odr.BloomTrieIndexer() != nil {
|
||||||
StoreBloomTrieRoot(self.chainDb, cp.SectionIdx, cp.SectionHead, cp.BloomRoot)
|
StoreBloomTrieRoot(self.chainDb, cp.SectionIndex, cp.SectionHead, cp.BloomRoot)
|
||||||
self.odr.BloomTrieIndexer().AddCheckpoint(cp.SectionIdx, cp.SectionHead)
|
self.odr.BloomTrieIndexer().AddCheckpoint(cp.SectionIndex, cp.SectionHead)
|
||||||
}
|
}
|
||||||
if self.odr.BloomIndexer() != nil {
|
if self.odr.BloomIndexer() != nil {
|
||||||
self.odr.BloomIndexer().AddCheckpoint(cp.SectionIdx, cp.SectionHead)
|
self.odr.BloomIndexer().AddCheckpoint(cp.SectionIndex, cp.SectionHead)
|
||||||
}
|
}
|
||||||
log.Info("Added trusted checkpoint", "chain", cp.name, "block", (cp.SectionIdx+1)*self.indexerConfig.ChtSize-1, "hash", cp.SectionHead)
|
log.Info("Added trusted checkpoint", "chain", cp.Name, "block", (cp.SectionIndex+1)*self.indexerConfig.ChtSize-1, "hash", cp.SectionHead)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LightChain) getProcInterrupt() bool {
|
func (self *LightChain) getProcInterrupt() bool {
|
||||||
|
@ -160,7 +160,7 @@ type BloomRequest struct {
|
|||||||
Config *IndexerConfig
|
Config *IndexerConfig
|
||||||
BloomTrieNum uint64
|
BloomTrieNum uint64
|
||||||
BitIdx uint
|
BitIdx uint
|
||||||
SectionIdxList []uint64
|
SectionIndexList []uint64
|
||||||
BloomTrieRoot common.Hash
|
BloomTrieRoot common.Hash
|
||||||
BloomBits [][]byte
|
BloomBits [][]byte
|
||||||
Proofs *NodeSet
|
Proofs *NodeSet
|
||||||
@ -168,7 +168,7 @@ type BloomRequest struct {
|
|||||||
|
|
||||||
// StoreResult stores the retrieved data in local database
|
// StoreResult stores the retrieved data in local database
|
||||||
func (req *BloomRequest) StoreResult(db ethdb.Database) {
|
func (req *BloomRequest) StoreResult(db ethdb.Database) {
|
||||||
for i, sectionIdx := range req.SectionIdxList {
|
for i, sectionIdx := range req.SectionIndexList {
|
||||||
sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.Config.BloomTrieSize-1)
|
sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.Config.BloomTrieSize-1)
|
||||||
// if we don't have the canonical hash stored for this section head number, we'll still store it under
|
// if we don't have the canonical hash stored for this section head number, we'll still store it under
|
||||||
// a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical
|
// a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical
|
||||||
|
@ -222,7 +222,7 @@ func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
r := &BloomRequest{BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1,
|
r := &BloomRequest{BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1,
|
||||||
BitIdx: bitIdx, SectionIdxList: reqList, Config: odr.IndexerConfig()}
|
BitIdx: bitIdx, SectionIndexList: reqList, Config: odr.IndexerConfig()}
|
||||||
if err := odr.Retrieve(ctx, r); err != nil {
|
if err := odr.Retrieve(ctx, r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,38 +104,11 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// trustedCheckpoint represents a set of post-processed trie roots (CHT and BloomTrie) associated with
|
|
||||||
// the appropriate section index and head hash. It is used to start light syncing from this checkpoint
|
|
||||||
// and avoid downloading the entire header chain while still being able to securely access old headers/logs.
|
|
||||||
type TrustedCheckpoint struct {
|
|
||||||
name string
|
|
||||||
SectionIdx uint64
|
|
||||||
SectionHead, CHTRoot, BloomRoot common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// trustedCheckpoints associates each known checkpoint with the genesis hash of the chain it belongs to
|
// trustedCheckpoints associates each known checkpoint with the genesis hash of the chain it belongs to
|
||||||
var trustedCheckpoints = map[common.Hash]TrustedCheckpoint{
|
var trustedCheckpoints = map[common.Hash]*params.TrustedCheckpoint{
|
||||||
params.MainnetGenesisHash: {
|
params.MainnetGenesisHash: params.MainnetTrustedCheckpoint,
|
||||||
name: "mainnet",
|
params.TestnetGenesisHash: params.TestnetTrustedCheckpoint,
|
||||||
SectionIdx: 187,
|
params.RinkebyGenesisHash: params.RinkebyTrustedCheckpoint,
|
||||||
SectionHead: common.HexToHash("e6baa034efa31562d71ff23676512dec6562c1ad0301e08843b907e81958c696"),
|
|
||||||
CHTRoot: common.HexToHash("28001955219719cf06de1b08648969139d123a9835fc760547a1e4dabdabc15a"),
|
|
||||||
BloomRoot: common.HexToHash("395ca2373fc662720ac6b58b3bbe71f68aa0f38b63b2d3553dd32ff3c51eebc4"),
|
|
||||||
},
|
|
||||||
params.TestnetGenesisHash: {
|
|
||||||
name: "ropsten",
|
|
||||||
SectionIdx: 117,
|
|
||||||
SectionHead: common.HexToHash("9529b38631ae30783f56cbe4c3b9f07575b770ecba4f6e20a274b1e2f40fede1"),
|
|
||||||
CHTRoot: common.HexToHash("6f48e9f101f1fac98e7d74fbbcc4fda138358271ffd974d40d2506f0308bb363"),
|
|
||||||
BloomRoot: common.HexToHash("8242342e66e942c0cd893484e6736b9862ceb88b43ca344bb06a8285ac1b6d64"),
|
|
||||||
},
|
|
||||||
params.RinkebyGenesisHash: {
|
|
||||||
name: "rinkeby",
|
|
||||||
SectionIdx: 85,
|
|
||||||
SectionHead: common.HexToHash("92cfa67afc4ad8ab0dcbc6fa49efd14b5b19402442e7317e6bc879d85f89d64d"),
|
|
||||||
CHTRoot: common.HexToHash("2802ec92cd7a54a75bca96afdc666ae7b99e5d96cf8192dcfb09588812f51564"),
|
|
||||||
BloomRoot: common.HexToHash("ebefeb31a9a42866d8cf2d2477704b4c3d7c20d0e4e9b5aaa77f396e016a1263"),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -329,7 +302,7 @@ func (b *BloomTrieIndexerBackend) fetchMissingNodes(ctx context.Context, section
|
|||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
for bitIndex := range indexCh {
|
for bitIndex := range indexCh {
|
||||||
r := &BloomRequest{BloomTrieRoot: root, BloomTrieNum: section - 1, BitIdx: bitIndex, SectionIdxList: []uint64{section - 1}, Config: b.odr.IndexerConfig()}
|
r := &BloomRequest{BloomTrieRoot: root, BloomTrieNum: section - 1, BitIdx: bitIndex, SectionIndexList: []uint64{section - 1}, Config: b.odr.IndexerConfig()}
|
||||||
for {
|
for {
|
||||||
if err := b.odr.Retrieve(ctx, r); err == ErrNoPeers {
|
if err := b.odr.Retrieve(ctx, r); err == ErrNoPeers {
|
||||||
// if there are no peers to serve, retry later
|
// if there are no peers to serve, retry later
|
||||||
|
@ -46,6 +46,15 @@ var (
|
|||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
|
||||||
|
MainnetTrustedCheckpoint = &TrustedCheckpoint{
|
||||||
|
Name: "mainnet",
|
||||||
|
SectionIndex: 193,
|
||||||
|
SectionHead: common.HexToHash("0xc2d574295ecedc4d58530ae24c31a5a98be7d2b3327fba0dd0f4ed3913828a55"),
|
||||||
|
CHTRoot: common.HexToHash("0x5d1027dfae688c77376e842679ceada87fd94738feb9b32ef165473bfbbb317b"),
|
||||||
|
BloomRoot: common.HexToHash("0xd38be1a06aabd568e10957fee4fcc523bc64996bcf31bae3f55f86e0a583919f"),
|
||||||
|
}
|
||||||
|
|
||||||
// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
||||||
TestnetChainConfig = &ChainConfig{
|
TestnetChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(3),
|
ChainID: big.NewInt(3),
|
||||||
@ -61,6 +70,15 @@ var (
|
|||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestnetTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
|
||||||
|
TestnetTrustedCheckpoint = &TrustedCheckpoint{
|
||||||
|
Name: "testnet",
|
||||||
|
SectionIndex: 123,
|
||||||
|
SectionHead: common.HexToHash("0xa372a53decb68ce453da12bea1c8ee7b568b276aa2aab94d9060aa7c81fc3dee"),
|
||||||
|
CHTRoot: common.HexToHash("0x6b02e7fada79cd2a80d4b3623df9c44384d6647fc127462e1c188ccd09ece87b"),
|
||||||
|
BloomRoot: common.HexToHash("0xf2d27490914968279d6377d42868928632573e823b5d1d4a944cba6009e16259"),
|
||||||
|
}
|
||||||
|
|
||||||
// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
|
// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
|
||||||
RinkebyChainConfig = &ChainConfig{
|
RinkebyChainConfig = &ChainConfig{
|
||||||
ChainID: big.NewInt(4),
|
ChainID: big.NewInt(4),
|
||||||
@ -79,6 +97,15 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
|
||||||
|
RinkebyTrustedCheckpoint = &TrustedCheckpoint{
|
||||||
|
Name: "rinkeby",
|
||||||
|
SectionIndex: 91,
|
||||||
|
SectionHead: common.HexToHash("0x435b7b2d8a7922f3b9a522f2fb02730e95e0e1782f0f5443894d5415bba37154"),
|
||||||
|
CHTRoot: common.HexToHash("0x0664bf7ecccfb6775c4eca6f0f264fb5282a22754a2135a1ac4bff2ef02898dd"),
|
||||||
|
BloomRoot: common.HexToHash("0x2a64df2400c3a2cb6400639bb6ed29389abdb4d93e2e525aa7c21f38767cd96f"),
|
||||||
|
}
|
||||||
|
|
||||||
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
|
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
// and accepted by the Ethereum core developers into the Ethash consensus.
|
// and accepted by the Ethereum core developers into the Ethash consensus.
|
||||||
//
|
//
|
||||||
@ -97,6 +124,18 @@ var (
|
|||||||
TestRules = TestChainConfig.Rules(new(big.Int))
|
TestRules = TestChainConfig.Rules(new(big.Int))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TrustedCheckpoint represents a set of post-processed trie roots (CHT and
|
||||||
|
// BloomTrie) associated with the appropriate section index and head hash. It is
|
||||||
|
// used to start light syncing from this checkpoint and avoid downloading the
|
||||||
|
// entire header chain while still being able to securely access old headers/logs.
|
||||||
|
type TrustedCheckpoint struct {
|
||||||
|
Name string `json:"-"`
|
||||||
|
SectionIndex uint64 `json:"sectionIndex"`
|
||||||
|
SectionHead common.Hash `json:"sectionHead"`
|
||||||
|
CHTRoot common.Hash `json:"chtRoot"`
|
||||||
|
BloomRoot common.Hash `json:"bloomRoot"`
|
||||||
|
}
|
||||||
|
|
||||||
// ChainConfig is the core config which determines the blockchain settings.
|
// ChainConfig is the core config which determines the blockchain settings.
|
||||||
//
|
//
|
||||||
// ChainConfig is stored in the database on a per block basis. This means
|
// ChainConfig is stored in the database on a per block basis. This means
|
||||||
|
Loading…
Reference in New Issue
Block a user