Skip to content

Commit

Permalink
fix nonce race conditions and threshold check
Browse files Browse the repository at this point in the history
  • Loading branch information
himanshu committed Jan 23, 2024
1 parent f6f9afc commit 360cbe8
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 148 deletions.
15 changes: 8 additions & 7 deletions src/helpers/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ export const normalizeKeysResult = (result: VerifierLookupResponse) => {
is_new_key: result.is_new_key,
};
if (result && result.keys && result.keys.length > 0) {
finalResult.keys = result.keys.map((key) => {
return {
pub_key_X: key.pub_key_X,
pub_key_Y: key.pub_key_Y,
address: key.address,
};
});
const finalKey = result.keys[0];
finalResult.keys = [
{
pub_key_X: finalKey.pub_key_X,
pub_key_Y: finalKey.pub_key_Y,
address: finalKey.address,
},
];
}
return finalResult;
};
Expand Down
39 changes: 22 additions & 17 deletions src/helpers/nodeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,6 @@ export const GetPubKeyOrKeyAssign = async (params: {
const result = await Some<void | JRPCResponse<VerifierLookupResponse>, KeyLookupResult>(lookupPromises, (lookupResults) => {
const lookupPubKeys = lookupResults.filter((x1) => {
if (x1 && !x1.error) {
if (!nonceResult) {
// currently only one node returns metadata nonce
// other nodes returns empty object
// pubNonce must be available to derive the public key
const pubNonceX = (x1.result?.keys[0].nonce_data as v2NonceResultType)?.pubNonce?.x;
if (pubNonceX) {
nonceResult = x1.result.keys[0].nonce_data;
}
}
return x1;
}
return false;
Expand All @@ -83,8 +74,7 @@ export const GetPubKeyOrKeyAssign = async (params: {
~~(endpoints.length / 2) + 1
);

// nonceResult must exist except for extendedVerifierId and legacy networks along with keyResult
if ((keyResult && (nonceResult || extendedVerifierId || LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE])) || errorResult) {
if (keyResult || errorResult) {
if (keyResult) {
lookupResults.forEach((x1) => {
if (x1 && x1.result) {
Expand All @@ -96,6 +86,16 @@ export const GetPubKeyOrKeyAssign = async (params: {
const nodeIndex = parseInt(x1.result.node_index);
if (nodeIndex) nodeIndexes.push(nodeIndex);
}
// check for nonce result in response if not a extendedVerifierId and not a legacy network
if (!extendedVerifierId && !LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE] && !nonceResult) {
// currently only one node returns metadata nonce
// other nodes returns empty object
// pubNonce must be available to derive the public key
const pubNonceX = (x1.result?.keys[0].nonce_data as v2NonceResultType)?.pubNonce?.x;
if (pubNonceX && currentNodePubKey === thresholdPubKey) {
nonceResult = x1.result.keys[0].nonce_data;
}
}
}
});
}
Expand Down Expand Up @@ -321,12 +321,6 @@ export async function retrieveOrImportShare(params: {
});
const pubkeys = shareResponses.map((x) => {
if (x && x.result && x.result.keys[0].public_key) {
if (!thresholdNonceData && !verifierParams.extended_verifier_id) {
const pubNonce = (x.result.keys[0].nonce_data as v2NonceResultType)?.pubNonce?.x;
if (pubNonce) {
thresholdNonceData = x.result.keys[0].nonce_data;
}
}
return x.result.keys[0].public_key;
}
return undefined;
Expand All @@ -338,6 +332,17 @@ export async function retrieveOrImportShare(params: {
throw new Error("invalid result from nodes, threshold number of public key results are not matching");
}

shareResponses.forEach((x) => {
const requiredShareResponse = x && x.result && x.result.keys[0].public_key && x.result.keys[0];
if (requiredShareResponse && !thresholdNonceData && !verifierParams.extended_verifier_id) {
const currentPubKey = requiredShareResponse.public_key;
const pubNonce = (requiredShareResponse.nonce_data as v2NonceResultType)?.pubNonce?.x;
if (pubNonce && currentPubKey.X === thresholdPublicKey.X) {
thresholdNonceData = requiredShareResponse.nonce_data;
}
}
});

// if both thresholdNonceData and extended_verifier_id are not available
// then we need to throw other wise address would be incorrect.
if (!thresholdNonceData && !verifierParams.extended_verifier_id && !LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) {
Expand Down
54 changes: 30 additions & 24 deletions test/aqua.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,26 @@ describe("torus utils aqua", function () {
const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL };
const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails);
const result1 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey;
expect(result1.finalKeyData.evmAddress).to.equal("0x79F06350eF34Aeed4BE68e26954D405D573f1438");
expect(result1.metadata.typeOfUser).to.equal("v1");
expect(result1.metadata.typeOfUser).to.equal("v2");
expect(result1).eql({
oAuthKeyData: {
evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d",
X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d",
Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c",
},
finalKeyData: {
evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d",
X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d",
Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c",
evmAddress: "0x79F06350eF34Aeed4BE68e26954D405D573f1438",
X: "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3",
Y: "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16",
},
metadata: {
pubNonce: undefined,
pubNonce: {
X: "dc5a031fd2e0b55dbaece314ea125bac9da5f0a916bf156ff36b5ad71380ea32",
Y: "affd749b98c209d2f9cf4dacb145d7897f82f1e2924a47b07874302ecc0b8ef1",
},
nonce: new BN(0),
upgraded: false,
typeOfUser: "v1",
typeOfUser: "v2",
},
nodesData: result1.nodesData,
});
Expand All @@ -84,24 +86,26 @@ describe("torus utils aqua", function () {
verifier: v2Verifier,
verifierId: v2TestEmail,
})) as TorusPublicKey;
expect(result2.finalKeyData.evmAddress).to.equal("0x5735dDC8d5125B23d77C3531aab3895A533584a3");
expect(result2.metadata.typeOfUser).to.equal("v1");
expect(result2.metadata.typeOfUser).to.equal("v2");
expect(result2).eql({
oAuthKeyData: {
evmAddress: "0x5735dDC8d5125B23d77C3531aab3895A533584a3",
X: "e1b419bc52b82e14b148c307f10479cfa464d20c947555fb4758c586eab12873",
Y: "75f47d7d5a271c0fcf51a790c1683a1cb3394b1d37d20e29c346ac249e3bfca2",
evmAddress: "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828",
X: "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337",
Y: "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d",
},
finalKeyData: {
evmAddress: "0x5735dDC8d5125B23d77C3531aab3895A533584a3",
X: "e1b419bc52b82e14b148c307f10479cfa464d20c947555fb4758c586eab12873",
Y: "75f47d7d5a271c0fcf51a790c1683a1cb3394b1d37d20e29c346ac249e3bfca2",
evmAddress: "0xBc32f315515AdE7010cabC5Fd68c966657A570BD",
X: "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022",
Y: "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968",
},
metadata: {
pubNonce: undefined,
pubNonce: {
X: "1601cf4dc4362b219260663d5ec5119699fbca185d08b7acb2e36cad914340d5",
Y: "c2f7871f61ee71b4486ac9fb40ec759099800e737139dc5dfaaaed8c9d77c3c1",
},
nonce: new BN(0),
upgraded: false,
typeOfUser: "v1",
typeOfUser: "v2",
},
nodesData: result2.nodesData,
});
Expand All @@ -112,24 +116,26 @@ describe("torus utils aqua", function () {
verifier: v2Verifier,
verifierId: v2nTestEmail,
})) as TorusPublicKey;
expect(result3.finalKeyData.evmAddress).to.equal("0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD");
expect(result3.metadata.typeOfUser).to.equal("v1");
expect(result3.metadata.typeOfUser).to.equal("v2");
expect(result3).eql({
oAuthKeyData: {
evmAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD",
X: "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281",
Y: "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f",
},
finalKeyData: {
evmAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD",
X: "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281",
Y: "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f",
evmAddress: "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D",
X: "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539",
Y: "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21",
},
metadata: {
pubNonce: undefined,
pubNonce: {
X: "17b1ebce1fa874452a96d0c6d74c1445b78f16957c7decc5d2a202b0ce4662f5",
Y: "b5432cb593753e1b3ecf98b05dc03e57bc02c415e1b80a1ffc5a401ec1f0abd6",
},
nonce: new BN(0),
upgraded: false,
typeOfUser: "v1",
typeOfUser: "v2",
},
nodesData: result3.nodesData,
});
Expand Down
17 changes: 10 additions & 7 deletions test/cyan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,27 @@ describe("torus utils cyan", function () {
const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL };
const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails);
const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails);
expect(result1.finalKeyData.evmAddress).to.equal("0xA3767911A84bE6907f26C572bc89426dDdDB2825");
expect(result1.metadata.typeOfUser).to.equal("v1");
expect(result1.finalKeyData.evmAddress).to.equal("0x3507F0d192a44E436B8a6C32a37d57D022861b1a");
expect(result1.metadata.typeOfUser).to.equal("v2");
expect(result1).eql({
oAuthKeyData: {
evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825",
X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a",
Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1",
},
finalKeyData: {
evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825",
X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a",
Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1",
evmAddress: "0x3507F0d192a44E436B8a6C32a37d57D022861b1a",
X: "8aaadab9530cb157d0b0dfb7b27d1a3aaca45274563c22c92c77ee2191779051",
Y: "d57b89d9f62bb6609d8542c3057943805c8c72f6f27d39781b820f27d7210f12",
},
metadata: {
pubNonce: undefined,
pubNonce: {
X: "5f2505155e2c1119ee8a76d0f3b22fccee45871d4aab3cb6209bdbc302b5abc2",
Y: "a20f30868759a6095697d5631483faa650f489b33c0e2958ad8dc29e707c0a99",
},
nonce: new BN(0),
upgraded: false,
typeOfUser: "v1",
typeOfUser: "v2",
},
nodesData: result1.nodesData,
});
Expand Down
35 changes: 18 additions & 17 deletions test/mainnet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,26 @@ describe("torus utils mainnet", function () {
const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL };
const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails);
const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails);
expect(result1.finalKeyData.evmAddress).to.equal("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A");
expect(result1.metadata.typeOfUser).to.equal("v1");
expect(result1.metadata.typeOfUser).to.equal("v2");
expect(result1).eql({
oAuthKeyData: {
evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A",
X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4",
Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1",
},
finalKeyData: {
evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A",
X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4",
Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1",
evmAddress: "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E",
X: "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55",
Y: "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5",
},
metadata: {
pubNonce: undefined,
pubNonce: {
X: "eb22d93244acf7fcbeb6566da722bc9c8e5433cd28da25ca0650d9cb32806c39",
Y: "765541e214f067cfc44dcf41e582ae09b71c2e607a301cc8a45e1f316a6ba91c",
},
nonce: new BN(0),
upgraded: false,
typeOfUser: "v1",
typeOfUser: "v2",
},
nodesData: result1.nodesData,
});
Expand Down Expand Up @@ -115,24 +117,26 @@ describe("torus utils mainnet", function () {
verifier: v2Verifier,
verifierId: v2nTestEmail,
});
expect(result3.finalKeyData.evmAddress).to.equal("0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53");
expect(result3.metadata.typeOfUser).to.equal("v1");
expect(result3.metadata.typeOfUser).to.equal("v2");
expect(result3).eql({
oAuthKeyData: {
evmAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53",
X: "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8",
Y: "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7",
},
finalKeyData: {
evmAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53",
X: "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8",
Y: "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7",
evmAddress: "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD",
X: "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc",
Y: "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff",
},
metadata: {
pubNonce: undefined,
pubNonce: {
X: "16214bf232167258fb5f98fa9d84968ffec3236aaf0994fc366940c4bc07a5b1",
Y: "475e8c09d2cc8f6c12a767f51c052b1bf8e8d3a2a2b6818d4b199dc283e80ac4",
},
nonce: new BN(0),
upgraded: false,
typeOfUser: "v1",
typeOfUser: "v2",
},
nodesData: result3.nodesData,
});
Expand All @@ -159,9 +163,6 @@ describe("torus utils mainnet", function () {
const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL };
const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails);
const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token);
expect(result.oAuthKeyData.evmAddress).to.be.equal("0x90A926b698047b4A87265ba1E9D8b512E8489067");
expect(result.finalKeyData.privKey).to.be.equal("0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44");
expect(result.finalKeyData.evmAddress).to.be.equal("0x90A926b698047b4A87265ba1E9D8b512E8489067");
delete result.sessionData;

expect(result).eql({
Expand Down
Loading

0 comments on commit 360cbe8

Please sign in to comment.