Merge pull request #1640 from chaosma/cross-fix

fix cross shard verification error
pull/1642/head
chaosma 5 years ago committed by GitHub
commit f585afe808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      consensus/engine/consensus_engine.go
  2. 2
      core/block_validator.go
  3. 24
      internal/chain/engine.go

@ -56,7 +56,8 @@ type Engine interface {
// is used for verifying "incoming" block header against commit signature and bitmap sent from the other chain cross-shard via libp2p. // is used for verifying "incoming" block header against commit signature and bitmap sent from the other chain cross-shard via libp2p.
// i.e. this header verification api is more flexible since the caller specifies which commit signature and bitmap to use // i.e. this header verification api is more flexible since the caller specifies which commit signature and bitmap to use
// for verifying the block header, which is necessary for cross-shard block header verification. Example of such is cross-shard transaction. // for verifying the block header, which is necessary for cross-shard block header verification. Example of such is cross-shard transaction.
VerifyHeaderWithSignature(chain ChainReader, header *block.Header, commitSig []byte, commitBitmap []byte) error // (TODO) For now, when doing cross shard, we need recalcualte the shard state since we don't have shard state of other shards
VerifyHeaderWithSignature(chain ChainReader, header *block.Header, commitSig []byte, commitBitmap []byte, reCalculate bool) error
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
// concurrently. The method returns a quit channel to abort the operations and // concurrently. The method returns a quit channel to abort the operations and

@ -225,5 +225,5 @@ func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) err
} }
// (4) verify blockHeader with seal // (4) verify blockHeader with seal
return v.engine.VerifyHeaderWithSignature(v.bc, cxp.Header, cxp.CommitSig, cxp.CommitBitmap) return v.engine.VerifyHeaderWithSignature(v.bc, cxp.Header, cxp.CommitSig, cxp.CommitBitmap, true)
} }

@ -11,10 +11,12 @@ import (
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core"
"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"
"github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard"
) )
type engineImpl struct{} type engineImpl struct{}
@ -103,7 +105,7 @@ func (e *engineImpl) VerifyHeaders(chain engine.ChainReader, headers []*block.He
// ReadPublicKeysFromLastBlock finds the public keys of last block's committee // ReadPublicKeysFromLastBlock finds the public keys of last block's committee
func ReadPublicKeysFromLastBlock(bc engine.ChainReader, header *block.Header) ([]*bls.PublicKey, error) { func ReadPublicKeysFromLastBlock(bc engine.ChainReader, header *block.Header) ([]*bls.PublicKey, error) {
parentHeader := bc.GetHeaderByHash(header.ParentHash()) parentHeader := bc.GetHeaderByHash(header.ParentHash())
return GetPublicKeys(bc, parentHeader) return GetPublicKeys(bc, parentHeader, false)
} }
// VerifySeal implements Engine, checking whether the given block's parent block satisfies // VerifySeal implements Engine, checking whether the given block's parent block satisfies
@ -176,8 +178,8 @@ func QuorumForBlock(chain engine.ChainReader, h *block.Header) (quorum int, err
// is used for verifying "incoming" block header against commit signature and bitmap sent from the other chain cross-shard via libp2p. // is used for verifying "incoming" block header against commit signature and bitmap sent from the other chain cross-shard via libp2p.
// i.e. this header verification api is more flexible since the caller specifies which commit signature and bitmap to use // i.e. this header verification api is more flexible since the caller specifies which commit signature and bitmap to use
// for verifying the block header, which is necessary for cross-shard block header verification. Example of such is cross-shard transaction. // for verifying the block header, which is necessary for cross-shard block header verification. Example of such is cross-shard transaction.
func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header *block.Header, commitSig []byte, commitBitmap []byte) error { func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header *block.Header, commitSig []byte, commitBitmap []byte, reCalculate bool) error {
publicKeys, err := GetPublicKeys(chain, header) publicKeys, err := GetPublicKeys(chain, header, reCalculate)
if err != nil { if err != nil {
return ctxerror.New("[VerifyHeaderWithSignature] Cannot get publickeys for block header").WithCause(err) return ctxerror.New("[VerifyHeaderWithSignature] Cannot get publickeys for block header").WithCause(err)
} }
@ -210,11 +212,17 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
} }
// GetPublicKeys finds the public keys of the committee that signed the block header // GetPublicKeys finds the public keys of the committee that signed the block header
func GetPublicKeys(chain engine.ChainReader, header *block.Header) ([]*bls.PublicKey, error) { func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate bool) ([]*bls.PublicKey, error) {
shardState, err := chain.ReadShardState(header.Epoch()) var shardState shard.State
if err != nil { var err error
return nil, ctxerror.New("failed to read shard state of epoch", if reCalculate {
"epoch", header.Epoch().Uint64()) shardState = core.CalculateShardState(header.Epoch())
} else {
shardState, err = chain.ReadShardState(header.Epoch())
if err != nil {
return nil, ctxerror.New("failed to read shard state of epoch",
"epoch", header.Epoch().Uint64())
}
} }
committee := shardState.FindCommitteeByID(header.ShardID()) committee := shardState.FindCommitteeByID(header.ShardID())

Loading…
Cancel
Save