@ -24,6 +24,7 @@ import (
bls2 "github.com/harmony-one/harmony/crypto/bls"
bls2 "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/block"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/types"
@ -109,19 +110,13 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
return nil
return nil
}
}
// VerifyBlockLastCommitSigs verifies the last commit sigs of the block
// VerifyHeaderWithSignature verifies the header with corresponding commit sigs
func VerifyBlockLastCommitSigs ( bc * BlockChain , block * types . Block ) error {
func VerifyHeaderWithSignature ( bc * BlockChain , header * block . Header , commitSig [ 96 ] byte , commitBitmap [ ] byte ) error {
header := block . Header ( )
shardState , err := bc . ReadShardState ( header . Epoch ( ) )
parentBlock := bc . GetBlockByNumber ( block . NumberU64 ( ) - 1 )
committee := shardState . FindCommitteeByID ( header . ShardID ( ) )
if parentBlock == nil {
return ctxerror . New ( "[VerifyNewBlock] Failed to get parent block" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) )
}
parentHeader := parentBlock . Header ( )
shardState , err := bc . ReadShardState ( parentHeader . Epoch ( ) )
committee := shardState . FindCommitteeByID ( parentHeader . ShardID ( ) )
if err != nil || committee == nil {
if err != nil || committee == nil {
return ctxerror . New ( "[VerifyNewBlock] Failed to read shard state for cross link header " , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
return ctxerror . New ( "[VerifyHeaderWithSignature] Failed to read shard state" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
}
}
var committerKeys [ ] * bls . PublicKey
var committerKeys [ ] * bls . PublicKey
@ -136,34 +131,46 @@ func VerifyBlockLastCommitSigs(bc *BlockChain, block *types.Block) error {
committerKeys = append ( committerKeys , committerKey )
committerKeys = append ( committerKeys , committerKey )
}
}
if ! parseKeysSuccess {
if ! parseKeysSuccess {
return ctxerror . New ( "[VerifyNew Block] cannot convert BLS public key" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
return ctxerror . New ( "[VerifyBlockWithSignature ] cannot convert BLS public key" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
}
}
mask , err := bls2 . NewMask ( committerKeys , nil )
mask , err := bls2 . NewMask ( committerKeys , nil )
if err != nil {
if err != nil {
return ctxerror . New ( "[VerifyNewBlock ] cannot create group sig mask" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
return ctxerror . New ( "[VerifyHeaderWithSignature ] cannot create group sig mask" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
}
}
if err := mask . SetMask ( header . LastC ommitBitmap( ) ) ; err != nil {
if err := mask . SetMask ( c ommitBitmap) ; err != nil {
return ctxerror . New ( "[VerifyNewBlock ] cannot set group sig mask bits" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
return ctxerror . New ( "[VerifyHeaderWithSignature ] cannot set group sig mask bits" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) ) . WithCause ( err )
}
}
aggSig := bls . Sign { }
aggSig := bls . Sign { }
lastCommitSig := header . LastCommitSignature ( )
err = aggSig . Deserialize ( commitSig [ : ] )
err = aggSig . Deserialize ( lastCommitSig [ : ] )
if err != nil {
if err != nil {
return ctxerror . New ( "[VerifyNewBlock] unable to deserialize multi-signature from payload" ) . WithCause ( err )
return ctxerror . New ( "[VerifyNewBlock] unable to deserialize multi-signature from payload" ) . WithCause ( err )
}
}
blockNumBytes := make ( [ ] byte , 8 )
blockNumBytes := make ( [ ] byte , 8 )
binary . LittleEndian . PutUint64 ( blockNumBytes , header . Number ( ) . Uint64 ( ) - 1 )
binary . LittleEndian . PutUint64 ( blockNumBytes , header . Number ( ) . Uint64 ( ) )
parentH ash := header . Parent Hash( )
h ash := header . Hash ( )
commitPayload := append ( blockNumBytes , parentH ash[ : ] ... )
commitPayload := append ( blockNumBytes , h ash[ : ] ... )
if ! aggSig . VerifyHash ( mask . AggregatePublic , commitPayload ) {
if ! aggSig . VerifyHash ( mask . AggregatePublic , commitPayload ) {
return ctxerror . New ( "[VerifyNewBlock ] Failed to verify the signature for last commit sig" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) )
return ctxerror . New ( "[VerifyHeaderWithSignature ] Failed to verify the signature for last commit sig" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) )
}
}
return nil
return nil
}
}
// VerifyBlockLastCommitSigs verifies the last commit sigs of the block
func VerifyBlockLastCommitSigs ( bc * BlockChain , header * block . Header ) error {
parentBlock := bc . GetBlockByNumber ( header . Number ( ) . Uint64 ( ) - 1 )
if parentBlock == nil {
return ctxerror . New ( "[VerifyBlockLastCommitSigs] Failed to get parent block" , "shardID" , header . ShardID ( ) , "blockNum" , header . Number ( ) )
}
parentHeader := parentBlock . Header ( )
lastCommitSig := header . LastCommitSignature ( )
lastCommitBitmap := header . LastCommitBitmap ( )
return VerifyHeaderWithSignature ( bc , parentHeader , lastCommitSig , lastCommitBitmap )
}
// CalcGasLimit computes the gas limit of the next block after parent. It aims
// CalcGasLimit computes the gas limit of the next block after parent. It aims
// to keep the baseline gas above the provided floor, and increase it towards the
// to keep the baseline gas above the provided floor, and increase it towards the
// ceil if the blocks are full. If the ceil is exceeded, it will always decrease
// ceil if the blocks are full. If the ceil is exceeded, it will always decrease