address comments

pull/1950/head
chao 5 years ago
parent 44a8e2a376
commit 05dd350906
  1. 6
      consensus/engine/consensus_engine.go
  2. 28
      core/blockchain.go
  3. 3
      core/chain_makers.go
  4. 27
      internal/chain/engine.go
  5. 2
      node/node_newblock.go

@ -34,6 +34,9 @@ type ChainReader interface {
// GetHeaderByHash retrieves a block header from the database by its hash.
GetHeaderByHash(hash common.Hash) *block.Header
// ShardID returns shardID
ShardID() uint32
// GetBlock retrieves a block from the database by hash and number.
GetBlock(hash common.Hash, number uint64) *types.Block
@ -52,7 +55,8 @@ type ChainReader interface {
ReadBlockRewardAccumulator(uint64) (*big.Int, error)
//SuperCommitteeForNextEpoch calculates the next epoch's supper committee
SuperCommitteeForNextEpoch(shardID uint32, beacon ChainReader, header *block.Header) (*shard.State, error)
// isVerify flag is to indicate which stage to call this function: true (verification stage), false(propose stage)
SuperCommitteeForNextEpoch(beacon ChainReader, header *block.Header, isVerify bool) (*shard.State, error)
}
// Engine is an algorithm agnostic consensus engine.

@ -2967,17 +2967,20 @@ func (bc *BlockChain) GetECDSAFromCoinbase(header *block.Header) (common.Address
}
// SuperCommitteeForNextEpoch ...
// TODO: remove shardID in parameter if not needed in worker code
// isVerify=true means validators use it to verify
// isVerify=false means leader is to propose
func (bc *BlockChain) SuperCommitteeForNextEpoch(
shardID uint32,
beacon consensus_engine.ChainReader,
header *block.Header,
isVerify bool,
) (*shard.State, error) {
var (
nextCommittee = new(shard.State)
err error
beaconEpoch = new(big.Int)
shardState = shard.State{}
)
switch shardID {
switch header.ShardID() {
case shard.BeaconChainShardID:
if shard.Schedule.IsLastBlock(header.Number().Uint64()) {
nextCommittee, err = committee.WithStakingEnabled.Compute(
@ -2987,7 +2990,24 @@ func (bc *BlockChain) SuperCommitteeForNextEpoch(
}
default:
// TODO: needs to make sure beacon chain sync works.
beaconEpoch := beacon.CurrentHeader().Epoch()
if isVerify {
//verify
shardState, err = header.GetShardState()
if err != nil {
return &shard.State{}, err
}
// before staking epoch
if shardState.Epoch == nil {
beaconEpoch = new(big.Int).Add(header.Epoch(), common.Big1)
} else { // after staking epoch
beaconEpoch = shardState.Epoch
}
} else {
//propose
beaconEpoch = beacon.CurrentHeader().Epoch()
}
utils.Logger().Debug().Msgf("[SuperCommitteeCalculation] isVerify: %+v, realBeaconEpoch:%+v, beaconEpoch: %+v, headerEpoch:%+v, shardStateEpoch:%+v",
isVerify, beacon.CurrentHeader().Epoch(), beaconEpoch, header.Epoch(), shardState.Epoch)
nextEpoch := new(big.Int).Add(header.Epoch(), common.Big1)
if bc.Config().IsStaking(nextEpoch) {
// If next epoch is staking epoch, I should wait and listen for beacon chain for epoch changes

@ -265,6 +265,7 @@ func (cr *fakeChainReader) Config() *params.ChainConfig {
}
func (cr *fakeChainReader) CurrentHeader() *block.Header { return nil }
func (cr *fakeChainReader) ShardID() uint32 { return 0 }
func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *block.Header { return nil }
func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *block.Header { return nil }
func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *block.Header { return nil }
@ -272,7 +273,7 @@ func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Bloc
func (cr *fakeChainReader) ReadShardState(epoch *big.Int) (*shard.State, error) { return nil, nil }
func (cr *fakeChainReader) ReadActiveValidatorList() ([]common.Address, error) { return nil, nil }
func (cr *fakeChainReader) ValidatorCandidates() []common.Address { return nil }
func (cr *fakeChainReader) SuperCommitteeForNextEpoch(shardID uint32, beacon consensus_engine.ChainReader, header *block.Header) (*shard.State, error) {
func (cr *fakeChainReader) SuperCommitteeForNextEpoch(beacon consensus_engine.ChainReader, header *block.Header, isVerify bool) (*shard.State, error) {
return nil, nil
}
func (cr *fakeChainReader) ReadValidatorInformation(addr common.Address) (*staking.ValidatorWrapper, error) {

@ -148,27 +148,34 @@ func ReadPublicKeysFromLastBlock(bc engine.ChainReader, header *block.Header) ([
// VerifyShardState implements Engine, checking the shardstate is valid at epoch transition
func (e *engineImpl) VerifyShardState(bc engine.ChainReader, beacon engine.ChainReader, header *block.Header) error {
headerShardState, _ := header.GetShardState()
if bc.ShardID() != header.ShardID() {
return ctxerror.New("[VerifyShardState] shardID not match", "bc.ShardID", bc.ShardID(), "header.ShardID", header.ShardID())
}
headerShardStateBytes := header.ShardState()
// TODO: figure out leader withhold shardState
if headerShardState.Epoch == nil {
if headerShardStateBytes == nil || len(headerShardStateBytes) == 0 {
return nil
}
shardState, err := bc.SuperCommitteeForNextEpoch(header.ShardID(), beacon, header)
shardState, err := bc.SuperCommitteeForNextEpoch(beacon, header, true)
if err != nil {
return ctxerror.New("[VerifyShardState] SuperCommitteeForNexEpoch calculation had error", "shardState", shardState).WithCause(err)
}
by1, err := shard.EncodeWrapper(*shardState, bc.Config().IsStaking(header.Epoch()))
if err != nil {
return ctxerror.New("[VerifyShardState] ShardState Encoding had error", "shardStateBytes", by1).WithCause(err)
isStaking := false
if shardState.Epoch != nil && bc.Config().IsStaking(shardState.Epoch) {
isStaking = true
}
by2, err := shard.EncodeWrapper(headerShardState, bc.Config().IsStaking(header.Epoch()))
shardStateBytes, err := shard.EncodeWrapper(*shardState, isStaking)
if err != nil {
return ctxerror.New("[VerifyShardState] ShardState Encoding had error", "headerShardStateBytes", by2).WithCause(err)
return ctxerror.New("[VerifyShardState] ShardState Encoding had error", "shardStateBytes", shardStateBytes).WithCause(err)
}
if !bytes.Equal(by1, by2) {
return ctxerror.New("[VerifyShardState] ShardState is Invalid", "shardState", shardState, "headerShardState", headerShardState)
if !bytes.Equal(shardStateBytes, headerShardStateBytes) {
headerSS, err := header.GetShardState()
if err != nil {
headerSS = shard.State{}
}
return ctxerror.New("[VerifyShardState] ShardState is Invalid", "shardStateEpoch", shardState.Epoch, "headerEpoch", header.Epoch(), "headerShardStateEpoch", headerSS.Epoch, "beaconEpoch", beacon.CurrentHeader().Epoch())
}
return nil

@ -152,7 +152,7 @@ func (node *Node) proposeNewBlock() (*types.Block, error) {
// Prepare shard state
shardState := new(shard.State)
if shardState, err = node.Blockchain().SuperCommitteeForNextEpoch(
node.Consensus.ShardID, node.Beaconchain(), node.Worker.GetCurrentHeader(),
node.Beaconchain(), node.Worker.GetCurrentHeader(), false,
); err != nil {
return nil, err
}

Loading…
Cancel
Save