Skip to content

Commit af579a3

Browse files
authored
Convert ECDSA Public Keys to EVM Addresses when building voters' merkle tree (#721)
* cargo fmt * flake.lock: Update Flake lock file updates: • Updated input 'flake-utils': 'github:numtide/flake-utils/cfacdce06f30d2b68473a46042957675eebb3401' (2023-04-11) → 'github:numtide/flake-utils/ff7b65b44d01cf9ba6a71320833626af21126384' (2023-09-12) • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb' (2023-05-01) → 'github:NixOS/nixpkgs/2646b294a146df2781b1ca49092450e8a32814e1' (2023-10-08) • Updated input 'rust-overlay': 'github:oxalica/rust-overlay/07f421299826591e2b28e03bbbe19a5292395afe' (2023-05-02) → 'github:oxalica/rust-overlay/c0df7f2a856b5ff27a3ce314f6d7aacf5fda546f' (2023-10-09) * Convert ECDSA Public Keys to EVM Addresses when building the merkle tree * pump runtime version * Update types * Pump pallet versions
1 parent ea2659e commit af579a3

File tree

21 files changed

+480
-426
lines changed

21 files changed

+480
-426
lines changed

Cargo.lock

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pallets/dkg-metadata/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "pallet-dkg-metadata"
33
description = "FRAME pallet for DKG metadata"
4-
version = "0.1.0"
4+
version = "0.2.0"
55
authors = { workspace = true }
66
license = { workspace = true }
77
publish = { workspace = true }
@@ -37,6 +37,7 @@ sp-core = { workspace = true }
3737
sp-io = { workspace = true }
3838
sp-staking = { workspace = true }
3939
sp-keystore = { workspace = true }
40+
k256 = { version = "0.11.5", default-features = false, features = ["arithmetic", "ecdsa"] }
4041

4142
[features]
4243
default = ["std"]

pallets/dkg-metadata/src/lib.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,12 @@ use weights::WeightInfo;
144144
// Reputation assigned to genesis authorities
145145
pub const INITIAL_REPUTATION: u32 = 1_000_000_000;
146146

147-
// Our goal is to trigger the ShouldExecuteNewKeygen to true if we have passed exactly X blocks from the last session rotation
148-
// and still have not seen a new key, this value cannot be too small either because we need to accomodate delays between `keygen
149-
// process starting + completion + posted onchain`. If the delay is smaller than the above then we might inadvertently rotate
147+
// Our goal is to trigger the ShouldExecuteNewKeygen to true if we have passed exactly X blocks from
148+
// the last session rotation and still have not seen a new key, this value cannot be too small
149+
// either because we need to accomodate delays between `keygen process starting + completion +
150+
// posted onchain`. If the delay is smaller than the above then we might inadvertently rotate
150151
// sessions.
151-
pub const BLOCKS_TO_WAIT_BEFORE_KEYGEN_RETRY_TRIGGER : u32 = 20;
152+
pub const BLOCKS_TO_WAIT_BEFORE_KEYGEN_RETRY_TRIGGER: u32 = 20;
152153

153154
// Reputation increase awarded to authorities on submission of next public key
154155
pub const REPUTATION_INCREMENT: u32 = INITIAL_REPUTATION / 1000;
@@ -210,6 +211,13 @@ pub mod pallet {
210211
+ Into<ecdsa::Public>
211212
+ From<ecdsa::Public>
212213
+ MaxEncodedLen;
214+
/// Convert DKG AuthorityId to a form that would end up in the Merkle Tree.
215+
///
216+
/// For instance for ECDSA (secp256k1) we want to store uncompressed public keys (65 bytes)
217+
/// and later to Ethereum Addresses (160 bits) to simplify using them on Ethereum chain,
218+
/// but the rest of the Substrate codebase is storing them compressed (33 bytes) for
219+
/// efficiency reasons.
220+
type DKGAuthorityToMerkleLeaf: Convert<Self::DKGId, Vec<u8>>;
213221
/// Jail lengths for misbehaviours
214222
type KeygenJailSentence: Get<BlockNumberFor<Self>>;
215223
type SigningJailSentence: Get<BlockNumberFor<Self>>;
@@ -409,12 +417,15 @@ pub mod pallet {
409417

410418
// Our goal is to trigger the ShouldExecuteNewKeygen if either of the two conditions are
411419
// true : 1. A SessionPeriod of blocks have passed from the LastSessionRotationBlock
412-
// 2. If 1 is true and we have not yet seen NextKey on chain for the last BLOCKS_TO_WAIT_BEFORE_KEYGEN_RETRY_TRIGGER blocks
413-
// check if we have passed exactly `Period` blocks from the last session rotation
420+
// 2. If 1 is true and we have not yet seen NextKey on chain for the last
421+
// BLOCKS_TO_WAIT_BEFORE_KEYGEN_RETRY_TRIGGER blocks check if we have passed exactly
422+
// `Period` blocks from the last session rotation
414423
let blocks_passed_since_last_session_rotation =
415424
n - LastSessionRotationBlock::<T>::get();
416425
if blocks_passed_since_last_session_rotation >= T::SessionPeriod::get() &&
417-
blocks_passed_since_last_session_rotation % BLOCKS_TO_WAIT_BEFORE_KEYGEN_RETRY_TRIGGER.into() == 0u32.into()
426+
blocks_passed_since_last_session_rotation %
427+
BLOCKS_TO_WAIT_BEFORE_KEYGEN_RETRY_TRIGGER.into() ==
428+
0u32.into()
418429
{
419430
// lets set the ShouldStartDKG to true
420431
// we dont set force_keygen to true, that is reserved for emergency rotate
@@ -1633,7 +1644,7 @@ impl<T: Config> Pallet<T> {
16331644
// Hash the external accounts into 32 byte chunks to form the base layer of the merkle tree
16341645
let mut base_layer: Vec<[u8; 32]> = voters
16351646
.iter()
1636-
.map(|account| account.to_raw_vec())
1647+
.map(|account| T::DKGAuthorityToMerkleLeaf::convert(account.clone()))
16371648
.map(|account| keccak_256(&account))
16381649
.collect();
16391650
// Pad base_layer to have length 2^height

pallets/dkg-metadata/src/mock.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ use sp_runtime::{
2929
impl_opaque_keys,
3030
testing::TestXt,
3131
traits::{
32-
BlakeTwo256, ConvertInto, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup,
33-
OpaqueKeys, Verify,
32+
BlakeTwo256, Convert, ConvertInto, Extrinsic as ExtrinsicT, IdentifyAccount,
33+
IdentityLookup, OpaqueKeys, Verify,
3434
},
3535
BuildStorage, Percent, Permill,
3636
};
@@ -141,6 +141,7 @@ parameter_types! {
141141

142142
impl pallet_dkg_metadata::Config for Test {
143143
type DKGId = DKGId;
144+
type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereumAddress;
144145
type RuntimeEvent = RuntimeEvent;
145146
type OnAuthoritySetChangeHandler = ();
146147
type OnDKGPublicKeyChangeHandler = ();
@@ -254,3 +255,23 @@ pub fn new_test_ext_raw_authorities(authorities: Vec<(AccountId, DKGId)>) -> Tes
254255
ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr));
255256
ext
256257
}
258+
259+
/// Convert DKG secp256k1 public keys into Ethereum addresses
260+
pub struct DKGEcdsaToEthereumAddress;
261+
impl Convert<dkg_runtime_primitives::crypto::AuthorityId, Vec<u8>> for DKGEcdsaToEthereumAddress {
262+
fn convert(a: dkg_runtime_primitives::crypto::AuthorityId) -> Vec<u8> {
263+
use k256::{ecdsa::VerifyingKey, elliptic_curve::sec1::ToEncodedPoint};
264+
let _x = VerifyingKey::from_sec1_bytes(sp_core::crypto::ByteArray::as_slice(&a));
265+
VerifyingKey::from_sec1_bytes(sp_core::crypto::ByteArray::as_slice(&a))
266+
.map(|pub_key| {
267+
// uncompress the key
268+
let uncompressed = pub_key.to_encoded_point(false);
269+
// convert to ETH address
270+
sp_io::hashing::keccak_256(&uncompressed.as_bytes()[1..])[12..].to_vec()
271+
})
272+
.map_err(|_| {
273+
log::error!(target: "runtime::dkg_proposals", "Invalid DKG PublicKey format!");
274+
})
275+
.unwrap_or_default()
276+
}
277+
}

pallets/dkg-proposal-handler/src/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ parameter_types! {
287287
impl pallet_dkg_metadata::Config for Test {
288288
type DKGId = DKGId;
289289
type RuntimeEvent = RuntimeEvent;
290+
type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereumAddress;
290291
type OnAuthoritySetChangeHandler = ();
291292
type OnDKGPublicKeyChangeHandler = ();
292293
type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId;

pallets/dkg-proposals/src/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ parameter_types! {
168168

169169
impl pallet_dkg_metadata::Config for Test {
170170
type DKGId = DKGId;
171+
type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereumAddress;
171172
type RuntimeEvent = RuntimeEvent;
172173
type OnAuthoritySetChangeHandler = DKGProposals;
173174
type OnDKGPublicKeyChangeHandler = ();

standalone/node/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "dkg-standalone-node"
3-
version = "3.0.0"
3+
version = "3.1.0"
44
build = "build.rs"
55
description = { workspace = true }
66
authors = { workspace = true }

standalone/runtime/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "dkg-standalone-runtime"
3-
version = "3.0.0"
3+
version = "3.1.0"
44
description = { workspace = true }
55
authors = { workspace = true }
66
license = { workspace = true }

standalone/runtime/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
140140
spec_name: create_runtime_str!("dkg-standalone-node"),
141141
impl_name: create_runtime_str!("dkg-standalone-node"),
142142
authoring_version: 1,
143-
spec_version: 19,
143+
spec_version: 20,
144144
impl_version: 0,
145145
apis: RUNTIME_API_VERSIONS,
146146
transaction_version: 1,
@@ -607,6 +607,7 @@ parameter_types! {
607607

608608
impl pallet_dkg_metadata::Config for Runtime {
609609
type DKGId = DKGId;
610+
type DKGAuthorityToMerkleLeaf = pallet_dkg_proposals::DKGEcdsaToEthereumAddress;
610611
type RuntimeEvent = RuntimeEvent;
611612
type OnAuthoritySetChangeHandler = DKGProposals;
612613
type OnDKGPublicKeyChangeHandler = ();

types/package.json

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,67 @@
11
{
2-
"name": "@webb-tools/dkg-substrate-types",
3-
"version": "0.0.6",
4-
"description": "Polkadot.js type definitions required for interacting with Webb's DKG protocol",
5-
"main": "./build/index.js",
6-
"author": "Webb Developers <drew@webb.tools>",
7-
"license": "Apache-2.0",
8-
"type": "commonjs",
9-
"publishConfig": {
10-
"access": "public",
11-
"registry": "https://registry.npmjs.org"
12-
},
13-
"repository": "https://github.com/webb-tools/dkg-substrate.git",
14-
"bugs": {
15-
"url": "https://github.com/webb-tools/dkg-substrate/issues"
16-
},
17-
"homepage": "https://github.com/webb-tools/dkg-substrate",
18-
"dependencies": {
19-
"@babel/cli": "^7.20.7",
20-
"@babel/core": "^7.20.12",
21-
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
22-
"@babel/plugin-proposal-numeric-separator": "^7.18.6",
23-
"@babel/plugin-proposal-optional-chaining": "^7.20.7",
24-
"@babel/plugin-syntax-bigint": "^7.8.3",
25-
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
26-
"@babel/plugin-syntax-import-assertions": "^7.20.0",
27-
"@babel/plugin-syntax-import-meta": "^7.10.4",
28-
"@babel/plugin-syntax-top-level-await": "^7.14.5",
29-
"@babel/plugin-transform-regenerator": "^7.20.5",
30-
"@babel/plugin-transform-runtime": "^7.19.6",
31-
"@babel/preset-env": "^7.20.2",
32-
"@babel/preset-react": "^7.18.6",
33-
"@babel/preset-typescript": "^7.18.6",
34-
"@babel/register": "^7.18.9",
35-
"@babel/runtime": "^7.20.13",
36-
"babel-jest": "^29.4.1",
37-
"babel-plugin-module-extension-resolver": "^1.0.0",
38-
"babel-plugin-module-resolver": "^5.0.0",
39-
"babel-plugin-styled-components": "^2.0.7",
40-
"@open-web3/orml-types": "^1.1.3",
41-
"@polkadot/api-derive": "10.4.1",
42-
"@polkadot/dev": "^0.72.42",
43-
"@polkadot/typegen": "10.4.1",
44-
"@polkadot/types": "10.4.1",
45-
"fs-extra": "^11.1.1",
46-
"glob2base": "^0.0.12",
47-
"minimatch": "^7.4.2",
48-
"mkdirp": "^2.1.5"
49-
},
50-
"devDependencies": {
51-
"@types/websocket": "^1.0.0",
52-
"rimraf": "3.0.2",
53-
"ts-node": "10.9.1",
54-
"tsconfig-paths": "^4.2.0",
55-
"typescript": "5.0.4",
56-
"websocket": "^1.0.31"
57-
},
58-
"scripts": {
59-
"build": "node ./scripts/build.js",
60-
"build:interfaces": "yarn build:interfaces:defs && yarn build:interfaces:chain && rm ./src/interfaces/index.ts && rm ./src/interfaces/types.ts",
61-
"build:interfaces:defs": "npx ts-node node_modules/.bin/polkadot-types-from-defs --input ./src/interfaces --package @webb-tools/dkg-substrate-types --endpoint ./src/metadata/metadata.json",
62-
"build:interfaces:chain": "npx ts-node node_modules/.bin/polkadot-types-from-chain --endpoint ./src/metadata/metadata.json --output ./src/interfaces",
63-
"clean": "rm -rf build && rm -rf ts-types",
64-
"publish-types": "node ./scripts/publish-types.js",
65-
"update:metadata": "npx ts-node ./scripts/updateMetadata.ts"
66-
}
2+
"name": "@webb-tools/dkg-substrate-types",
3+
"version": "0.0.7",
4+
"description": "Polkadot.js type definitions required for interacting with Webb's DKG protocol",
5+
"main": "./build/index.js",
6+
"author": "Webb Developers <drew@webb.tools>",
7+
"license": "Apache-2.0",
8+
"type": "commonjs",
9+
"publishConfig": {
10+
"access": "public",
11+
"registry": "https://registry.npmjs.org"
12+
},
13+
"repository": "https://github.com/webb-tools/dkg-substrate.git",
14+
"bugs": {
15+
"url": "https://github.com/webb-tools/dkg-substrate/issues"
16+
},
17+
"homepage": "https://github.com/webb-tools/dkg-substrate",
18+
"dependencies": {
19+
"@babel/cli": "^7.20.7",
20+
"@babel/core": "^7.20.12",
21+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
22+
"@babel/plugin-proposal-numeric-separator": "^7.18.6",
23+
"@babel/plugin-proposal-optional-chaining": "^7.20.7",
24+
"@babel/plugin-syntax-bigint": "^7.8.3",
25+
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
26+
"@babel/plugin-syntax-import-assertions": "^7.20.0",
27+
"@babel/plugin-syntax-import-meta": "^7.10.4",
28+
"@babel/plugin-syntax-top-level-await": "^7.14.5",
29+
"@babel/plugin-transform-regenerator": "^7.20.5",
30+
"@babel/plugin-transform-runtime": "^7.19.6",
31+
"@babel/preset-env": "^7.20.2",
32+
"@babel/preset-react": "^7.18.6",
33+
"@babel/preset-typescript": "^7.18.6",
34+
"@babel/register": "^7.18.9",
35+
"@babel/runtime": "^7.20.13",
36+
"babel-jest": "^29.4.1",
37+
"babel-plugin-module-extension-resolver": "^1.0.0",
38+
"babel-plugin-module-resolver": "^5.0.0",
39+
"babel-plugin-styled-components": "^2.0.7",
40+
"@open-web3/orml-types": "^1.1.3",
41+
"@polkadot/api-derive": "10.4.1",
42+
"@polkadot/dev": "^0.72.42",
43+
"@polkadot/typegen": "10.4.1",
44+
"@polkadot/types": "10.4.1",
45+
"fs-extra": "^11.1.1",
46+
"glob2base": "^0.0.12",
47+
"minimatch": "^7.4.2",
48+
"mkdirp": "^2.1.5"
49+
},
50+
"devDependencies": {
51+
"@types/websocket": "^1.0.0",
52+
"rimraf": "3.0.2",
53+
"ts-node": "10.9.1",
54+
"tsconfig-paths": "^4.2.0",
55+
"typescript": "5.0.4",
56+
"websocket": "^1.0.31"
57+
},
58+
"scripts": {
59+
"build": "node ./scripts/build.js",
60+
"build:interfaces": "yarn build:interfaces:defs && yarn build:interfaces:chain && rm ./src/interfaces/index.ts && rm ./src/interfaces/types.ts",
61+
"build:interfaces:defs": "npx ts-node node_modules/.bin/polkadot-types-from-defs --input ./src/interfaces --package @webb-tools/dkg-substrate-types --endpoint ./src/metadata/metadata.json",
62+
"build:interfaces:chain": "npx ts-node node_modules/.bin/polkadot-types-from-chain --endpoint ./src/metadata/metadata.json --output ./src/interfaces",
63+
"clean": "rm -rf build && rm -rf ts-types",
64+
"publish-types": "node ./scripts/publish-types.js",
65+
"update:metadata": "npx ts-node ./scripts/updateMetadata.ts"
66+
}
6767
}

types/src/interfaces/augment-api-consts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { ApiTypes, AugmentedConst } from '@polkadot/api-base/types';
99
import type { Vec, u128, u16, u32, u64, u8 } from '@polkadot/types-codec';
1010
import type { Codec } from '@polkadot/types-codec/types';
1111
import type { Perbill } from '@polkadot/types/interfaces/runtime';
12+
import { WebbProposalsHeaderTypedChainId, SpWeightsWeightV2Weight, FrameSupportPalletId, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, SpWeightsRuntimeDbWeight, SpVersionRuntimeVersion } from '@polkadot/types/lookup';
1213

1314
export type __AugmentedConst<ApiType extends ApiTypes> = AugmentedConst<ApiType>;
1415

0 commit comments

Comments
 (0)