From 4364c166a45cb591624030a88f28de02567f31dc Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 12:18:38 +1100 Subject: [PATCH 01/31] Extract get_swap function that allows for handling of non-present swaps --- nectar/src/database.rs | 22 +++++++++++++++------- nectar/src/database/hbit.rs | 12 ++++++------ nectar/src/database/herc20.rs | 16 ++++++++-------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/nectar/src/database.rs b/nectar/src/database.rs index 934f250b92..620d3a6e5f 100644 --- a/nectar/src/database.rs +++ b/nectar/src/database.rs @@ -109,7 +109,7 @@ impl Database { pub async fn insert_swap(&self, swap: SwapKind) -> anyhow::Result<()> { let swap_id = swap.swap_id(); - let stored_swap = self.get_swap(&swap_id); + let stored_swap = self.get_swap_or_bail(&swap_id); match stored_swap { Ok(_) => Err(anyhow!("Swap is already stored")), @@ -168,15 +168,23 @@ impl Database { .context("Could not flush db") } - fn get_swap(&self, swap_id: &SwapId) -> anyhow::Result { - let key = serialize(swap_id)?; - + fn get_swap_or_bail(&self, swap_id: &SwapId) -> anyhow::Result { let swap = self - .db - .get(&key)? + .get_swap(swap_id)? .ok_or_else(|| anyhow!("Swap does not exists {}", swap_id))?; - deserialize(&swap).context("Could not deserialize swap") + Ok(swap) + } + + fn get_swap(&self, swap_id: &SwapId) -> anyhow::Result> { + let key = serialize(swap_id)?; + + let swap = match self.db.get(&key)? { + Some(data) => deserialize(&data).context("Could not deserialize swap")?, + None => return Ok(None), + }; + + Ok(Some(swap)) } } diff --git a/nectar/src/database/hbit.rs b/nectar/src/database/hbit.rs index ac3552e989..3ec267f869 100644 --- a/nectar/src/database/hbit.rs +++ b/nectar/src/database/hbit.rs @@ -51,7 +51,7 @@ impl From for HbitFunded { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: hbit::Funded, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.hbit_funded { Some(_) => Err(anyhow!("Hbit Funded event is already stored")), @@ -82,7 +82,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.hbit_funded.map(Into::into)) } @@ -115,7 +115,7 @@ impl From for HbitRedeemed { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: hbit::Redeemed, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.hbit_redeemed { Some(_) => Err(anyhow!("Hbit Redeemed event is already stored")), @@ -146,7 +146,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.hbit_redeemed.map(Into::into)) } @@ -176,7 +176,7 @@ impl From for HbitRefunded { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: hbit::Refunded, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.hbit_refunded { Some(_) => Err(anyhow!("Hbit Refunded event is already stored")), None => { @@ -206,7 +206,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.hbit_refunded.map(Into::into)) } diff --git a/nectar/src/database/herc20.rs b/nectar/src/database/herc20.rs index 1046643b1e..a0456a7008 100644 --- a/nectar/src/database/herc20.rs +++ b/nectar/src/database/herc20.rs @@ -40,7 +40,7 @@ impl From for Herc20Deployed { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: herc20::Deployed, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.herc20_deployed { Some(_) => Err(anyhow!("Herc20 Deployed event is already stored")), @@ -71,7 +71,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.herc20_deployed.map(Into::into)) } @@ -104,7 +104,7 @@ impl From for Herc20Funded { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: herc20::Funded, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.herc20_funded { Some(_) => Err(anyhow!("Herc20 Funded event is already stored")), @@ -135,7 +135,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.herc20_funded.map(Into::into)) } @@ -168,7 +168,7 @@ impl From for Herc20Redeemed { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: herc20::Redeemed, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.herc20_redeemed { Some(_) => Err(anyhow!("Herc20 Redeemed event is already stored")), @@ -199,7 +199,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.herc20_redeemed.map(Into::into)) } @@ -229,7 +229,7 @@ impl From for Herc20Refunded { #[async_trait::async_trait] impl Save for Database { async fn save(&self, event: herc20::Refunded, swap_id: SwapId) -> anyhow::Result<()> { - let stored_swap = self.get_swap(&swap_id)?; + let stored_swap = self.get_swap_or_bail(&swap_id)?; match stored_swap.herc20_refunded { Some(_) => Err(anyhow!("Herc20 Refunded event is already stored")), @@ -260,7 +260,7 @@ impl Save for Database { impl Load for Database { fn load(&self, swap_id: SwapId) -> anyhow::Result> { - let swap = self.get_swap(&swap_id)?; + let swap = self.get_swap_or_bail(&swap_id)?; Ok(swap.herc20_refunded.map(Into::into)) } From cb214b16c30021b4ebd94885c0e92d88c2f46370 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 14:25:15 +1100 Subject: [PATCH 02/31] Allow full Swap to be loaded from the DB --- nectar/src/database.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nectar/src/database.rs b/nectar/src/database.rs index 620d3a6e5f..67f39e7324 100644 --- a/nectar/src/database.rs +++ b/nectar/src/database.rs @@ -188,6 +188,15 @@ impl Database { } } +impl Load for Database { + fn load(&self, swap_id: SwapId) -> anyhow::Result> { + let swap = self.get_swap(&swap_id)?; + let swap_kind = swap.map(|swap| SwapKind::from((swap, swap_id))); + + Ok(swap_kind) + } +} + /// These methods are used to prevent a peer from having more than one ongoing /// swap with nectar An active peer refers to one that has an ongoing swap with /// nectar. From 08728cec30af01e0fc4753f0fbee5229d99148f4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 14:28:04 +1100 Subject: [PATCH 03/31] Improve error logging of JSON-RPC client The previous error logged the error twice when printed with anyhow. We are not using the error outside of the module so we can just replace it with .context --- nectar/src/jsonrpc.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/nectar/src/jsonrpc.rs b/nectar/src/jsonrpc.rs index 79b8505f40..af97deed9c 100644 --- a/nectar/src/jsonrpc.rs +++ b/nectar/src/jsonrpc.rs @@ -1,5 +1,4 @@ use anyhow::Context; -use futures::TryFutureExt; use serde::{de::DeserializeOwned, Serialize}; use std::fmt::Debug; @@ -41,8 +40,8 @@ impl Client { .post(url.clone()) .json(&request) .send() - .map_err(ConnectionFailed) - .await? + .await + .context("failed to send request")? .json::>() .await .context("failed to deserialize JSON response as JSON-RPC response")? @@ -107,10 +106,6 @@ pub struct JsonRpcError { message: String, } -#[derive(Debug, thiserror::Error)] -#[error("connection error: {0}")] -pub struct ConnectionFailed(#[from] reqwest::Error); - pub fn serialize(t: T) -> anyhow::Result where T: Serialize, From 1ac8c30bf3cc170875e55c89ec31cf3fc9049583 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 9 Oct 2020 10:41:36 +1100 Subject: [PATCH 04/31] Introduce ethereum::Wallet::sign_and_send --- nectar/src/ethereum/wallet.rs | 138 +++++++++++++++++----------------- 1 file changed, 71 insertions(+), 67 deletions(-) diff --git a/nectar/src/ethereum/wallet.rs b/nectar/src/ethereum/wallet.rs index a129e6a702..61e66d569c 100644 --- a/nectar/src/ethereum/wallet.rs +++ b/nectar/src/ethereum/wallet.rs @@ -127,24 +127,15 @@ impl Wallet { }: DeployContract, gas_price: ether::Amount, ) -> anyhow::Result { - self.assert_chain(chain_id).await?; - - let nonce = self.get_transaction_count().await?; - - let transaction = clarity::Transaction { - nonce: nonce.into(), - gas_price: gas_price.into(), - gas_limit: gas_limit.into(), - to: clarity::Address::default(), - value: 0u64.into(), - data, - signature: None, - }; - let transaction_hex = self.sign(transaction)?; - let hash = self - .geth_client - .send_raw_transaction(transaction_hex) + .sign_and_send( + data, + 0u64.into(), + clarity::Address::default(), + gas_limit.into(), + gas_price.into(), + chain_id, + ) .await?; let contract_address = match self.wait_until_transaction_receipt(hash, chain_id).await? { @@ -179,10 +170,6 @@ impl Wallet { chain_id: ChainId, gas_price: ether::Amount, ) -> anyhow::Result { - self.assert_chain(chain_id).await?; - - let nonce = self.get_transaction_count().await?; - let gas_limit = match gas_limit { Some(gas_limit) => gas_limit.into(), None => { @@ -196,21 +183,15 @@ impl Wallet { .await? } }; - - let transaction = clarity::Transaction { - nonce: nonce.into(), - gas_price: gas_price.into(), - gas_limit, - to: to_clarity_address(to)?, - value: value.into(), - data: data.unwrap_or_default(), - signature: None, - }; - let transaction_hex = self.sign(transaction)?; - let hash = self - .geth_client - .send_raw_transaction(transaction_hex) + .sign_and_send( + data.unwrap_or_default(), + value.into(), + to_clarity_address(to)?, + gas_limit, + gas_price.into(), + chain_id, + ) .await?; let _ = self.wait_until_transaction_receipt(hash, chain_id).await?; @@ -225,10 +206,6 @@ impl Wallet { chain_id: ChainId, gas_price: ether::Amount, ) -> anyhow::Result { - self.assert_chain(chain_id).await?; - - let nonce = self.get_transaction_count().await?; - let to = to_clarity_address(to)?; let dai_contract_addr = to_clarity_address(self.chain.dai_contract_address())?; @@ -237,20 +214,15 @@ impl Wallet { clarity::abi::Token::Uint(Uint256::from_bytes_le(value.to_bytes().as_slice())), ])?; - let transaction = clarity::Transaction { - nonce: nonce.into(), - gas_price: gas_price.into(), - gas_limit: DAI_TRANSFER_GAS_LIMIT.into(), - to: dai_contract_addr, - value: 0u16.into(), - data, - signature: None, - }; - let transaction_hex = self.sign(transaction)?; - let hash = self - .geth_client - .send_raw_transaction(transaction_hex) + .sign_and_send( + data, + 0u64.into(), + dai_contract_addr, + DAI_TRANSFER_GAS_LIMIT.into(), + gas_price.into(), + chain_id, + ) .await?; let _ = self.wait_until_transaction_receipt(hash, chain_id).await?; @@ -269,28 +241,51 @@ impl Wallet { }: CallContract, gas_price: ether::Amount, ) -> anyhow::Result { - self.assert_chain(chain_id).await?; + let hash = self + .sign_and_send( + data.unwrap_or_default(), + 0u64.into(), + to_clarity_address(to)?, + gas_limit.into(), + gas_price.into(), + chain_id, + ) + .await?; - let nonce = self.get_transaction_count().await?; + let _ = self.wait_until_transaction_receipt(hash, chain_id).await?; - let transaction = clarity::Transaction { - nonce: nonce.into(), - gas_price: gas_price.into(), - gas_limit: gas_limit.into(), - to: to_clarity_address(to)?, - value: 0u32.into(), - data: data.unwrap_or_default(), - signature: None, - }; - let transaction_hex = self.sign(transaction)?; + Ok(hash) + } + + pub async fn sign_and_send( + &self, + data: Vec, + value: Uint256, + to: clarity::Address, + gas_limit: Uint256, + gas_price: Uint256, + chain_id: ChainId, + ) -> anyhow::Result { + let transaction_hex = self + .sign( + |nonce| clarity::Transaction { + nonce, + gas_price, + gas_limit, + to, + value, + data, + signature: None, + }, + chain_id, + ) + .await?; let hash = self .geth_client .send_raw_transaction(transaction_hex) .await?; - let _ = self.wait_until_transaction_receipt(hash, chain_id).await?; - Ok(hash) } @@ -369,7 +364,16 @@ impl Wallet { self.geth_client.gas_limit(request).await } - fn sign(&self, transaction: clarity::Transaction) -> anyhow::Result { + async fn sign( + &self, + transaction_fn: impl FnOnce(Uint256) -> clarity::Transaction, + chain_id: ChainId, + ) -> anyhow::Result { + self.assert_chain(chain_id).await?; + + let nonce = self.get_transaction_count().await?; + let transaction = transaction_fn(nonce.into()); + let signed_transaction = transaction.sign( &self.private_key, Some(u32::from(self.chain.chain_id()) as u64), From 3afbd4f6e02cecd4ca219b02ab00d131a4f67e0b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 14:26:13 +1100 Subject: [PATCH 05/31] Make ethereum::Wallet::sign public so we can use it outside of this module --- nectar/src/ethereum/wallet.rs | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/nectar/src/ethereum/wallet.rs b/nectar/src/ethereum/wallet.rs index 61e66d569c..f385098324 100644 --- a/nectar/src/ethereum/wallet.rs +++ b/nectar/src/ethereum/wallet.rs @@ -307,6 +307,32 @@ impl Wallet { .await } + pub async fn sign( + &self, + transaction_fn: impl FnOnce(Uint256) -> clarity::Transaction, + chain_id: ChainId, + ) -> anyhow::Result { + self.assert_chain(chain_id).await?; + + let nonce = self.get_transaction_count().await?; + let transaction = transaction_fn(nonce.into()); + + let signed_transaction = transaction.sign( + &self.private_key, + Some(u32::from(self.chain.chain_id()) as u64), + ); + let transaction_hex = format!( + "0x{}", + hex::encode( + signed_transaction + .to_bytes() + .context("failed to serialize signed transaction to bytes")? + ) + ); + + Ok(transaction_hex) + } + async fn get_transaction_receipt( &self, transaction_hash: Hash, @@ -364,32 +390,6 @@ impl Wallet { self.geth_client.gas_limit(request).await } - async fn sign( - &self, - transaction_fn: impl FnOnce(Uint256) -> clarity::Transaction, - chain_id: ChainId, - ) -> anyhow::Result { - self.assert_chain(chain_id).await?; - - let nonce = self.get_transaction_count().await?; - let transaction = transaction_fn(nonce.into()); - - let signed_transaction = transaction.sign( - &self.private_key, - Some(u32::from(self.chain.chain_id()) as u64), - ); - let transaction_hex = format!( - "0x{}", - hex::encode( - signed_transaction - .to_bytes() - .context("failed to serialize signed transaction to bytes")? - ) - ); - - Ok(transaction_hex) - } - #[cfg(test)] pub async fn deploy_dai_token_contract( &mut self, From 63b04f2e5ac6643d954278be4fe36b01d547e2c7 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 14:26:50 +1100 Subject: [PATCH 06/31] Move to_clarity_address to root of Ethereum module This allows us to use it outside of this module. --- nectar/src/ethereum.rs | 7 +++++++ nectar/src/ethereum/wallet.rs | 9 ++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/nectar/src/ethereum.rs b/nectar/src/ethereum.rs index 0105245115..fd86794787 100644 --- a/nectar/src/ethereum.rs +++ b/nectar/src/ethereum.rs @@ -11,6 +11,8 @@ pub use wallet::Wallet; pub const STANDARD_ETH_TRANSFER_GAS_LIMIT: u64 = 21_000; pub const DAI_TRANSFER_GAS_LIMIT: u64 = 100_000; +use anyhow::{Context, Result}; + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Chain { Mainnet, @@ -65,6 +67,11 @@ impl Chain { } } +pub fn to_clarity_address(to: Address) -> Result { + clarity::Address::from_slice(to.as_bytes()) + .context("failed to create private key from byte slice") +} + #[cfg(test)] impl crate::StaticStub for Chain { fn static_stub() -> Self { diff --git a/nectar/src/ethereum/wallet.rs b/nectar/src/ethereum/wallet.rs index f385098324..e65f184e46 100644 --- a/nectar/src/ethereum/wallet.rs +++ b/nectar/src/ethereum/wallet.rs @@ -2,11 +2,11 @@ use crate::{ ethereum::{ self, dai, ether, geth::{Client, EstimateGasRequest}, - Address, ChainId, Hash, DAI_TRANSFER_GAS_LIMIT, + to_clarity_address, Address, ChainId, Hash, DAI_TRANSFER_GAS_LIMIT, }, Seed, }; -use anyhow::{Context, Result}; +use anyhow::Context; use bitcoin::util::bip32::{DerivationPath, ExtendedPrivKey}; use clarity::Uint256; use comit::{ @@ -608,8 +608,3 @@ mod tests { .unwrap(); } } - -fn to_clarity_address(to: Address) -> Result { - clarity::Address::from_slice(to.as_bytes()) - .context("failed to create private key from byte slice") -} From 6519078cda5c6925691c7455881d44fd40ef9edc Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 14:27:22 +1100 Subject: [PATCH 07/31] Make SwapId implement FromStr This allows us to use it with struct-opt and parse SwapIds from the commandline. --- nectar/src/swap_id.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nectar/src/swap_id.rs b/nectar/src/swap_id.rs index a7ccdb88db..eab645917a 100644 --- a/nectar/src/swap_id.rs +++ b/nectar/src/swap_id.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use std::fmt; +use std::{fmt, str::FromStr}; use uuid::Uuid; #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] @@ -23,6 +23,14 @@ impl fmt::Display for SwapId { } } +impl FromStr for SwapId { + type Err = uuid::Error; + + fn from_str(s: &str) -> Result { + Ok(SwapId(Uuid::from_str(s)?)) + } +} + #[cfg(test)] mod arbitrary { use super::*; From 427be7efc872a786c0bcc5c26dae65dd459ebccb Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Oct 2020 17:15:36 +1100 Subject: [PATCH 08/31] Add commands to nectar for creating and signing redeem/refund tx These commands take the swap-id, the HTLC location and in case of redeem also the secret and produce a signed transaction for the particular ledger that just needs to be broadcasted in order to trigger this action. This can be useful in cases where nectar's swap execution gets stuck and one just wants to manually trigger a specific action. --- nectar/src/command.rs | 55 ++++++++++ nectar/src/command/create_transaction.rs | 126 +++++++++++++++++++++++ nectar/src/main.rs | 26 ++++- 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 nectar/src/command/create_transaction.rs diff --git a/nectar/src/command.rs b/nectar/src/command.rs index 472f48f256..c1a9a72773 100644 --- a/nectar/src/command.rs +++ b/nectar/src/command.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use structopt::StructOpt; mod balance; +mod create_transaction; mod deposit; mod resume_only; mod trade; @@ -15,11 +16,14 @@ use crate::{ history, network::ActivePeer, swap::SwapKind, + SwapId, }; use num::BigUint; use std::str::FromStr; pub use balance::balance; +use comit::Secret; +pub use create_transaction::create_transaction; pub use deposit::deposit; pub use resume_only::resume_only; use time::OffsetDateTime; @@ -64,6 +68,8 @@ pub enum Command { Withdraw(Withdraw), /// Only resume ongoing swaps, do not publish or accept new orders ResumeOnly, + /// Manually create and sign a transaction for a specific swap. + CreateTransaction(CreateTransaction), } pub fn dump_config(settings: Settings) -> anyhow::Result<()> { @@ -94,6 +100,48 @@ pub enum Withdraw { }, } +#[derive(StructOpt, Debug, Clone)] +pub enum CreateTransaction { + /// Create the transaction for the `redeem` action. + Redeem { + /// The ID of the swap. + swap_id: SwapId, + /// The hex-encoded, 32-byte secret needed to unlock the coins. + #[structopt(long, parse(try_from_str = parse_secret))] + secret: Secret, + /// The Bitcoin outpoint where the `hbit` HTLC is located in the form of + /// `:`. Only required for swaps where nectar buys BTC/DAI. + #[structopt(long)] + outpoint: Option<::bitcoin::OutPoint>, + /// The Ethereum address where the `herc20` HTLC is located. Only + /// required for swaps where nectar sells BTC/DAI. + #[structopt(long)] + address: Option, + }, + /// Create the transaction for the `refund` action. + Refund { + /// The ID of the swap. + swap_id: SwapId, + /// The Bitcoin outpoint where the `hbit` HTLC is located in the form of + /// `:`. Only required for swaps where nectar sells BTC/DAI. + #[structopt(long)] + outpoint: Option<::bitcoin::OutPoint>, + /// The Ethereum address where the `herc20` HTLC is located. Only + /// required for swaps where nectar buys BTC/DAI. + #[structopt(long)] + address: Option, + }, +} + +impl CreateTransaction { + pub fn swap_id(&self) -> SwapId { + match self { + CreateTransaction::Redeem { swap_id, .. } => *swap_id, + CreateTransaction::Refund { swap_id, .. } => *swap_id, + } + } +} + fn parse_bitcoin(str: &str) -> anyhow::Result { // TODO: In addition to providing an interface to withdraw satoshi, we could use // string instead of float here @@ -114,6 +162,13 @@ fn parse_ether(str: &str) -> anyhow::Result { ether::Amount::from_ether_str(str) } +fn parse_secret(str: &str) -> anyhow::Result { + let mut secret = [0u8; 32]; + hex::decode_to_slice(str, &mut secret)?; + + Ok(Secret::from(secret)) +} + pub fn into_history_trade( peer_id: libp2p::PeerId, swap: SwapKind, diff --git a/nectar/src/command/create_transaction.rs b/nectar/src/command/create_transaction.rs new file mode 100644 index 0000000000..de77540e47 --- /dev/null +++ b/nectar/src/command/create_transaction.rs @@ -0,0 +1,126 @@ +use crate::{ + bitcoin, + command::CreateTransaction, + database::{Database, Load}, + ethereum, + ethereum::to_clarity_address, + swap::SwapKind, +}; +use anyhow::{Context, Result}; + +pub async fn create_transaction( + input: CreateTransaction, + db: Database, + bitcoin_wallet: bitcoin::Wallet, + bitcoin_fee: bitcoin::Fee, + ethereum_wallet: ethereum::Wallet, + gas_price: ethereum::GasPrice, +) -> Result { + let swap_id = input.swap_id(); + let swap = db + .load(swap_id)? + .with_context(|| format!("unable to find swap with id {}", swap_id))?; + + let hex = match (swap, input) { + ( + SwapKind::HbitHerc20(params), + CreateTransaction::Redeem { + secret, outpoint, .. + }, + ) => { + let redeem_address = bitcoin_wallet.new_address().await?; + let vbyte_rate = bitcoin_fee.vbyte_rate().await?; + + let action = params.hbit_params.shared.build_redeem_action( + &crate::SECP, + params.hbit_params.shared.asset, /* TODO: allow the user to override this on the + * commandline */ + outpoint.context( + "HTLC outpoint required but not provided, please provide with --outpoint", + )?, + params.hbit_params.transient_sk, + redeem_address, + secret, + vbyte_rate, + )?; + + hex::encode(::bitcoin::consensus::serialize(&action.transaction)) + } + (SwapKind::HbitHerc20(params), CreateTransaction::Refund { address, .. }) => { + let action = params.herc20_params.build_refund_action(address.context( + "HTLC address required but not provided, please provide with --address", + )?); + let gas_price = gas_price.gas_price().await?; + let to = to_clarity_address(action.to)?; + let chain_id = action.chain_id; + + ethereum_wallet + .sign( + |nonce| clarity::Transaction { + nonce, + gas_price: gas_price.into(), + gas_limit: action.gas_limit.into(), + to, + value: 0u32.into(), + data: action.data.unwrap_or_default(), + signature: None, + }, + chain_id, + ) + .await? + } + + ( + SwapKind::Herc20Hbit(params), + CreateTransaction::Redeem { + secret, address, .. + }, + ) => { + let action = params.herc20_params.build_redeem_action( + address.context( + "HTLC address required but not provided, please provide with --address", + )?, + secret, + ); + + let gas_price = gas_price.gas_price().await?; + let to = to_clarity_address(action.to)?; + let chain_id = action.chain_id; + + ethereum_wallet + .sign( + |nonce| clarity::Transaction { + nonce, + gas_price: gas_price.into(), + gas_limit: action.gas_limit.into(), + to, + value: 0u32.into(), + data: action.data.unwrap_or_default(), + signature: None, + }, + chain_id, + ) + .await? + } + (SwapKind::Herc20Hbit(params), CreateTransaction::Refund { outpoint, .. }) => { + let redeem_address = bitcoin_wallet.new_address().await?; + let vbyte_rate = bitcoin_fee.vbyte_rate().await?; + + let action = params.hbit_params.shared.build_refund_action( + &crate::SECP, + params.hbit_params.shared.asset, /* TODO: allow the user to override this on the + * commandline */ + outpoint.context( + "HTLC outpoint required but not provided, please provide with --outpoint", + )?, + params.hbit_params.transient_sk, + redeem_address, + vbyte_rate, + )?; + + hex::encode(::bitcoin::consensus::serialize(&action.transaction)) + } + }; + + Ok(hex) +} diff --git a/nectar/src/main.rs b/nectar/src/main.rs index 06f73e5d95..599b3c2765 100644 --- a/nectar/src/main.rs +++ b/nectar/src/main.rs @@ -41,7 +41,8 @@ mod arbitrary; use crate::{ command::{ - balance, deposit, dump_config, resume_only, trade, wallet_info, withdraw, Command, Options, + balance, create_transaction, deposit, dump_config, resume_only, trade, wallet_info, + withdraw, Command, Options, }, config::{read_config, Settings}, fs::default_config_path, @@ -56,6 +57,7 @@ pub use rate::{Rate, Spread}; pub use seed::Seed; pub use swap_id::SwapId; +use crate::database::Database; #[cfg(test)] pub use test_harness::StaticStub; @@ -163,6 +165,28 @@ async fn main() -> Result<()> { .await .expect("Wrapping up") } + Command::CreateTransaction(input) => { + let bitcoind_client = bitcoin::Client::new(settings.bitcoin.bitcoind.node_url.clone()); + let bitcoin_fee = bitcoin::Fee::new(settings.bitcoin.clone(), bitcoind_client); + let ethereum_gas_price = ethereum::GasPrice::new(settings.ethereum.gas_price.clone()); + #[cfg(not(test))] + let db = Database::new(&settings.data.dir.join("database"))?; + #[cfg(test)] + let db = Database::new_test()?; + + let hex = create_transaction( + input, + db, + bitcoin_wallet.context("could not initialize bitcoin wallet")?, + bitcoin_fee, + ethereum_wallet.context("could not initialize ethereum wallet")?, + ethereum_gas_price, + ) + .await + .context("failed to create transaction")?; + + println!("{}", hex); + } }; Ok(()) From 8ca9e16897676fbe91a4201c91377adb1a160531 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 11:08:59 +1100 Subject: [PATCH 09/31] Merge master into dev instead of the release branch Previously, we've only merged the release branch back into dev after a release. That ensured that any commits to the release branch like bumping the version in the manifest and updating the changelog were also present in the dev branch. Even though those changes were merged back into dev, GitHub still considered a new release branch to be "out-of-date" with master because it was missing the _merge_ commit that represents the actual release. There is no semantic difference between merging the release branch and merging the master branch back into dev. We change the workflow to use the master branch to have the warning go away and avoid developers being distracted by it, thinking the have to action it somehow. --- .github/workflows/merge-release-branch-back-into-dev.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge-release-branch-back-into-dev.yml b/.github/workflows/merge-release-branch-back-into-dev.yml index 41123e04ec..42505f4dd4 100644 --- a/.github/workflows/merge-release-branch-back-into-dev.yml +++ b/.github/workflows/merge-release-branch-back-into-dev.yml @@ -13,13 +13,14 @@ jobs: name: Merge release-branch back into dev runs-on: ubuntu-latest steps: - - name: Create pull request for merging release-branch back into dev + - name: Create pull request for merging master back into dev uses: thomaseizinger/create-pull-request@1.0.0 with: GITHUB_TOKEN: ${{ secrets.BOTTY_GITHUB_TOKEN }} - head: ${{ github.event.pull_request.head.ref }} + head: master base: dev - title: Merge `${{ github.event.pull_request.head.ref }}` into `dev` + title: Merge `master` into `dev` body: | - This PR merges the `${{ github.event.pull_request.head.ref }}` branch back into `dev`. + This PR merges the `master` branch back into `dev`. This happens to ensure that the updates that happend on the release branch, i.e. CHANGELOG and manifest updates are also present on the dev branch. + Otherwise, GitHub will "complain" that the next release branch is not up to date with master because it is missing the merge commit from the last release. From 9f1b0b58b0f29caa2cbecf0793882b5e1e759dab Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 15:47:12 +1100 Subject: [PATCH 10/31] Bump to Rust 1.47 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 50aceaa7b7..21998d3c2d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.45.0 +1.47.0 From 68e7f64f3f3ca56098b425b8353b6cc6c0f63b85 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 16:15:51 +1100 Subject: [PATCH 11/31] Create a dedicated wrapper type for Ethereum's "Unformatted Data" This type knows how to serialize itself in the specified format and allows us to avoid repeating ourselves in several places. --- cnd/src/http_api/action.rs | 30 +++++-------------- .../ethereum/watch_for_contract_creation.rs | 4 +-- comit/src/ethereum.rs | 9 +++--- comit/src/herc20.rs | 4 +-- nectar/src/database/herc20.rs | 6 ++-- nectar/src/ethereum/geth.rs | 8 ++--- 6 files changed, 21 insertions(+), 40 deletions(-) diff --git a/cnd/src/http_api/action.rs b/cnd/src/http_api/action.rs index 4307e7c3f5..49b9a607a7 100644 --- a/cnd/src/http_api/action.rs +++ b/cnd/src/http_api/action.rs @@ -8,7 +8,7 @@ use crate::{ ethereum::ChainId, identity, transaction, RelativeTime, Secret, SecretHash, Timestamp, }; -use comit::ledger; +use comit::{ethereum::UnformattedData, ledger}; use serde::Serialize; #[derive(Clone, Debug, Serialize)] @@ -27,7 +27,7 @@ pub enum ActionResponseBody { min_median_block_time: Option, }, EthereumDeployContract { - data: EthereumData, + data: crate::ethereum::UnformattedData, amount: asset::Ether, gas_limit: crate::ethereum::U256, chain_id: ChainId, @@ -35,7 +35,7 @@ pub enum ActionResponseBody { EthereumCallContract { contract_address: identity::Ethereum, #[serde(skip_serializing_if = "Option::is_none")] - data: Option, + data: Option, gas_limit: crate::ethereum::U256, chain_id: ChainId, #[serde(skip_serializing_if = "Option::is_none")] @@ -69,23 +69,6 @@ pub enum ActionResponseBody { }, } -/// A wrapper type for serializing bytes to hex with a `0x` prefix. -/// -/// In the Ethereum ecosystem (i.e. Web3-based clients), the `data` field of a -/// transaction is serialized to hex with a `0x` prefix when represented as a -/// string. -/// We want our API to be easily interoperable with such clients, hence we -/// serialize this data already in that format so consumers of our API can -/// simply pass it along to a Web3-based client. -#[derive(Clone, Debug, Serialize)] -pub struct EthereumData(#[serde(with = "serde_hex::SerHexSeq::")] Vec); - -impl>> From for EthereumData { - fn from(data: T) -> Self { - EthereumData(data.into()) - } -} - impl ActionResponseBody { pub fn bitcoin_broadcast_signed_transaction( transaction: &transaction::Bitcoin, @@ -168,7 +151,7 @@ impl From for ActionResponseBody { } = action; ActionResponseBody::EthereumDeployContract { - data: EthereumData(data), + data: UnformattedData(data), amount, gas_limit: gas_limit.into(), chain_id, @@ -230,7 +213,7 @@ impl From for ActionResponseBody { ActionResponseBody::EthereumCallContract { contract_address: to, - data: data.map(EthereumData), + data: data.map(UnformattedData), gas_limit: gas_limit.into(), chain_id, min_block_timestamp, @@ -250,6 +233,7 @@ mod test { use crate::{ asset::ethereum::FromWei, bitcoin::Address as BitcoinAddress, ethereum::U256, identity, }; + use comit::ethereum::UnformattedData; use std::str::FromStr; #[test] @@ -274,7 +258,7 @@ mod test { #[test] fn deploy_contract_serializes_correctly_to_json() { let response_body = ActionResponseBody::EthereumDeployContract { - data: EthereumData::from(vec![0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10]), + data: UnformattedData(vec![0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10]), amount: asset::Ether::from_wei(10000u32), gas_limit: U256::from(1), chain_id: ChainId::from(3), diff --git a/comit/src/btsieve/ethereum/watch_for_contract_creation.rs b/comit/src/btsieve/ethereum/watch_for_contract_creation.rs index 74ce93e835..73243f695a 100644 --- a/comit/src/btsieve/ethereum/watch_for_contract_creation.rs +++ b/comit/src/btsieve/ethereum/watch_for_contract_creation.rs @@ -27,7 +27,7 @@ where // creates a contract. let is_contract_creation = transaction.to.is_none(); - let is_expected_contract = transaction.input.as_slice() == expected_bytecode; + let is_expected_contract = transaction.input.0.as_slice() == expected_bytecode; if !is_contract_creation { tracing::trace!("rejected because transaction doesn't create a contract"); @@ -38,7 +38,7 @@ where // only compute levenshtein distance if we are on trace level, converting to hex is expensive at this scale if tracing::level_enabled!(tracing::level_filters::LevelFilter::TRACE) { - let actual = hex::encode(&transaction.input); + let actual = hex::encode(&transaction.input.0); let expected = hex::encode(expected_bytecode); let distance = levenshtein::levenshtein(&actual, &expected); diff --git a/comit/src/ethereum.rs b/comit/src/ethereum.rs index c7e1854b7f..ceffd1d3d6 100644 --- a/comit/src/ethereum.rs +++ b/comit/src/ethereum.rs @@ -158,8 +158,7 @@ pub struct Transaction { /// Transfered value pub value: U256, /// Input data - #[serde(with = "serde_hex_data")] - pub input: Vec, + pub input: crate::ethereum::UnformattedData, } /// A log produced by a transaction. @@ -170,8 +169,7 @@ pub struct Log { /// Topics pub topics: Vec, /// Data - #[serde(with = "serde_hex_data")] - pub data: Vec, + pub data: crate::ethereum::UnformattedData, } /// The block returned from RPC calls. @@ -193,6 +191,9 @@ pub struct Block { pub transactions: Vec, } +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +pub struct UnformattedData(#[serde(with = "serde_hex_data")] pub Vec); + #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct ChainId(u32); diff --git a/comit/src/herc20.rs b/comit/src/herc20.rs index 40033eeef7..c36bac53ca 100644 --- a/comit/src/herc20.rs +++ b/comit/src/herc20.rs @@ -210,7 +210,7 @@ where let expected_asset = ¶ms.asset; - let quantity = Erc20Quantity::from_wei(U256::from_big_endian(&log.data)); + let quantity = Erc20Quantity::from_wei(U256::from_big_endian(&log.data.0)); let asset = Erc20::new(log.address, quantity); let event = match expected_asset.cmp(&asset) { @@ -244,7 +244,7 @@ where .await?; let secret = - Secret::from_vec(&log.data).expect("Must be able to construct secret from log data"); + Secret::from_vec(&log.data.0).expect("Must be able to construct secret from log data"); Ok(Redeemed { transaction, diff --git a/nectar/src/database/herc20.rs b/nectar/src/database/herc20.rs index 1046643b1e..42ff6b4229 100644 --- a/nectar/src/database/herc20.rs +++ b/nectar/src/database/herc20.rs @@ -7,11 +7,10 @@ use anyhow::{anyhow, Context}; use comit::{ asset::Erc20, ethereum, - ethereum::{Hash, Transaction, U256}, + ethereum::{Hash, Transaction, UnformattedData, U256}, identity, Secret, SecretHash, Timestamp, }; use serde::{Deserialize, Serialize}; -use serde_hex::{SerHexSeq, StrictPfx}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Herc20Deployed { @@ -271,8 +270,7 @@ pub struct EthereumTransaction { pub hash: Hash, pub to: Option, pub value: U256, - #[serde(with = "SerHexSeq::")] - pub input: Vec, + pub input: UnformattedData, } impl From for ethereum::Transaction { diff --git a/nectar/src/ethereum/geth.rs b/nectar/src/ethereum/geth.rs index 50f361c1e6..c3b44b9207 100644 --- a/nectar/src/ethereum/geth.rs +++ b/nectar/src/ethereum/geth.rs @@ -7,11 +7,10 @@ use asset::Erc20Quantity; use clarity::Uint256; use comit::{ asset::{self, ethereum::TryFromWei}, - ethereum::{ChainId, Hash, Transaction, TransactionReceipt}, + ethereum::{ChainId, Hash, Transaction, TransactionReceipt, UnformattedData}, }; use ethereum_types::U256; use num::{BigUint, Num}; -use serde_hex::{SerHexSeq, StrictPfx}; pub const JSONRPC_VERSION: &str = "2.0"; @@ -114,13 +113,12 @@ impl Client { #[derive(Debug, serde::Serialize)] struct CallRequest { to: Address, - #[serde(with = "SerHexSeq::")] - data: Vec, + data: UnformattedData, } let call_request = CallRequest { to: token_contract, - data: balance_of_fn(account)?, + data: UnformattedData(balance_of_fn(account)?), }; let quantity: String = self From efcbc1ceadb9b5a996603f4a3d75e2678cb59e4d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 16:19:49 +1100 Subject: [PATCH 12/31] Remove serde_hex With Rust 1.47, we can remove the serde_hex dependency and instead directly use the `hex` library for serializing arrays of arbitrary length. --- Cargo.lock | 54 +++---------------- cnd/Cargo.toml | 1 - comit/Cargo.toml | 1 - .../src/network/protocols/bitcoin_identity.rs | 4 +- .../network/protocols/lightning_identity.rs | 4 +- comit/src/network/protocols/secret_hash.rs | 3 +- nectar/Cargo.toml | 1 - 7 files changed, 11 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd8cae6c32..17f7b5e987 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,15 +93,6 @@ version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" -[[package]] -name = "array-init" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" -dependencies = [ - "nodrop", -] - [[package]] name = "arrayref" version = "0.3.6" @@ -570,7 +561,6 @@ dependencies = [ "regex", "reqwest", "serde", - "serde-hex", "serde_derive", "serde_json", "serde_urlencoded 0.7.0", @@ -625,7 +615,6 @@ dependencies = [ "rand 0.7.3", "reqwest", "serde", - "serde-hex", "serde_derive", "serde_json", "serdebug", @@ -1785,7 +1774,7 @@ dependencies = [ "parity-multiaddr", "parking_lot 0.10.2", "pin-project", - "smallvec 1.4.2", + "smallvec", "wasm-timer", ] @@ -1816,7 +1805,7 @@ dependencies = [ "ring", "rw-stream-sink", "sha2 0.8.2", - "smallvec 1.4.2", + "smallvec", "thiserror", "unsigned-varint 0.4.0", "void", @@ -1865,7 +1854,7 @@ dependencies = [ "prost-build", "rand 0.7.3", "sha2 0.8.2", - "smallvec 1.4.2", + "smallvec", "unsigned-varint 0.4.0", "wasm-timer", ] @@ -1923,7 +1912,7 @@ dependencies = [ "lru", "minicbor", "rand 0.7.3", - "smallvec 1.4.2", + "smallvec", "unsigned-varint 0.5.1", "wasm-timer", ] @@ -1939,7 +1928,7 @@ dependencies = [ "libp2p-core", "log 0.4.11", "rand 0.7.3", - "smallvec 1.4.2", + "smallvec", "void", "wasm-timer", ] @@ -2234,7 +2223,7 @@ dependencies = [ "futures", "log 0.4.11", "pin-project", - "smallvec 1.4.2", + "smallvec", "unsigned-varint 0.4.0", ] @@ -2288,7 +2277,6 @@ dependencies = [ "reqwest", "rust_decimal", "serde", - "serde-hex", "serde_cbor", "serde_json", "sled", @@ -2321,12 +2309,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "nohash-hasher" version = "0.2.0" @@ -2673,7 +2655,7 @@ dependencies = [ "cloudabi 0.0.3", "libc", "redox_syscall", - "smallvec 1.4.2", + "smallvec", "winapi 0.3.9", ] @@ -2688,7 +2670,7 @@ dependencies = [ "instant", "libc", "redox_syscall", - "smallvec 1.4.2", + "smallvec", "winapi 0.3.9", ] @@ -3437,17 +3419,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-hex" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca37e3e4d1b39afd7ff11ee4e947efae85adfddf4841787bfa47c470e96dc26d" -dependencies = [ - "array-init", - "serde", - "smallvec 0.6.13", -] - [[package]] name = "serde-rlp" version = "0.1.4" @@ -3662,15 +3633,6 @@ dependencies = [ "parking_lot 0.11.0", ] -[[package]] -name = "smallvec" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -dependencies = [ - "maybe-uninit", -] - [[package]] name = "smallvec" version = "1.4.2" diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 97f225ede9..b738e79641 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -36,7 +36,6 @@ pem = "0.8" rand = "0.7" reqwest = { version = "0.10", default-features = false, features = ["json", "native-tls-vendored"] } serde = { version = "1", features = ["derive"] } -serde-hex = "0.1.0" serde_derive = "1.0" serde_json = "1" serdebug = "1" diff --git a/comit/Cargo.toml b/comit/Cargo.toml index bc24d50ba8..e9eb7a3ce8 100644 --- a/comit/Cargo.toml +++ b/comit/Cargo.toml @@ -27,7 +27,6 @@ primitive-types = { version = "0.7", features = ["serde"] } rand = "0.7" reqwest = { version = "0.10", default-features = false, features = ["json", "native-tls-vendored"] } serde = { version = "1", features = ["derive"] } -serde-hex = "0.1.0" serde_derive = "1.0" serde_json = "1" serdebug = "1" diff --git a/comit/src/network/protocols/bitcoin_identity.rs b/comit/src/network/protocols/bitcoin_identity.rs index 6427f45301..82edb975b6 100644 --- a/comit/src/network/protocols/bitcoin_identity.rs +++ b/comit/src/network/protocols/bitcoin_identity.rs @@ -1,6 +1,5 @@ use crate::{identity, network::oneshot_protocol, SharedSwapId}; use serde::{Deserialize, Serialize}; -use serde_hex::{SerHex, Strict}; use serdebug::SerDebug; /// The message for the Bitcoin identity sharing protocol. @@ -9,8 +8,7 @@ pub struct Message { pub swap_id: SharedSwapId, /// A compressed Bitcoin public key, serialized as hex without a `0x` prefix /// as per convention in the Bitcoin ecosystem. - // TODO: Replace with #[serde(with = "hex")] on Rust 1.47 and remove serde-hex from dependencies - #[serde(with = "SerHex::")] + #[serde(with = "hex")] pub pubkey: [u8; 33], } diff --git a/comit/src/network/protocols/lightning_identity.rs b/comit/src/network/protocols/lightning_identity.rs index 5e3edf4cea..a765459366 100644 --- a/comit/src/network/protocols/lightning_identity.rs +++ b/comit/src/network/protocols/lightning_identity.rs @@ -1,6 +1,5 @@ use crate::{identity, network::oneshot_protocol, SharedSwapId}; use serde::{Deserialize, Serialize}; -use serde_hex::{SerHex, Strict}; use serdebug::SerDebug; /// The message for the Lightning identity sharing protocol. @@ -9,8 +8,7 @@ pub struct Message { pub swap_id: SharedSwapId, /// A Lightning node identifier is a compressed secp256k1 public key, /// serialized without a `0x` prefix. - // TODO: Replace with #[serde(with = "hex")] on Rust 1.47 and remove serde-hex from dependencies - #[serde(with = "SerHex::")] + #[serde(with = "hex")] pub pubkey: [u8; 33], } diff --git a/comit/src/network/protocols/secret_hash.rs b/comit/src/network/protocols/secret_hash.rs index 00d211add9..a5e89ee8c0 100644 --- a/comit/src/network/protocols/secret_hash.rs +++ b/comit/src/network/protocols/secret_hash.rs @@ -1,6 +1,5 @@ use crate::{network::oneshot_protocol, SecretHash, SharedSwapId}; use serde::{Deserialize, Serialize}; -use serde_hex::{SerHex, Strict}; use serdebug::SerDebug; /// The message for the secret hash sharing protocol. @@ -8,7 +7,7 @@ use serdebug::SerDebug; pub struct Message { pub swap_id: SharedSwapId, /// A SHA-256 hash, serialized as hex without a `0x` prefix. - #[serde(with = "SerHex::")] + #[serde(with = "hex")] pub secret_hash: [u8; 32], } diff --git a/nectar/Cargo.toml b/nectar/Cargo.toml index 4a4ce41a37..3d3bf6f5cd 100644 --- a/nectar/Cargo.toml +++ b/nectar/Cargo.toml @@ -28,7 +28,6 @@ pem = "0.8" reqwest = { version = "0.10", default-features = false, features = ["json", "native-tls-vendored"] } rust_decimal = "1.8" serde = { version = "1", features = ["derive"] } -serde-hex = "0.1" serde_cbor = "0.11" serde_json = "1.0" sled = "0.34" From aee20c48c5d254aa4e3dcdc16fb468d91b082aef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 14:03:03 +0000 Subject: [PATCH 13/31] Bump serde_json from 1.0.58 to 1.0.59 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.58...v1.0.59) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd8cae6c32..c5c6f34773 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3492,9 +3492,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", From f12cd81eafd50283f563cb5865c5fcdb8cc49a46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 14:03:13 +0000 Subject: [PATCH 14/31] Bump structopt from 0.3.19 to 0.3.20 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.19 to 0.3.20. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.19...v0.3.20) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd8cae6c32..03e606c20f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3804,9 +3804,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a7159e7d0dbcab6f9c980d7971ef50f3ff5753081461eeda120d5974a4ee95" +checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8" dependencies = [ "clap", "lazy_static", @@ -3815,9 +3815,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc47de4dfba76248d1e9169ccff240eea2a4dc1e34e309b95b2393109b4b383" +checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8" dependencies = [ "heck", "proc-macro-error", From 3019ff7fec27cf03eed6b013076c6e6fbca288d4 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 12 Oct 2020 15:34:19 +1100 Subject: [PATCH 15/31] Use lowercase for log levels Align with the other configuration parameters. --- cnd/CHANGELOG.md | 4 ++++ cnd/src/config/file.rs | 3 ++- nectar/CHANGELOG.md | 4 +--- nectar/sample-config.toml | 4 ++-- nectar/src/config/file.rs | 5 +++-- tests/src/environment/cnd_config.ts | 2 +- tests/src/environment/nectar_config.ts | 4 ++-- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/cnd/CHANGELOG.md b/cnd/CHANGELOG.md index f2e3a82381..667df3285b 100644 --- a/cnd/CHANGELOG.md +++ b/cnd/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Change log level configuration format from capitalised (e.g. "Debug") to lowercase (e.g. "debug"). + ## [cnd-0.9.0] - 2020-10-12 ### Added diff --git a/cnd/src/config/file.rs b/cnd/src/config/file.rs index 6cd541b953..3676d14457 100644 --- a/cnd/src/config/file.rs +++ b/cnd/src/config/file.rs @@ -136,6 +136,7 @@ pub struct Logging { } #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, PartialEq)] +#[serde(rename_all = "lowercase")] pub enum Level { Error, Warn, @@ -381,7 +382,7 @@ allowed_origins = "all" dir = "/tmp/comit/" [logging] -level = "Debug" +level = "debug" [bitcoin] network = "regtest" diff --git a/nectar/CHANGELOG.md b/nectar/CHANGELOG.md index 6e348a1bc2..c03b292ad0 100644 --- a/nectar/CHANGELOG.md +++ b/nectar/CHANGELOG.md @@ -18,10 +18,8 @@ Previously, unknown configuration keys would just be ignored. ### Changed - Update the expected network times to calculate the expiries: We expect Bitcoin's transactions to be included within 6 blocks and Ethereum's within 30 blocks. - -### Changed - - By default, use bitcoind's `estimatsmartfee` feature to estimate Bitcoin fees. For Ethereum, Eth Gas Station API is used. +- Change log level configuration format from capitalised (e.g. "Debug") to lowercase (e.g. "debug"). [Unreleased]: https://github.com/comit-network/comit-rs/compare/d5d26e42a2d8dd026ae94f2c8a9e0bd80ab81133...HEAD diff --git a/nectar/sample-config.toml b/nectar/sample-config.toml index 2e132ae20c..a04a2edbcc 100644 --- a/nectar/sample-config.toml +++ b/nectar/sample-config.toml @@ -29,8 +29,8 @@ listen = ["/ip4/0.0.0.0/tcp/9939"] dir = "/Users/froyer/Library/Application Support/nectar" [logging] -# Logging level for nectar: Error, Warn, Info, Debug or Trace. -level = "Info" +# Logging level for nectar: error, warn, info, debug or trace. +level = "info" [bitcoin] # The Bitcoin network nectar is acting on: mainnet, testnet or regtest diff --git a/nectar/src/config/file.rs b/nectar/src/config/file.rs index e2b827d17c..3748e9603a 100644 --- a/nectar/src/config/file.rs +++ b/nectar/src/config/file.rs @@ -129,6 +129,7 @@ pub struct Logging { } #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, PartialEq)] +#[serde(rename_all = "lowercase")] pub enum Level { Error, Warn, @@ -217,7 +218,7 @@ listen = ["/ip4/0.0.0.0/tcp/9939"] dir = "/tmp/nectar/" [logging] -level = "Debug" +level = "debug" [bitcoin] network = "regtest" @@ -360,7 +361,7 @@ listen = ["/ip4/0.0.0.0/tcp/9939"] dir = "/tmp/nectar/" [logging] -level = "Debug" +level = "debug" [bitcoin] network = "regtest" diff --git a/tests/src/environment/cnd_config.ts b/tests/src/environment/cnd_config.ts index eb863b6df3..1cbdd0ff70 100644 --- a/tests/src/environment/cnd_config.ts +++ b/tests/src/environment/cnd_config.ts @@ -25,7 +25,7 @@ export async function newCndConfig( listen: [`/ip4/0.0.0.0/tcp/${comitPort}`], }, logging: { - level: "Trace", + level: "trace", }, ...makeLedgerConfig(env, role), }; diff --git a/tests/src/environment/nectar_config.ts b/tests/src/environment/nectar_config.ts index 5e10e59ad0..99e353af94 100644 --- a/tests/src/environment/nectar_config.ts +++ b/tests/src/environment/nectar_config.ts @@ -16,7 +16,7 @@ export async function newNectarConfig(env: Environment): Promise { listen: [`/ip4/0.0.0.0/tcp/${comitPort}`], }, logging: { - level: "Trace", + level: "trace", }, ...makeLedgerConfig(env), ...makeMakerConfig(env), @@ -117,7 +117,7 @@ interface Data { } interface Logging { - level?: "Trace" | "Debug" | "Info" | "Warn" | "Error"; + level?: "trace" | "debug" | "info" | "warn" | "error"; } interface Bitcoin { From 20012bf1d1667ccf2a8f04ec813dce69f3d2ca71 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 14 Oct 2020 10:04:35 +1100 Subject: [PATCH 16/31] Fix email Team email is only accessible internally --- Cargo.lock | 16 ++++++++-------- cnd/Cargo.toml | 2 +- comit/Cargo.toml | 2 +- nectar/Cargo.toml | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5c6f34773..1fea7d76d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3175,9 +3175,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f45b719a674bf4b828ff318906d6c133264c793eff7a41e30074a45b5099e2" +checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" dependencies = [ "aho-corasick", "memchr", @@ -3197,9 +3197,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.19" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17be88d9eaa858870aa5e48cc406c206e4600e983fc4f06bbe5750d93d09761" +checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" [[package]] name = "remove_dir_all" @@ -3492,9 +3492,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" dependencies = [ "itoa", "ryu", @@ -4101,9 +4101,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.7" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" dependencies = [ "serde", ] diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 97f225ede9..9da883c803 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -1,5 +1,5 @@ [package] -authors = ["CoBloX developers "] +authors = ["CoBloX "] name = "cnd" version = "0.9.0" edition = "2018" diff --git a/comit/Cargo.toml b/comit/Cargo.toml index bc24d50ba8..6f4bdf5fec 100644 --- a/comit/Cargo.toml +++ b/comit/Cargo.toml @@ -1,5 +1,5 @@ [package] -authors = ["CoBloX developers "] +authors = ["CoBloX "] name = "comit" version = "0.1.0" edition = "2018" diff --git a/nectar/Cargo.toml b/nectar/Cargo.toml index 4a4ce41a37..667a71d2fb 100644 --- a/nectar/Cargo.toml +++ b/nectar/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nectar" version = "0.1.0" -authors = ["CoBloX Team "] +authors = ["CoBloX "] edition = "2018" [dependencies] From 8fca3541f517a0628dbe5487eee12174aa409d4d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 14:14:04 +1100 Subject: [PATCH 17/31] Make cnd's main function use `#[tokio::main]` This allows us to declare the function `async` and makes it more convenient to do async stuff during startup. --- cnd/src/main.rs | 64 +++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index e2e56847dc..466fe1a787 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -90,14 +90,16 @@ use comit::{ Side, Timestamp, }; use conquer_once::Lazy; +use futures::future; use rand::rngs::OsRng; use std::{env, process}; use structopt::StructOpt; -use tokio::{net::TcpListener, runtime}; +use tokio::{net::TcpListener, runtime::Handle}; pub static SECP: Lazy> = Lazy::new(Secp256k1::new); -fn main() -> anyhow::Result<()> { +#[tokio::main] +async fn main() -> anyhow::Result<()> { let options = cli::Options::from_args(); if options.version { @@ -131,11 +133,6 @@ fn main() -> anyhow::Result<()> { let _locked_datadir = &settings.data.dir.try_lock_exclusive()?; - let mut runtime = runtime::Builder::new() - .enable_all() - .threaded_scheduler() - .build()?; - let bitcoin_connector = { let config::Bitcoin { bitcoind, @@ -144,16 +141,11 @@ fn main() -> anyhow::Result<()> { } = &settings.bitcoin; let connector = BitcoindConnector::new(bitcoind.node_url.clone())?; - runtime.block_on(async { - match validate_connection_to_network(&connector, *network).await { - Ok(Err(network_mismatch)) => Err(network_mismatch), - Ok(Ok(())) => Ok(()), - Err(e) => { - tracing::warn!("Could not validate Bitcoin node config: {}", e); - Ok(()) - } - } - })?; + match validate_connection_to_network(&connector, *network).await { + Ok(Err(network_mismatch)) => return Err(network_mismatch.into()), + Ok(Ok(())) => {} + Err(e) => tracing::warn!("Could not validate Bitcoin node config: {}", e), + } const BITCOIN_BLOCK_CACHE_CAPACITY: usize = 144; @@ -164,16 +156,11 @@ fn main() -> anyhow::Result<()> { let config::Ethereum { geth, chain_id, .. } = &settings.ethereum; let connector = Web3Connector::new(geth.node_url.clone()); - runtime.block_on(async { - match validate_connection_to_network(&connector, *chain_id).await { - Ok(Err(network_mismatch)) => Err(network_mismatch), - Ok(Ok(())) => Ok(()), - Err(e) => { - tracing::warn!("Could not validate Ethereum node config: {}", e); - Ok(()) - } - } - })?; + match validate_connection_to_network(&connector, *chain_id).await { + Ok(Err(network_mismatch)) => return Err(network_mismatch.into()), + Ok(Ok(())) => {} + Err(e) => tracing::warn!("Could not validate Ethereum node config: {}", e), + } const ETHEREUM_BLOCK_CACHE_CAPACITY: usize = 720; const ETHEREUM_RECEIPT_CACHE_CAPACITY: usize = 720; @@ -202,24 +189,21 @@ fn main() -> anyhow::Result<()> { let connectors = Connectors::new(bitcoin_connector, ethereum_connector, lnd_connector_params); let storage = Storage::new(database, seed); - let swarm = runtime.block_on(Swarm::new( + let swarm = Swarm::new( &settings, seed, - runtime.handle().clone(), + Handle::current(), storage.clone(), connectors.clone(), - ))?; + ) + .await?; - let http_api_listener = runtime.block_on(bind_http_api_socket(&settings))?; - match runtime.block_on(respawn( - storage.clone(), - connectors.clone(), - runtime.handle().clone(), - )) { + let http_api_listener = bind_http_api_socket(&settings).await?; + match respawn(storage.clone(), connectors.clone(), Handle::current()).await { Ok(()) => {} Err(e) => tracing::warn!("failed to respawn swaps: {:#}", e), }; - match runtime.block_on(republish_open_orders(storage.clone(), swarm.clone())) { + match republish_open_orders(storage.clone(), swarm.clone()).await { Ok(()) => {} Err(e) => tracing::warn!("failed to republish orders: {:#}", e), }; @@ -231,7 +215,7 @@ fn main() -> anyhow::Result<()> { } }; - runtime.spawn(make_http_api_worker( + tokio::spawn(make_http_api_worker( settings, bitcoin_fees, options.network.unwrap_or_default(), @@ -240,9 +224,9 @@ fn main() -> anyhow::Result<()> { connectors, http_api_listener, )); - runtime.spawn(make_network_api_worker(swarm)); + tokio::spawn(make_network_api_worker(swarm)); - ::std::thread::park(); + future::pending::<()>().await; Ok(()) } From b482a9c5bd754c8893309bd708881c55267c67a5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 14:15:20 +1100 Subject: [PATCH 18/31] Make error handling more concise Returning in case of Err and continuing when Ok is exactly what the `?` operator does. Let's utilize that. --- cnd/src/main.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 466fe1a787..89e1e4030b 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -142,8 +142,7 @@ async fn main() -> anyhow::Result<()> { let connector = BitcoindConnector::new(bitcoind.node_url.clone())?; match validate_connection_to_network(&connector, *network).await { - Ok(Err(network_mismatch)) => return Err(network_mismatch.into()), - Ok(Ok(())) => {} + Ok(inner) => inner?, Err(e) => tracing::warn!("Could not validate Bitcoin node config: {}", e), } @@ -157,8 +156,7 @@ async fn main() -> anyhow::Result<()> { let connector = Web3Connector::new(geth.node_url.clone()); match validate_connection_to_network(&connector, *chain_id).await { - Ok(Err(network_mismatch)) => return Err(network_mismatch.into()), - Ok(Ok(())) => {} + Ok(inner) => inner?, Err(e) => tracing::warn!("Could not validate Ethereum node config: {}", e), } From 3758dc3cf8efcb5ca1796e77549cbcb14096a404 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 14:32:39 +1100 Subject: [PATCH 19/31] Import anyhow::Result within main.rs --- cnd/src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 89e1e4030b..e9fdfd9ef6 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -85,6 +85,7 @@ use self::{ storage::{RootSeed, Sqlite, Storage}, }; use ::bitcoin::secp256k1::{All, Secp256k1}; +use anyhow::Result; use comit::{ ledger, lnd::LndConnectorParams, LockProtocol, Never, RelativeTime, Role, Secret, SecretHash, Side, Timestamp, @@ -99,7 +100,7 @@ use tokio::{net::TcpListener, runtime::Handle}; pub static SECP: Lazy> = Lazy::new(Secp256k1::new); #[tokio::main] -async fn main() -> anyhow::Result<()> { +async fn main() -> Result<()> { let options = cli::Options::from_args(); if options.version { @@ -245,7 +246,7 @@ fn version() { /// Fails if we cannot bind to the socket. /// We do this ourselves so we can shut down if this fails and don't just panic /// some worker thread in tokio. -async fn bind_http_api_socket(settings: &Settings) -> anyhow::Result { +async fn bind_http_api_socket(settings: &Settings) -> Result { let listen_addr = settings.http_api.socket; let listener = TcpListener::bind(listen_addr).await?; From 8ab41ad4c4c310334ab09781f64e2197d6e7b95c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 14:50:27 +1100 Subject: [PATCH 20/31] Update formatting toolchain The nightly version we use for formatting is pretty old already. For example, if we were to use attributes on expressions, the formatter would complain that this is still unstable although it was already stablized. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9c6fbf8368..c273f6b42f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ RUSTUP = rustup TOOLCHAIN = $(shell cat rust-toolchain) CARGO = $(RUSTUP) run --install $(TOOLCHAIN) cargo --color always -NIGHTLY_TOOLCHAIN = nightly-2020-01-15 +NIGHTLY_TOOLCHAIN = nightly-2020-09-15 CARGO_NIGHTLY = $(RUSTUP) run --install $(NIGHTLY_TOOLCHAIN) cargo --color always GIT_HOOKS_PATH = ".githooks" From e223addf120b8ffacd08e27ab9444cdfacb8e883 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 15:13:59 +1100 Subject: [PATCH 21/31] Write all logs to stderr Printing diagnostics output to stderr is a useful thing for a commandline tool because it allows users to print the stdout output to a file or pipe it to other commands. --- cnd/src/trace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cnd/src/trace.rs b/cnd/src/trace.rs index 4d01b5b328..2c42ac2844 100644 --- a/cnd/src/trace.rs +++ b/cnd/src/trace.rs @@ -12,7 +12,7 @@ pub fn init_tracing(level: log::LevelFilter) -> anyhow::Result<()> { // We want upstream library log messages, just only at Info level. LogTracer::init_with_filter(LevelFilter::Info)?; - let is_terminal = atty::is(Stream::Stdout); + let is_terminal = atty::is(Stream::Stderr); let subscriber = FmtSubscriber::builder() .with_env_filter(format!("cnd={},comit={}", level, level)) .with_ansi(is_terminal) From c30e984858f1b0bf9489c21c5dd0869d5e60c67c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 13 Oct 2020 14:53:45 +1100 Subject: [PATCH 22/31] Add sub-commands to cnd that aid manual recovery For the hbit protocol, we create and sign the transaction for redeeming and refunding within the node. We can offer sub-commands that produce exactly these transactions for a swap. For the herc20 protocol, we don't create and sign these transactions. However, manually redeeming / refunding those is fairly trivial through MyEtherWallet as long as you have the secret. We offer a sub- command for printing the secret in case we are Alice. --- cnd/src/cli.rs | 58 +++++++++++++++- cnd/src/main.rs | 178 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 225 insertions(+), 11 deletions(-) diff --git a/cnd/src/cli.rs b/cnd/src/cli.rs index faa6a39e66..f25b700760 100644 --- a/cnd/src/cli.rs +++ b/cnd/src/cli.rs @@ -1,6 +1,9 @@ +use crate::LocalSwapId; +use comit::Secret; use std::path::PathBuf; +use structopt::StructOpt; -#[derive(structopt::StructOpt, Debug)] +#[derive(StructOpt, Debug)] pub struct Options { /// Path to configuration file #[structopt(short = "c", long = "config", parse(from_os_str))] @@ -17,4 +20,57 @@ pub struct Options { /// Which network to connect to #[structopt(short = "n", long = "network")] pub network: Option, + + /// Commands available + #[structopt(subcommand)] + pub cmd: Option, +} + +#[derive(StructOpt, Debug, Clone)] +pub enum Command { + /// Prints the secret in case this node acts in the role of Alice that was + /// derived for a specific swap. Bob doesn't get to choose the secret hence + /// this command will fail for swaps where this node acts as Bob. + PrintSecret { swap_id: LocalSwapId }, + /// Manually create and sign a transaction for a specific swap. + CreateTransaction(CreateTransaction), +} + +#[derive(StructOpt, Debug, Clone)] +pub enum CreateTransaction { + /// Create the transaction for the `redeem` action. + Redeem { + /// The ID of the swap. + swap_id: LocalSwapId, + /// The hex-encoded, 32-byte secret needed to unlock the coins. Only + /// needed if this node acts in the role of Bob for this swap. + #[structopt(long, parse(try_from_str = parse_secret))] + secret: Option, + /// The Bitcoin outpoint where the `hbit` HTLC is located in the form of + /// `:`. + #[structopt(long)] + outpoint: ::bitcoin::OutPoint, + /// The Bitcoin address the coins should be redeemed to. + #[structopt(long)] + address: ::bitcoin::Address, + }, + /// Create the transaction for the `refund` action. + Refund { + /// The ID of the swap. + swap_id: LocalSwapId, + /// The Bitcoin outpoint where the `hbit` HTLC is located in the form of + /// `:`. + #[structopt(long)] + outpoint: ::bitcoin::OutPoint, + /// The Bitcoin address the coins should be refunded to. + #[structopt(long)] + address: ::bitcoin::Address, + }, +} + +fn parse_secret(str: &str) -> anyhow::Result { + let mut secret = [0u8; 32]; + hex::decode_to_slice(str, &mut secret)?; + + Ok(Secret::from(secret)) } diff --git a/cnd/src/main.rs b/cnd/src/main.rs index e9fdfd9ef6..8006970224 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -84,8 +84,12 @@ use self::{ spawn::*, storage::{RootSeed, Sqlite, Storage}, }; +use crate::{ + cli::{Command, CreateTransaction}, + storage::{Load, SwapContext}, +}; use ::bitcoin::secp256k1::{All, Secp256k1}; -use anyhow::Result; +use anyhow::{Context, Result}; use comit::{ ledger, lnd::LndConnectorParams, LockProtocol, Never, RelativeTime, Role, Secret, SecretHash, Side, Timestamp, @@ -129,11 +133,28 @@ async fn main() -> Result<()> { })); let database = Sqlite::new_in_dir(&settings.data.dir)?; - let seed = RootSeed::from_dir_or_generate(&settings.data.dir, OsRng)?; + let storage = Storage::new(database, seed); let _locked_datadir = &settings.data.dir.try_lock_exclusive()?; + let bitcoin_fees = match &settings.bitcoin.fees { + config::BitcoinFees::StaticSatPerVbyte(fee) => BitcoinFees::static_rate(*fee), + config::BitcoinFees::CypherBlock(url) => { + BitcoinFees::block_cypher(url.clone(), options.network.unwrap_or_default()) + } + }; + + #[allow(clippy::print_stdout)] // The point of these sub-commands is to print to stdout. + if let Some(cmd) = options.cmd { + let to_print = execute_subcommand(cmd, &storage, &bitcoin_fees) + .await + .context("failed to execute subcommand")?; + + println!("{}", to_print); + return Ok(()); + } + let bitcoin_connector = { let config::Bitcoin { bitcoind, @@ -186,7 +207,6 @@ async fn main() -> Result<()> { .ok(); let connectors = Connectors::new(bitcoin_connector, ethereum_connector, lnd_connector_params); - let storage = Storage::new(database, seed); let swarm = Swarm::new( &settings, @@ -207,13 +227,6 @@ async fn main() -> Result<()> { Err(e) => tracing::warn!("failed to republish orders: {:#}", e), }; - let bitcoin_fees = match &settings.bitcoin.fees { - config::BitcoinFees::StaticSatPerVbyte(fee) => BitcoinFees::static_rate(*fee), - config::BitcoinFees::CypherBlock(url) => { - BitcoinFees::block_cypher(url.clone(), options.network.unwrap_or_default()) - } - }; - tokio::spawn(make_http_api_worker( settings, bitcoin_fees, @@ -284,3 +297,148 @@ async fn make_network_api_worker(swarm: Swarm) { worker.await } + +async fn execute_subcommand( + cmd: Command, + storage: &Storage, + bitcoin_fees: &BitcoinFees, +) -> Result { + match cmd { + Command::PrintSecret { swap_id } => { + let swap_context: SwapContext = storage + .load(swap_id) + .await + .with_context(|| format!("failed to load swap {} from database", swap_id))?; + + if let Role::Bob = swap_context.role { + anyhow::bail!( + "We are Bob for swap {} and Bob doesn't choose the secret", + swap_id + ) + } + + let secret = storage.seed.derive_swap_seed(swap_id).derive_secret(); + + Ok(format!("{:x}", secret)) + } + Command::CreateTransaction(CreateTransaction::Redeem { + swap_id, + secret, + outpoint, + address, + }) => { + let swap_context: SwapContext = storage + .load(swap_id) + .await + .with_context(|| format!("failed to load swap {} from database", swap_id))?; + + let secret = match (secret, swap_context.role) { + (Some(_), Role::Alice) => anyhow::bail!( + "We are Alice for swap {}, no need to provide a secret on the commandline", + swap_id + ), + (None, Role::Bob) => anyhow::bail!( + "We are Bob for swap {}, please provide the secret for this swap with --secret", + swap_id + ), + (Some(secret), Role::Bob) => secret, + (None, Role::Alice) => storage.seed.derive_swap_seed(swap_id).derive_secret(), + }; + + let hbit_params = match swap_context { + SwapContext { + alpha: LockProtocol::Hbit, + beta: LockProtocol::Herc20, + role: Role::Bob, + .. + } => { + let swap: Swap = storage.load(swap_id).await?; + + swap.alpha + } + SwapContext { + alpha: LockProtocol::Herc20, + beta: LockProtocol::Hbit, + role: Role::Alice, + .. + } => { + let swap: Swap = storage.load(swap_id).await?; + + swap.beta + } + _ => { + anyhow::bail!("Swap {} does either not involve hbit or we are not in the correct role to redeem it") + } + }; + + let transaction = hbit_params.build_redeem_action( + &*SECP, + hbit_params.asset, + outpoint, + storage + .seed + .derive_swap_seed(swap_id) + .derive_transient_redeem_identity(), + address, + secret, + bitcoin_fees.get_per_vbyte_rate().await?, + )?; + + Ok(hex::encode(::bitcoin::consensus::serialize( + &transaction.transaction, + ))) + } + Command::CreateTransaction(CreateTransaction::Refund { + swap_id, + outpoint, + address, + }) => { + let swap_context: SwapContext = storage + .load(swap_id) + .await + .with_context(|| format!("failed to load swap {} from database", swap_id))?; + + let hbit_params = match swap_context { + SwapContext { + alpha: LockProtocol::Hbit, + beta: LockProtocol::Herc20, + role: Role::Bob, + .. + } => { + let swap: Swap = storage.load(swap_id).await?; + + swap.alpha + } + SwapContext { + alpha: LockProtocol::Herc20, + beta: LockProtocol::Hbit, + role: Role::Alice, + .. + } => { + let swap: Swap = storage.load(swap_id).await?; + + swap.beta + } + _ => { + anyhow::bail!("Swap {} does either not involve hbit or we are not in the correct role to redeem it") + } + }; + + let transaction = hbit_params.build_refund_action( + &*SECP, + hbit_params.asset, + outpoint, + storage + .seed + .derive_swap_seed(swap_id) + .derive_transient_redeem_identity(), + address, + bitcoin_fees.get_per_vbyte_rate().await?, + )?; + + Ok(hex::encode(::bitcoin::consensus::serialize( + &transaction.transaction, + ))) + } + } +} From 97123ea63af82ef287019350419edfa7aa6a0100 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 14 Oct 2020 13:32:15 +1100 Subject: [PATCH 23/31] Update changelog with new sub commands --- cnd/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cnd/CHANGELOG.md b/cnd/CHANGELOG.md index 667df3285b..301d8e6c03 100644 --- a/cnd/CHANGELOG.md +++ b/cnd/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- `create-transaction` sub-command: Create a signed transactions for redeeming or refunding `hbit` protocols. +- `print-secret` sub-command: Prints the secret of a swap IF the node acts in the role of Alice for this swap. + ### Changed - Change log level configuration format from capitalised (e.g. "Debug") to lowercase (e.g. "debug"). From bc89539e08a7237aebaf191b72ffde87a8fc071d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2020 14:06:28 +0000 Subject: [PATCH 24/31] Bump serde_json from 1.0.58 to 1.0.59 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.58...v1.0.59) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5cf4b3d7e..e858c198fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3463,9 +3463,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", From 799041d5d7dd1820b7ee95edc8687a2445433939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2020 14:06:37 +0000 Subject: [PATCH 25/31] Bump toml from 0.5.6 to 0.5.7 Bumps [toml](https://github.com/alexcrichton/toml-rs) from 0.5.6 to 0.5.7. - [Release notes](https://github.com/alexcrichton/toml-rs/releases) - [Commits](https://github.com/alexcrichton/toml-rs/compare/0.5.6...0.5.7) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5cf4b3d7e..1f71387e1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4063,9 +4063,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" dependencies = [ "serde", ] From a7e581d960767eef8f5e5b6bc85d5dd3b467232d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2020 14:01:30 +0000 Subject: [PATCH 26/31] Bump serde from 1.0.116 to 1.0.117 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91294f84ac..4c420ba9bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3412,9 +3412,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" dependencies = [ "serde_derive", ] @@ -3452,9 +3452,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", From b79817081f6c39cb429174cd997de8a60180cb0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2020 14:01:33 +0000 Subject: [PATCH 27/31] Bump syn from 1.0.44 to 1.0.45 Bumps [syn](https://github.com/dtolnay/syn) from 1.0.44 to 1.0.45. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.44...1.0.45) Signed-off-by: dependabot[bot] --- Cargo.lock | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91294f84ac..c7b2a0e907 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,7 +121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -132,7 +132,7 @@ checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -814,7 +814,7 @@ checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -836,7 +836,7 @@ checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -885,7 +885,7 @@ dependencies = [ "hex 0.4.2", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -1174,7 +1174,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -1819,7 +1819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213" dependencies = [ "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -2113,7 +2113,7 @@ dependencies = [ "migrations_internals", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -2158,7 +2158,7 @@ checksum = "c214bf3d90099b52f3e4b328ae0fe34837fd0fab683ad1e10fceb4629106df48" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -2440,7 +2440,7 @@ checksum = "6f09b9841adb6b5e1f89ef7087ea636e0fd94b2851f887c1e3eb5d5f8228fab3" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -2724,7 +2724,7 @@ checksum = "c82fb1329f632c3552cf352d14427d57a511b1cf41db93b3a7d77906a82dcc8e" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -2792,7 +2792,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", "version_check 0.9.2", ] @@ -2895,7 +2895,7 @@ dependencies = [ "itertools", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -2933,7 +2933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "247df671941313a4e255a5015772917368f1b21bfedfbd89d68fbb27e802b2fa" dependencies = [ "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3458,7 +3458,7 @@ checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3723,7 +3723,7 @@ dependencies = [ "quote 1.0.7", "serde", "serde_derive", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3739,7 +3739,7 @@ dependencies = [ "serde_derive", "serde_json", "sha1", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3785,7 +3785,7 @@ dependencies = [ "proc-macro-error", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3803,7 +3803,7 @@ dependencies = [ "heck", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3831,9 +3831,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd" +checksum = "ea9c5432ff16d6152371f808fb5a871cd67368171b09bb21b43df8e4a47a3556" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", @@ -3848,7 +3848,7 @@ checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", "unicode-xid 0.2.1", ] @@ -3908,7 +3908,7 @@ checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -3967,7 +3967,7 @@ dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", "standback", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -4021,7 +4021,7 @@ checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -4097,7 +4097,7 @@ checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", ] [[package]] @@ -4429,7 +4429,7 @@ dependencies = [ "log 0.4.11", "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", "wasm-bindgen-shared", ] @@ -4463,7 +4463,7 @@ checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4614,6 +4614,6 @@ checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.44", + "syn 1.0.45", "synstructure", ] From 3f933d6adb9a283b40a5c40b8186f2eadf3308ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2020 14:05:54 +0000 Subject: [PATCH 28/31] Bump jasmine from 3.6.1 to 3.6.2 in /tests Bumps [jasmine](https://github.com/jasmine/jasmine-npm) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/jasmine/jasmine-npm/releases) - [Commits](https://github.com/jasmine/jasmine-npm/compare/v3.6.1...v3.6.2) Signed-off-by: dependabot[bot] --- tests/package.json | 2 +- tests/yarn.lock | 84 ++++------------------------------------------ 2 files changed, 7 insertions(+), 79 deletions(-) diff --git a/tests/package.json b/tests/package.json index e5ce964b78..ab1854b897 100644 --- a/tests/package.json +++ b/tests/package.json @@ -43,7 +43,7 @@ "find-cache-dir": "^3.3.1", "get-port": "^5.1.1", "glob": "^7.1.6", - "jasmine": "^3.6.1", + "jasmine": "^3.6.2", "jest": "^26.5.3", "lodash": "^4.17.20", "log4js": "^6.3.0", diff --git a/tests/yarn.lock b/tests/yarn.lock index c9e278f70f..e7d5e927ad 100644 --- a/tests/yarn.lock +++ b/tests/yarn.lock @@ -825,19 +825,6 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -1819,11 +1806,6 @@ cacheable-request@^2.1.1: normalize-url "2.0.1" responselike "1.0.2" -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2689,18 +2671,6 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -2981,19 +2951,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - glob@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" @@ -3393,11 +3350,6 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -3420,20 +3372,6 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" @@ -3586,12 +3524,12 @@ jasmine-core@~3.6.0: resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.6.0.tgz#491f3bb23941799c353ceb7a45b38a950ebc5a20" integrity sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw== -jasmine@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.6.1.tgz#a20456b309a669b547a3c24bb2120f16f70cfc65" - integrity sha512-Jqp8P6ZWkTVFGmJwBK46p+kJNrZCdqkQ4GL+PGuBXZwK1fM4ST9BizkYgIwCFqYYqnTizAy6+XG2Ej5dFrej9Q== +jasmine@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.6.2.tgz#a8df3fc92f2ef322bcdafb890f744f3ff5751e86" + integrity sha512-Uc0o2MRnC8TS1MjDrB8jE1umKEo2mflzGvdg0Ncs+yuLtOJ+uz/Wz8VmGsNGtuASr8+E0LDgPkOpvdoC76m5WQ== dependencies: - fast-glob "^2.2.6" + glob "^7.1.6" jasmine-core "~3.6.0" jest-changed-files@^26.5.2: @@ -4315,11 +4253,6 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - merkle-lib@^2.0.10: version "2.0.10" resolved "https://registry.yarnpkg.com/merkle-lib/-/merkle-lib-2.0.10.tgz#82b8dbae75e27a7785388b73f9d7725d0f6f3326" @@ -4330,7 +4263,7 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -4887,11 +4820,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" From 085053194fde0b2c591a8f5722c95f5b50c0397e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2020 14:06:06 +0000 Subject: [PATCH 29/31] Bump @types/node from 14.11.8 to 14.11.10 in /tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.11.8 to 14.11.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] --- tests/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/yarn.lock b/tests/yarn.lock index c9e278f70f..f2c3fb2312 100644 --- a/tests/yarn.lock +++ b/tests/yarn.lock @@ -1124,9 +1124,9 @@ "@types/node" "*" "@types/node@*", "@types/node@^14.11": - version "14.11.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.8.tgz#fe2012f2355e4ce08bca44aeb3abbb21cf88d33f" - integrity sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw== + version "14.11.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.10.tgz#8c102aba13bf5253f35146affbf8b26275069bef" + integrity sha512-yV1nWZPlMFpoXyoknm4S56y2nlTAuFYaJuQtYRAOU7xA/FJ9RY0Xm7QOkaYMMmr8ESdHIuUb6oQgR/0+2NqlyA== "@types/node@10.12.18": version "10.12.18" From a44997c430a01a60adf8b7a3e856bd57b495503d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2020 14:06:41 +0000 Subject: [PATCH 30/31] Bump jest from 26.5.3 to 26.6.0 in /tests Bumps [jest](https://github.com/facebook/jest) from 26.5.3 to 26.6.0. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/compare/v26.5.3...v26.6.0) Signed-off-by: dependabot[bot] --- tests/package.json | 2 +- tests/yarn.lock | 574 ++++++++++++++++++++++----------------------- 2 files changed, 288 insertions(+), 288 deletions(-) diff --git a/tests/package.json b/tests/package.json index ab1854b897..5bfb6ec545 100644 --- a/tests/package.json +++ b/tests/package.json @@ -44,7 +44,7 @@ "get-port": "^5.1.1", "glob": "^7.1.6", "jasmine": "^3.6.2", - "jest": "^26.5.3", + "jest": "^26.6.0", "lodash": "^4.17.20", "log4js": "^6.3.0", "morgan": "^1.10.0", diff --git a/tests/yarn.lock b/tests/yarn.lock index a2d57b0a7f..5b130f92e4 100644 --- a/tests/yarn.lock +++ b/tests/yarn.lock @@ -633,93 +633,93 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^26.5.2": - version "26.5.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.5.2.tgz#94fc4865b1abed7c352b5e21e6c57be4b95604a6" - integrity sha512-lJELzKINpF1v74DXHbCRIkQ/+nUV1M+ntj+X1J8LxCgpmJZjfLmhFejiMSbjjD66fayxl5Z06tbs3HMyuik6rw== +"@jest/console@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.0.tgz#fd4a4733df3c50260aefb227414296aee96e682f" + integrity sha512-ArGcZWAEYMWmWnc/QvxLDvFmGRPvmHeulhS7FUUAlUGR5vS/SqMfArsGaYmIFEThSotCMnEihwx1h62I1eg5lg== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^26.5.2" - jest-util "^26.5.2" + jest-message-util "^26.6.0" + jest-util "^26.6.0" slash "^3.0.0" -"@jest/core@^26.5.3": - version "26.5.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.5.3.tgz#712ed4adb64c3bda256a3f400ff1d3eb2a031f13" - integrity sha512-CiU0UKFF1V7KzYTVEtFbFmGLdb2g4aTtY0WlyUfLgj/RtoTnJFhh50xKKr7OYkdmBUlGFSa2mD1TU3UZ6OLd4g== +"@jest/core@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.0.tgz#04dd3e046e9ebbe06a4f330e05a67f21f7bb314a" + integrity sha512-7wbunxosnC5zXjxrEtTQSblFjRVOT8qz1eSytw8riEeWgegy3ct91NLPEP440CDuWrmW3cOLcEGxIf9q2u6O9Q== dependencies: - "@jest/console" "^26.5.2" - "@jest/reporters" "^26.5.3" - "@jest/test-result" "^26.5.2" - "@jest/transform" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/console" "^26.6.0" + "@jest/reporters" "^26.6.0" + "@jest/test-result" "^26.6.0" + "@jest/transform" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^26.5.2" - jest-config "^26.5.3" - jest-haste-map "^26.5.2" - jest-message-util "^26.5.2" + jest-changed-files "^26.6.0" + jest-config "^26.6.0" + jest-haste-map "^26.6.0" + jest-message-util "^26.6.0" jest-regex-util "^26.0.0" - jest-resolve "^26.5.2" - jest-resolve-dependencies "^26.5.3" - jest-runner "^26.5.3" - jest-runtime "^26.5.3" - jest-snapshot "^26.5.3" - jest-util "^26.5.2" - jest-validate "^26.5.3" - jest-watcher "^26.5.2" + jest-resolve "^26.6.0" + jest-resolve-dependencies "^26.6.0" + jest-runner "^26.6.0" + jest-runtime "^26.6.0" + jest-snapshot "^26.6.0" + jest-util "^26.6.0" + jest-validate "^26.6.0" + jest-watcher "^26.6.0" micromatch "^4.0.2" p-each-series "^2.1.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^26.5.2": - version "26.5.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.5.2.tgz#eba3cfc698f6e03739628f699c28e8a07f5e65fe" - integrity sha512-YjhCD/Zhkz0/1vdlS/QN6QmuUdDkpgBdK4SdiVg4Y19e29g4VQYN5Xg8+YuHjdoWGY7wJHMxc79uDTeTOy9Ngw== +"@jest/environment@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.0.tgz#695ee24cbf110456272caa9debbbf7e01afb2f78" + integrity sha512-l+5MSdiC4rUUrz8xPdj0TwHBwuoqMcAbFnsYDTn5FkenJl8b+lvC5NdJl1tVICGHWnx0fnjdd1luRZ7u3U4xyg== dependencies: - "@jest/fake-timers" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/fake-timers" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" - jest-mock "^26.5.2" + jest-mock "^26.6.0" -"@jest/fake-timers@^26.5.2": - version "26.5.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.5.2.tgz#1291ac81680ceb0dc7daa1f92c059307eea6400a" - integrity sha512-09Hn5Oraqt36V1akxQeWMVL0fR9c6PnEhpgLaYvREXZJAh2H2Y+QLCsl0g7uMoJeoWJAuz4tozk1prbR1Fc1sw== +"@jest/fake-timers@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.0.tgz#5b4cc83fab91029963c53e6e2716f02544323b22" + integrity sha512-7VQpjChrwlwvGNysS10lDBLOVLxMvMtpx0Xo6aIotzNVyojYk0NN0CR8R4T6h/eu7Zva/LB3P71jqwGdtADoag== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@sinonjs/fake-timers" "^6.0.1" "@types/node" "*" - jest-message-util "^26.5.2" - jest-mock "^26.5.2" - jest-util "^26.5.2" + jest-message-util "^26.6.0" + jest-mock "^26.6.0" + jest-util "^26.6.0" -"@jest/globals@^26.5.3": - version "26.5.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.5.3.tgz#90769b40e0af3fa0b28f6d8c5bbe3712467243fd" - integrity sha512-7QztI0JC2CuB+Wx1VdnOUNeIGm8+PIaqngYsZXQCkH2QV0GFqzAYc9BZfU0nuqA6cbYrWh5wkuMzyii3P7deug== +"@jest/globals@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.0.tgz#da2f58d17105b6a7531ee3c8724acb5f233400e2" + integrity sha512-rs3a/a8Lq8FgTx11SxbqIU2bDjsFU2PApl2oK2oUVlo84RSF76afFm2nLojW93AGssr715GHUwhq5b6mpCI5BQ== dependencies: - "@jest/environment" "^26.5.2" - "@jest/types" "^26.5.2" - expect "^26.5.3" + "@jest/environment" "^26.6.0" + "@jest/types" "^26.6.0" + expect "^26.6.0" -"@jest/reporters@^26.5.3": - version "26.5.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.5.3.tgz#e810e9c2b670f33f1c09e9975749260ca12f1c17" - integrity sha512-X+vR0CpfMQzYcYmMFKNY9n4jklcb14Kffffp7+H/MqitWnb0440bW2L76NGWKAa+bnXhNoZr+lCVtdtPmfJVOQ== +"@jest/reporters@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.0.tgz#2a8d631ad3b19a722fd0fae58ce9fa25e8aac1cf" + integrity sha512-PXbvHhdci5Rj1VFloolgLb+0kkdtzswhG8MzVENKJRI3O1ndwr52G6E/2QupjwrRcYnApZOelFf4nNpf5+SDxA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^26.5.2" - "@jest/test-result" "^26.5.2" - "@jest/transform" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/console" "^26.6.0" + "@jest/test-result" "^26.6.0" + "@jest/transform" "^26.6.0" + "@jest/types" "^26.6.0" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -730,9 +730,9 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^26.5.2" - jest-resolve "^26.5.2" - jest-util "^26.5.2" + jest-haste-map "^26.6.0" + jest-resolve "^26.6.0" + jest-util "^26.6.0" jest-worker "^26.5.0" slash "^3.0.0" source-map "^0.6.0" @@ -751,42 +751,42 @@ graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^26.5.2": - version "26.5.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.5.2.tgz#cc1a44cfd4db2ecee3fb0bc4e9fe087aa54b5230" - integrity sha512-E/Zp6LURJEGSCWpoMGmCFuuEI1OWuI3hmZwmULV0GsgJBh7u0rwqioxhRU95euUuviqBDN8ruX/vP/4bwYolXw== +"@jest/test-result@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.0.tgz#79705c8a57165777af5ef1d45c65dcc4a5965c11" + integrity sha512-LV6X1ry+sKjseQsIFz3e6XAZYxwidvmeJFnVF08fq98q08dF1mJYI0lDq/LmH/jas+R4s0pwnNGiz1hfC4ZUBw== dependencies: - "@jest/console" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/console" "^26.6.0" + "@jest/types" "^26.6.0" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^26.5.3": - version "26.5.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.5.3.tgz#9ae0ab9bc37d5171b28424029192e50229814f8d" - integrity sha512-Wqzb7aQ13L3T47xHdpUqYMOpiqz6Dx2QDDghp5AV/eUDXR7JieY+E1s233TQlNyl+PqtqgjVokmyjzX/HA51BA== +"@jest/test-sequencer@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.0.tgz#a9dbc6545b1c59e7f375b05466e172126609906d" + integrity sha512-rWPTMa+8rejvePZnJmnKkmKWh0qILFDPpN0qbSif+KNGvFxqqDGafMo4P2Y8+I9XWrZQBeXL9IxPL4ZzDgRlbw== dependencies: - "@jest/test-result" "^26.5.2" + "@jest/test-result" "^26.6.0" graceful-fs "^4.2.4" - jest-haste-map "^26.5.2" - jest-runner "^26.5.3" - jest-runtime "^26.5.3" + jest-haste-map "^26.6.0" + jest-runner "^26.6.0" + jest-runtime "^26.6.0" -"@jest/transform@^26.5.2": - version "26.5.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.5.2.tgz#6a0033a1d24316a1c75184d010d864f2c681bef5" - integrity sha512-AUNjvexh+APhhmS8S+KboPz+D3pCxPvEAGduffaAJYxIFxGi/ytZQkrqcKDUU0ERBAo5R7087fyOYr2oms1seg== +"@jest/transform@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.0.tgz#1a6b95d0c7f9b4f96dd3aab9d28422a9e5e4043e" + integrity sha512-NUNA1NMCyVV9g5NIQF1jzW7QutQhB/HAocteCiUyH0VhmLXnGMTfPYQu1G6IjPk+k1SWdh2PD+Zs1vMqbavWzg== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" babel-plugin-istanbul "^6.0.0" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^26.5.2" + jest-haste-map "^26.6.0" jest-regex-util "^26.0.0" - jest-util "^26.5.2" + jest-util "^26.6.0" micromatch "^4.0.2" pirates "^4.0.1" slash "^3.0.0" @@ -814,10 +814,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^26.5.2": - version "26.5.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.5.2.tgz#44c24f30c8ee6c7f492ead9ec3f3c62a5289756d" - integrity sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg== +"@jest/types@^26.6.0": + version "26.6.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.0.tgz#2c045f231bfd79d52514cda3fbc93ef46157fa6a" + integrity sha512-8pDeq/JVyAYw7jBGU83v8RMYAkdrRxLG3BGnAJuqaQAUd6GWBmND2uyl+awI88+hit48suLoLjNFtR+ZXxWaYg== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -1425,13 +1425,13 @@ axios@^0.20.0: dependencies: follow-redirects "^1.10.0" -babel-jest@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.5.2.tgz#164f367a35946c6cf54eaccde8762dec50422250" - integrity sha512-U3KvymF3SczA3vOL/cgiUFOznfMET+XDIXiWnoJV45siAp2pLMG8i2+/MGZlAC3f/F6Q40LR4M4qDrWZ9wkK8A== +babel-jest@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.0.tgz#eca57ac8af99d6e06047e595b1faf0b5adf8a7bb" + integrity sha512-JI66yILI7stzjHccAoQtRKcUwJrJb4oMIxLTirL3GdAjGpaUBQSjZDFi9LsPkN4gftsS4R2AThAJwOjJxadwbg== dependencies: - "@jest/transform" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/transform" "^26.6.0" + "@jest/types" "^26.6.0" "@types/babel__core" "^7.1.7" babel-plugin-istanbul "^6.0.0" babel-preset-jest "^26.5.0" @@ -2559,16 +2559,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.5.3.tgz#89d9795036f7358b0a9a5243238eb8086482d741" - integrity sha512-kkpOhGRWGOr+TEFUnYAjfGvv35bfP+OlPtqPIJpOCR9DVtv8QV+p8zG0Edqafh80fsjeE+7RBcVUq1xApnYglw== +expect@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.0.tgz#f48861317f62bb9f1248eaab7ae9e50a9a5a8339" + integrity sha512-EzhbZ1tbwcaa5Ok39BI11flIMeIUSlg1QsnXOrleaMvltwHsvIQPBtL710l+ma+qDFLUgktCXK4YuQzmHdm7cg== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" ansi-styles "^4.0.0" jest-get-type "^26.3.0" - jest-matcher-utils "^26.5.2" - jest-message-util "^26.5.2" + jest-matcher-utils "^26.6.0" + jest-message-util "^26.6.0" jest-regex-util "^26.0.0" express@^4.17.1: @@ -3532,57 +3532,57 @@ jasmine@^3.6.2: glob "^7.1.6" jasmine-core "~3.6.0" -jest-changed-files@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.5.2.tgz#330232c6a5c09a7f040a5870e8f0a9c6abcdbed5" - integrity sha512-qSmssmiIdvM5BWVtyK/nqVpN3spR5YyvkvPqz1x3BR1bwIxsWmU/MGwLoCrPNLbkG2ASAKfvmJpOduEApBPh2w== +jest-changed-files@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.0.tgz#63b04aa261b5733c6ade96b7dd24784d12d8bb2d" + integrity sha512-k8PZzlp3cRWDe0fDc/pYs+c4w36+hiWXe1PpW/pW1UJmu1TNTAcQfZUrVYleij+uEqlY6z4mPv7Iff3kY0o5SQ== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" execa "^4.0.0" throat "^5.0.0" -jest-cli@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.5.3.tgz#f936b98f247b76b7bc89c7af50af82c88e356a80" - integrity sha512-HkbSvtugpSXBf2660v9FrNVUgxvPkssN8CRGj9gPM8PLhnaa6zziFiCEKQAkQS4uRzseww45o0TR+l6KeRYV9A== +jest-cli@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.0.tgz#dc3ae34fd5937310493ed07dc79c5ffba2bf6671" + integrity sha512-lJAMZGpmML+y3Kfln6L5DGRTfKGQ+n1JDM1RQstojSLUhe/EaXWR8vmcx70v4CyJKvFZs7c/0QDkPX5ra/aDew== dependencies: - "@jest/core" "^26.5.3" - "@jest/test-result" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/core" "^26.6.0" + "@jest/test-result" "^26.6.0" + "@jest/types" "^26.6.0" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^26.5.3" - jest-util "^26.5.2" - jest-validate "^26.5.3" + jest-config "^26.6.0" + jest-util "^26.6.0" + jest-validate "^26.6.0" prompts "^2.0.1" yargs "^15.4.1" -jest-config@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.5.3.tgz#baf51c9be078c2c755c8f8a51ec0f06c762c1d3f" - integrity sha512-NVhZiIuN0GQM6b6as4CI5FSCyXKxdrx5ACMCcv/7Pf+TeCajJhJc+6dwgdAVPyerUFB9pRBIz3bE7clSrRge/w== +jest-config@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.0.tgz#cb879a37002f881edb66d673fd40b6704595de89" + integrity sha512-RCR1Kf7MGJ5waVCvrj/k3nCAJKquWZlzs8rkskzj0KlG392hNBOaYd5FQ4cCac08j6pwfIDOwNvMcy0/FqguJg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^26.5.3" - "@jest/types" "^26.5.2" - babel-jest "^26.5.2" + "@jest/test-sequencer" "^26.6.0" + "@jest/types" "^26.6.0" + babel-jest "^26.6.0" chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-environment-jsdom "^26.5.2" - jest-environment-node "^26.5.2" + jest-environment-jsdom "^26.6.0" + jest-environment-node "^26.6.0" jest-get-type "^26.3.0" - jest-jasmine2 "^26.5.3" + jest-jasmine2 "^26.6.0" jest-regex-util "^26.0.0" - jest-resolve "^26.5.2" - jest-util "^26.5.2" - jest-validate "^26.5.3" + jest-resolve "^26.6.0" + jest-util "^26.6.0" + jest-validate "^26.6.0" micromatch "^4.0.2" - pretty-format "^26.5.2" + pretty-format "^26.6.0" jest-diff@^25.2.1: version "25.5.0" @@ -3594,15 +3594,15 @@ jest-diff@^25.2.1: jest-get-type "^25.2.6" pretty-format "^25.5.0" -jest-diff@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.5.2.tgz#8e26cb32dc598e8b8a1b9deff55316f8313c8053" - integrity sha512-HCSWDUGwsov5oTlGzrRM+UPJI/Dpqi9jzeV0fdRNi3Ch5bnoXhnyJMmVg2juv9081zLIy3HGPI5mcuGgXM2xRA== +jest-diff@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.0.tgz#5e5bbbaf93ec5017fae2b3ef12fc895e29988379" + integrity sha512-IH09rKsdWY8YEY7ii2BHlSq59oXyF2pK3GoK+hOK9eD/x6009eNB5Jv1shLMKgxekodPzLlV7eZP1jPFQYds8w== dependencies: chalk "^4.0.0" diff-sequences "^26.5.0" jest-get-type "^26.3.0" - pretty-format "^26.5.2" + pretty-format "^26.6.0" jest-docblock@^26.0.0: version "26.0.0" @@ -3611,41 +3611,41 @@ jest-docblock@^26.0.0: dependencies: detect-newline "^3.0.0" -jest-each@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.5.2.tgz#35e68d6906a7f826d3ca5803cfe91d17a5a34c31" - integrity sha512-w7D9FNe0m2D3yZ0Drj9CLkyF/mGhmBSULMQTypzAKR746xXnjUrK8GUJdlLTWUF6dd0ks3MtvGP7/xNFr9Aphg== +jest-each@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.0.tgz#9e9d90a4fc5a79e1d99a008897038325a6c7fbbf" + integrity sha512-7LzSNwNviYnm4FWK46itIE03NqD/8O8/7tVQ5rwTdTNrmPMQoQ1Z7hEFQ1uzRReluOFislpurpnQ0QsclSiDkA== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" chalk "^4.0.0" jest-get-type "^26.3.0" - jest-util "^26.5.2" - pretty-format "^26.5.2" + jest-util "^26.6.0" + pretty-format "^26.6.0" -jest-environment-jsdom@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.5.2.tgz#5feab05b828fd3e4b96bee5e0493464ddd2bb4bc" - integrity sha512-fWZPx0bluJaTQ36+PmRpvUtUlUFlGGBNyGX1SN3dLUHHMcQ4WseNEzcGGKOw4U5towXgxI4qDoI3vwR18H0RTw== +jest-environment-jsdom@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.0.tgz#2ce353fb82d27a9066bfea3ff2c27d9405076c69" + integrity sha512-bXO9IG7a3YlyiHxwfKF+OWoTA+GIw4FrD+Y0pb6CC+nKs5JuSRZmR2ovEX6PWo6KY42ka3JoZOp3KEnXiFPPCg== dependencies: - "@jest/environment" "^26.5.2" - "@jest/fake-timers" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/environment" "^26.6.0" + "@jest/fake-timers" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" - jest-mock "^26.5.2" - jest-util "^26.5.2" + jest-mock "^26.6.0" + jest-util "^26.6.0" jsdom "^16.4.0" -jest-environment-node@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.5.2.tgz#275a0f01b5e47447056f1541a15ed4da14acca03" - integrity sha512-YHjnDsf/GKFCYMGF1V+6HF7jhY1fcLfLNBDjhAOvFGvt6d8vXvNdJGVM7uTZ2VO/TuIyEFhPGaXMX5j3h7fsrA== +jest-environment-node@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.0.tgz#97f6e48085e67bda43b97f48e678ce78d760cd14" + integrity sha512-kWU6ZD1h6fs7sIl6ufuK0sXW/3d6WLaj48iow0NxhgU6eY89d9K+0MVmE0cRcVlh53yMyxTK6b+TnhLOnlGp/A== dependencies: - "@jest/environment" "^26.5.2" - "@jest/fake-timers" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/environment" "^26.6.0" + "@jest/fake-timers" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" - jest-mock "^26.5.2" - jest-util "^26.5.2" + jest-mock "^26.6.0" + jest-util "^26.6.0" jest-get-type@^25.2.6: version "25.2.6" @@ -3657,12 +3657,12 @@ jest-get-type@^26.3.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.5.2.tgz#a15008abfc502c18aa56e4919ed8c96304ceb23d" - integrity sha512-lJIAVJN3gtO3k4xy+7i2Xjtwh8CfPcH08WYjZpe9xzveDaqGw9fVNCpkYu6M525wKFVkLmyi7ku+DxCAP1lyMA== +jest-haste-map@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.0.tgz#4cd392bc51109bd8e0f765b2d5afa746bebb5ce2" + integrity sha512-RpNqAGMR58uG9E9vWITorX2/R7he/tSbHWldX5upt1ymEcmCaXczqXxjqI6xOtRR8Ev6ZEYDfgSA5Fy7WHUL5w== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" @@ -3670,7 +3670,7 @@ jest-haste-map@^26.5.2: graceful-fs "^4.2.4" jest-regex-util "^26.0.0" jest-serializer "^26.5.0" - jest-util "^26.5.2" + jest-util "^26.6.0" jest-worker "^26.5.0" micromatch "^4.0.2" sane "^4.0.3" @@ -3678,55 +3678,55 @@ jest-haste-map@^26.5.2: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.5.3.tgz#baad2114ce32d16aff25aeb877d18bb4e332dc4c" - integrity sha512-nFlZOpnGlNc7y/+UkkeHnvbOM+rLz4wB1AimgI9QhtnqSZte0wYjbAm8hf7TCwXlXgDwZxAXo6z0a2Wzn9FoOg== +jest-jasmine2@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.0.tgz#1b59e26aa56651bae3d4637965c8cd4d3851de6d" + integrity sha512-2E3c+0A9y2OIK5caw5qlcm3b4doaf8FSfXKTX3xqKTUJoR4zXh0xvERBNWxZP9xMNXEi/2Z3LVsZpR2hROgixA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.5.2" + "@jest/environment" "^26.6.0" "@jest/source-map" "^26.5.0" - "@jest/test-result" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/test-result" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^26.5.3" + expect "^26.6.0" is-generator-fn "^2.0.0" - jest-each "^26.5.2" - jest-matcher-utils "^26.5.2" - jest-message-util "^26.5.2" - jest-runtime "^26.5.3" - jest-snapshot "^26.5.3" - jest-util "^26.5.2" - pretty-format "^26.5.2" + jest-each "^26.6.0" + jest-matcher-utils "^26.6.0" + jest-message-util "^26.6.0" + jest-runtime "^26.6.0" + jest-snapshot "^26.6.0" + jest-util "^26.6.0" + pretty-format "^26.6.0" throat "^5.0.0" -jest-leak-detector@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.5.2.tgz#83fcf9a4a6ef157549552cb4f32ca1d6221eea69" - integrity sha512-h7ia3dLzBFItmYERaLPEtEKxy3YlcbcRSjj0XRNJgBEyODuu+3DM2o62kvIFvs3PsaYoIIv+e+nLRI61Dj1CNw== +jest-leak-detector@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.0.tgz#a211c4c7627743e8d87b392bf92502cd64275df3" + integrity sha512-3oMv34imWTl1/nwKnmE/DxYo3QqHnZeF3nO6UzldppkhW0Za7OY2DYyWiamqVzwdUrjhoQkY5g+aF6Oc3alYEQ== dependencies: jest-get-type "^26.3.0" - pretty-format "^26.5.2" + pretty-format "^26.6.0" -jest-matcher-utils@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.5.2.tgz#6aa2c76ce8b9c33e66f8856ff3a52bab59e6c85a" - integrity sha512-W9GO9KBIC4gIArsNqDUKsLnhivaqf8MSs6ujO/JDcPIQrmY+aasewweXVET8KdrJ6ADQaUne5UzysvF/RR7JYA== +jest-matcher-utils@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.0.tgz#8f57d78353275bfa7a3ccea128c1030b347138e2" + integrity sha512-BUy/dQYb7ELGRazmK4ZVkbfPYCaNnrMtw1YljVhcKzWUxBM0xQ+bffrfnMLdRZp4wUUcT4ahaVnA3VWZtXWP9Q== dependencies: chalk "^4.0.0" - jest-diff "^26.5.2" + jest-diff "^26.6.0" jest-get-type "^26.3.0" - pretty-format "^26.5.2" + pretty-format "^26.6.0" -jest-message-util@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.5.2.tgz#6c4c4c46dcfbabb47cd1ba2f6351559729bc11bb" - integrity sha512-Ocp9UYZ5Jl15C5PNsoDiGEk14A4NG0zZKknpWdZGoMzJuGAkVt10e97tnEVMYpk7LnQHZOfuK2j/izLBMcuCZw== +jest-message-util@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.0.tgz#c3499053022e05765f71b8c2535af63009e2d4be" + integrity sha512-WPAeS38Kza29f04I0iOIQrXeiebRXjmn6cFehzI7KKJOgT0NmqYAcLgjWnIAfKs5FBmEQgje1kXab0DaLKCl2w== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" @@ -3734,12 +3734,12 @@ jest-message-util@^26.5.2: slash "^3.0.0" stack-utils "^2.0.2" -jest-mock@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.5.2.tgz#c9302e8ef807f2bfc749ee52e65ad11166a1b6a1" - integrity sha512-9SiU4b5PtO51v0MtJwVRqeGEroH66Bnwtq4ARdNP7jNXbpT7+ByeWNAk4NeT/uHfNSVDXEXgQo1XRuwEqS6Rdw== +jest-mock@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.0.tgz#5d13a41f3662a98a55c7742ac67c482e232ded13" + integrity sha512-HsNmL8vVIn1rL1GWA21Drpy9Cl+7GImwbWz/0fkWHrUXVzuaG7rP0vwLtE+/n70Mt0U8nPkz8fxioi3SC0wqhw== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -3752,83 +3752,83 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-resolve-dependencies@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.5.3.tgz#11483f91e534bdcd257ab21e8622799e59701aba" - integrity sha512-+KMDeke/BFK+mIQ2IYSyBz010h7zQaVt4Xie6cLqUGChorx66vVeQVv4ErNoMwInnyYHi1Ud73tDS01UbXbfLQ== +jest-resolve-dependencies@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.0.tgz#05bfecc977a3a48929fc7d9876f03d93a16b7df0" + integrity sha512-4di+XUT7LwJJ8b8qFEEDQssC5+aeVjLhvRICCaS4alh/EVS9JCT1armfJ3pnSS8t4o6659WbMmKVo82H4LuUVw== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" jest-regex-util "^26.0.0" - jest-snapshot "^26.5.3" + jest-snapshot "^26.6.0" -jest-resolve@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.5.2.tgz#0d719144f61944a428657b755a0e5c6af4fc8602" - integrity sha512-XsPxojXGRA0CoDD7Vis59ucz2p3cQFU5C+19tz3tLEAlhYKkK77IL0cjYjikY9wXnOaBeEdm1rOgSJjbZWpcZg== +jest-resolve@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.0.tgz#070fe7159af87b03e50f52ea5e17ee95bbee40e1" + integrity sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" chalk "^4.0.0" graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.2" - jest-util "^26.5.2" + jest-util "^26.6.0" read-pkg-up "^7.0.1" resolve "^1.17.0" slash "^3.0.0" -jest-runner@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.5.3.tgz#800787459ea59c68e7505952933e33981dc3db38" - integrity sha512-qproP0Pq7IIule+263W57k2+8kWCszVJTC9TJWGUz0xJBr+gNiniGXlG8rotd0XxwonD5UiJloYoSO5vbUr5FQ== +jest-runner@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.0.tgz#465a76efc9ec12cfd83a2af3a6cfb695b13a3efe" + integrity sha512-QpeN6pje8PQvFgT+wYOlzeycKd67qAvSw5FgYBiX2cTW+QTiObTzv/k09qRvT09rcCntFxUhy9VB1mgNGFLYIA== dependencies: - "@jest/console" "^26.5.2" - "@jest/environment" "^26.5.2" - "@jest/test-result" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/console" "^26.6.0" + "@jest/environment" "^26.6.0" + "@jest/test-result" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" chalk "^4.0.0" emittery "^0.7.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-config "^26.5.3" + jest-config "^26.6.0" jest-docblock "^26.0.0" - jest-haste-map "^26.5.2" - jest-leak-detector "^26.5.2" - jest-message-util "^26.5.2" - jest-resolve "^26.5.2" - jest-runtime "^26.5.3" - jest-util "^26.5.2" + jest-haste-map "^26.6.0" + jest-leak-detector "^26.6.0" + jest-message-util "^26.6.0" + jest-resolve "^26.6.0" + jest-runtime "^26.6.0" + jest-util "^26.6.0" jest-worker "^26.5.0" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.5.3.tgz#5882ae91fd88304310f069549e6bf82f3f198bea" - integrity sha512-IDjalmn2s/Tc4GvUwhPHZ0iaXCdMRq5p6taW9P8RpU+FpG01O3+H8z+p3rDCQ9mbyyyviDgxy/LHPLzrIOKBkQ== +jest-runtime@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.0.tgz#90f80ea5eb0d97a1089120f582fb84bd36ca5491" + integrity sha512-JEz4YGnybFvtN4NLID6lsZf0bcd8jccwjWcG5TRE3fYVnxoX1egTthPjnC4btIwWJ6QaaHhtOQ/E3AGn8iClAw== dependencies: - "@jest/console" "^26.5.2" - "@jest/environment" "^26.5.2" - "@jest/fake-timers" "^26.5.2" - "@jest/globals" "^26.5.3" + "@jest/console" "^26.6.0" + "@jest/environment" "^26.6.0" + "@jest/fake-timers" "^26.6.0" + "@jest/globals" "^26.6.0" "@jest/source-map" "^26.5.0" - "@jest/test-result" "^26.5.2" - "@jest/transform" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/test-result" "^26.6.0" + "@jest/transform" "^26.6.0" + "@jest/types" "^26.6.0" "@types/yargs" "^15.0.0" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-config "^26.5.3" - jest-haste-map "^26.5.2" - jest-message-util "^26.5.2" - jest-mock "^26.5.2" + jest-config "^26.6.0" + jest-haste-map "^26.6.0" + jest-message-util "^26.6.0" + jest-mock "^26.6.0" jest-regex-util "^26.0.0" - jest-resolve "^26.5.2" - jest-snapshot "^26.5.3" - jest-util "^26.5.2" - jest-validate "^26.5.3" + jest-resolve "^26.6.0" + jest-snapshot "^26.6.0" + jest-util "^26.6.0" + jest-validate "^26.6.0" slash "^3.0.0" strip-bom "^4.0.0" yargs "^15.4.1" @@ -3841,26 +3841,26 @@ jest-serializer@^26.5.0: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.5.3.tgz#f6b4b4b845f85d4b0dadd7cf119c55d0c1688601" - integrity sha512-ZgAk0Wm0JJ75WS4lGaeRfa0zIgpL0KD595+XmtwlIEMe8j4FaYHyZhP1LNOO+8fXq7HJ3hll54+sFV9X4+CGVw== +jest-snapshot@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.0.tgz#457aa9c1761efc781ac9c02b021a0b21047c6a38" + integrity sha512-mcqJZeIZqxomvBcsaiIbiEe2g7K1UxnUpTwjMoHb+DX4uFGnuZoZ6m28YOYRyCfZsdU9mmq73rNBnEH2atTR4Q== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.0.0" chalk "^4.0.0" - expect "^26.5.3" + expect "^26.6.0" graceful-fs "^4.2.4" - jest-diff "^26.5.2" + jest-diff "^26.6.0" jest-get-type "^26.3.0" - jest-haste-map "^26.5.2" - jest-matcher-utils "^26.5.2" - jest-message-util "^26.5.2" - jest-resolve "^26.5.2" + jest-haste-map "^26.6.0" + jest-matcher-utils "^26.6.0" + jest-message-util "^26.6.0" + jest-resolve "^26.6.0" natural-compare "^1.4.0" - pretty-format "^26.5.2" + pretty-format "^26.6.0" semver "^7.3.2" jest-util@^26.1.0: @@ -3875,41 +3875,41 @@ jest-util@^26.1.0: is-ci "^2.0.0" micromatch "^4.0.2" -jest-util@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.5.2.tgz#8403f75677902cc52a1b2140f568e91f8ed4f4d7" - integrity sha512-WTL675bK+GSSAYgS8z9FWdCT2nccO1yTIplNLPlP0OD8tUk/H5IrWKMMRudIQQ0qp8bb4k+1Qa8CxGKq9qnYdg== +jest-util@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.0.tgz#a81547f6d38738b505c5a594b37d911335dea60f" + integrity sha512-/cUGqcnKeZMjvTQLfJo65nBOEZ/k0RB/8usv2JpfYya05u0XvBmKkIH5o5c4nCh9DD61B1YQjMGGqh1Ha0aXdg== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" "@types/node" "*" chalk "^4.0.0" graceful-fs "^4.2.4" is-ci "^2.0.0" micromatch "^4.0.2" -jest-validate@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.5.3.tgz#eefd5a5c87059550548c5ad8d6589746c66929e3" - integrity sha512-LX07qKeAtY+lsU0o3IvfDdN5KH9OulEGOMN1sFo6PnEf5/qjS1LZIwNk9blcBeW94pQUI9dLN9FlDYDWI5tyaA== +jest-validate@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.0.tgz#b95e2076cca1a58b183e5bcce2bf43af52eebf10" + integrity sha512-FKHNqvh1Pgs4NWas56gsTPmjcIoGAAzSVUCK1+g8euzuCGbmdEr8LRTtOEFjd29uMZUk0PhzmzKGlHPe6j3UWw== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" camelcase "^6.0.0" chalk "^4.0.0" jest-get-type "^26.3.0" leven "^3.1.0" - pretty-format "^26.5.2" + pretty-format "^26.6.0" -jest-watcher@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.5.2.tgz#2957f4461007e0769d74b537379ecf6b7c696916" - integrity sha512-i3m1NtWzF+FXfJ3ljLBB/WQEp4uaNhX7QcQUWMokcifFTUQBDFyUMEwk0JkJ1kopHbx7Een3KX0Q7+9koGM/Pw== +jest-watcher@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.0.tgz#06001c22831583a16f9ccb388ee33316a7f4200f" + integrity sha512-gw5BvcgPi0PKpMlNWQjUet5C5A4JOYrT7gexdP6+DR/f7mRm7wE0o1GqwPwcTsTwo0/FNf9c/kIDXTRaSAYwlw== dependencies: - "@jest/test-result" "^26.5.2" - "@jest/types" "^26.5.2" + "@jest/test-result" "^26.6.0" + "@jest/types" "^26.6.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^26.5.2" + jest-util "^26.6.0" string-length "^4.0.1" jest-worker@^26.5.0: @@ -3921,14 +3921,14 @@ jest-worker@^26.5.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^26.5.3: - version "26.5.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-26.5.3.tgz#5e7a322d16f558dc565ca97639e85993ef5affe6" - integrity sha512-uJi3FuVSLmkZrWvaDyaVTZGLL8WcfynbRnFXyAHuEtYiSZ+ijDDIMOw1ytmftK+y/+OdAtsG9QrtbF7WIBmOyA== +jest@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.0.tgz#546b25a1d8c888569dbbe93cae131748086a4a25" + integrity sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA== dependencies: - "@jest/core" "^26.5.3" + "@jest/core" "^26.6.0" import-local "^3.0.2" - jest-cli "^26.5.3" + jest-cli "^26.6.0" js-sha3@0.5.7: version "0.5.7" @@ -4948,12 +4948,12 @@ pretty-format@^25.2.1, pretty-format@^25.5.0: ansi-styles "^4.0.0" react-is "^16.12.0" -pretty-format@^26.5.2: - version "26.5.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.5.2.tgz#5d896acfdaa09210683d34b6dc0e6e21423cd3e1" - integrity sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og== +pretty-format@^26.6.0: + version "26.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.0.tgz#1e1030e3c70e3ac1c568a5fd15627671ea159391" + integrity sha512-Uumr9URVB7bm6SbaByXtx+zGlS+0loDkFMHP0kHahMjmfCtmFY03iqd++5v3Ld6iB5TocVXlBN/T+DXMn9d4BA== dependencies: - "@jest/types" "^26.5.2" + "@jest/types" "^26.6.0" ansi-regex "^5.0.0" ansi-styles "^4.0.0" react-is "^16.12.0" From 154159c9bd8e7cddc693161dfe665b2ce2724d48 Mon Sep 17 00:00:00 2001 From: COMIT Botty McBotface Date: Tue, 20 Oct 2020 00:25:12 +0000 Subject: [PATCH 31/31] Prepare release nectar 0.1.0 --- nectar/CHANGELOG.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nectar/CHANGELOG.md b/nectar/CHANGELOG.md index c03b292ad0..1b92ac2e8c 100644 --- a/nectar/CHANGELOG.md +++ b/nectar/CHANGELOG.md @@ -7,19 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [nectar-0.1.0] - 2020-10-20 + ### Added - Ability to configure strategies to be used for Bitcoin fees and Ethereum Gas Price resolution. See `./sample-config.toml` for more details. - Disallow unknown keys in the config file. -Previously, unknown configuration keys would just be ignored. -`nectar` will now refuse to startup if the configuration file contains unknown keys. + Previously, unknown configuration keys would just be ignored. + `nectar` will now refuse to startup if the configuration file contains unknown keys. ### Changed - Update the expected network times to calculate the expiries: We expect Bitcoin's transactions to be included within 6 blocks and Ethereum's within 30 blocks. - By default, use bitcoind's `estimatsmartfee` feature to estimate Bitcoin fees. -For Ethereum, Eth Gas Station API is used. + For Ethereum, Eth Gas Station API is used. - Change log level configuration format from capitalised (e.g. "Debug") to lowercase (e.g. "debug"). -[Unreleased]: https://github.com/comit-network/comit-rs/compare/d5d26e42a2d8dd026ae94f2c8a9e0bd80ab81133...HEAD +[Unreleased]: https://github.com/comit-network/comit-rs/compare/nectar-0.1.0...HEAD + +[nectar-0.1.0]: https://github.com/comit-network/comit-rs/compare/b4ad16d63579c542a3885d57f0522b445cfa8bae...nectar-0.1.0