Skip to content

Commit 7918210

Browse files
authored
feat: parse generic keys in 'register' and 'upsert-permissioned-candidates
1 parent 4c6c109 commit 7918210

File tree

6 files changed

+98
-35
lines changed

6 files changed

+98
-35
lines changed

dev/local-environment/configurations/partner-chains-setup/entrypoint.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ node2_aura_vkey=$(cat /partner-chains-nodes/partner-chains-node-2/keys/aura.vkey
9191
node2_grandpa_vkey=$(cat /partner-chains-nodes/partner-chains-node-2/keys/grandpa.vkey)
9292

9393
cat <<EOF > permissioned_candidates.csv
94-
$node1_sidechain_vkey:$node1_aura_vkey:$node1_grandpa_vkey
95-
$node2_sidechain_vkey:$node2_aura_vkey:$node2_grandpa_vkey
94+
$node1_sidechain_vkey,aura:$node1_aura_vkey,gran:$node1_grandpa_vkey
95+
$node2_sidechain_vkey,aura:$node2_aura_vkey,gran:$node2_grandpa_vkey
9696
EOF
9797

9898
./partner-chains-node smart-contracts upsert-permissioned-candidates \
@@ -136,7 +136,7 @@ node4_grandpa_vkey=$(cat /partner-chains-nodes/partner-chains-node-4/keys/grandp
136136
--genesis-utxo $GENESIS_UTXO \
137137
--spo-public-key $node4_spo_public_key \
138138
--spo-signature $node4_spo_signature \
139-
--sidechain-public-keys $node4_sidechain_public_key:$node4_aura_vkey:$node4_grandpa_vkey \
139+
--partner-chain-public-keys $node4_sidechain_public_key,aura:$node4_aura_vkey,gran:$node4_grandpa_vkey \
140140
--sidechain-signature $node4_sidechain_signature \
141141
--registration-utxo $node4_utxo \
142142
--payment-key-file /partner-chains-nodes/partner-chains-node-4/keys/payment.skey
@@ -176,7 +176,7 @@ node5_grandpa_vkey=$(cat /partner-chains-nodes/partner-chains-node-5/keys/grandp
176176
--genesis-utxo $GENESIS_UTXO \
177177
--spo-public-key $node5_spo_public_key \
178178
--spo-signature $node5_spo_signature \
179-
--sidechain-public-keys $node5_sidechain_public_key:$node5_aura_vkey:$node5_grandpa_vkey \
179+
--partner-chain-public-keys $node5_sidechain_public_key,aura:$node5_aura_vkey,gran:$node5_grandpa_vkey \
180180
--sidechain-signature $node5_sidechain_signature \
181181
--registration-utxo $node5_utxo \
182182
--payment-key-file /partner-chains-nodes/partner-chains-node-5/keys/payment.skey

toolkit/partner-chains-cli/src/register/mod.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use partner_chains_cardano_offchain::register::run_register;
77
use plutus_datum_derive::ToDatum;
88
use secp256k1::PublicKey;
99
use sidechain_domain::*;
10-
use sp_runtime::KeyTypeId;
1110
use std::{convert::Infallible, fmt::Display, str::FromStr};
1211

1312
use crate::cmd_traits::Register;
@@ -64,16 +63,7 @@ impl FromStr for CandidateKeyParam {
6463
type Err = Box<dyn std::error::Error + Send + Sync>;
6564

6665
fn from_str(s: &str) -> Result<Self, Self::Err> {
67-
let parts: Vec<_> = s.split(":").collect();
68-
if parts.len() != 2 {
69-
return Err("Incorrect format, expected: <key type>:<key hex>".into());
70-
}
71-
72-
let key_type = KeyTypeId::try_from(parts[0])
73-
.map_err(|_| format!("{} is not a correct key type", parts[0]))?;
74-
let key = hex::decode(parts[1].strip_prefix("0x").unwrap_or(parts[1]))?;
75-
76-
Ok(Self(CandidateKey::new(key_type, key)))
66+
Ok(Self(CandidateKey::from_str(s)?))
7767
}
7868
}
7969

toolkit/sidechain/domain/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,21 @@ pub struct CandidateKey {
11721172
pub bytes: Vec<u8>,
11731173
}
11741174

1175+
impl FromStr for CandidateKey {
1176+
type Err = &'static str;
1177+
1178+
fn from_str(s: &str) -> Result<Self, Self::Err> {
1179+
if let Some((id, bytes)) = s.split_once(':') {
1180+
let id: [u8; 4] = id.as_bytes().try_into().map_err(|_| "invalid key type id")?;
1181+
let bytes = bytes.trim_start_matches("0x");
1182+
let bytes = hex::decode(bytes).map_err(|_| "key bytes are not in hex format")?;
1183+
Ok(CandidateKey { id, bytes })
1184+
} else {
1185+
Err("invalid format of CandidateKey, expected '<key type>:<key>'")
1186+
}
1187+
}
1188+
}
1189+
11751190
/// Key type id of Partner Chains cross-chain key, used with ECDSA cryptography
11761191
pub const CROSS_CHAIN_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"crch");
11771192

toolkit/smart-contracts/commands/src/lib.rs

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use partner_chains_cardano_offchain::{
3131
};
3232
use serde::Serialize;
3333
use sidechain_domain::*;
34-
use std::time::Duration;
34+
use std::{str::FromStr, time::Duration};
3535

3636
pub mod assemble_tx;
3737
pub mod d_parameter;
@@ -181,23 +181,54 @@ impl From<GenesisUtxo> for UtxoId {
181181
}
182182
}
183183

184-
// Parses public keys in formatted as SIDECHAIN_KEY:AURA_KEY:GRANDPA_KEY
184+
/// Parses public keys formatted as PARTNER_CHAINS_KEY:AURA_KEY:GRANDPA_KEY or PARTNER_CHAINS_KEY,KEY_ID_1:KEY_1,...,KEY_ID_N:KEY_N
185185
pub(crate) fn parse_partnerchain_public_keys(
186186
partner_chain_public_keys: &str,
187187
) -> CmdResult<PermissionedCandidateData> {
188-
let partner_chain_public_keys = partner_chain_public_keys.replace("0x", "");
189-
if let [sidechain_pub_key, aura_pub_key, grandpa_pub_key] =
190-
partner_chain_public_keys.split(":").collect::<Vec<_>>()[..]
191-
{
192-
Ok(PermissionedCandidateData {
193-
sidechain_public_key: SidechainPublicKey(hex::decode(sidechain_pub_key)?),
194-
keys: CandidateKeys(vec![
195-
AuraPublicKey(hex::decode(aura_pub_key)?).into(),
196-
GrandpaPublicKey(hex::decode(grandpa_pub_key)?).into(),
197-
]),
198-
})
188+
fn is_legacy_format(line: &str) -> bool {
189+
line.contains(':') && !line.contains(',')
190+
}
191+
192+
fn parse_legacy_format(line: &str) -> CmdResult<PermissionedCandidateData> {
193+
let line = line.replace("0x", "");
194+
if let [sidechain_pub_key, aura_pub_key, grandpa_pub_key] =
195+
line.split(":").collect::<Vec<_>>()[..]
196+
{
197+
Ok(PermissionedCandidateData {
198+
sidechain_public_key: SidechainPublicKey(hex::decode(sidechain_pub_key)?),
199+
keys: CandidateKeys(vec![
200+
AuraPublicKey(hex::decode(aura_pub_key)?).into(),
201+
GrandpaPublicKey(hex::decode(grandpa_pub_key)?).into(),
202+
]),
203+
})
204+
} else {
205+
Err(format!("Failed to parse partner chain public keys (legacy) from '{line}'").into())
206+
}
207+
}
208+
209+
fn parse_generic_format(line: &str) -> CmdResult<PermissionedCandidateData> {
210+
let mut columns = line.split(",");
211+
if let Some(partner_chains_key) = columns.next() {
212+
let partner_chains_key =
213+
SidechainPublicKey(hex::decode(partner_chains_key.trim_start_matches("0x"))?);
214+
let mut keys = vec![];
215+
for column in columns {
216+
let key = CandidateKey::from_str(column)?;
217+
keys.push(key);
218+
}
219+
Ok(PermissionedCandidateData {
220+
sidechain_public_key: partner_chains_key,
221+
keys: CandidateKeys(keys),
222+
})
223+
} else {
224+
Err("Failed to parse partner chain public keys (generic) from '{line}'.".into())
225+
}
226+
}
227+
228+
if is_legacy_format(&partner_chain_public_keys) {
229+
parse_legacy_format(&partner_chain_public_keys)
199230
} else {
200-
Err("Failed to parse partner chain public keys.".into())
231+
parse_generic_format(&partner_chain_public_keys)
201232
}
202233
}
203234

@@ -206,22 +237,49 @@ mod test {
206237
use crate::parse_partnerchain_public_keys;
207238
use hex_literal::hex;
208239
use sidechain_domain::{
209-
AuraPublicKey, CandidateKeys, GrandpaPublicKey, PermissionedCandidateData,
240+
AuraPublicKey, CandidateKey, CandidateKeys, GrandpaPublicKey, PermissionedCandidateData,
210241
SidechainPublicKey,
211242
};
212243

213244
#[test]
214-
fn parse_partnerchain_public_keys_with_0x_prefix() {
245+
fn parse_partnerchain_public_keys_legacy_format_without_0x_prefix() {
215246
let input = "039799ff93d184146deacaa455dade51b13ed16f23cdad11d1ad6af20103391180:e85534c93315d60f808568d1dce5cb9e8ba6ed0b204209c5cc8f3bec56c10b73:cdf3e5b33f53c8b541bbaea383225c45654f24de38c585725f3cff25b2802f55";
216247
assert_eq!(parse_partnerchain_public_keys(input).unwrap(), expected_public_keys())
217248
}
218249

219250
#[test]
220-
fn parse_partnerchain_public_keys_without_0x_prefix() {
251+
fn parse_partnerchain_public_keys_legacy_format_with_0x_prefix() {
221252
let input = "0x039799ff93d184146deacaa455dade51b13ed16f23cdad11d1ad6af20103391180:0xe85534c93315d60f808568d1dce5cb9e8ba6ed0b204209c5cc8f3bec56c10b73:0xcdf3e5b33f53c8b541bbaea383225c45654f24de38c585725f3cff25b2802f55";
222253
assert_eq!(parse_partnerchain_public_keys(input).unwrap(), expected_public_keys())
223254
}
224255

256+
#[test]
257+
fn parse_partnerchain_public_keys_generic_format_without_0x_prefix() {
258+
let input = "039799ff93d184146deacaa455dade51b13ed16f23cdad11d1ad6af20103391180,aura:e85534c93315d60f808568d1dce5cb9e8ba6ed0b204209c5cc8f3bec56c10b73,gran:cdf3e5b33f53c8b541bbaea383225c45654f24de38c585725f3cff25b2802f55";
259+
assert_eq!(parse_partnerchain_public_keys(input).unwrap(), expected_public_keys())
260+
}
261+
262+
#[test]
263+
fn parse_partnerchain_public_keys_generic_format_with_0x_prefix() {
264+
let input = "0x039799ff93d184146deacaa455dade51b13ed16f23cdad11d1ad6af20103391180,aura:0xe85534c93315d60f808568d1dce5cb9e8ba6ed0b204209c5cc8f3bec56c10b73,gran:0xcdf3e5b33f53c8b541bbaea383225c45654f24de38c585725f3cff25b2802f55";
265+
assert_eq!(parse_partnerchain_public_keys(input).unwrap(), expected_public_keys())
266+
}
267+
268+
#[test]
269+
fn key_id_can_contain_0x() {
270+
let input = "0x0102,0xxd:0xffff";
271+
assert_eq!(
272+
parse_partnerchain_public_keys(input).unwrap(),
273+
PermissionedCandidateData {
274+
sidechain_public_key: SidechainPublicKey([1, 2].to_vec()),
275+
keys: CandidateKeys(vec![CandidateKey {
276+
id: *b"0xxd",
277+
bytes: [255, 255].to_vec()
278+
}])
279+
}
280+
)
281+
}
282+
225283
fn expected_public_keys() -> PermissionedCandidateData {
226284
PermissionedCandidateData {
227285
sidechain_public_key: SidechainPublicKey(

toolkit/smart-contracts/commands/src/permissioned_candidates.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ pub struct UpsertPermissionedCandidatesCmd {
99
common_arguments: crate::CommonArguments,
1010
#[arg(long)]
1111
/// Path to the file containing the permissioned candidates data.
12-
/// Each line represents one permissioned candidate in format SIDECHAIN_KEY:AURA_KEY:GRANDPA_KEY
12+
/// Each line represents one permissioned candidate in format PARTNER_CHAINS_KEY,KEY_1_ID:KEY_1_BYTES,...,KEY_N_ID:KEY_N_BYTES.
13+
/// Legacy format of PARTNER_CHAINS_KEY:AURA_PUB_KEY:GRANDPA_PUB_KEY is supported, each line is eqivalent to `PARTNER_CHAINS_KEY,aura:AURA_PUB_KEY,gran:GRANDPA_PUB_KEY`.
1314
permissioned_candidates_file: String,
1415
#[clap(flatten)]
1516
/// Path to the payment key file

toolkit/smart-contracts/commands/src/register.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@ pub struct RegisterCmd {
2424
payment_key_file: PaymentFilePath,
2525
#[arg(
2626
long,
27-
value_name = "PARTNERCHAIN_KEY:AURA_KEY:GRANDPA_KEY",
2827
alias = "sidechain-public-keys",
2928
value_parser = parse_partnerchain_public_keys
3029
)]
31-
/// Colon separated hex strings representing bytes of the Sidechain, Aura and Grandpa public keys
30+
/// Candidate public keys in format PARTNER_CHAINS_KEY_HEX:AURA_KEY_HEX:GRANDPA_KEY_HEX or PARTNER_CHAINS_KEY_HEX,KEY_ID_1:KEY_1_HEX,...,KEY_ID_N:KEY_N_HEX
3231
partner_chain_public_keys: PermissionedCandidateData,
3332
#[arg(long, alias = "sidechain-signature")]
3433
/// Hex string of bytes of the registration message signature by partner-chain key, obtained by 'registration-signatures' command

0 commit comments

Comments
 (0)