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

Generate multiple signing sets, create signing set IDs #680

Merged
merged 5 commits into from
Jul 18, 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
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">
<a href="https://www.webb.tools/">

![Webb Logo](./assets/webb_banner_light.png#gh-light-mode-only)
![Webb Logo](./assets/webb_banner_dark.png#gh-dark-mode-only)
</a>
Expand Down Expand Up @@ -29,7 +29,7 @@
<li><a href="#test">Testing</a></li>
<li><a href="#contribute">Contributing</a></li>
<li><a href="#license">License</a></li>
</ul>
</ul>
</details>

<h1 id="start"> Getting Started 🎉 </h1>
Expand Down Expand Up @@ -131,3 +131,13 @@ If you have a contribution in mind, please check out our [Contribution Guide](./
Licensed under <a href="LICENSE">GNU General Public License v3.0</a>.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the GNU General Public License v3.0 license, shall be licensed as above, without any additional terms or conditions.


## Troubleshooting
The linking phase may fail due to not finding libgmp (i.e., "could not find library -lgmp") when building on a mac M1. To fix this problem, run:

```bash
brew install gmp
# make sure to run the commands below each time when starting a new env, or, append them to .zshrc
export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/lib
export INCLUDE_PATH=$INCLUDE_PATH:/opt/homebrew/include
1 change: 1 addition & 0 deletions dkg-gadget/src/async_protocols/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ where
recipient_id: maybe_recipient_id,
payload,
session_id: params.session_id,
ssid: params.handle.ssid,
};
if let Err(err) = params.engine.sign_and_send_msg(unsigned_dkg_message) {
params
Expand Down
30 changes: 5 additions & 25 deletions dkg-gadget/src/async_protocols/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub struct AsyncProtocolRemote<C> {
pub(crate) current_round_blame_tx: Arc<tokio::sync::watch::Sender<CurrentRoundBlame>>,
pub(crate) session_id: SessionId,
pub(crate) associated_block_id: u64,
/// The signing set index. For keygen, this is always 0
pub(crate) ssid: u8,
pub(crate) logger: DebugLogger,
status_history: Arc<Mutex<Vec<MetaHandlerStatus>>>,
}
Expand Down Expand Up @@ -74,6 +76,7 @@ impl<C: Clone> Clone for AsyncProtocolRemote<C> {
logger: self.logger.clone(),
status_history: self.status_history.clone(),
associated_block_id: self.associated_block_id,
ssid: self.ssid,
}
}
}
Expand Down Expand Up @@ -101,6 +104,7 @@ impl<C: AtLeast32BitUnsigned + Copy + Send> AsyncProtocolRemote<C> {
session_id: SessionId,
logger: DebugLogger,
associated_block_id: u64,
ssid: u8,
) -> Self {
let (stop_tx, stop_rx) = tokio::sync::mpsc::unbounded_channel();
let (tx_keygen_signing, rx_keygen_signing) = tokio::sync::mpsc::unbounded_channel();
Expand All @@ -113,31 +117,6 @@ impl<C: AtLeast32BitUnsigned + Copy + Send> AsyncProtocolRemote<C> {
let status = Arc::new(Atomic::new(MetaHandlerStatus::Beginning));
let status_history = Arc::new(Mutex::new(vec![MetaHandlerStatus::Beginning]));

// let status_debug = status.clone();
// let status_history_debug = status_history.clone();
// let logger_debug = logger.clone();

// The purpose of this task is to log the status of the meta handler
// in the case that it is stalled/not-progressing. This is useful for debugging.
// tokio::task::spawn(async move {
// loop {
// tokio::time::sleep(std::time::Duration::from_secs(2)).await;
// let status = status_debug.load(Ordering::Relaxed);
// if [MetaHandlerStatus::Terminated, MetaHandlerStatus::Complete].contains(&status) {
// break
// }
// let status_history = status_history_debug.lock();

// if status == MetaHandlerStatus::Beginning && status_history.len() == 1 {
// continue
// }

// logger_debug.debug(format!(
// "AsyncProtocolRemote status: {status:?} ||||| history: {status_history:?} |||||
// session_id: {session_id:?}", ));
// }
// });

Self {
status,
tx_keygen_signing,
Expand All @@ -156,6 +135,7 @@ impl<C: AtLeast32BitUnsigned + Copy + Send> AsyncProtocolRemote<C> {
is_primary_remote: false,
session_id,
associated_block_id,
ssid,
}
}

Expand Down
1 change: 1 addition & 0 deletions dkg-gadget/src/async_protocols/sign/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ where
recipient_id: None,
payload,
session_id: params.session_id,
ssid: params.handle.ssid,
};

params.engine.sign_and_send_msg(unsigned_dkg_message.clone())?;
Expand Down
1 change: 1 addition & 0 deletions dkg-gadget/src/dkg_modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub enum SigningProtocolSetupParameters<B: Block> {
>,
signing_set: Vec<KeygenPartyId>,
associated_block_id: NumberFor<B>,
ssid: u8,
},
WTFrost {},
}
Expand Down
8 changes: 6 additions & 2 deletions dkg-gadget/src/dkg_modules/mp_ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ where
keygen_protocol_hash,
} = params
{
const KEYGEN_SSID: u8 = 0;
match self.dkg_worker.generate_async_proto_params(
best_authorities,
authority_public_key,
Expand All @@ -58,9 +59,10 @@ where
stage,
crate::DKG_KEYGEN_PROTOCOL_NAME,
associated_block,
KEYGEN_SSID,
) {
Ok(async_proto_params) => {
let err_handler_tx = self.dkg_worker.error_handler.clone();
let err_handler_tx = self.dkg_worker.error_handler_channel.tx.clone();

let remote = async_proto_params.handle.clone();
let keygen_manager = self.dkg_worker.keygen_manager.clone();
Expand Down Expand Up @@ -152,6 +154,7 @@ where
unsigned_proposal_batch,
signing_set,
associated_block_id,
ssid,
} = params
{
self.dkg_worker.logger.debug(format!("{party_i:?} All Parameters: {best_authorities:?} | authority_pub_key: {authority_public_key:?} | session_id: {session_id:?} | threshold: {threshold:?} | stage: {stage:?} | unsigned_proposal_batch: {unsigned_proposal_batch:?} | signing_set: {signing_set:?} | associated_block_id: {associated_block_id:?}"));
Expand All @@ -163,11 +166,12 @@ where
stage,
crate::DKG_SIGNING_PROTOCOL_NAME,
associated_block_id,
ssid,
)?;

let handle = async_proto_params.handle.clone();

let err_handler_tx = self.dkg_worker.error_handler.clone();
let err_handler_tx = self.dkg_worker.error_handler_channel.tx.clone();
let meta_handler = GenericAsyncHandler::setup_signing(
async_proto_params,
threshold,
Expand Down
1 change: 1 addition & 0 deletions dkg-gadget/src/gossip_messages/misbehaviour_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ where
recipient_id: None,
session_id: report.session_id,
payload,
ssid: 0,
};
let encoded_dkg_message = message.encode();

Expand Down
1 change: 1 addition & 0 deletions dkg-gadget/src/gossip_messages/public_key_gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ pub(crate) fn gossip_public_key<GE>(
recipient_id: None,
session_id: msg.session_id,
payload,
ssid: 0,
};
let encoded_dkg_message = message.encode();

Expand Down
2 changes: 1 addition & 1 deletion dkg-gadget/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub mod keystore;

pub mod gossip_engine;
mod keygen_manager;
mod signing_manager;
pub mod signing_manager;
// mod meta_async_rounds;
pub mod db;
mod metrics;
Expand Down
116 changes: 61 additions & 55 deletions dkg-gadget/src/signing_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const MAX_RUNNING_TASKS: usize = 4;
const MAX_ENQUEUED_TASKS: usize = 20;
// How often to poll the jobs to check completion status
const JOB_POLL_INTERVAL_IN_MILLISECONDS: u64 = 500;
pub const MAX_POTENTIAL_SIGNING_SETS_PER_PROPOSAL: u8 = 2;

impl<B, BE, C, GE> SigningManager<B, BE, C, GE>
where
Expand Down Expand Up @@ -200,65 +201,70 @@ where
if we are not, we continue the loop.
*/
let unsigned_proposal_bytes = batch.encode();
let concat_data = dkg_pub_key
.clone()
.into_iter()
//.chain(at.encode())
.chain(unsigned_proposal_bytes)
.collect::<Vec<u8>>();
let seed = sp_core::keccak_256(&concat_data);
let unsigned_proposal_hash = batch.hash().expect("unable to hash proposal");

let maybe_set = self
.generate_signers(&seed, threshold, best_authorities.clone(), dkg_worker)
.ok();
if let Some(signing_set) = maybe_set {
// if we are in the set, send to work manager
if signing_set.contains(&party_i) {
dkg_worker.logger.info(format!(
"🕸️ Session Id {:?} | {}-out-of-{} signers: ({:?})",
session_id,
threshold,
best_authorities.len(),
signing_set,
));
for ssid in 0..MAX_POTENTIAL_SIGNING_SETS_PER_PROPOSAL {
let concat_data = dkg_pub_key
.clone()
.into_iter()
.chain(unsigned_proposal_bytes.clone())
.chain(ssid.encode())
.collect::<Vec<u8>>();
let seed = sp_core::keccak_256(&concat_data);

let params = SigningProtocolSetupParameters::MpEcdsa {
best_authorities: best_authorities.clone(),
authority_public_key: authority_public_key.clone(),
party_i,
session_id,
threshold,
stage: ProtoStageType::Signing { unsigned_proposal_hash },
unsigned_proposal_batch: batch,
signing_set,
associated_block_id: *header.number(),
};
let maybe_set = self
.generate_signers(&seed, threshold, best_authorities.clone(), dkg_worker)
.ok();
if let Some(signing_set) = maybe_set {
// if we are in the set, send to work manager
if signing_set.contains(&party_i) {
dkg_worker.logger.info(format!(
"🕸️ Session Id {:?} | SSID {} | {}-out-of-{} signers: ({:?})",
session_id,
ssid,
threshold,
best_authorities.len(),
signing_set,
));

let signing_protocol = dkg_worker
.dkg_modules
.get_signing_protocol(&params)
.expect("Standard signing protocol should exist");
match signing_protocol.initialize_signing_protocol(params).await {
Ok((handle, task)) => {
// Send task to the work manager. Force start if the type chain ID is
// None, implying this is a proposal needed for rotating sessions and
// thus a priority
let force_start = typed_chain_id == TypedChainId::None;
self.work_manager.push_task(
unsigned_proposal_hash,
force_start,
handle,
task,
)?;
},
Err(err) => {
dkg_worker
.logger
.error(format!("Error creating signing protocol: {:?}", &err));
dkg_worker.handle_dkg_error(err.clone()).await;
return Err(err)
},
let params = SigningProtocolSetupParameters::MpEcdsa {
best_authorities: best_authorities.clone(),
authority_public_key: authority_public_key.clone(),
party_i,
session_id,
threshold,
stage: ProtoStageType::Signing { unsigned_proposal_hash },
unsigned_proposal_batch: batch.clone(),
signing_set,
associated_block_id: *header.number(),
ssid,
};

let signing_protocol = dkg_worker
.dkg_modules
.get_signing_protocol(&params)
.expect("Standard signing protocol should exist");
match signing_protocol.initialize_signing_protocol(params).await {
Ok((handle, task)) => {
// Send task to the work manager. Force start if the type chain ID
// is None, implying this is a proposal needed for rotating sessions
// and thus a priority
let force_start = typed_chain_id == TypedChainId::None;
self.work_manager.push_task(
unsigned_proposal_hash,
force_start,
handle,
task,
)?;
},
Err(err) => {
dkg_worker
.logger
.error(format!("Error creating signing protocol: {:?}", &err));
dkg_worker.handle_dkg_error(err.clone()).await;
return Err(err)
},
}
}
}
}
Expand Down
Loading
Loading