The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
woop/p2p/stream/protocols/sync/chain.go

142 lines
3.9 KiB

package sync
import (
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/types"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
"github.com/harmony-one/harmony/internal/utils/keylocker"
"github.com/pkg/errors"
)
// chainHelper is the adapter for blockchain which is friendly to unit test.
type chainHelper interface {
getCurrentBlockNumber() uint64
getBlockHashes(bns []uint64) []common.Hash
getBlocksByNumber(bns []uint64) ([]*types.Block, error)
getBlocksByHashes(hs []common.Hash) ([]*types.Block, error)
}
type chainHelperImpl struct {
chain engine.ChainReader
schedule shardingconfig.Schedule
keyLocker *keylocker.KeyLocker
}
func newChainHelper(chain engine.ChainReader, schedule shardingconfig.Schedule) *chainHelperImpl {
return &chainHelperImpl{
chain: chain,
schedule: schedule,
keyLocker: keylocker.New(),
}
}
func (ch *chainHelperImpl) getCurrentBlockNumber() uint64 {
return ch.chain.CurrentBlock().NumberU64()
}
func (ch *chainHelperImpl) getBlockHashes(bns []uint64) []common.Hash {
hashes := make([]common.Hash, 0, len(bns))
for _, bn := range bns {
var h common.Hash
header := ch.chain.GetHeaderByNumber(bn)
if header != nil {
h = header.Hash()
}
hashes = append(hashes, h)
}
return hashes
}
func (ch *chainHelperImpl) getBlocksByNumber(bns []uint64) ([]*types.Block, error) {
Epoch syncing - syncing only epoch blocks. (#4070) * Epoch syncing - syncing only epoch blocks. * Fix go test, added command to run. * Block signature validation. * Support getting block by height. * Fix to compile. * Http method. * Generate fix. * Install protoc-gen-go-grpc. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Added limit to avoid abuse, small fixes. * Fix duplicate code. * Fix isInSyn. * Fix method call. * Removed additional block sending. * Fix in sync. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Add logs. * Fix msgf call. * Epoch syncing - syncing only epoch blocks. * Block signature validation. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Support getting block by height. * Http method. * Fix duplicate code. * Fix isInSyn. * Added limit to avoid abuse, small fixes. * Fix method call. * Removed additional block sending. * Fix in sync. * Small fix. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Fix msgf call. * Sending crosslinks from beacon to non-beacon chains. * Receiving crosslinks. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink hardbeat signal receiving. * Sending crosslinks from beacon to non-beacon chains. * Sending crosslinks from beacon to non-beacon chains. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink signal. * Add comment to run tests. * Fix comments. * Fix comments. * Fix review comments. * Updated with last crosslink heart beat signal. * Merged crosslink signal. * Clean up code. * Add logs for cl debug. * Stop iterate on receiving result. * Add logs. * Fix in sync check. * Fix reconnect problems. * Fix tests and reduce dependency. * Updated with main. * Fix review comments. * Changed to compare epochs. * Fix crosslinks usage. * Fix initialization. * Epoch chain implementation. * Legacy sync by default. * Revert "Legacy sync by default." This reverts commit 5fa6ce002a16699cc3ca75bdd40b068dbe6cefb6. * Epoch sync for downloader. * Build docker image while tests. * Fix paths. * Updated travis. * Review improvements. Co-authored-by: Konstantin <k.potapov@softpro.com>
2 years ago
curBlock := ch.chain.CurrentHeader().Number().Uint64()
blocks := make([]*types.Block, 0, len(bns))
for _, bn := range bns {
Epoch syncing - syncing only epoch blocks. (#4070) * Epoch syncing - syncing only epoch blocks. * Fix go test, added command to run. * Block signature validation. * Support getting block by height. * Fix to compile. * Http method. * Generate fix. * Install protoc-gen-go-grpc. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Added limit to avoid abuse, small fixes. * Fix duplicate code. * Fix isInSyn. * Fix method call. * Removed additional block sending. * Fix in sync. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Add logs. * Fix msgf call. * Epoch syncing - syncing only epoch blocks. * Block signature validation. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Support getting block by height. * Http method. * Fix duplicate code. * Fix isInSyn. * Added limit to avoid abuse, small fixes. * Fix method call. * Removed additional block sending. * Fix in sync. * Small fix. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Fix msgf call. * Sending crosslinks from beacon to non-beacon chains. * Receiving crosslinks. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink hardbeat signal receiving. * Sending crosslinks from beacon to non-beacon chains. * Sending crosslinks from beacon to non-beacon chains. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink signal. * Add comment to run tests. * Fix comments. * Fix comments. * Fix review comments. * Updated with last crosslink heart beat signal. * Merged crosslink signal. * Clean up code. * Add logs for cl debug. * Stop iterate on receiving result. * Add logs. * Fix in sync check. * Fix reconnect problems. * Fix tests and reduce dependency. * Updated with main. * Fix review comments. * Changed to compare epochs. * Fix crosslinks usage. * Fix initialization. * Epoch chain implementation. * Legacy sync by default. * Revert "Legacy sync by default." This reverts commit 5fa6ce002a16699cc3ca75bdd40b068dbe6cefb6. * Epoch sync for downloader. * Build docker image while tests. * Fix paths. * Updated travis. * Review improvements. Co-authored-by: Konstantin <k.potapov@softpro.com>
2 years ago
if curBlock < bn {
continue
}
header := ch.chain.GetHeaderByNumber(bn)
if header != nil {
Epoch syncing - syncing only epoch blocks. (#4070) * Epoch syncing - syncing only epoch blocks. * Fix go test, added command to run. * Block signature validation. * Support getting block by height. * Fix to compile. * Http method. * Generate fix. * Install protoc-gen-go-grpc. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Added limit to avoid abuse, small fixes. * Fix duplicate code. * Fix isInSyn. * Fix method call. * Removed additional block sending. * Fix in sync. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Add logs. * Fix msgf call. * Epoch syncing - syncing only epoch blocks. * Block signature validation. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Support getting block by height. * Http method. * Fix duplicate code. * Fix isInSyn. * Added limit to avoid abuse, small fixes. * Fix method call. * Removed additional block sending. * Fix in sync. * Small fix. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Fix msgf call. * Sending crosslinks from beacon to non-beacon chains. * Receiving crosslinks. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink hardbeat signal receiving. * Sending crosslinks from beacon to non-beacon chains. * Sending crosslinks from beacon to non-beacon chains. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink signal. * Add comment to run tests. * Fix comments. * Fix comments. * Fix review comments. * Updated with last crosslink heart beat signal. * Merged crosslink signal. * Clean up code. * Add logs for cl debug. * Stop iterate on receiving result. * Add logs. * Fix in sync check. * Fix reconnect problems. * Fix tests and reduce dependency. * Updated with main. * Fix review comments. * Changed to compare epochs. * Fix crosslinks usage. * Fix initialization. * Epoch chain implementation. * Legacy sync by default. * Revert "Legacy sync by default." This reverts commit 5fa6ce002a16699cc3ca75bdd40b068dbe6cefb6. * Epoch sync for downloader. * Build docker image while tests. * Fix paths. * Updated travis. * Review improvements. Co-authored-by: Konstantin <k.potapov@softpro.com>
2 years ago
block, err := ch.getBlockWithSigByHeader(header)
if err != nil {
return nil, errors.Wrapf(err, "get block %v at %v", header.Hash().String(), header.Number())
}
Epoch syncing - syncing only epoch blocks. (#4070) * Epoch syncing - syncing only epoch blocks. * Fix go test, added command to run. * Block signature validation. * Support getting block by height. * Fix to compile. * Http method. * Generate fix. * Install protoc-gen-go-grpc. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Added limit to avoid abuse, small fixes. * Fix duplicate code. * Fix isInSyn. * Fix method call. * Removed additional block sending. * Fix in sync. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Add logs. * Fix msgf call. * Epoch syncing - syncing only epoch blocks. * Block signature validation. * Fix sync, additional timeouts, fix epoch. * Chain behaviour options, optional state validation on blockchain initialization. * Support getting block by height. * Http method. * Fix duplicate code. * Fix isInSyn. * Added limit to avoid abuse, small fixes. * Fix method call. * Removed additional block sending. * Fix in sync. * Small fix. * Code clean up. * Fix beacon chain func. * Return back Beaconchain. * Fix sending only epoch blocks. * Fix failed startup with validator. * Increase recv message size. * Remove peer. * Add logs. * Fix msgf call. * Sending crosslinks from beacon to non-beacon chains. * Receiving crosslinks. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink hardbeat signal receiving. * Sending crosslinks from beacon to non-beacon chains. * Sending crosslinks from beacon to non-beacon chains. * Broadcast. * Fix comment. * Crosslink signal. * Crosslink signal. * Add comment to run tests. * Fix comments. * Fix comments. * Fix review comments. * Updated with last crosslink heart beat signal. * Merged crosslink signal. * Clean up code. * Add logs for cl debug. * Stop iterate on receiving result. * Add logs. * Fix in sync check. * Fix reconnect problems. * Fix tests and reduce dependency. * Updated with main. * Fix review comments. * Changed to compare epochs. * Fix crosslinks usage. * Fix initialization. * Epoch chain implementation. * Legacy sync by default. * Revert "Legacy sync by default." This reverts commit 5fa6ce002a16699cc3ca75bdd40b068dbe6cefb6. * Epoch sync for downloader. * Build docker image while tests. * Fix paths. * Updated travis. * Review improvements. Co-authored-by: Konstantin <k.potapov@softpro.com>
2 years ago
blocks = append(blocks, block)
}
}
return blocks, nil
}
func (ch *chainHelperImpl) getBlocksByHashes(hs []common.Hash) ([]*types.Block, error) {
var (
blocks = make([]*types.Block, 0, len(hs))
)
for _, h := range hs {
var (
block *types.Block
err error
)
header := ch.chain.GetHeaderByHash(h)
if header != nil {
block, err = ch.getBlockWithSigByHeader(header)
if err != nil {
return nil, errors.Wrapf(err, "get block %v at %v", header.Hash().String(), header.Number())
}
}
blocks = append(blocks, block)
}
return blocks, nil
}
func (ch *chainHelperImpl) getBlockWithSigByHeader(header *block.Header) (*types.Block, error) {
rs, err := ch.keyLocker.Lock(header.Number().Uint64(), func() (interface{}, error) {
b := ch.chain.GetBlock(header.Hash(), header.Number().Uint64())
if b == nil {
return nil, errors.Errorf("block %d not found", header.Number().Uint64())
}
commitSig, err := ch.getBlockSigAndBitmap(header)
if err != nil {
return nil, errors.New("missing commit signature")
}
b.SetCurrentCommitSig(commitSig)
return b, nil
})
if err != nil {
return nil, err
}
return rs.(*types.Block), nil
}
func (ch *chainHelperImpl) getBlockSigAndBitmap(header *block.Header) ([]byte, error) {
sb := ch.getBlockSigFromNextBlock(header)
if len(sb) != 0 {
return sb, nil
}
// Note: some commit sig read from db is different from [nextHeader.sig, nextHeader.bitMap]
// nextBlock data is better to be used.
return ch.getBlockSigFromDB(header)
}
func (ch *chainHelperImpl) getBlockSigFromNextBlock(header *block.Header) []byte {
nextBN := header.Number().Uint64() + 1
nextHeader := ch.chain.GetHeaderByNumber(nextBN)
if nextHeader == nil {
return nil
}
sigBytes := nextHeader.LastCommitSignature()
bitMap := nextHeader.LastCommitBitmap()
sb := make([]byte, len(sigBytes)+len(bitMap))
copy(sb[:], sigBytes[:])
copy(sb[len(sigBytes):], bitMap[:])
return sb
}
func (ch *chainHelperImpl) getBlockSigFromDB(header *block.Header) ([]byte, error) {
return ch.chain.ReadCommitSig(header.Number().Uint64())
}