Skip to content

Commit

Permalink
Merge branch 'develop' into xiangyi/versioned_contract
Browse files Browse the repository at this point in the history
  • Loading branch information
ppca authored May 13, 2024
2 parents a7dd06a + 15b3b86 commit 7406421
Show file tree
Hide file tree
Showing 18 changed files with 501 additions and 158 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 34 additions & 16 deletions contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use near_sdk::{log, Gas};
use primitives::{CandidateInfo, Candidates, ParticipantInfo, Participants, PkVotes, Votes};
use std::collections::{BTreeMap, HashSet};

const GAS_FOR_SIGN_CALL: Gas = Gas::from_gas(3 * 100_000_000_000_000);
const GAS_FOR_SIGN_CALL: Gas = Gas::from_tgas(250);

#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Debug)]
pub struct InitializingContractState {
Expand Down Expand Up @@ -258,11 +258,11 @@ impl VersionedMpcContract {
}
}

pub fn vote_leave(&mut self, acc_id_to_leave: AccountId) -> bool {
pub fn vote_leave(&mut self, kick: AccountId) -> bool {
log!(
"vote_leave: signer={}, acc_id_to_leave={}",
"vote_leave: signer={}, kick={}",
env::signer_account_id(),
acc_id_to_leave
kick
);
let protocol_state = self.mutable_state();
match protocol_state {
Expand All @@ -278,14 +278,17 @@ impl VersionedMpcContract {
if !participants.contains_key(&signer_account_id) {
env::panic_str("calling account is not in the participant set");
}
if !participants.contains_key(&acc_id_to_leave) {
if !participants.contains_key(&kick) {
env::panic_str("account to leave is not in the participant set");
}
let voted = leave_votes.entry(acc_id_to_leave.clone());
if participants.len() <= *threshold {
env::panic_str("the number of participants can not go below the threshold");
}
let voted = leave_votes.entry(kick.clone());
voted.insert(signer_account_id);
if voted.len() >= *threshold {
let mut new_participants = participants.clone();
new_participants.remove(&acc_id_to_leave);
new_participants.remove(&kick);
*protocol_state = ProtocolContractState::Resharing(ResharingContractState {
old_epoch: *epoch,
old_participants: participants.clone(),
Expand Down Expand Up @@ -441,20 +444,30 @@ impl VersionedMpcContract {
PromiseOrValue::Value(signature)
}
None => {
if depth > 30 {
// Make sure we have enough gas left to do 1 more call and clean up afterwards
// Observationally 30 calls < 300 TGas so 2 calls < 20 TGas
// We keep one call back so we can cleanup then call panic on the next call
// Start cleaning up if there's less than 25 teragas left regardless of how deep you are.
if depth > 30 || env::prepaid_gas() < Gas::from_tgas(25) {
self.remove_request(&payload);
env::panic_str("Signature was not provided in time. Please, try again.");
let self_id = env::current_account_id();
PromiseOrValue::Promise(Self::ext(self_id).fail_helper(
"Signature was not provided in time. Please, try again.".to_string(),
))
} else {
log!(&format!(
"sign_helper: signature not ready yet (depth={})",
depth
));
let account_id = env::current_account_id();
PromiseOrValue::Promise(
Self::ext(account_id).sign_helper(payload, depth + 1),
)
}
log!(&format!(
"sign_helper: signature not ready yet (depth={})",
depth
));
let account_id = env::current_account_id();
PromiseOrValue::Promise(Self::ext(account_id).sign_helper(payload, depth + 1))
}
}
} else {
env::panic_str("unexpected request");
env::panic_str("unexpected request")
}
}

Expand Down Expand Up @@ -493,6 +506,11 @@ impl VersionedMpcContract {

pub fn version(&self) -> String {
env!("CARGO_PKG_VERSION").to_string()

/// This allows us to return a panic, without rolling back the state from this call
#[private]
pub fn fail_helper(&mut self, message: String) {
env::panic_str(&message);
}

pub fn respond(&mut self, payload: [u8; 32], big_r: String, s: String) {
Expand Down
30 changes: 15 additions & 15 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
# More agressively cache build artefacts
# Uses more disk but speeds up compile times significantly
env = {
SCCACHE_GHA_ENABLED = true;
RUSTC_WRAPPER = "sccache";
# SCCACHE_GHA_ENABLED = true;
# RUSTC_WRAPPER = "sccache";
};

# Everything in this list is added to your path
Expand All @@ -39,14 +39,11 @@
# A nice LSP IDE backend
rust-analyzer

# A very opinionated linter
clippy

# Adds cargo, rustc and rustfmt
(rustVersion.override {

# We need this for rust analyzer to jump to library code
extensions = [ "rust-src" ];
extensions = [ "rust-src" "clippy" "rustfmt" ];

# Add foreign compile targets here
targets = [
Expand Down
28 changes: 24 additions & 4 deletions integration-tests/src/multichain/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod containers;
pub mod local;
pub mod utils;

use crate::env::containers::DockerClient;
use crate::mpc::TARGET_CONTRACT_DIR;
Expand All @@ -12,7 +13,7 @@ use mpc_recovery_node::storage;
use mpc_recovery_node::storage::triple_storage::TripleNodeStorageBox;
use near_workspaces::network::Sandbox;
use near_workspaces::types::SecretKey;
use near_workspaces::{AccountId, Contract, Worker};
use near_workspaces::{Account, AccountId, Contract, Worker};
use serde_json::json;
use std::collections::HashMap;

Expand Down Expand Up @@ -99,6 +100,15 @@ impl Nodes<'_> {
account_to_sk
}

pub fn near_accounts(&self) -> Vec<Account> {
self.near_acc_sk()
.iter()
.map(|(account_id, account_sk)| {
Account::from_secret_key(account_id.clone(), account_sk.clone(), &self.ctx().worker)
})
.collect()
}

pub async fn start_node(
&mut self,
new_node_account_id: &AccountId,
Expand All @@ -118,14 +128,24 @@ impl Nodes<'_> {
Ok(())
}

pub async fn kill_node(&mut self, index: usize) -> anyhow::Result<()> {
pub async fn kill_node(&mut self, account_id: &AccountId) -> anyhow::Result<()> {
match self {
Nodes::Local { nodes, .. } => {
nodes[index].kill()?;
let (index, node) = nodes
.iter_mut()
.enumerate()
.find(|(_, node)| node.account_id == *account_id)
.unwrap();
node.kill()?;
nodes.remove(index);
}
Nodes::Docker { nodes, .. } => {
nodes[index].kill();
let (index, node) = nodes
.iter_mut()
.enumerate()
.find(|(_, node)| node.account_id == *account_id)
.unwrap();
node.kill();
nodes.remove(index);
}
}
Expand Down
54 changes: 54 additions & 0 deletions integration-tests/src/multichain/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use near_workspaces::{result::ExecutionFinalResult, Account, AccountId};

pub async fn vote_join(
accounts: Vec<Account>,
mpc_contract: &AccountId,
account_id: &AccountId,
) -> anyhow::Result<()> {
let vote_futures = accounts
.iter()
.map(|account| {
tracing::info!(
"{} voting for new participant: {}",
account.id(),
account_id
);
account
.call(mpc_contract, "vote_join")
.args_json(serde_json::json!({
"candidate_account_id": account_id
}))
.transact()
})
.collect::<Vec<_>>();

futures::future::join_all(vote_futures)
.await
.iter()
.for_each(|result| {
assert!(result.as_ref().unwrap().failures().is_empty());
});

Ok(())
}

pub async fn vote_leave(
accounts: Vec<Account>,
mpc_contract: &AccountId,
account_id: &AccountId,
) -> Vec<Result<ExecutionFinalResult, near_workspaces::error::Error>> {
let vote_futures = accounts
.iter()
.filter(|account| account.id() != account_id)
.map(|account| {
account
.call(mpc_contract, "vote_leave")
.args_json(serde_json::json!({
"kick": account_id
}))
.transact()
})
.collect::<Vec<_>>();

futures::future::join_all(vote_futures).await
}
Loading

0 comments on commit 7406421

Please sign in to comment.