forked from hyperledger/fabric
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SmartBFT consensus support (hyperledger#3781)
* add SMaRtBFT consensus support Signed-off-by: Parameswaran Selvam <[email protected]> * Upgraded smartbft consensus library Signed-off-by: Parameswaran Selvam <[email protected]> * smartbft mock interfaces Signed-off-by: Parameswaran Selvam <[email protected]> * smartbft consensus unit tests Signed-off-by: Yacov Manevich [email protected] Signed-off-by: Yoav Tock [email protected] Signed-off-by: Parameswaran Selvam <[email protected]> * Validate block validation policy matches consenter set Change-Id: Ia0f926ddb984cc3008542328a85d41af56be36d3 Signed-off-by: Yacov Manevich <[email protected]> * bft configtxgen updates Signed-off-by: Parameswaran Selvam <[email protected]> * integration test updates Signed-off-by: Parameswaran Selvam <[email protected]> * update to orderer main with debug statements Signed-off-by: Parameswaran Selvam <[email protected]> * BFT chains are up and running Change-Id: I59bf40ff90be2299aa1733cc672ea88f94984b4f Signed-off-by: Yacov Manevich <[email protected]> * WIP first integration test DO NOT MERGE - the signature verification in the peer has been temporarily disabled Signed-off-by: andrew-coleman <[email protected]> * Only append block signature if needed Change-Id: I13ebe069fe4f8fb9b7a3d4671668a5da85cab8ea Signed-off-by: Yacov Manevich <[email protected]> * Use identifier headers instead of signature headers and properly encode/decode signatures Change-Id: Ifdd7e9a2a690dc6328bfec60ad22efae9a42fa7c Signed-off-by: Yacov Manevich <[email protected]> * integration test for update config transaction Signed-off-by: Parameswaran Selvam <[email protected]> * Properly encode BFT policy when updating consenters Change-Id: I9eb09e2874f4c4fbea77d99aa0528204412c0820 Signed-off-by: Yacov Manevich <[email protected]> * block puller failing while block data identity referencing Signed-off-by: Parameswaran Selvam <[email protected]> * Fix signature verification Change the BlockPuller to use the protoutil.BlockVerifierFunc generator which works for BFT blocks. Signed-off-by: andrew-coleman <[email protected]> * reconfig with node removal failing Signed-off-by: Parameswaran Selvam <[email protected]> * Add “smartbft multiple nodes view change” test Signed-off-by: andrew-coleman <[email protected]> * integration test iteratively add and remove nodes Signed-off-by: Parameswaran Selvam <[email protected]> * updated orderer rejoin integration test scenario Signed-off-by: Parameswaran Selvam <[email protected]> * fixed lint erros and upgrade consensus module Signed-off-by: Parameswaran Selvam <[email protected]> * Fix unit tests Most of the test build failures were due to changing the signature verifier from an interface to a function generated by a HOF. This meant that the mocks in the tests had to be rewritten. There are still some test failures in the smartbft package that I suspect haven’t worked in this version of Fabric. They will be addressed in another commit. Signed-off-by: andrew-coleman <[email protected]> * Fix ConfigTx ConsenterMapping integration test Signed-off-by: andrew-coleman <[email protected]> * Fix raft integration tests The Raft channel_participation integration tests were failing because the new logic in initializeMultichannelRegistrar() for initialising without system channel assumes that the consenter type is BFT unless it is told otherwise in the local config. This commit adds the consenter type to the orderer config template Signed-off-by: andrew-coleman <[email protected]> * Fix linter error Fixes CI failure in BasicChecks phase Signed-off-by: andrew-coleman <[email protected]> * Fix failures in smartbft unit tests Many of these were failing due to comparing error message that contain serialized proto structures. Ideally, these shouldn’t be relied on in tests. Signed-off-by: andrew-coleman <[email protected]> * Add smartbft integration test to CI Signed-off-by: andrew-coleman <[email protected]> * Fix configtx integration test Signed-off-by: andrew-coleman <[email protected]> * Align log expectation in test to actual log printed by the BFT library Signed-off-by: Yacov Manevich <[email protected]> * Fix autonomous synchronization integration test Signed-off-by: Yacov Manevich <[email protected]> * Make smartbft node addition and removal pass Signed-off-by: Yacov Manevich <[email protected]> * code cleanup and updated quorum calculation Signed-off-by: Parameswaran Selvam <[email protected]> * go modules conflict Signed-off-by: Parameswaran Selvam <[email protected]> * Removed commneted code Signed-off-by: Parameswaran Selvam <[email protected]> * addressed first set of review comments Signed-off-by: Parameswaran Selvam <[email protected]> * Updated detectSelfID to use consentermapping ecert Signed-off-by: Parameswaran Selvam <[email protected]> * BFTchain uses new communication service Signed-off-by: Parameswaran Selvam <[email protected]> * Configure ingress at reconfig and include intermediate TLS CA certs Signed-off-by: Yacov Manevich <[email protected]> * Sanitize e-certs in communication mapping and when looking up ids Signed-off-by: Yacov Manevich <[email protected]> * Vendor latest consensus library Signed-off-by: Yacov Manevich <[email protected]> * Fix iterated removal integration test Signed-off-by: Yacov Manevich <[email protected]> * Fix Raft integration tests Signed-off-by: Yacov Manevich <[email protected]> * Verify requests received from followers Signed-off-by: Yacov Manevich <[email protected]> * Remove redundant print Signed-off-by: Yacov Manevich <[email protected]> * Follower detects rogue genesis block, uses BFT signature verification Signed-off-by: Yacov Manevich <[email protected]> * Sanitize certs in UT Signed-off-by: Yacov Manevich <[email protected]> * Fix UT Signed-off-by: Yacov Manevich <[email protected]> * Fix integration test Signed-off-by: Yacov Manevich <[email protected]> * Fix UTs, fix some ITs Signed-off-by: Yacov Manevich <[email protected]> * add err check Signed-off-by: Yacov Manevich <[email protected]> * Rebuild verifier when encountering config block Signed-off-by: Yacov Manevich <[email protected]> * Remove print, elaborate comment Signed-off-by: Yacov Manevich <[email protected]> * Resolve module conflicts and rebase on top of main Signed-off-by: Yacov Manevich <[email protected]> --------- Signed-off-by: Parameswaran Selvam <[email protected]> Signed-off-by: Yacov Manevich [email protected] Signed-off-by: Yoav Tock [email protected] Signed-off-by: Yacov Manevich <[email protected]> Signed-off-by: andrew-coleman <[email protected]> Signed-off-by: Yacov Manevich <[email protected]> Co-authored-by: Yacov Manevich <[email protected]> Co-authored-by: andrew-coleman <[email protected]> Co-authored-by: Yacov Manevich <[email protected]>
- Loading branch information
1 parent
969040c
commit cf9030b
Showing
167 changed files
with
20,304 additions
and
1,036 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package crypto | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"crypto/x509" | ||
"crypto/x509/pkix" | ||
"encoding/asn1" | ||
"encoding/pem" | ||
"math/big" | ||
"time" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger/fabric-protos-go/msp" | ||
"github.com/hyperledger/fabric/bccsp/utils" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// SanitizeIdentity sanitizes the signature scheme of the identity | ||
func SanitizeIdentity(identity []byte) ([]byte, error) { | ||
sID := &msp.SerializedIdentity{} | ||
if err := proto.Unmarshal(identity, sID); err != nil { | ||
return nil, errors.Wrapf(err, "failed unmarshaling identity %s", string(identity)) | ||
} | ||
|
||
finalPEM, err := SanitizeX509Cert(sID.IdBytes) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
sID.IdBytes = finalPEM | ||
|
||
return proto.Marshal(sID) | ||
} | ||
|
||
func SanitizeX509Cert(initialPEM []byte) ([]byte, error) { | ||
der, _ := pem.Decode(initialPEM) | ||
if der == nil { | ||
return nil, errors.Errorf("failed to PEM decode identity bytes: %s", string(initialPEM)) | ||
} | ||
cert, err := x509.ParseCertificate(der.Bytes) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed parsing certificate %s", string(initialPEM)) | ||
} | ||
|
||
r, s, err := utils.UnmarshalECDSASignature(cert.Signature) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed unmarshaling ECDSA signature on identity: %s", string(initialPEM)) | ||
} | ||
|
||
// We assume that the consenter and the CA use the same signature scheme. | ||
curveOrderUsedByCryptoGen := cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().N | ||
halfOrder := new(big.Int).Rsh(curveOrderUsedByCryptoGen, 1) | ||
// Low S, nothing to do here! | ||
if s.Cmp(halfOrder) != 1 { | ||
return initialPEM, nil | ||
} | ||
// Else it's high-S, so shift it below half the order. | ||
s.Sub(curveOrderUsedByCryptoGen, s) | ||
|
||
var newCert certificate | ||
_, err = asn1.Unmarshal(cert.Raw, &newCert) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed unmarshaling certificate") | ||
} | ||
|
||
newSig, err := utils.MarshalECDSASignature(r, s) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed marshaling ECDSA signature") | ||
} | ||
newCert.SignatureValue = asn1.BitString{Bytes: newSig, BitLength: len(newSig) * 8} | ||
|
||
newCert.Raw = nil | ||
newRaw, err := asn1.Marshal(newCert) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "failed marshaling new certificate") | ||
} | ||
|
||
finalPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: newRaw}) | ||
return finalPEM, nil | ||
} | ||
|
||
type certificate struct { | ||
Raw asn1.RawContent | ||
TBSCertificate tbsCertificate | ||
SignatureAlgorithm pkix.AlgorithmIdentifier | ||
SignatureValue asn1.BitString | ||
} | ||
|
||
type tbsCertificate struct { | ||
Raw asn1.RawContent | ||
Version int `asn1:"optional,explicit,default:0,tag:0"` | ||
SerialNumber *big.Int | ||
SignatureAlgorithm pkix.AlgorithmIdentifier | ||
Issuer asn1.RawValue | ||
Validity validity | ||
Subject asn1.RawValue | ||
PublicKey publicKeyInfo | ||
UniqueId asn1.BitString `asn1:"optional,tag:1"` | ||
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"` | ||
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"` | ||
} | ||
|
||
type validity struct { | ||
NotBefore, NotAfter time.Time | ||
} | ||
|
||
type publicKeyInfo struct { | ||
Raw asn1.RawContent | ||
Algorithm pkix.AlgorithmIdentifier | ||
PublicKey asn1.BitString | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package policies | ||
|
||
import ( | ||
"math" | ||
|
||
cb "github.com/hyperledger/fabric-protos-go/common" | ||
mspa "github.com/hyperledger/fabric-protos-go/msp" | ||
"github.com/hyperledger/fabric/common/policydsl" | ||
"github.com/hyperledger/fabric/protoutil" | ||
) | ||
|
||
const ( | ||
BlockValidationPolicyKey = "BlockValidation" | ||
) | ||
|
||
func EncodeBFTBlockVerificationPolicy(consenterProtos []*cb.Consenter, ordererGroup *cb.ConfigGroup) { | ||
n := len(consenterProtos) | ||
f := (n - 1) / 3 | ||
|
||
var identities []*mspa.MSPPrincipal | ||
var pols []*cb.SignaturePolicy | ||
for i, consenter := range consenterProtos { | ||
pols = append(pols, &cb.SignaturePolicy{ | ||
Type: &cb.SignaturePolicy_SignedBy{ | ||
SignedBy: int32(i), | ||
}, | ||
}) | ||
identities = append(identities, &mspa.MSPPrincipal{ | ||
PrincipalClassification: mspa.MSPPrincipal_IDENTITY, | ||
Principal: protoutil.MarshalOrPanic(&mspa.SerializedIdentity{Mspid: consenter.MspId, IdBytes: consenter.Identity}), | ||
}) | ||
} | ||
|
||
quorumSize := ComputeBFTQuorum(n, f) | ||
sp := &cb.SignaturePolicyEnvelope{ | ||
Rule: policydsl.NOutOf(int32(quorumSize), pols), | ||
Identities: identities, | ||
} | ||
ordererGroup.Policies[BlockValidationPolicyKey] = &cb.ConfigPolicy{ | ||
// Inherit modification policy | ||
ModPolicy: ordererGroup.Policies[BlockValidationPolicyKey].ModPolicy, | ||
Policy: &cb.Policy{ | ||
Type: int32(cb.Policy_SIGNATURE), | ||
Value: protoutil.MarshalOrPanic(sp), | ||
}, | ||
} | ||
} | ||
|
||
func ComputeBFTQuorum(totalNodes, faultyNodes int) int { | ||
return int(math.Ceil(float64(totalNodes+faultyNodes+1) / 2)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.