Skip to content

Commit

Permalink
Merge branch 'master' of github.com:harmony-one/harmony into pr_txn_h…
Browse files Browse the repository at this point in the history
…istory
  • Loading branch information
denniswon committed Mar 2, 2020
2 parents a38f832 + 2e27e1b commit 6ce1733
Show file tree
Hide file tree
Showing 14 changed files with 235 additions and 161 deletions.
12 changes: 0 additions & 12 deletions consensus/votepower/roster.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard"
staking "github.com/harmony-one/harmony/staking/types"
Expand Down Expand Up @@ -202,23 +201,12 @@ func Compute(staked shard.SlotList) (*Roster, error) {
if diff := numeric.OneDec().Sub(
ourPercentage.Add(theirPercentage),
); !diff.IsZero() && lastStakedVoter != nil {
utils.Logger().Info().
Str("theirs", theirPercentage.String()).
Str("ours", ourPercentage.String()).
Str("diff", diff.String()).
Str("combined", theirPercentage.Add(diff).Add(ourPercentage).String()).
Str("bls-public-key-of-receipent", lastStakedVoter.Identity.Hex()).
Msg("voting power of hmy & staked slots not sum to 1, giving diff to staked slot")
lastStakedVoter.EffectivePercent = lastStakedVoter.EffectivePercent.Add(diff)
theirPercentage = theirPercentage.Add(diff)
}

if lastStakedVoter != nil &&
!ourPercentage.Add(theirPercentage).Equal(numeric.OneDec()) {
utils.Logger().Error().
Str("theirs", theirPercentage.String()).
Str("ours", ourPercentage.String()).
Msg("Total voting power not equal 100 percent")
return nil, ErrVotingPowerNotEqualOne
}

Expand Down
21 changes: 3 additions & 18 deletions core/offchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,10 @@ func (bc *BlockChain) CommitOffChainData(
return NonStatTy, err
}

// Find all the elected validator addresses and store them in db
allElectedValidators := []common.Address{}
processed := make(map[common.Address]struct{})
for i := range newShardState.Shards {
shard := newShardState.Shards[i]
for j := range shard.Slots {
slot := shard.Slots[j]
if slot.EffectiveStake != nil { // For external validator
_, ok := processed[slot.EcdsaAddress]
if !ok {
processed[slot.EcdsaAddress] = struct{}{}
allElectedValidators = append(allElectedValidators, shard.Slots[j].EcdsaAddress)
}
}
}
}

// Update elected validators
if err := bc.WriteElectedValidatorList(batch, allElectedValidators); err != nil {
if err := bc.WriteElectedValidatorList(
batch, newShardState.StakedValidators().Addrs,
); err != nil {
return NonStatTy, err
}

Expand Down
11 changes: 5 additions & 6 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.DB, cfg vm.C
var (
receipts types.Receipts
outcxs types.CXReceipts

incxs = block.IncomingReceipts()
usedGas = new(uint64)
header = block.Header()
allLogs []*types.Log
gp = new(GasPool).AddGas(block.GasLimit())
incxs = block.IncomingReceipts()
usedGas = new(uint64)
header = block.Header()
allLogs []*types.Log
gp = new(GasPool).AddGas(block.GasLimit())
)
beneficiary, err := p.bc.GetECDSAFromCoinbase(header)

Expand Down
96 changes: 42 additions & 54 deletions internal/chain/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (e *engineImpl) VerifyShardState(bc engine.ChainReader, beacon engine.Chain
}
headerShardStateBytes := header.ShardState()
// TODO: figure out leader withhold shardState
if headerShardStateBytes == nil || len(headerShardStateBytes) == 0 {
if len(headerShardStateBytes) == 0 {
return nil
}
shardState, err := bc.SuperCommitteeForNextEpoch(beacon, header, true)
Expand Down Expand Up @@ -240,7 +240,10 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
lastCommitPayload := append(blockNumHash, parentHash[:]...)

if !aggSig.VerifyHash(mask.AggregatePublic, lastCommitPayload) {
return ctxerror.New("[VerifySeal] Unable to verify aggregated signature from last block", "lastBlockNum", header.Number().Uint64()-1, "lastBlockHash", parentHash)
const msg = "[VerifySeal] Unable to verify aggregated signature from last block"
return ctxerror.New(
msg, "lastBlockNum", header.Number().Uint64()-1, "lastBlockHash", parentHash,
)
}
return nil
}
Expand All @@ -254,7 +257,6 @@ func (e *engineImpl) Finalize(
incxs []*types.CXReceiptsProof, stks []*staking.StakingTransaction,
doubleSigners slash.Records,
) (*types.Block, *big.Int, error) {

// Accumulate block rewards and commit the final state root
// Header seems complete, assemble into a block and return
payout, err := AccumulateRewards(
Expand All @@ -272,7 +274,8 @@ func (e *engineImpl) Finalize(
if isBeaconChain && isNewEpoch && inStakingEra {
validators, err := chain.ReadValidatorList()
if err != nil {
return nil, nil, ctxerror.New("[Finalize] failed to read all validators").WithCause(err)
const msg = "[Finalize] failed to read all validators"
return nil, nil, ctxerror.New(msg).WithCause(err)
}
// Payout undelegated/unlocked tokens
for _, validator := range validators {
Expand Down Expand Up @@ -304,56 +307,42 @@ func (e *engineImpl) Finalize(
Uint64("block-number", header.Number().Uint64())

if isBeaconChain && inStakingEra {
superCommittee, err := chain.ReadShardState(
chain.CurrentHeader().Epoch(),
)
nowEpoch := chain.CurrentHeader().Epoch()
superCommittee, err := chain.ReadShardState(nowEpoch)
if err != nil {
return nil, nil, err
}
staked := superCommittee.StakedValidators()
// could happen that only harmony nodes are running,
if staked.CountStakedValidator > 0 {
l.RawJSON("external", []byte(staked.StateSubset.String())).
Msg("have non-zero external")

if err != nil {
return nil, nil, err
}

l.Msg("bumping validator signing counts")
if err := availability.IncrementValidatorSigningCounts(
chain, header, header.ShardID(), state, staked.LookupSet,
if isNewEpoch && staked.CountStakedValidator > 0 {
l.Msg("in new epoch (aka last block), apply availability check for activity")
if err := availability.SetInactiveUnavailableValidators(
chain, state, staked.Addrs,
); err != nil {
return nil, nil, err
}
// Now can reset the counters, do note, only
// after the availability logic runs
newShardState, err := header.GetShardState()
if err != nil {
const msg = "[Finalize] failed to read shard state"
return nil, nil, ctxerror.New(msg).WithCause(err)
}

if isNewEpoch {
l.Msg("in new epoch (aka last block), apply availability check for activity")
if err := availability.SetInactiveUnavailableValidators(
chain, state,
); err != nil {
return nil, nil, err
}
// Now can reset the counters, do note, only
// after the availability logic runs
newShardState, err := header.GetShardState()
if err != nil {
const msg = "[Finalize] failed to read shard state"
return nil, nil, ctxerror.New(msg).WithCause(err)
}

if stkd := newShardState.StakedValidators(); stkd.CountStakedValidator > 0 {
for _, addr := range stkd.Addrs {
wrapper, err := state.ValidatorWrapper(addr)
if err != nil {
return nil, nil, err
}
// Set the LastEpochInCommittee field for all
// external validators in the upcoming epoch.
// and set the availability tracking counters to 0
wrapper.LastEpochInCommittee = newShardState.Epoch
if err := state.UpdateValidatorWrapper(addr, wrapper); err != nil {
return nil, nil, ctxerror.New(
"[Finalize] failed update validator info",
).WithCause(err)
}
if stkd := newShardState.StakedValidators(); stkd.CountStakedValidator > 0 {
for _, addr := range stkd.Addrs {
wrapper, err := state.ValidatorWrapper(addr)
if err != nil {
return nil, nil, err
}
// Set the LastEpochInCommittee field for all
// external validators in the upcoming epoch.
// and set the availability tracking counters to 0
wrapper.LastEpochInCommittee = newShardState.Epoch
if err := state.UpdateValidatorWrapper(addr, wrapper); err != nil {
return nil, nil, ctxerror.New(
"[Finalize] failed update validator info",
).WithCause(err)
}
}
}
Expand Down Expand Up @@ -479,7 +468,9 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
}

// GetPublicKeys finds the public keys of the committee that signed the block header
func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate bool) ([]*bls.PublicKey, error) {
func GetPublicKeys(
chain engine.ChainReader, header *block.Header, reCalculate bool,
) ([]*bls.PublicKey, error) {
shardState := new(shard.State)
var err error
if reCalculate {
Expand All @@ -499,13 +490,10 @@ func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate b
"shardID", header.ShardID(),
)
}
var committerKeys []*bls.PublicKey

utils.Logger().Print(committee.Slots)
committerKeys := []*bls.PublicKey{}
for _, member := range committee.Slots {
committerKey := new(bls.PublicKey)
err := member.BlsPublicKey.ToLibBLSPublicKey(committerKey)
if err != nil {
if err := member.BlsPublicKey.ToLibBLSPublicKey(committerKey); err != nil {
return nil, ctxerror.New("cannot convert BLS public key",
"blsPublicKey", member.BlsPublicKey).WithCause(err)
}
Expand Down
30 changes: 24 additions & 6 deletions internal/chain/reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ func AccumulateRewards(
//// After staking
if bc.Config().IsStaking(header.Epoch()) &&
bc.CurrentHeader().ShardID() == shard.BeaconChainShardID {

defaultReward := network.BaseStakedReward

// TODO Use cached result in off-chain db instead of full computation
_, percentageStaked, err := network.WhatPercentStakedNow(beaconChain, header.Time().Int64())
_, percentageStaked, err := network.WhatPercentStakedNow(
beaconChain, header.Time().Int64(),
)
if err != nil {
return network.NoReward, err
}
Expand All @@ -73,11 +73,21 @@ func AccumulateRewards(
newRewards := big.NewInt(0)

// Take care of my own beacon chain committee, _ is missing, for slashing
members, payable, _, err := ballotResultBeaconchain(beaconChain, header)
members, payable, missing, err := ballotResultBeaconchain(beaconChain, header)
if err != nil {
return network.NoReward, err
}

if err := availability.IncrementValidatorSigningCounts(
beaconChain,
shard.Committee{shard.BeaconChainShardID, members}.StakedValidators(),
state,
payable,
missing,
); err != nil {
return network.NoReward, err
}

votingPower, err := votepower.Compute(members)
if err != nil {
return network.NoReward, err
Expand Down Expand Up @@ -130,13 +140,21 @@ func AccumulateRewards(
}

subComm := shardState.FindCommitteeByID(cxLink.ShardID())
// _ are the missing signers, later for slashing
payableSigners, _, err := availability.BlockSigners(cxLink.Bitmap(), subComm)
payableSigners, missing, err := availability.BlockSigners(
cxLink.Bitmap(), subComm,
)

if err != nil {
return network.NoReward, err
}

staked := subComm.StakedValidators()
if err := availability.IncrementValidatorSigningCounts(
beaconChain, staked, state, payableSigners, missing,
); err != nil {
return network.NoReward, err
}

votingPower, err := votepower.Compute(payableSigners)
if err != nil {
return network.NoReward, err
Expand Down
1 change: 0 additions & 1 deletion internal/hmyapi/apiv1/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ type Backend interface {
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool

// Staking related apis
GetElectedValidatorAddresses() []common.Address
GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper
Expand Down
1 change: 0 additions & 1 deletion internal/hmyapi/apiv2/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ type Backend interface {
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool

// Staking related apis
GetElectedValidatorAddresses() []common.Address
GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper
Expand Down
2 changes: 1 addition & 1 deletion internal/hmyapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type Backend interface {
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool

// Staking related apis
// Staking info query apis
GetElectedValidatorAddresses() []common.Address
GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper
Expand Down
20 changes: 9 additions & 11 deletions node/node_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ func (node *Node) BroadcastCrossLink(newBlock *types.Block) {
// VerifyNewBlock is called by consensus participants to verify the block (account model) they are
// running consensus on
func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
err := node.Blockchain().Validator().ValidateHeader(newBlock, true)
if err != nil {
if err := node.Blockchain().Validator().ValidateHeader(newBlock, true); err != nil {
utils.Logger().Error().
Str("blockHash", newBlock.Hash().Hex()).
Err(err).
Expand All @@ -327,20 +326,21 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
newBlock.Hash(),
).WithCause(err)
}

if newBlock.ShardID() != node.Blockchain().ShardID() {
utils.Logger().Error().
Uint32("my shard ID", node.Blockchain().ShardID()).
Uint32("new block's shard ID", newBlock.ShardID()).
Msg("wrong shard ID")
return ctxerror.New("wrong shard ID",
"my shard ID", node.Blockchain().ShardID(),
"new block's shard ID", newBlock.ShardID())
"new block's shard ID", newBlock.ShardID(),
)
}

err = node.Blockchain().Engine().VerifyShardState(
if err := node.Blockchain().Engine().VerifyShardState(
node.Blockchain(), node.Beaconchain(), newBlock.Header(),
)
if err != nil {
); err != nil {
utils.Logger().Error().
Str("blockHash", newBlock.Hash().Hex()).
Err(err).
Expand All @@ -351,8 +351,7 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
).WithCause(err)
}

err = node.Blockchain().ValidateNewBlock(newBlock)
if err != nil {
if err := node.Blockchain().ValidateNewBlock(newBlock); err != nil {
utils.Logger().Error().
Str("blockHash", newBlock.Hash().Hex()).
Int("numTx", len(newBlock.Transactions())).
Expand All @@ -367,7 +366,7 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {

// Verify cross links
// TODO: move into ValidateNewBlock
if node.NodeConfig.ShardID == 0 {
if node.NodeConfig.ShardID == shard.BeaconChainShardID {
err := node.VerifyBlockCrossLinks(newBlock)
if err != nil {
utils.Logger().Debug().Err(err).Msg("ops2 VerifyBlockCrossLinks Failed")
Expand All @@ -376,8 +375,7 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
}

// TODO: move into ValidateNewBlock
err = node.verifyIncomingReceipts(newBlock)
if err != nil {
if err := node.verifyIncomingReceipts(newBlock); err != nil {
utils.Logger().Error().
Str("blockHash", newBlock.Hash().Hex()).
Int("numIncomingReceipts", len(newBlock.IncomingReceipts())).
Expand Down
Loading

0 comments on commit 6ce1733

Please sign in to comment.