Feature/spend coconut (#1261)

* Add coconut verifier structure for coconut protocol in gateway

* Add endpoint for validator-api cred verification

* Remove unused signature field

* Register new endpoint

* Improve validator-api config handling

* Aggregate verif result from all apis

* Simplify aggregate functions

* Verify cred on apis correctly

* Introduced coconut bandwidth contract to validator client

* Fix rebase double import

* Fix clippy on non-coconut

* Add multisig contract address to validator client

* Refactor Credential struct

* Do bincode magic in the coconut interface

* Implement serialization for credential and remove bindcode

* Fix clippy and don't remove dkg

* Client release funds proposal

* Add wrapper for blinded serial number

Also compare theta with a blinded serial number (in base 58 form)
for future double spend protection.

* Only post blinded serial number to blockchain

* Validator api propose credential spending

* Fix wallet

* Gateway calls proposal creation

* Query for proposal in verify coconut

* Remove db from git

* Verify against proposal description

* Validator apis vote based on verification of cred

* Fix wallet fmt

* Execute the release of funds

* Fix translation between token and bytes

* Update CHANGELOG
This commit is contained in:
Bogdan-Ștefan Neacşu
2022-06-02 16:54:59 +03:00
committed by GitHub
parent a5759ab227
commit 5f7b3db9a4
75 changed files with 1580 additions and 565 deletions
+52 -23
View File
@@ -2,16 +2,13 @@
// SPDX-License-Identifier: Apache-2.0
use crate::config::template::config_template;
use config::defaults::{default_api_endpoints, DEFAULT_NETWORK};
use config::defaults::DEFAULT_NETWORK;
use config::NymConfig;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::time::Duration;
use url::Url;
#[cfg(feature = "coconut")]
use coconut_interface::{Base58, KeyPair};
mod template;
pub const DEFAULT_LOCAL_VALIDATOR: &str = "http://localhost:26657";
@@ -82,17 +79,20 @@ impl NymConfig for Config {
}
fn config_directory(&self) -> PathBuf {
self.root_directory().join("config")
self.root_directory().join(self.get_id()).join("config")
}
fn data_directory(&self) -> PathBuf {
self.root_directory().join("data")
self.root_directory().join(self.get_id()).join("data")
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(default)]
pub struct Base {
/// ID specifies the human readable ID of this particular validator-api.
id: String,
local_validator: Url,
/// Address of the validator contract managing the network
@@ -105,6 +105,7 @@ pub struct Base {
impl Default for Base {
fn default() -> Self {
Base {
id: String::default(),
local_validator: DEFAULT_LOCAL_VALIDATOR
.parse()
.expect("default local validator is malformed!"),
@@ -128,11 +129,6 @@ pub struct NetworkMonitor {
#[serde(default)]
disabled_credentials_mode: bool,
/// Specifies list of all validators on the network issuing coconut credentials.
/// A special care must be taken to ensure they are in correct order.
/// The list must also contain THIS validator that is running the test
all_validator_apis: Vec<Url>,
/// Specifies the interval at which the network monitor sends the test packets.
#[serde(with = "humantime_serde")]
run_interval: Duration,
@@ -189,8 +185,10 @@ pub struct NetworkMonitor {
}
impl NetworkMonitor {
pub const DB_FILE: &'static str = "credentials_database.db";
fn default_credentials_database_path() -> PathBuf {
Config::default_data_directory(None).join("credentials_database.db")
Config::default_data_directory(None).join(Self::DB_FILE)
}
}
@@ -201,7 +199,6 @@ impl Default for NetworkMonitor {
min_gateway_reliability: DEFAULT_MIN_GATEWAY_RELIABILITY,
enabled: false,
disabled_credentials_mode: true,
all_validator_apis: default_api_endpoints(),
run_interval: DEFAULT_MONITOR_RUN_INTERVAL,
gateway_ping_interval: DEFAULT_GATEWAY_PING_INTERVAL,
gateway_sending_rate: DEFAULT_GATEWAY_SENDING_RATE,
@@ -230,8 +227,10 @@ pub struct NodeStatusAPI {
}
impl NodeStatusAPI {
pub const DB_FILE: &'static str = "db.sqlite";
fn default_database_path() -> PathBuf {
Config::default_data_directory(None).join("db.sqlite")
Config::default_data_directory(None).join(Self::DB_FILE)
}
}
@@ -279,15 +278,31 @@ impl Default for Rewarding {
}
}
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(default)]
#[cfg(feature = "coconut")]
pub struct CoconutSigner {
/// Specifies whether rewarding service is enabled in this process.
enabled: bool,
/// Base58 encoded signing keypair
keypair_bs58: String,
/// Path to the signing keypair
keypair_path: PathBuf,
/// Specifies list of all validators on the network issuing coconut credentials.
/// A special care must be taken to ensure they are in correct order.
/// The list must also contain THIS validator that is running the test
all_validator_apis: Vec<Url>,
}
#[cfg(feature = "coconut")]
impl Default for CoconutSigner {
fn default() -> Self {
CoconutSigner {
enabled: false,
keypair_path: PathBuf::default(),
all_validator_apis: config::defaults::default_api_endpoints(),
}
}
}
impl Config {
@@ -295,9 +310,18 @@ impl Config {
Config::default()
}
pub fn with_id(mut self, id: &str) -> Self {
self.base.id = id.to_string();
self.node_status_api.database_path =
Config::default_data_directory(Some(id)).join(NodeStatusAPI::DB_FILE);
self.network_monitor.credentials_database_path =
Config::default_data_directory(Some(id)).join(NetworkMonitor::DB_FILE);
self
}
#[cfg(feature = "coconut")]
pub fn keypair(&self) -> KeyPair {
KeyPair::try_from_bs58(self.coconut_signer.keypair_bs58.clone()).unwrap()
pub fn keypair_path(&self) -> PathBuf {
self.coconut_signer.keypair_path.clone()
}
pub fn with_network_monitor_enabled(mut self, enabled: bool) -> Self {
@@ -337,13 +361,14 @@ impl Config {
}
#[cfg(feature = "coconut")]
pub fn with_keypair<S: Into<String>>(mut self, keypair_bs58: S) -> Self {
self.coconut_signer.keypair_bs58 = keypair_bs58.into();
pub fn with_keypair_path(mut self, keypair_path: PathBuf) -> Self {
self.coconut_signer.keypair_path = keypair_path;
self
}
#[cfg(feature = "coconut")]
pub fn with_custom_validator_apis(mut self, validator_api_urls: Vec<Url>) -> Self {
self.network_monitor.all_validator_apis = validator_api_urls;
self.coconut_signer.all_validator_apis = validator_api_urls;
self
}
@@ -374,6 +399,10 @@ impl Config {
self
}
pub fn get_id(&self) -> String {
self.base.id.clone()
}
pub fn get_network_monitor_enabled(&self) -> bool {
self.network_monitor.enabled
}
@@ -474,7 +503,7 @@ impl Config {
// fix dead code warnings as this method is only ever used with coconut feature
#[cfg(feature = "coconut")]
pub fn get_all_validator_api_endpoints(&self) -> Vec<Url> {
self.network_monitor.all_validator_apis.clone()
self.coconut_signer.all_validator_apis.clone()
}
// TODO: Remove if still unused
+23 -12
View File
@@ -10,12 +10,18 @@ pub(crate) fn config_template() -> &'static str {
[base]
# ID specifies the human readable ID of this particular validator-api.
id = '{{ base.id }}'
# Validator server to which the API will be getting information about the network.
local_validator = '{{ base.local_validator }}'
# Address of the validator contract managing the network.
mixnet_contract_address = '{{ base.mixnet_contract_address }}'
# Mnemonic used for rewarding and validator interaction
mnemonic = '{{ base.mnemonic }}'
##### network monitor config options #####
[network_monitor]
@@ -26,15 +32,6 @@ enabled = {{ network_monitor.enabled }}
# to claim bandwidth without presenting bandwidth credentials.
disabled_credentials_mode = {{ network_monitor.disabled_credentials_mode }}
# Specifies list of all validators on the network issuing coconut credentials.
# A special care must be taken to ensure they are in correct order.
# The list must also contain THIS validator that is running the test
all_validator_apis = [
{{#each network_monitor.all_validator_apis }}
'{{this}}',
{{/each}}
]
# Specifies the interval at which the network monitor sends the test packets.
run_interval = '{{ network_monitor.run_interval }}'
@@ -92,13 +89,27 @@ database_path = '{{ node_status_api.database_path }}'
# Specifies whether rewarding service is enabled in this process.
enabled = {{ rewarding.enabled }}
# Mnemonic (currently of the network monitor) used for rewarding
mnemonic = '{{ rewarding.mnemonic }}'
# Specifies the minimum percentage of monitor test run data present in order to
# distribute rewards for given interval.
# Note, only values in range 0-100 are valid
minimum_interval_monitor_threshold = {{ rewarding.minimum_interval_monitor_threshold }}
[coconut_signer]
# Specifies whether rewarding service is enabled in this process.
enabled = {{ coconut_signer.enabled }}
# Path to the signing keypair
keypair_path = '{{ coconut_signer.keypair_path }}'
# Specifies list of all validators on the network issuing coconut credentials.
# A special care must be taken to ensure they are in correct order.
# The list must also contain THIS validator that is running the test
all_validator_apis = [
{{#each coconut_signer.all_validator_apis }}
'{{this}}',
{{/each}}
]
"#
}