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

feat: use contract configs #731

Merged
merged 27 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ce04dcf
Renamed chain-signature MPC_RECOVERY_* env vars to MPC_*
ChaoticTempest Jul 25, 2024
c02b47e
Rename mpc-recovery-node binary to mpc-node
ChaoticTempest Jul 25, 2024
cf59bf2
Rename some forgotten binary names
ChaoticTempest Jul 25, 2024
c02663a
Made update methods us MpcContractError
ChaoticTempest Jul 24, 2024
54044b8
Made proposed updates more space efficient
ChaoticTempest Jul 24, 2024
6381121
Added bytes_used for config and code updates
ChaoticTempest Jul 24, 2024
a98dd91
Removed unnecessary near-rng crate
ChaoticTempest Jul 24, 2024
00847f6
Added deposit to propose_update
ChaoticTempest Jul 24, 2024
a5d4cc4
Make config dynamic for easier changes
ChaoticTempest Jul 24, 2024
31342cc
Added proper borsh serialization and payable
ChaoticTempest Jul 24, 2024
7270810
Use to_vec instead for config borsh ser
ChaoticTempest Jul 24, 2024
41340b6
Update deposit cost
ChaoticTempest Jul 24, 2024
3858a82
Clippy
ChaoticTempest Jul 24, 2024
b213d8e
Added propose_update refund diff and migrate
ChaoticTempest Jul 24, 2024
cf17f8a
Added additional test case for a contract that fails to migrate
ChaoticTempest Jul 24, 2024
81af3fb
Update INVALID contract path
ChaoticTempest Jul 25, 2024
8dab958
Made config module
ChaoticTempest Jul 25, 2024
2190faf
Made config an option that can be initialized from contract
ChaoticTempest Jul 25, 2024
644be9b
Made node use contract config with LocalConfig
ChaoticTempest Jul 25, 2024
cf320f7
Added --override-config for partial overrides
ChaoticTempest Jul 25, 2024
eb84b36
Added SignatureConfig
ChaoticTempest Jul 25, 2024
a08817e
Use timeouts from contract configs
ChaoticTempest Jul 25, 2024
4d7931f
Removed no longer needed env variables from tf
ChaoticTempest Jul 25, 2024
d9b358b
Moved GC timeout to contract config
ChaoticTempest Jul 25, 2024
464887e
Merge branch 'develop' of github.com:near/mpc-recovery into phuong/fe…
ChaoticTempest Jul 25, 2024
1cd0878
fix contract tests, use updated config struct
volovyks Jul 25, 2024
583bf42
Merge branch 'develop' into phuong/feat/use-contract-configs
volovyks Jul 26, 2024
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
86 changes: 0 additions & 86 deletions chain-signatures/contract/src/config.rs

This file was deleted.

107 changes: 107 additions & 0 deletions chain-signatures/contract/src/config/impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use borsh::{self, BorshDeserialize, BorshSerialize};

use super::{
Config, DynamicValue, PresignatureConfig, ProtocolConfig, SignatureConfig, TripleConfig,
};

const MAX_EXPECTED_PARTICIPANTS: usize = 32;

// The network multiplier is used to calculate the maximum amount of protocols in totality
// that should be in the network.
const NETWORK_MULTIPLIER: usize = 128;

impl Config {
pub fn get(&self, key: &str) -> Option<serde_json::Value> {
match key {
"protocol" => Some(serde_json::to_value(self.protocol.clone()).unwrap()),
_ => {
let value = self.other.get(key)?;
Some(value.0.clone())
}
}
}
}

impl Default for ProtocolConfig {
fn default() -> Self {
Self {
message_timeout: min_to_ms(5),
garbage_timeout: hours_to_ms(2),
max_concurrent_introduction: 4,
max_concurrent_generation: 4 * MAX_EXPECTED_PARTICIPANTS,
triple: TripleConfig::default(),
presignature: PresignatureConfig::default(),
signature: Default::default(),

other: Default::default(),
}
}
}

impl Default for TripleConfig {
fn default() -> Self {
Self {
min_triples: 1024,
max_triples: 1024 * MAX_EXPECTED_PARTICIPANTS * NETWORK_MULTIPLIER,
generation_timeout: min_to_ms(20),

other: Default::default(),
}
}
}

impl Default for PresignatureConfig {
fn default() -> Self {
Self {
min_presignatures: 512,
max_presignatures: 512 * MAX_EXPECTED_PARTICIPANTS * NETWORK_MULTIPLIER,
generation_timeout: secs_to_ms(60),

other: Default::default(),
}
}
}

impl Default for SignatureConfig {
fn default() -> Self {
Self {
generation_timeout: secs_to_ms(60),

other: Default::default(),
}
}
}

impl From<serde_json::Value> for DynamicValue {
fn from(value: serde_json::Value) -> Self {
Self(value)
}
}
impl BorshSerialize for DynamicValue {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
let buf = serde_json::to_vec(&self.0)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
BorshSerialize::serialize(&buf, writer)
}
}

impl BorshDeserialize for DynamicValue {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let buf: Vec<u8> = BorshDeserialize::deserialize_reader(reader)?;
let value = serde_json::from_slice(&buf)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
Ok(Self(value))
}
}

pub const fn secs_to_ms(secs: u64) -> u64 {
secs * 1000
}

pub const fn min_to_ms(min: u64) -> u64 {
min * 60 * 1000
}

pub const fn hours_to_ms(hours: u64) -> u64 {
hours * 60 * 60 * 1000
}
160 changes: 160 additions & 0 deletions chain-signatures/contract/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
mod impls;

pub use impls::{min_to_ms, secs_to_ms};

use std::collections::HashMap;

use borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::serde::{Deserialize, Serialize};

/// Dynamic value is used to store any kind of value in the contract state. These values
/// can be deserialized on the fly to get the actual configurations, but the contract will
/// not be the ones directly utilizing these values unless they are concrete types.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct DynamicValue(serde_json::Value);

#[derive(
Clone, Default, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, PartialEq, Eq,
)]
pub struct Config {
pub protocol: ProtocolConfig,

/// The remaining entries that can be present in future forms of the configuration.
#[serde(flatten)]
pub other: HashMap<String, DynamicValue>,
}

#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
pub struct ProtocolConfig {
/// Message timeout in milliseconds for any protocol message that gets sent over the wire.
/// This can be overriden by more specific timeouts in each protocol.
pub message_timeout: u64,
/// Garbage collection timeout in milliseconds for any protocol message. This is the timeout
/// used for when any protocols have either been spent or failed, their IDs are kept to keep
/// track of the state of the protocol until this timeout reaches.
pub garbage_timeout: u64,
/// Maximum amount of concurrent protocol generation that can be introduced by this node.
/// This only includes protocols that generate triples and presignatures.
pub max_concurrent_introduction: usize,
/// Maximum amount of concurrent protocol generation that can be done per node.
/// This only includes protocols that generate triples and presignatures.
pub max_concurrent_generation: usize,
/// Configuration for triple generation.
pub triple: TripleConfig,
/// Configuration for presignature generation.
pub presignature: PresignatureConfig,
/// Configuration for signature generation.
pub signature: SignatureConfig,

/// The remaining entries that can be present in future forms of the configuration.
#[serde(flatten)]
pub other: HashMap<String, DynamicValue>,
}

#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
pub struct TripleConfig {
/// Minimum amount of triples that is owned by each node.
pub min_triples: usize,
/// Maximum amount of triples that is in the whole network.
pub max_triples: usize,
/// Timeout for triple generation in milliseconds.
pub generation_timeout: u64,

/// The remaining entries that can be present in future forms of the configuration.
#[serde(flatten)]
pub other: HashMap<String, DynamicValue>,
}

#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
pub struct PresignatureConfig {
/// Minimum amount of presignatures that is owned by each node.
pub min_presignatures: usize,
/// Maximum amount of presignatures that is in the whole network.
pub max_presignatures: usize,
/// Timeout for presignature generation in milliseconds.
pub generation_timeout: u64,

/// The remaining entries that can be present in future forms of the configuration.
#[serde(flatten)]
pub other: HashMap<String, DynamicValue>,
}

#[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
pub struct SignatureConfig {
/// Timeout for signature generation in milliseconds.
pub generation_timeout: u64,

/// The remaining entries that can be present in future forms of the configuration.
#[serde(flatten)]
pub other: HashMap<String, DynamicValue>,
}

#[cfg(test)]
mod tests {
use crate::config::Config;

#[test]
fn test_load_config() {
let config_str: serde_json::Value = serde_json::from_str(
r#"{
"protocol": {
"message_timeout": 10000,
"garbage_timeout": 20000,
"max_concurrent_introduction": 10,
"max_concurrent_generation": 10,
"triple": {
"min_triples": 10,
"max_triples": 100,
"generation_timeout": 10000
},
"presignature": {
"min_presignatures": 10,
"max_presignatures": 100,
"generation_timeout": 10000
},
"signature": {
"generation_timeout": 10000
},
"string": "value",
"integer": 1000
},
"string": "value2",
"integer": 20
}"#,
)
.unwrap();

let config_macro = serde_json::json!({
"protocol": {
"message_timeout": 10000,
"garbage_timeout": 20000,
"max_concurrent_introduction": 10,
"max_concurrent_generation": 10,
"triple": {
"min_triples": 10,
"max_triples": 100,
"generation_timeout": 10000
},
"presignature": {
"min_presignatures": 10,
"max_presignatures": 100,
"generation_timeout": 10000
},
"signature": {
"generation_timeout": 10000
},
"string": "value",
"integer": 1000
},
"string": "value2",
"integer": 20
});

assert_eq!(config_str, config_macro);

let config: Config = serde_json::from_value(config_macro).unwrap();
assert_eq!(config.protocol.message_timeout, 10000);
assert_eq!(config.get("integer").unwrap(), serde_json::json!(20));
assert_eq!(config.get("string").unwrap(), serde_json::json!("value2"));
}
}
Loading
Loading