Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Re-arrange Chains traits for better composability #3912

Merged
merged 7 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::{anyhow, bail, Context, Result};
use async_trait::async_trait;
use cf_chains::{
address::EncodedAddress,
eth::{to_ethereum_address, Address as EthereumAddress},
evm::{to_evm_address, Address as EthereumAddress},
CcmChannelMetadata, ForeignChain,
};
use cf_primitives::{AccountRole, Asset, BasisPoints, ChannelId};
Expand Down Expand Up @@ -434,7 +434,7 @@ pub fn generate_ethereum_key(
secret_key: secret_key.serialize().to_vec(),
public_key: public_key.serialize_compressed().to_vec(),
},
to_ethereum_address(public_key),
to_evm_address(public_key),
))
}

Expand Down
2 changes: 1 addition & 1 deletion engine/multisig/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ pub trait ECPoint:
pub trait ChainSigning: 'static + Clone + Send + Sync + Debug + PartialEq {
type CryptoScheme: CryptoScheme;

type Chain: cf_chains::ChainCrypto;
type ChainCrypto: cf_chains::ChainCrypto;

/// Name of the Chain
const NAME: &'static str;
Expand Down
10 changes: 6 additions & 4 deletions engine/multisig/src/crypto/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{
};
use crate::crypto::ECScalar;
use anyhow::Context;
use cf_chains::Bitcoin;
use cf_chains::{Bitcoin, Chain, ChainCrypto};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};

Expand Down Expand Up @@ -32,8 +32,10 @@ impl BtcSchnorrSignature {
}
}

impl SignatureToThresholdSignature<Bitcoin> for Vec<BtcSchnorrSignature> {
fn to_threshold_signature(&self) -> <Bitcoin as cf_chains::ChainCrypto>::ThresholdSignature {
impl SignatureToThresholdSignature<<Bitcoin as Chain>::ChainCrypto> for Vec<BtcSchnorrSignature> {
fn to_threshold_signature(
&self,
) -> <<Bitcoin as Chain>::ChainCrypto as ChainCrypto>::ThresholdSignature {
self.iter().map(|s| s.to_raw()).collect()
}
}
Expand Down Expand Up @@ -62,7 +64,7 @@ pub struct BtcCryptoScheme;

impl ChainSigning for BtcSigning {
type CryptoScheme = BtcCryptoScheme;
type Chain = cf_chains::Bitcoin;
type ChainCrypto = <Bitcoin as Chain>::ChainCrypto;
const NAME: &'static str = "Bitcoin";
const CHAIN_TAG: ChainTag = ChainTag::Bitcoin;

Expand Down
3 changes: 2 additions & 1 deletion engine/multisig/src/crypto/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::{
curve25519::edwards::Point, CanonicalEncoding, ChainSigning, ChainTag, CryptoScheme, CryptoTag,
ECPoint,
};
use cf_chains::Chain;
use ed25519_consensus::VerificationKeyBytes;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -49,7 +50,7 @@ pub struct Ed25519CryptoScheme;
impl ChainSigning for Ed25519Signing {
type CryptoScheme = Ed25519CryptoScheme;
// This scheme isn't implemented on the state chain.
type Chain = cf_chains::none::NoneChain;
type ChainCrypto = <cf_chains::none::NoneChain as Chain>::ChainCrypto;

const NAME: &'static str = "Ed25519";

Expand Down
18 changes: 10 additions & 8 deletions engine/multisig/src/crypto/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::{
// solely use "CryptoScheme" as generic parameter instead.
pub use super::secp256k1::{Point, Scalar};
use anyhow::Context;
use cf_chains::{eth::ParityBit, ChainCrypto, Ethereum};
use cf_chains::{evm::ParityBit, Chain, ChainCrypto, Ethereum};
use num_bigint::BigUint;
use secp256k1::constants::CURVE_ORDER;
use serde::{Deserialize, Serialize};
Expand All @@ -23,14 +23,16 @@ pub struct EthSchnorrSignature {
pub r: secp256k1::PublicKey,
}

impl From<EthSchnorrSignature> for cf_chains::eth::SchnorrVerificationComponents {
impl From<EthSchnorrSignature> for cf_chains::evm::SchnorrVerificationComponents {
fn from(cfe_sig: EthSchnorrSignature) -> Self {
Self { s: cfe_sig.s, k_times_g_address: pubkey_to_eth_addr(cfe_sig.r) }
}
}

impl SignatureToThresholdSignature<Ethereum> for Vec<EthSchnorrSignature> {
fn to_threshold_signature(&self) -> <Ethereum as ChainCrypto>::ThresholdSignature {
impl SignatureToThresholdSignature<<Ethereum as Chain>::ChainCrypto> for Vec<EthSchnorrSignature> {
fn to_threshold_signature(
&self,
) -> <<Ethereum as Chain>::ChainCrypto as ChainCrypto>::ThresholdSignature {
self.iter()
.map(|s| s.clone().into())
.next()
Expand Down Expand Up @@ -62,14 +64,14 @@ pub struct EvmCryptoScheme;

impl ChainSigning for EthSigning {
type CryptoScheme = EvmCryptoScheme;
type Chain = cf_chains::Ethereum;
type ChainCrypto = <Ethereum as Chain>::ChainCrypto;
const NAME: &'static str = "Ethereum";
const CHAIN_TAG: ChainTag = ChainTag::Ethereum;
}
impl CryptoScheme for EvmCryptoScheme {
type Point = Point;
type Signature = EthSchnorrSignature;
type PublicKey = cf_chains::eth::AggKey;
type PublicKey = cf_chains::evm::AggKey;
type SigningPayload = SigningPayload;
const CRYPTO_TAG: CryptoTag = CryptoTag::Evm;
const NAME: &'static str = "Evm Crypto";
Expand All @@ -84,7 +86,7 @@ impl CryptoScheme for EvmCryptoScheme {
nonce_commitment: Self::Point,
payload: &Self::SigningPayload,
) -> Scalar {
use cf_chains::eth::AggKey;
use cf_chains::evm::AggKey;

let e = AggKey::from_pubkey_compressed(pubkey.get_element().serialize())
.message_challenge(&payload.0, &pubkey_to_eth_addr(nonce_commitment.get_element()));
Expand Down Expand Up @@ -130,7 +132,7 @@ impl CryptoScheme for EvmCryptoScheme {
}

fn pubkey_from_point(pubkey_point: &Self::Point) -> Self::PublicKey {
cf_chains::eth::AggKey {
cf_chains::evm::AggKey {
pub_key_x: pubkey_point.x_bytes(),
pub_key_y_parity: if pubkey_point.is_even_y() {
ParityBit::Even
Expand Down
2 changes: 1 addition & 1 deletion engine/multisig/src/crypto/key_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl CanonicalEncoding for cf_chains::dot::PolkadotPublicKey {
}
}

impl CanonicalEncoding for cf_chains::eth::AggKey {
impl CanonicalEncoding for cf_chains::evm::AggKey {
fn encode_key(&self) -> Vec<u8> {
self.to_pubkey_compressed().to_vec()
}
Expand Down
10 changes: 6 additions & 4 deletions engine/multisig/src/crypto/polkadot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{
curve25519::ristretto::Point, CanonicalEncoding, ChainSigning, ChainTag, CryptoScheme,
CryptoTag, ECPoint, SignatureToThresholdSignature,
};
use cf_chains::{ChainCrypto, Polkadot};
use cf_chains::{Chain, ChainCrypto, Polkadot};
use schnorrkel::context::{SigningContext, SigningTranscript};
use serde::{Deserialize, Serialize};

Expand All @@ -17,8 +17,10 @@ const SIGNING_CTX: &[u8] = b"substrate";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PolkadotSignature(schnorrkel::Signature);

impl SignatureToThresholdSignature<Polkadot> for Vec<PolkadotSignature> {
fn to_threshold_signature(&self) -> <Polkadot as ChainCrypto>::ThresholdSignature {
impl SignatureToThresholdSignature<<Polkadot as Chain>::ChainCrypto> for Vec<PolkadotSignature> {
fn to_threshold_signature(
&self,
) -> <<Polkadot as Chain>::ChainCrypto as ChainCrypto>::ThresholdSignature {
self.iter()
.map(|s| s.clone().into())
.next()
Expand Down Expand Up @@ -66,7 +68,7 @@ pub struct PolkadotCryptoScheme;

impl ChainSigning for PolkadotSigning {
type CryptoScheme = PolkadotCryptoScheme;
type Chain = cf_chains::Polkadot;
type ChainCrypto = <Polkadot as Chain>::ChainCrypto;
const NAME: &'static str = "Polkadot";
const CHAIN_TAG: ChainTag = ChainTag::Polkadot;
}
Expand Down
2 changes: 1 addition & 1 deletion engine/src/eth/broadcaster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ where
pub async fn send(
&self,
// This is from the SC.
unsigned_tx: cf_chains::eth::Transaction,
unsigned_tx: cf_chains::evm::Transaction,
) -> Result<TxHash> {
async move {
let mut transaction_request = Eip1559TransactionRequest {
Expand Down
4 changes: 2 additions & 2 deletions engine/src/multisig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use state_chain_runtime::AccountId;
pub fn start_client<C: ChainSigning>(
my_account_id: AccountId,
key_store: KeyStore<C>,
incoming_p2p_message_receiver: MultisigMessageReceiver<<C as ChainSigning>::Chain>,
outgoing_p2p_message_sender: MultisigMessageSender<<C as ChainSigning>::Chain>,
incoming_p2p_message_receiver: MultisigMessageReceiver<<C as ChainSigning>::ChainCrypto>,
outgoing_p2p_message_sender: MultisigMessageSender<<C as ChainSigning>::ChainCrypto>,
latest_ceremony_id: CeremonyId,
) -> (MultisigClient<C, KeyStore<C>>, impl futures::Future<Output = Result<()>> + Send) {
info!("Starting {} MultisigClient", C::NAME);
Expand Down
22 changes: 11 additions & 11 deletions engine/src/p2p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use self::{
muxer::{ProtocolVersion, VersionedCeremonyMessage, CURRENT_PROTOCOL_VERSION},
};
use anyhow::Context;
use cf_chains::{Bitcoin, Chain, Ethereum, Polkadot};
use cf_chains::{btc::BitcoinCrypto, dot::PolkadotCrypto, evm::EvmCrypto, ChainCrypto};
use cf_primitives::AccountId;
use futures::{Future, FutureExt};
use multisig::p2p::OutgoingMultisigStageMessages;
Expand All @@ -38,22 +38,22 @@ use utilities::{read_clean_and_decode_hex_str_file, task_scope::task_scope};
type EdPublicKey = ed25519::Public;
type XPublicKey = x25519_dalek::PublicKey;

pub struct MultisigMessageSender<C: Chain>(
pub struct MultisigMessageSender<C: ChainCrypto>(
pub UnboundedSender<OutgoingMultisigStageMessages>,
PhantomData<C>,
);

impl<C: Chain> MultisigMessageSender<C> {
impl<C: ChainCrypto> MultisigMessageSender<C> {
pub fn new(sender: UnboundedSender<OutgoingMultisigStageMessages>) -> Self {
MultisigMessageSender(sender, PhantomData)
}
}
pub struct MultisigMessageReceiver<C: Chain>(
pub struct MultisigMessageReceiver<C: ChainCrypto>(
pub UnboundedReceiver<(AccountId, VersionedCeremonyMessage)>,
PhantomData<C>,
);

impl<C: Chain> MultisigMessageReceiver<C> {
impl<C: ChainCrypto> MultisigMessageReceiver<C> {
pub fn new(receiver: UnboundedReceiver<(AccountId, VersionedCeremonyMessage)>) -> Self {
MultisigMessageReceiver(receiver, PhantomData)
}
Expand Down Expand Up @@ -89,12 +89,12 @@ pub async fn start<StateChainClient>(
settings: P2PSettings,
latest_block_hash: H256,
) -> anyhow::Result<(
MultisigMessageSender<Ethereum>,
MultisigMessageReceiver<Ethereum>,
MultisigMessageSender<Polkadot>,
MultisigMessageReceiver<Polkadot>,
MultisigMessageSender<Bitcoin>,
MultisigMessageReceiver<Bitcoin>,
MultisigMessageSender<EvmCrypto>,
MultisigMessageReceiver<EvmCrypto>,
MultisigMessageSender<PolkadotCrypto>,
MultisigMessageReceiver<PolkadotCrypto>,
MultisigMessageSender<BitcoinCrypto>,
MultisigMessageReceiver<BitcoinCrypto>,
UnboundedSender<PeerUpdate>,
impl Future<Output = anyhow::Result<()>>,
)>
Expand Down
26 changes: 13 additions & 13 deletions engine/src/p2p/muxer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{anyhow, Result};
use cf_chains::{Bitcoin, Ethereum, Polkadot};
use cf_chains::{btc::BitcoinCrypto, dot::PolkadotCrypto, evm::EvmCrypto};
use futures::Future;
use state_chain_runtime::AccountId;
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
Expand Down Expand Up @@ -87,12 +87,12 @@ impl P2PMuxer {
all_incoming_receiver: UnboundedReceiver<(AccountId, Vec<u8>)>,
all_outgoing_sender: UnboundedSender<OutgoingMultisigStageMessages>,
) -> (
MultisigMessageSender<Ethereum>,
MultisigMessageReceiver<Ethereum>,
MultisigMessageSender<Polkadot>,
MultisigMessageReceiver<Polkadot>,
MultisigMessageSender<Bitcoin>,
MultisigMessageReceiver<Bitcoin>,
MultisigMessageSender<EvmCrypto>,
MultisigMessageReceiver<EvmCrypto>,
MultisigMessageSender<PolkadotCrypto>,
MultisigMessageReceiver<PolkadotCrypto>,
MultisigMessageSender<BitcoinCrypto>,
MultisigMessageReceiver<BitcoinCrypto>,
impl Future<Output = ()>,
) {
let (eth_outgoing_sender, eth_outgoing_receiver) = tokio::sync::mpsc::unbounded_channel();
Expand All @@ -118,12 +118,12 @@ impl P2PMuxer {
let muxer_fut = muxer.run().instrument(info_span!("P2PMuxer"));

(
MultisigMessageSender::<Ethereum>::new(eth_outgoing_sender),
MultisigMessageReceiver::<Ethereum>::new(eth_incoming_receiver),
MultisigMessageSender::<Polkadot>::new(dot_outgoing_sender),
MultisigMessageReceiver::<Polkadot>::new(dot_incoming_receiver),
MultisigMessageSender::<Bitcoin>::new(btc_outgoing_sender),
MultisigMessageReceiver::<Bitcoin>::new(btc_incoming_receiver),
MultisigMessageSender::<EvmCrypto>::new(eth_outgoing_sender),
MultisigMessageReceiver::<EvmCrypto>::new(eth_incoming_receiver),
MultisigMessageSender::<PolkadotCrypto>::new(dot_outgoing_sender),
MultisigMessageReceiver::<PolkadotCrypto>::new(dot_incoming_receiver),
MultisigMessageSender::<BitcoinCrypto>::new(btc_outgoing_sender),
MultisigMessageReceiver::<BitcoinCrypto>::new(btc_incoming_receiver),
muxer_fut,
)
}
Expand Down
21 changes: 13 additions & 8 deletions engine/src/state_chain_observer/sc_observer/crypto_compat.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
use cf_chains::{dot::PolkadotPublicKey, ChainCrypto};
use cf_chains::{
btc::BitcoinCrypto,
dot::{PolkadotCrypto, PolkadotPublicKey},
evm::EvmCrypto,
ChainCrypto,
};
use multisig::{
bitcoin::BtcSigning, eth::EthSigning, polkadot::PolkadotSigning, ChainSigning, CryptoScheme,
};
use state_chain_runtime::{BitcoinInstance, EthereumInstance, PolkadotInstance};

/// Compatibility layer for converting between public keys generated using the [CryptoScheme] types
/// and the on-chain representation as defined by [ChainCrypto].
pub trait CryptoCompat<S: ChainSigning<Chain = C>, C: ChainCrypto> {
pub trait CryptoCompat<S: ChainSigning<ChainCrypto = C>, C: ChainCrypto> {
fn pubkey_to_aggkey(
pubkey: <<S as ChainSigning>::CryptoScheme as CryptoScheme>::PublicKey,
) -> C::AggKey;
}

impl CryptoCompat<EthSigning, cf_chains::Ethereum> for EthereumInstance {
impl CryptoCompat<EthSigning, EvmCrypto> for EthereumInstance {
fn pubkey_to_aggkey(
pubkey: <<EthSigning as ChainSigning>::CryptoScheme as CryptoScheme>::PublicKey,
) -> <cf_chains::Ethereum as ChainCrypto>::AggKey {
) -> <EvmCrypto as ChainCrypto>::AggKey {
pubkey
}
}

impl CryptoCompat<BtcSigning, cf_chains::Bitcoin> for BitcoinInstance {
impl CryptoCompat<BtcSigning, BitcoinCrypto> for BitcoinInstance {
fn pubkey_to_aggkey(
pubkey: <<BtcSigning as ChainSigning>::CryptoScheme as CryptoScheme>::PublicKey,
) -> <cf_chains::Bitcoin as ChainCrypto>::AggKey {
) -> <BitcoinCrypto as ChainCrypto>::AggKey {
cf_chains::btc::AggKey { previous: None, current: pubkey.serialize() }
}
}

impl CryptoCompat<PolkadotSigning, cf_chains::Polkadot> for PolkadotInstance {
impl CryptoCompat<PolkadotSigning, PolkadotCrypto> for PolkadotInstance {
fn pubkey_to_aggkey(
pubkey: <<PolkadotSigning as ChainSigning>::CryptoScheme as CryptoScheme>::PublicKey,
) -> <cf_chains::Polkadot as ChainCrypto>::AggKey {
) -> <PolkadotCrypto as ChainCrypto>::AggKey {
PolkadotPublicKey::from_aliased(pubkey.to_bytes())
}
}
11 changes: 7 additions & 4 deletions engine/src/state_chain_observer/sc_observer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ mod crypto_compat;
mod tests;

use anyhow::{anyhow, Context};
use cf_chains::btc::{self, PreviousOrCurrent};
use cf_chains::{
btc::{self, PreviousOrCurrent},
Chain,
};
use cf_primitives::{BlockNumber, CeremonyId, EpochIndex};
use crypto_compat::CryptoCompat;
use futures::{FutureExt, StreamExt};
Expand Down Expand Up @@ -52,9 +55,9 @@ async fn handle_keygen_request<'a, StateChainClient, MultisigClient, C, I>(
MultisigClient: MultisigClientApi<C::CryptoScheme>,
StateChainClient: SignedExtrinsicApi + 'static + Send + Sync,
state_chain_runtime::Runtime: pallet_cf_vaults::Config<I>,
C: ChainSigning<Chain = <state_chain_runtime::Runtime as pallet_cf_vaults::Config<I>>::Chain>
C: ChainSigning<ChainCrypto = <<state_chain_runtime::Runtime as pallet_cf_vaults::Config<I>>::Chain as Chain>::ChainCrypto>
+ 'static,
I: CryptoCompat<C, C::Chain> + 'static + Sync + Send,
I: CryptoCompat<C, C::ChainCrypto> + 'static + Sync + Send,
state_chain_runtime::RuntimeCall:
std::convert::From<pallet_cf_vaults::Call<state_chain_runtime::Runtime, I>>,
{
Expand Down Expand Up @@ -150,7 +153,7 @@ async fn handle_signing_request<'a, StateChainClient, MultisigClient, C, I>(
state_chain_runtime::RuntimeCall:
std::convert::From<pallet_cf_threshold_signature::Call<state_chain_runtime::Runtime, I>>,
Vec<C::Signature>: SignatureToThresholdSignature<
<state_chain_runtime::Runtime as pallet_cf_threshold_signature::Config<I>>::TargetChain,
<state_chain_runtime::Runtime as pallet_cf_threshold_signature::Config<I>>::TargetChainCrypto,
>,
{
if signers.contains(&state_chain_client.account_id()) {
Expand Down
Loading