Skip to content

Commit

Permalink
fixed an error after deleting a node when it participated in block si…
Browse files Browse the repository at this point in the history
…gning immediately before deletion

Signed-off-by: Fedor Partanskiy <fredprtnsk@gmail.com>
  • Loading branch information
pfi79 committed Oct 11, 2024
1 parent 1e9c269 commit d7c45ac
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 12 deletions.
43 changes: 35 additions & 8 deletions orderer/consensus/smartbft/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import (
"sync/atomic"

"github.com/hyperledger-labs/SmartBFT/pkg/types"
"github.com/hyperledger/fabric-lib-go/bccsp"
"github.com/hyperledger/fabric-lib-go/common/flogging"
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
"github.com/hyperledger/fabric/common/channelconfig"
"github.com/hyperledger/fabric/orderer/common/cluster"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
)

//go:generate mockery -dir . -name Ledger -case underscore -output mocks
Expand Down Expand Up @@ -138,28 +141,52 @@ func lastConfigBlockFromLedger(ledger Ledger) (*cb.Block, error) {
return lastConfigBlock, nil
}

func PreviousConfigBlockFromLedgerOrPanic(ledger Ledger, logger Logger) *cb.Block {
block, err := previousConfigBlockFromLedger(ledger)
func PreviousLastConfigBlockFromLedgerOrPanic(ledger Ledger, bccsp bccsp.BCCSP, logger Logger) *cb.Block {
block, err := previousLastConfigBlockFromLedger(ledger, bccsp)
if err != nil {
logger.Panicf("Failed retrieving previous config block: %v", err)
}
return block
}

func previousConfigBlockFromLedger(ledger Ledger) (*cb.Block, error) {
previousBlockSeq := ledger.Height() - 2
if ledger.Height() == 1 {
previousBlockSeq = 0
func previousLastConfigBlockFromLedger(ledger Ledger, bccsp bccsp.BCCSP) (*cb.Block, error) {
block, err := lastConfigBlockFromLedger(ledger)
if err != nil {
return nil, err
}
if block.Header.Number == 0 {
return nil, nil
}

previousBlockSeq := block.Header.Number - 1
previousBlock := ledger.Block(previousBlockSeq)
if previousBlock == nil {
return nil, errors.Errorf("unable to retrieve block [%d]", previousBlockSeq)
}
previousConfigBlock, err := cluster.LastConfigBlock(previousBlock, ledger)
previousLastConfigBlock, err := cluster.LastConfigBlock(previousBlock, ledger)
if err != nil {
return nil, err
}
return previousConfigBlock, nil

env := &cb.Envelope{}
if err = proto.Unmarshal(previousLastConfigBlock.Data.Data[0], env); err != nil {
return nil, errors.Wrap(err, "failed unmarshaling envelope of config block")
}
bundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)
if err != nil {
return nil, errors.Wrap(err, "failed getting a new bundle from envelope of config block")
}

oc, ok := bundle.OrdererConfig()
if !ok {
return nil, errors.New("no orderer config in config block")
}

if oc.ConsensusType() != "BFT" {
return nil, nil
}

return previousLastConfigBlock, nil
}

// LastBlockFromLedgerOrPanic returns the last block from the ledger
Expand Down
10 changes: 9 additions & 1 deletion orderer/consensus/smartbft/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,20 @@ func NewChain(

lastBlock := LastBlockFromLedgerOrPanic(support, c.Logger)
lastConfigBlock := LastConfigBlockFromLedgerOrPanic(support, c.Logger)
previousLastConfigBlock := PreviousLastConfigBlockFromLedgerOrPanic(support, bccsp, c.Logger)

var err error
rtc := RuntimeConfig{
logger: logger,
id: selfID,
}
rtc, err := rtc.BlockCommitted(lastConfigBlock, bccsp)
if previousLastConfigBlock != nil {
rtc, err = rtc.BlockCommitted(previousLastConfigBlock, bccsp)
if err != nil {
return nil, errors.Wrap(err, "failed constructing RuntimeConfig")
}
}
rtc, err = rtc.BlockCommitted(lastConfigBlock, bccsp)
if err != nil {
return nil, errors.Wrap(err, "failed constructing RuntimeConfig")
}
Expand Down
3 changes: 3 additions & 0 deletions orderer/consensus/smartbft/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type RuntimeConfig struct {
LastCommittedBlockHash string
RemoteNodes []cluster.RemoteNode
ID2Identities NodeIdentitiesByID
ID2IdentitiesPrev NodeIdentitiesByID
LastBlock *cb.Block
LastConfigBlock *cb.Block
Nodes []uint64
Expand All @@ -65,6 +66,7 @@ func (rtc RuntimeConfig) BlockCommitted(block *cb.Block, bccsp bccsp.BCCSP) (Run
LastCommittedBlockHash: hex.EncodeToString(protoutil.BlockHeaderHash(block.Header)),
Nodes: rtc.Nodes,
ID2Identities: rtc.ID2Identities,
ID2IdentitiesPrev: rtc.ID2IdentitiesPrev,
RemoteNodes: rtc.RemoteNodes,
LastBlock: block,
LastConfigBlock: rtc.LastConfigBlock,
Expand All @@ -91,6 +93,7 @@ func (rtc RuntimeConfig) configBlockCommitted(block *cb.Block, bccsp bccsp.BCCSP
LastCommittedBlockHash: hex.EncodeToString(protoutil.BlockHeaderHash(block.Header)),
Nodes: nodeConf.nodeIDs,
ID2Identities: nodeConf.id2Identities,
ID2IdentitiesPrev: rtc.ID2Identities,
RemoteNodes: nodeConf.remoteNodes,
LastBlock: block,
LastConfigBlock: block,
Expand Down
26 changes: 23 additions & 3 deletions orderer/consensus/smartbft/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package smartbft

import (
"bytes"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"fmt"
Expand Down Expand Up @@ -209,11 +210,30 @@ func (v *Verifier) verifyRequest(rawRequest []byte, noConfigAllowed bool) (types

// VerifyConsenterSig verifies consenter signature
func (v *Verifier) VerifyConsenterSig(signature types.Signature, prop types.Proposal) ([]byte, error) {
id2Identity := v.RuntimeConfig.Load().(RuntimeConfig).ID2Identities
rtc := v.RuntimeConfig.Load().(RuntimeConfig)

identity, exists := id2Identity[signature.ID]
var (
identity []byte
exists bool
)
identity, exists = rtc.ID2Identities[signature.ID]
if !exists {
return nil, errors.Errorf("node with id of %d doesn't exist", signature.ID)
if len(prop.Header) == 0 {
return nil, errors.New("proposal header cannot be nil")
}
hdr := &asn1Header{}
if _, err := asn1.Unmarshal(prop.Header, hdr); err != nil {
return nil, errors.Wrap(err, "bad header")
}
numBlockProp := hdr.Number.Uint64()
if numBlockProp <= rtc.LastBlock.GetHeader().GetNumber() {
identity, exists = rtc.ID2IdentitiesPrev[signature.ID]
if !exists {
return nil, errors.Errorf("node with id of %d doesn't exist", signature.ID)
}
} else {
return nil, errors.Errorf("node with id of %d doesn't exist", signature.ID)
}
}

sig := &Signature{}
Expand Down

0 comments on commit d7c45ac

Please sign in to comment.