Skip to content

Commit

Permalink
Avoid MVCC_READ_CONFLICT when adding public keys (#77)
Browse files Browse the repository at this point in the history
* Avoid MVCC_READ_CONFLICT when adding public keys

Signed-off-by: Denis Glotov <[email protected]>

* Update Fabric contract with foreign keys simultaneously

Signed-off-by: Denis Glotov <[email protected]>
  • Loading branch information
denis-yu-glotov authored and petermetz committed Dec 5, 2019
1 parent e6e9981 commit eaa5a37
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ var logger = shim.NewLogger("mycc")
type MyChaincode struct {
}

const pubKeyPrefix = "pubKey:"

// Init is the function to be called when the chaincode is instantiated
func (t *MyChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
Expand Down Expand Up @@ -55,16 +57,6 @@ func (t *MyChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
}
}

func readPubKeysMap(stub shim.ChaincodeStubInterface) (map[string]string, error) {
pubKeysMap := make(map[string]string)
pubKeysBytes, err := stub.GetState("pubs")
if err == nil {
err = json.Unmarshal(pubKeysBytes, &pubKeysMap)
return pubKeysMap, nil
}
return pubKeysMap, err
}

func parsePubKey(pubKey string, verify bool) ([]byte, error) {
if len(pubKey) != 66 {
return nil, errors.New("Public key ie expected in compressed format - 66 hex digits")
Expand Down Expand Up @@ -98,21 +90,14 @@ func (t *MyChaincode) addPubKey(stub shim.ChaincodeStubInterface, args []string)
return shim.Error(err.Error())
}

pubKeysMap, err := readPubKeysMap(stub)
if err != nil {
return shim.Error("Public key storage is broken")
}
pubKeysMap[pubKey] = name

// Put the asset to the blockchain KVS
pubKeysBytes, _ := json.Marshal(pubKeysMap)
logger.Infof("%s\n", pubKeysBytes)
err = stub.PutState("pubs", pubKeysBytes)
err = stub.PutState(pubKeyPrefix+pubKey, []byte(name))
if err != nil {
return shim.Error("Failed to write asset to the blockchain")
}
logger.Infof("public key named '%s' added: %s.\n", name, pubKey)

return shim.Success(pubKeysBytes)
return shim.Success([]byte(name))
}

func getKey(assetID string) string {
Expand Down Expand Up @@ -148,13 +133,12 @@ func (t *MyChaincode) verifyInt(stub shim.ChaincodeStubInterface, args []string)
var numGood int = 0
results := make([]bool, len(args)/2)
msg := args[0]
pubKeysMap, _ := readPubKeysMap(stub)

for i := 0; i < len(args)/2; i++ {
pubkey := args[1+i*2]
signature := args[2+i*2]
_, ok := pubKeysMap[pubkey]
results[i] = ok && t.verifyOne(msg, pubkey, signature)
_, err := stub.GetState(pubKeyPrefix + pubkey)
results[i] = (err == nil) && t.verifyOne(msg, pubkey, signature)
if results[i] {
numGood += 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,56 +18,47 @@ const connectorFabric = new ConnectorFabric(conf.blockchains.fabric);
const noCorda = process.argv.indexOf('nocorda') > -1;

// Step.1: Ask for Corda public keys
let cordaPubKeys;
let cordaPubKeys = [];
if (!noCorda) {
const askForCordaPubKeyRequests = conf.federations.corda.map(endpoint => Client.askForPubKey(endpoint));
cordaPubKeys = await Promise.all(askForCordaPubKeyRequests);
logger.info(`Foreign Public Keys has been received`, { cordaPubKeys });
}

// Step.2: Ask for Quorum public keys
let quorumPubKeys;
let quorumPubKeys = [];
if (!noQuorum) {
const askForQuorumPubKeyRequests = conf.federations.quorum.map(endpoint => Client.askForPubKey(endpoint));
quorumPubKeys = await Promise.all(askForQuorumPubKeyRequests);
logger.info(`Foreign Public Keys has been received`, { quorumPubKeys });
}

// Step.3: Ask for Fabric public keys
let fabricPubKeys;
let fabricPubKeys = [];
if (!noFabric) {
const askForFabricPubKeyRequests = conf.federations.fabric.map(endpoint => Client.askForPubKey(endpoint));
fabricPubKeys = await Promise.all(askForFabricPubKeyRequests);
logger.info(`Foreign Public Keys has been received`, { fabricPubKeys });
}

// Step.4 Add Corda + Quorum public keys to Fabric network
if (!noCorda && !noFabric) {
const cordaValForFabric = await cordaPubKeys.reduce(
(acc, currentKey, index) =>
acc.then(() => connectorFabric.addForeignValidator(currentKey, `corda_validator_${index + 1}`)),
Promise.resolve()
);
logger.info(`Corda Validators has been added to Fabric successfully`, { cordaValForFabric });
}
if (!noQuorum && !noFabric) {
const quorumValForFabric = await quorumPubKeys.reduce(
(acc, currentKey, index) =>
acc.then(() => connectorFabric.addForeignValidator(currentKey, `quorum_validator_${index + 1}`)),
Promise.resolve()
);
logger.info(`Quorum Validators has been added to Fabric successfully`, { quorumValForFabric });
if (!noFabric) {
const otherKeys = quorumPubKeys.concat(cordaPubKeys);
const quorumValForFabric = await Promise.all(quorumPubKeys.map(
(currentKey, index) =>
connectorFabric.addForeignValidator(currentKey, `quorum_validator_${index + 1}`)
));
logger.info(`Corda and Quorum Validators has been added to Fabric successfully`, { quorumValForFabric });
}

// Step.5 Add Fabric + Quorum public keys to Corda network
if (!noQuorum && !noCorda) {
if (!noCorda) {
const addQuorumValToCordaRequests = await quorumPubKeys.map((key, index) =>
connectorCorda.addForeignValidator(key, `quorum_validator_${index + 1}`)
);
const quorumValForCorda = await Promise.all(addQuorumValToCordaRequests);
logger.info(`Foreign Validators has been added to Corda successfully`, { quorumValForCorda });
}
if (!noFabric && !noCorda) {

const addFabricValToCordaRequests = await fabricPubKeys.map((key, index) =>
connectorCorda.addForeignValidator(key, `fabric_validator_${index + 1}`)
);
Expand All @@ -76,14 +67,13 @@ const connectorFabric = new ConnectorFabric(conf.blockchains.fabric);
}

// Step.6 Add Corda + Fabric pubic keys to Quorum network
if (!noCorda && !noQuorum) {
if (!noQuorum) {
const addCordaValToQuorumRequests = cordaPubKeys.map((key, index) =>
connectorQuorum.addForeignValidator(key, `corda_validator_${index + 1}`)
);
const cordaValForQuorum = await Promise.all(addCordaValToQuorumRequests);
logger.info(`Foreign Validators has been added to Quorum successfully`, { cordaValForQuorum });
}
if (!noFabric && !noQuorum) {

const addFabricValToQuorumRequests = fabricPubKeys.map((key, index) =>
connectorQuorum.addForeignValidator(key, `fabric_validator_${index + 1}`)
);
Expand Down

0 comments on commit eaa5a37

Please sign in to comment.