gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-depolymerization] branch master updated (60e4b9b -> 3e080b2)


From: gnunet
Subject: [taler-depolymerization] branch master updated (60e4b9b -> 3e080b2)
Date: Mon, 14 Feb 2022 19:41:04 +0100

This is an automated email from the git hooks/post-receive script.

antoine pushed a change to branch master
in repository depolymerization.

    from 60e4b9b  Fix worker loop continuing when stuck on removed transactions
     new f8e660f  eth-wire: add analysis
     new 805094f  presentation: progress
     new da0d6bc  presentation: compress media
     new 3e080b2  Use taler amount format for bounce fee in config

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Cargo.lock                                   |  37 ++--
 README.md                                    |  12 +-
 btc-wire/src/loops/analysis.rs               |  12 +-
 btc-wire/src/loops/worker.rs                 |   3 +-
 btc-wire/src/main.rs                         |  37 ++--
 common/src/config.rs                         |  24 +--
 common/src/lib.rs                            |  15 ++
 docs/media/fee.png                           | Bin 25200 -> 13811 bytes
 docs/media/fee_var.png                       | Bin 0 -> 24339 bytes
 docs/media/news0.png                         | Bin 45301 -> 11089 bytes
 docs/media/news1.png                         | Bin 367250 -> 121542 bytes
 docs/media/news2.png                         | Bin 36734 -> 21284 bytes
 docs/media/taler.png                         | Bin 24424 -> 5134 bytes
 docs/presentation.tex                        | 261 +++++++++++++--------------
 eth-wire/src/loops.rs                        |  20 ++
 {btc-wire => eth-wire}/src/loops/analysis.rs |  52 ++++--
 eth-wire/src/loops/watcher.rs                |   2 +-
 eth-wire/src/loops/worker.rs                 |   7 +-
 eth-wire/src/main.rs                         |  50 ++---
 eth-wire/src/rpc.rs                          |   2 +-
 makefile                                     |   2 +
 test/conf/taler_btc_bump.conf                |   2 +-
 test/conf/taler_btc_lifetime.conf            |   2 +-
 test/eth/analysis.sh                         |  66 +++++++
 24 files changed, 364 insertions(+), 242 deletions(-)
 create mode 100644 docs/media/fee_var.png
 copy {btc-wire => eth-wire}/src/loops/analysis.rs (61%)
 create mode 100644 test/eth/analysis.sh

diff --git a/Cargo.lock b/Cargo.lock
index 0ad9236..fdb75e4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -341,9 +341,9 @@ checksum = 
"7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
 
 [[package]]
 name = "crypto-common"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0"
+checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06"
 dependencies = [
  "generic-array",
 ]
@@ -440,13 +440,12 @@ dependencies = [
 
 [[package]]
 name = "digest"
-version = "0.10.1"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b"
+checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837"
 dependencies = [
  "block-buffer",
  "crypto-common",
- "generic-array",
  "subtle",
 ]
 
@@ -772,9 +771,9 @@ checksum = 
"c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 
 [[package]]
 name = "hyper"
-version = "0.14.16"
+version = "0.14.17"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55"
+checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -784,7 +783,7 @@ dependencies = [
  "http-body",
  "httparse",
  "httpdate",
- "itoa 0.4.8",
+ "itoa 1.0.1",
  "pin-project-lite",
  "socket2",
  "tokio",
@@ -975,9 +974,9 @@ dependencies = [
 
 [[package]]
 name = "ntapi"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
+checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
 dependencies = [
  "winapi",
 ]
@@ -1247,14 +1246,13 @@ dependencies = [
 
 [[package]]
 name = "rand"
-version = "0.8.4"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
  "libc",
  "rand_chacha",
  "rand_core",
- "rand_hc",
 ]
 
 [[package]]
@@ -1276,15 +1274,6 @@ dependencies = [
  "getrandom",
 ]
 
-[[package]]
-name = "rand_hc"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
-dependencies = [
- "rand_core",
-]
-
 [[package]]
 name = "rayon"
 version = "1.5.1"
@@ -1451,9 +1440,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.78"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
+checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
 dependencies = [
  "itoa 1.0.1",
  "ryu",
diff --git a/README.md b/README.md
index 7fab976..c3b676d 100644
--- a/README.md
+++ b/README.md
@@ -15,14 +15,14 @@ The configuration is based on 
[taler.conf](https://docs.taler.net/manpages/taler
 ``` ini
 # taler.conf - common config
 [taler]
-CURRENCY     = ___ 
+CURRENCY = ___ 
 
 [exchange]
-BASE_URL     = https://___
+BASE_URL = https://___
 
 [depolymerizer-___]
-DB_URL       = postgres://___
-PAYTO        = payto://___
+DB_URL   = postgres://___
+PAYTO    = payto://___
 ```
 
 ### Process lifetime
@@ -35,9 +35,9 @@ done.
 ``` ini
 [depolymerizer-___]
 # Number of requests to serve before gateway shutdown (0 mean never)
-HTTP_LIFETIME  = 0
+HTTP_LIFETIME = 0
 # Number of worker's loops before wire implementation shutdown (0 mean never)
-WIRE_LIFETIME  = 0
+WIRE_LIFETIME = 0
 ```
 
 ### Stuck transaction
diff --git a/btc-wire/src/loops/analysis.rs b/btc-wire/src/loops/analysis.rs
index e956c2c..9803eae 100644
--- a/btc-wire/src/loops/analysis.rs
+++ b/btc-wire/src/loops/analysis.rs
@@ -38,7 +38,7 @@ pub fn analysis(mut rpc: AutoReconnectRPC, mut db: 
AutoReconnectDb, state: &Wire
             db.batch_execute("LISTEN new_block")?;
             loop {
                 // Get biggest known valid fork
-                let max_fork = rpc
+                let fork = rpc
                     .get_chain_tips()?
                     .into_iter()
                     .filter_map(|t| {
@@ -47,17 +47,17 @@ pub fn analysis(mut rpc: AutoReconnectRPC, mut db: 
AutoReconnectDb, state: &Wire
                     .max()
                     .unwrap_or(0) as u16;
                 // The first time we see a fork that big
-                if max_fork > max_seen {
-                    max_seen = max_fork;
+                if fork > max_seen {
+                    max_seen = fork;
                     let current_conf = 
state.confirmation.load(Ordering::SeqCst);
                     // If new fork is bigger than the current confirmation
-                    if max_fork > current_conf {
+                    if fork > current_conf {
                         // Max two time the configuration
-                        let new_conf = max_fork.min(state.config.confirmation 
* 2);
+                        let new_conf = fork.min(state.max_confirmation);
                         state.confirmation.store(new_conf, Ordering::SeqCst);
                         warn!(
                             "analysis: found dangerous fork of {} blocks, 
adapt confirmation to {} blocks capped at {}, you should update taler.conf",
-                            max_fork, new_conf, state.config.confirmation * 2
+                            fork, new_conf, state.max_confirmation 
                         );
                     }
                 }
diff --git a/btc-wire/src/loops/worker.rs b/btc-wire/src/loops/worker.rs
index 0e3080e..88f176a 100644
--- a/btc-wire/src/loops/worker.rs
+++ b/btc-wire/src/loops/worker.rs
@@ -119,9 +119,8 @@ pub fn worker(mut rpc: AutoReconnectRPC, mut db: 
AutoReconnectDb, state: &WireSt
                     );
                 }
 
-                let bounce_fee = BtcAmount::from_sat(state.config.bounce_fee);
                 // Send requested bounce
-                while bounce(db, rpc, &bounce_fee)? {}
+                while bounce(db, rpc, &state.bounce_fee)? {}
             }
 
             Ok(())
diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs
index 16fc0e2..777e6b2 100644
--- a/btc-wire/src/main.rs
+++ b/btc-wire/src/main.rs
@@ -13,18 +13,21 @@
   You should have received a copy of the GNU Affero General Public License 
along with
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
-use bitcoin::Network;
+use bitcoin::{Amount as BtcAmount, Network};
 use btc_wire::{
     config::{BitcoinConfig, WIRE_WALLET_NAME},
     rpc::{auto_reconnect_rpc, Rpc},
     rpc_utils::default_data_dir,
 };
 use common::{
+    api_common::Amount,
     config::{load_btc_config, BtcConfig},
     log::log::info,
+    named_spawn,
     reconnect::auto_reconnect_db,
 };
-use std::{sync::atomic::AtomicU16, thread::JoinHandle};
+use std::{str::FromStr, sync::atomic::AtomicU16};
+use taler_util::taler_to_btc;
 
 use crate::loops::{analysis::analysis, watcher::watcher, worker::worker};
 
@@ -34,9 +37,22 @@ mod metadata;
 mod sql;
 mod taler_util;
 
+const DEFAULT_CONFIRMATION: u16 = 6;
+const DEFAULT_BOUNCE_FEE: &'static str = "BTC:0.00001";
+
 pub struct WireState {
     confirmation: AtomicU16,
+    max_confirmation: u16,
     config: BtcConfig,
+    bounce_fee: BtcAmount,
+}
+
+fn config_bounce_fee(config: &BtcConfig) -> BtcAmount {
+    let config = config.bounce_fee.as_deref().unwrap_or(DEFAULT_BOUNCE_FEE);
+    Amount::from_str(&config)
+        .ok()
+        .and_then(|a| taler_to_btc(&a).ok())
+        .expect("config value BOUNCE_FEE is no a valid bitcoin amount")
 }
 
 fn main() {
@@ -68,8 +84,11 @@ fn main() {
     };
     info!("Running on {} chain", chain_name);
 
+    let init_confirmation = 
config.confirmation.unwrap_or(DEFAULT_CONFIRMATION);
     let state: &'static WireState = Box::leak(Box::new(WireState {
-        confirmation: AtomicU16::new(config.confirmation),
+        confirmation: AtomicU16::new(init_confirmation),
+        max_confirmation: init_confirmation * 2,
+        bounce_fee: config_bounce_fee(&config),
         config,
     }));
 
@@ -88,15 +107,3 @@ fn main() {
     });
     worker(rpc_worker, db_worker, state);
 }
-
-pub fn named_spawn<F, T>(name: impl Into<String>, f: F) -> JoinHandle<T>
-where
-    F: FnOnce() -> T,
-    F: Send + 'static,
-    T: Send + 'static,
-{
-    std::thread::Builder::new()
-        .name(name.into())
-        .spawn(f)
-        .unwrap()
-}
diff --git a/common/src/config.rs b/common/src/config.rs
index d74865b..b4e57f2 100644
--- a/common/src/config.rs
+++ b/common/src/config.rs
@@ -92,26 +92,24 @@ impl Config for GatewayConfig {
 // TODO currency name as const generic
 
 #[derive(Debug, Clone, PartialEq, Eq)]
-pub struct WireConfig<const DEFAULT_FEE: u64, const DEFAULT_CONFIRMATION: u16> 
{
+pub struct WireConfig {
     pub base_url: Url,
-    pub confirmation: u16,
-    pub bounce_fee: u64,
+    pub confirmation: Option<u16>,
+    pub bounce_fee: Option<String>,
     pub wire_lifetime: Option<u32>,
     pub bump_delay: Option<u32>,
     pub payto: Url,
     pub core: CoreConfig,
 }
 
-impl<const DEFAULT_FEE: u64, const DEFAULT_CONFIRMATION: u16> Config
-    for WireConfig<DEFAULT_FEE, DEFAULT_CONFIRMATION>
-{
+impl Config for WireConfig {
     fn load_from_ini(ini: &Ini, currency: &str, dep: &Properties) -> Self {
         let ex = section(ini, "exchange");
-        Self {
+        let config = Self {
             base_url: require(ex, "BASE_URL", url),
             payto: require(dep, "PAYTO", url),
-            confirmation: nb(dep, 
"CONFIRMATION").unwrap_or(DEFAULT_CONFIRMATION),
-            bounce_fee: nb(dep, "BOUNCE_FEE").unwrap_or(DEFAULT_FEE),
+            confirmation: nb(dep, "CONFIRMATION"),
+            bounce_fee: string(dep, "BOUNCE_FEE"),
             wire_lifetime: nb(dep, "WIRE_LIFETIME")
                 .and_then(|nb| (nb != 0).then(|| Some(nb)))
                 .unwrap_or(None),
@@ -119,11 +117,13 @@ impl<const DEFAULT_FEE: u64, const DEFAULT_CONFIRMATION: 
u16> Config
                 .and_then(|nb| (nb != 0).then(|| Some(nb)))
                 .unwrap_or(None),
             core: CoreConfig::load_from_ini(ini, currency, dep),
-        }
+        };
+        assert_eq!(config.core.currency, currency);
+        return config;
     }
 }
 
-pub type BtcConfig = WireConfig<1000, 6>;
+pub type BtcConfig = WireConfig;
 
 pub fn load_btc_config(path: Option<&str>) -> BtcConfig {
     let config = WireConfig::load_taler_config(path);
@@ -131,7 +131,7 @@ pub fn load_btc_config(path: Option<&str>) -> BtcConfig {
     return config;
 }
 
-pub type EthConfig = WireConfig<10_000_000_000_000, 24>;
+pub type EthConfig = WireConfig;
 
 pub fn load_eth_config(path: Option<&str>) -> EthConfig {
     let config = WireConfig::load_taler_config(path);
diff --git a/common/src/lib.rs b/common/src/lib.rs
index ade1e60..07d52b7 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -1,3 +1,5 @@
+use std::thread::JoinHandle;
+
 /*
   This file is part of TALER
   Copyright (C) 2022 Taler Systems SA
@@ -34,3 +36,16 @@ pub fn rand_slice<const N: usize>() -> [u8; N] {
     OsRng.fill_bytes(slice.as_mut_slice());
     slice
 }
+
+/// Spawned a named thread
+pub fn named_spawn<F, T>(name: impl Into<String>, f: F) -> JoinHandle<T>
+where
+    F: FnOnce() -> T,
+    F: Send + 'static,
+    T: Send + 'static,
+{
+    std::thread::Builder::new()
+        .name(name.into())
+        .spawn(f)
+        .unwrap()
+}
diff --git a/docs/media/fee.png b/docs/media/fee.png
index 283c286..2ccdec2 100644
Binary files a/docs/media/fee.png and b/docs/media/fee.png differ
diff --git a/docs/media/fee_var.png b/docs/media/fee_var.png
new file mode 100644
index 0000000..d02cc3c
Binary files /dev/null and b/docs/media/fee_var.png differ
diff --git a/docs/media/news0.png b/docs/media/news0.png
index d1f5ab7..bb96d06 100644
Binary files a/docs/media/news0.png and b/docs/media/news0.png differ
diff --git a/docs/media/news1.png b/docs/media/news1.png
index c567581..4ea00f9 100644
Binary files a/docs/media/news1.png and b/docs/media/news1.png differ
diff --git a/docs/media/news2.png b/docs/media/news2.png
index f33c1ba..fbafb5c 100644
Binary files a/docs/media/news2.png and b/docs/media/news2.png differ
diff --git a/docs/media/taler.png b/docs/media/taler.png
index 503ae20..97493ca 100644
Binary files a/docs/media/taler.png and b/docs/media/taler.png differ
diff --git a/docs/presentation.tex b/docs/presentation.tex
index 3c0e0b2..a0c2bee 100644
--- a/docs/presentation.tex
+++ b/docs/presentation.tex
@@ -85,13 +85,14 @@
         \column{0.47\paperwidth}
         \begin{block}{Settlement layer}
             \begin{itemize}
-                \item Blockchain?
+                \item This work, Blockchain!
             \end{itemize}
         \end{block}
         \begin{block}{Taler payment system}
             \begin{itemize}
+                \item Realtime transactions, 1 RTT
+                \item Scalable microtransactions
                 \item Blind signatures (privacy)
-                \item Rotate keys every year, forget previous transactions 
(pruning)
             \end{itemize}
         \end{block}
 
@@ -101,7 +102,7 @@
 \begin{frame}{Taler}{Blockchain settlement layer}
     \begin{center}
         \begin{tikzpicture}[
-                rect/.style={rectangle, draw=black, minimum width=28mm},
+                rect/.style={rectangle, draw=black, minimum width=30mm},
                 sym/.style={stealth-stealth, shorten >= 2pt, shorten <= 2pt},
                 block/.style={rectangle,draw=black,fill=black!10,minimum 
size=7mm},
             ]
@@ -111,7 +112,7 @@
             \node[rect,below=0cm of Tt](Tc){Exchange};
             \node[rect,fit={(Tt) (Tc)}](T){};
 
-            \node[rect,below=7mm of Tc](D) {Depolymerization};
+            \node[rect,below=7mm of Tc](D) {\textbf{Depolymerization}};
 
             \node[rect,below=7mm of D](Bc){Node};
             \node[below=0cm of Bc](Bt){Blockchain};
@@ -143,7 +144,7 @@
             \node[above=-0.5mm of off] 
{\includegraphics[height=7mm]{media/taler.png}};
 
             %% Depolymerization
-            \node[right=12mm of D] {\small{Deposit}};
+            \node[right=11mm of D] {\small{Deposit}};
             \node[right=50mm of D] {\small{Withdraw}};
             \draw[dashed,-stealth] (1.north) |- (off.west);
             \draw[dashed,-stealth] (off.east) -| (6.north);
@@ -156,20 +157,17 @@
         \begin{itemize}
             \item Metadata are required to link a wallet to its deposits and 
withdraws
             \item Putting metadata in blockchain transactions can be tricky
-            \item The whole on-chain transaction history can be retrieved from
-                  the blockchain. \textbf{Easily auditable}
         \end{itemize}
     \end{block}
     \begin{block}{Blockchain based cryptocurrencies}
         \begin{itemize}
-            \item Reorganisation resilient
-            \item Adaptive confirmation
-            \item Resolve stuck transactions
+            \item Blockchain transactions lack finality (fork)
+            \item Transactions can be stuck for a long time (mempool)
         \end{itemize}
     \end{block}
 \end{frame}
 
-\begin{frame}{Challenges}{Chain reorganisation}
+\begin{frame}{Blockchain challenges}{Chain reorganisation}
     \begin{center}
         \begin{tikzpicture}[
                 block/.style={rectangle,draw=black,fill=black!10,minimum 
size=7mm},
@@ -207,34 +205,36 @@
     \end{center}
     A fork is when concurrent blockchain states coexist. Nodes will follow
     the longest chain, replacing recent blocks if necessary. That is a
-    blockchain reorganisation. Taler expects deposit transactions to be
-    consistent. If a deposit transaction disappears from the blockchain,
-    depolymerizer is comprised.
+    blockchain reorganisation. If a deposit transaction disappears from the
+    blockchain, an irrevocable withdraw transactions would no longer be backed
+    by credit.
 \end{frame}
 
-\begin{frame}{Challenges}{Stuck transactions}
-    \begin{center}
-        \begin{tikzpicture}[
-                dot/.style={circle,fill,inner sep=1pt,}
-            ]
-
-            % TODO caption with source (Ychart)
-
-            \node (I) {\includegraphics[width=\textwidth]{media/fee.png}};
-            \only<2->{
+\begin{frame}{Blockchain challenges}{Stuck transactions}
+    We want confirmed debits within a limited time frame.
+    \begin{figure}
+        \centering
+        \only<1> {
+            \begin{tikzpicture}[
+                    dot/.style={circle,fill,inner sep=1pt,}
+                ]
+                \node (I) {\includegraphics[width=\textwidth]{media/fee.png}};
                 \node [below left=-2.5mm and -1.5cm of I] (Tx) {\small Tx};
                 \node [dot,above=8.4mm of Tx](D) {};
                 \draw [dotted,thick] (Tx) -- (D);
                 \node [left=-4.5cm of Tx] (C) {\small conf};
                 \node [dot,above=8.4mm of C](D1) {};
                 \draw [dotted,thick] (C) -- (D1);
-            };
-        \end{tikzpicture}
-    \end{center}
-    \only<1>{We want confirmation of transactions within a limited time frame.
-        However, transaction fees are variable, and we can only predict them.}
-    \only<2>{When we send a transaction with a fee too small compared to other
-        transactions, it can take an unlimited amount of time for it to be 
mined.}
+            \end{tikzpicture}
+        }
+        \only<2> {
+            \includegraphics[width=\textwidth]{media/fee_var.png}
+            \caption{Bitcoin average transaction fee over 6 months {\tiny 
(ychart)}}
+        }
+    \end{figure}
+    \only<1>{When we trigger a debit with a fee too small, it may no be
+        confirmed in timely fashion.}
+    \only<2>{However, transaction fees are unpredictable.}
 \end{frame}
 
 
@@ -247,7 +247,7 @@
             \node[rect](1) {Taler Exchange};
             \node[rect,below=of 1](2) {Wire Gateway};
             \node[rect,right=of 2](3) {PostgreSQL};
-            \node[rect,right=of 3](4) {DLT Wire};
+            \node[rect,right=of 3](4) {DLT Adapter};
             \node[rect,above=of 4](5) {DLT Full Node};
 
             \draw[sym] (1) -- node [midway,right] {\tiny HTTP} (2);
@@ -266,77 +266,46 @@
         \item Common database to store transactions state and communicate
               with notifications
         \item Wire Gateway for Taler API compatibility
-        \item Specific wire for DLT compatibility
+        \item DLT specific adapter
     \end{itemize}
 \end{frame}
 
-\begin{frame}{Depolymerization}{Metadata}
-    \begin{block}{Bitcoin - Withdraw}
+\begin{frame}{Storing metadata}{Bitcoin}
+    \begin{block}{Bitcoin - Credit}
         \begin{itemize}
             \item Transactions from code
             \item Only 32B + URI
             \item \textbf{OP\_RETURN}
         \end{itemize}
     \end{block}
-    \begin{block}{Bitcoin - Deposit}
+    \begin{block}{Bitcoin - Debit}
         \begin{itemize}
             \item Transactions from common wallet software
             \item Only 32B
             \item \textbf{Fake Segwit Addresses}
         \end{itemize}
     \end{block}
-    \begin{block}{Ethereum - Withdraw and Deposit}
+\end{frame}
+\begin{frame}{Storing metadata}{Ethereum}
+    \begin{block}{Smart contract ?}
         \begin{itemize}
-            \item Smart contract is the recommend way
-            \item Expensive and error prone (bigger attack surface)
-            \item \textbf{Custom contract input format}
+            \item Logs in smart contract is the recommend way {\tiny 
(ethereum.org)}
+            \item Expensive (additional storage and execution fees)
+            \item Avoidable attack surface (error prone)
         \end{itemize}
     \end{block}
+    \begin{block}{Custom input format}
+        Use input data in transactions usually to call smart contract to
+        store metadata.
+    \end{block}
 \end{frame}
 
-\begin{frame}{Depolymerization}{Architecture}
-    \begin{center}
-        \begin{tikzpicture}[
-                rect/.style={rectangle, draw=black, minimum height=6mm, 
minimum width=38mm},
-            ]
-
-            % Watcher loop
-            \node(wat) {Watcher};
-            \node[rect, below=1mm of wat](wa1) {Wait for new block};
-            \node[rect, below=4mm of wa1](wa2) {Notify new block};
-            \draw[-stealth] (wa1) -- (wa2);
-            \draw[-stealth] (wa2) .. controls ([xshift=-0.3cm] wa2.west) and 
([xshift=-0.3cm] wa1.west) .. (wa1);
-
-            % Analysis loop
-            \node[below=7mm of wa2] (at) {Analysis};
-            \node[rect, below=1mm of at](a1) {Wait for notification};
-            \node[rect, below=4mm of a1](a2) {Analyse};
-            \draw[-stealth] (a1) -- (a2);
-            \draw[-stealth] (a2) .. controls ([xshift=-0.3cm] a2.west) and 
([xshift=-0.3cm] a1.west) .. (a1);
-
-            % Worker loop
-            \node[rect, right= 1cm of wa1](wo1) {Wait for notification};
-            \node[rect, below=4mm of wo1](wo2) {Synchronize chain};
-            \node[rect, below=4mm of wo2](wo3) {Withdraw};
-            \node[rect, below=4mm of wo3](wo4) {Bump};
-            \node[rect, below=4mm of wo4](wo5) {Bounce};
-            \node[above=1mm of wo1]{Worker};
-            \draw[-stealth] (wo1) -- (wo2);
-            \draw[-stealth] (wo2) -- (wo3);
-            \draw[-stealth] (wo3) -- (wo4);
-            \draw[-stealth] (wo4) -- (wo5);
-            \draw[-stealth] (wo5) .. controls ([xshift=-0.4cm] wo5.west) and 
([xshift=-0.4cm] wo1.west) .. (wo1);
-        \end{tikzpicture}
-    \end{center}
-    \centering
-    Three concurrent loops
-\end{frame}
-
-\begin{frame}{Reorganisation resilient}
+\begin{frame}{Handling blockchain reorganisation}
     \begin{center}
         \begin{tikzpicture}[
                 block/.style={rectangle,draw=black,fill=black!10,minimum 
size=7mm},
                 conf/.style={draw=black!60!green,fill=black!60!green!10},
+                nconf/.style={dotted},
                 err/.style={draw=black!60!red,fill=black!60!red!10},
                 ar/.style={-stealth}
             ]
@@ -354,22 +323,22 @@
             \only<2->{
                 \node [block,conf,right=5mm of 3](4){\only<3>{$D_3$}};
             }
-            \node[block,right=5mm of 4](5){};
-            \node[block,right=5mm of 5](6){$D_1$};
+            \node[block,nconf,right=5mm of 4](5){};
+            \node[block,nconf,right=5mm of 5](6){$D_1$};
             \draw[ar] (3) -- (4);
             \draw[ar] (4) -- (5);
             \draw[ar] (5) -- (6);
 
             % Fork
             \only<-2>{
-                \node [block,above=7mm of 4](4p){};
+                \node [block,nconf,above=7mm of 4](4p){};
             }
             \only<3>{
-                \node [block,err,above=7mm of 4](4p){$D_3'$};
+                \node [block,dashed,err,above=7mm of 4](4p){$D_3'$};
             }
-            \node[block,right=5mm of 4p](5p){$D_2$};
-            \node[block,right=5mm of 5p](6p){};
-            \node[block,right=5mm of 6p](7p){};
+            \node[block,nconf,right=5mm of 4p](5p){$D_2$};
+            \node[block,nconf,right=5mm of 5p](6p){};
+            \node[block,nconf,right=5mm of 6p](7p){};
             \draw[ar] (3.east) -- (4p.west);
             \draw[ar] (4p) -- (5p);
             \draw[ar] (5p) -- (6p);
@@ -380,13 +349,14 @@
             \node [right=17mm of 6]{\emph{active}};
         \end{tikzpicture}
     \end{center}
-    \only<1>{As small reorganisations are common, we apply a confirmation delay
-        to handle most disturbances and attacks.}
+    \only<1>{As small reorganisations are common, Satoshi already recommend to
+        apply a confirmation delay to handle most disturbances and attacks.}
     \only<2>{If a reorganisation longer than the confirmation delay happens,
-        but it does not remove deposits, btc-wire is safe.}
-    \only<3>{If it removed a confirmed deposit a powerful attacker may have
-        created a conflicting transaction. btc-wire suspends operation until
-        lost deposits reappear.}
+        but it did not remove credits, depolymerizer is safe and automatically
+        resume.}
+    \only<3>{If a fork removed a confirmed debit an attacker may create a
+        conflicting transaction. Depolymerizer suspends operation until lost
+        credits reappear.}
 \end{frame}
 
 \begin{frame}{Adaptive confirmation}
@@ -394,6 +364,7 @@
         \begin{tikzpicture}[
                 block/.style={rectangle,draw=black,fill=black!10,minimum 
size=7mm},
                 conf/.style={draw=black!60!green,fill=black!60!green!10},
+                nconf/.style={dotted},
                 conft/.style={text=black!60!green},
                 confl/.style={draw=black!60!green},
                 ar/.style={-stealth}
@@ -407,20 +378,20 @@
 
             % Current
             \node[block,conf,right=5mm of 2](3){};
-            \node[block,right=5mm of 3](4){};
-            \node[block,right=5mm of 4](5){};
-            \node[block,right=5mm of 5](6){};
+            \node[block,nconf,right=5mm of 3](4){};
+            \node[block,nconf,right=5mm of 4](5){};
+            \node[block,nconf,right=5mm of 5](6){};
             \draw[ar] (2) -- (3);
             \draw[ar] (3) -- (4);
             \draw[ar] (4) -- (5);
             \draw[ar] (5) -- (6);
 
             % Fork
-            \node[block,above=7mm of 3](3p){};
-            \node[block,right=5mm of 3p](4p){};
-            \node[block,right=5mm of 4p](5p){};
-            \node[block,right=5mm of 5p](6p){};
-            \node[block,right=5mm of 6p](7p){};
+            \node[block,nconf,above=7mm of 3](3p){};
+            \node[block,nconf,right=5mm of 3p](4p){};
+            \node[block,nconf,right=5mm of 4p](5p){};
+            \node[block,nconf,right=5mm of 5p](6p){};
+            \node[block,nconf,right=5mm of 6p](7p){};
             \draw[ar] (2.east) -- (3p.west);
             \draw[ar] (3p) -- (4p);
             \draw[ar] (4p) -- (5p);
@@ -443,47 +414,56 @@
             \draw[confl,thick,dotted](I) -- (Ip);
         \end{tikzpicture}
     \end{center}
-    If we experience a reorganisation once, its plausible for another one of 
the
-    same size to happen again. btc-wire learns from reorganisations by updating
-    its confirmation time.
+    If we experience a reorganisation once, its dangerously likely for another
+    one of the same size to happen again. btc-wire learns from reorganisations
+    by increasing its confirmation time.
 \end{frame}
 
-\begin{frame}{Handle stuck transactions}
-    \begin{center}
-        \begin{tikzpicture}[
-                dot/.style={circle,fill,inner sep=1pt,}
-            ]
 
-            % TODO caption with source (Ychart)
 
-            \node (I) {\includegraphics[width=\textwidth]{media/fee.png}};
-            \node [below left=-2.5mm and -1.5cm of I] (Tx) {\small Tx};
-            \node [dot,above=8.4mm of Tx](D) {};
-            \draw [dotted,thick] (Tx) -- (D);
-
-            \only<1>{
-                \node [left=-4.5cm of Tx] (C) {\small conf};
-                \node [dot,above=8.4mm of C](D1) {};
-                \draw [dotted,thick] (C) -- (D1);
-            };
-            \only<2>{
-                \node [left=-17mm of Tx] (Tx1) {\small Tx'};
-                \node [dot,above=15.5mm of Tx1](D1) {};
-                \draw [dotted,thick] (Tx1) -- (D1);
-
-                \node [left=-14.3mm of Tx1] (C) {\small conf};
-                \node [dot,above=15.5mm of C](D2) {};
-                \draw [dotted,thick] (C) -- (D2);
-            };
-        \end{tikzpicture}
-    \end{center}
-    \only<1>{When we send a transaction with a fee too small compared to other
-        transactions, it can take an unlimited amount of time for it to be 
mined.}
-    \only<2>{You can configure btc-wire to monitor pending transactions and
-        bump their fees if they take too much time to be mined.}
+\begin{frame}{DLT Adapter}{Architecture}
+    \begin{block}{Event system}
+        \begin{itemize}
+            \item \textbf{Watcher} listen for new blocks
+            \item \textbf{Wire Gateway} notify requested debits
+            \item \textbf{Worker} notify state change
+        \end{itemize}
+    \end{block}
 \end{frame}
 
 
+\begin{frame}{DLT Adapter state machine}
+    \begin{columns}
+        \column{0.5\paperwidth}
+        \begin{figure}
+            \begin{tikzpicture}[
+                    rect/.style={rectangle, draw=black, minimum height=6mm, 
minimum width=50mm},
+                ]
+
+                \node[rect](wo1) {Wait for notification};
+                \node[rect, below=4mm of wo1](wo2) {Reconcile local DB with 
DLT};
+                \node[rect, below=4mm of wo2](wo3) {Trigger debits};
+                \node[rect, below=4mm of wo3](wo4) {Reissue stuck debits};
+                \node[rect, below=4mm of wo4](wo5) {Bounce malformed credits};
+                \draw[-stealth] (wo1) -- (wo2);
+                \draw[-stealth] (wo2) -- (wo3);
+                \draw[-stealth] (wo3) -- (wo4);
+                \draw[-stealth] (wo4) -- (wo5);
+                \draw[-stealth] (wo5) .. controls ([xshift=-0.4cm] wo5.west) 
and ([xshift=-0.4cm] wo1.west) .. (wo1);
+            \end{tikzpicture}
+            \caption{Worker loop}
+        \end{figure}
+        \column{0.47\paperwidth}
+        \begin{block}{DLT reconcialisation}
+            \begin{itemize}
+                \item List new and removed transactions since last 
reconciliation
+                \item Check for confirmed deposits removal
+                \item Register new credits
+                \item Recover lost debits
+            \end{itemize}
+        \end{block}
+    \end{columns}
+\end{frame}
 
 \begin{frame}{Related work}
     \begin{block}{Centralization - Coinbase off-chain sending}
@@ -495,13 +475,15 @@
     \begin{block}{Layering - Lightning Network}
         \begin{itemize}
             \item [$+$] Fast and cheap: off chain transaction
-            \item [$-$] Incompatible with Bitcoin: require setting up a 
Bidirectional Payment Channel
+            \item [$-$] Incompatible with Bitcoin: require setting up a 
bidirectional payment channel
             \item [$-$] Fraud attempts are mitigated via a complex penalty 
system
         \end{itemize}
     \end{block}
 \end{frame}
 
 \begin{frame}{Conclusion}
+    Blockchain can be used a settlement layer for Taler payment system using
+    depolymerizer.
     \begin{itemize}
         \item [$-$] Trust exchange operator or auditors
         \item [$+$] Fast and cheap
@@ -509,7 +491,14 @@
         \item [$+$] Linear scalability
         \item [$+$] Ecological
         \item [$+$] Privacy when it can, transparency when it must (avoid tax 
evasion and money laundering)
-        \item [$+$] Compatibility with blockchains
+    \end{itemize}
+\end{frame}
+
+\begin{frame}{Future work}
+    \begin{itemize}
+        \item  Universal auditability, using onchain transactions history
+        \item  Smarter analysis, update confirmation delay based on currency 
network behavior
+        \item  Multisig by multiple operator for debit
     \end{itemize}
 \end{frame}
 \end{document}
\ No newline at end of file
diff --git a/eth-wire/src/loops.rs b/eth-wire/src/loops.rs
index 6bcc715..851f555 100644
--- a/eth-wire/src/loops.rs
+++ b/eth-wire/src/loops.rs
@@ -14,5 +14,25 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
+use common::postgres;
+use eth_wire::rpc;
+
+use crate::fail_point::Injected;
+
+pub mod analysis;
 pub mod watcher;
 pub mod worker;
+
+#[derive(Debug, thiserror::Error)]
+pub enum LoopError {
+    #[error(transparent)]
+    RPC(#[from] rpc::Error),
+    #[error(transparent)]
+    DB(#[from] postgres::Error),
+    #[error("Another eth-wire process is running concurrently")]
+    Concurrency,
+    #[error(transparent)]
+    Injected(#[from] Injected),
+}
+
+pub type LoopResult<T> = Result<T, LoopError>;
diff --git a/btc-wire/src/loops/analysis.rs b/eth-wire/src/loops/analysis.rs
similarity index 61%
copy from btc-wire/src/loops/analysis.rs
copy to eth-wire/src/loops/analysis.rs
index e956c2c..f01ece1 100644
--- a/btc-wire/src/loops/analysis.rs
+++ b/eth-wire/src/loops/analysis.rs
@@ -13,14 +13,16 @@
   You should have received a copy of the GNU Affero General Public License 
along with
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
+
 use std::sync::atomic::Ordering;
 
-use btc_wire::rpc::{AutoReconnectRPC, ChainTipsStatus};
 use common::{
     log::log::{error, warn},
     postgres::fallible_iterator::FallibleIterator,
     reconnect::AutoReconnectDb,
 };
+use eth_wire::rpc::{AutoReconnectRPC, Rpc};
+use ethereum_types::{H256, U64};
 
 use crate::WireState;
 
@@ -30,6 +32,7 @@ use super::LoopResult;
 pub fn analysis(mut rpc: AutoReconnectRPC, mut db: AutoReconnectDb, state: 
&WireState) {
     // The biggest fork ever seen
     let mut max_seen = 0;
+    let mut tip: Option<(U64, H256)> = None;
     loop {
         let rpc = rpc.client();
         let db = db.client();
@@ -38,26 +41,20 @@ pub fn analysis(mut rpc: AutoReconnectRPC, mut db: 
AutoReconnectDb, state: &Wire
             db.batch_execute("LISTEN new_block")?;
             loop {
                 // Get biggest known valid fork
-                let max_fork = rpc
-                    .get_chain_tips()?
-                    .into_iter()
-                    .filter_map(|t| {
-                        (t.status == ChainTipsStatus::ValidFork).then(|| 
t.branch_length)
-                    })
-                    .max()
-                    .unwrap_or(0) as u16;
+                let (fork, new_tip) = check_fork(rpc, &tip)?;
+                tip.replace(new_tip);
                 // The first time we see a fork that big
-                if max_fork > max_seen {
-                    max_seen = max_fork;
+                if fork > max_seen {
+                    max_seen = fork;
                     let current_conf = 
state.confirmation.load(Ordering::SeqCst);
                     // If new fork is bigger than the current confirmation
-                    if max_fork > current_conf {
+                    if fork > current_conf {
                         // Max two time the configuration
-                        let new_conf = max_fork.min(state.config.confirmation 
* 2);
+                        let new_conf = fork.min(state.max_confirmations);
                         state.confirmation.store(new_conf, Ordering::SeqCst);
                         warn!(
                             "analysis: found dangerous fork of {} blocks, 
adapt confirmation to {} blocks capped at {}, you should update taler.conf",
-                            max_fork, new_conf, state.config.confirmation * 2
+                            fork, new_conf, state.max_confirmations 
                         );
                     }
                 }
@@ -73,3 +70,30 @@ pub fn analysis(mut rpc: AutoReconnectRPC, mut db: 
AutoReconnectDb, state: &Wire
         }
     }
 }
+
+/// Return fork size and new tip
+pub fn check_fork(rpc: &mut Rpc, tip: &Option<(U64, H256)>) -> 
LoopResult<(u16, (U64, H256))> {
+    let mut size = 0;
+    let latest = rpc.latest_block()?;
+    if let Some((number, hash)) = tip {
+        let mut chain_cursor = latest.clone();
+        // Skip until tip height
+        while chain_cursor.number.unwrap() != *number {
+            chain_cursor = rpc.block(&chain_cursor.parent_hash)?.unwrap();
+            size += 1;
+        }
+
+        // Check fork
+        if chain_cursor.hash.unwrap() != *hash {
+            let mut fork_cursor = rpc.block(hash)?.unwrap();
+            while fork_cursor.hash != chain_cursor.hash {
+                chain_cursor = rpc.block(&chain_cursor.parent_hash)?.unwrap();
+                fork_cursor = rpc.block(&fork_cursor.parent_hash)?.unwrap();
+                size += 1;
+            }
+        } else {
+            size = 0;
+        }
+    }
+    Ok((size, (latest.number.unwrap(), latest.hash.unwrap())))
+}
diff --git a/eth-wire/src/loops/watcher.rs b/eth-wire/src/loops/watcher.rs
index 05396ab..3f81d70 100644
--- a/eth-wire/src/loops/watcher.rs
+++ b/eth-wire/src/loops/watcher.rs
@@ -16,7 +16,7 @@
 use common::{log::log::error, reconnect::AutoReconnectDb};
 use eth_wire::rpc::AutoReconnectRPC;
 
-use crate::LoopResult;
+use super::LoopResult;
 
 /// Wait for new block and notify arrival with postgreSQL notifications
 pub fn watcher(mut rpc: AutoReconnectRPC, mut db: AutoReconnectDb) {
diff --git a/eth-wire/src/loops/worker.rs b/eth-wire/src/loops/worker.rs
index 5dda0ed..3888feb 100644
--- a/eth-wire/src/loops/worker.rs
+++ b/eth-wire/src/loops/worker.rs
@@ -33,10 +33,13 @@ use ethereum_types::{Address, H256, U256, U64};
 
 use crate::{
     fail_point::fail_point,
+    loops::LoopError,
     sql::{sql_addr, sql_eth_amount, sql_hash},
-    LoopError, LoopResult, WireState,
+    WireState,
 };
 
+use super::LoopResult;
+
 pub fn worker(mut rpc: AutoReconnectRPC, mut db: AutoReconnectDb, state: 
&WireState) {
     let mut lifetime = state.config.wire_lifetime;
     let mut status = true;
@@ -95,7 +98,7 @@ pub fn worker(mut rpc: AutoReconnectRPC, mut db: 
AutoReconnectDb, state: &WireSt
                 while withdraw(db, rpc, state)? {}
 
                 // Send requested bounce
-                while bounce(db, rpc, U256::from(state.config.bounce_fee))? {}
+                while bounce(db, rpc, state.bounce_fee)? {}
             }
             Ok(())
         })();
diff --git a/eth-wire/src/main.rs b/eth-wire/src/main.rs
index fdcd618..fc3e947 100644
--- a/eth-wire/src/main.rs
+++ b/eth-wire/src/main.rs
@@ -14,65 +14,73 @@
   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
 
-use std::sync::atomic::AtomicU16;
+use std::{str::FromStr, sync::atomic::AtomicU16};
 
 use common::{
+    api_common::Amount,
     config::{load_eth_config, EthConfig},
-    postgres,
+    named_spawn,
     reconnect::auto_reconnect_db,
 };
 use eth_wire::{
-    rpc::{self, auto_reconnect_rpc},
-    taler_util::eth_payto_addr,
+    rpc::auto_reconnect_rpc,
+    taler_util::{eth_payto_addr, taler_to_eth},
 };
-use ethereum_types::H160;
-use fail_point::Injected;
-use loops::{watcher::watcher, worker::worker};
+use ethereum_types::{H160, U256};
+use loops::{analysis::analysis, watcher::watcher, worker::worker};
 
 mod fail_point;
 mod loops;
 mod sql;
 
+const DEFAULT_CONFIRMATION: u16 = 24;
+const DEFAULT_BOUNCE_FEE: &'static str = "ETH:0.00001";
+
 pub struct WireState {
     confirmation: AtomicU16,
+    max_confirmations: u16,
     address: H160,
     config: EthConfig,
+    bounce_fee: U256,
 }
 
-#[derive(Debug, thiserror::Error)]
-pub enum LoopError {
-    #[error(transparent)]
-    RPC(#[from] rpc::Error),
-    #[error(transparent)]
-    DB(#[from] postgres::Error),
-    #[error("Another eth-wire process is running concurrently")]
-    Concurrency,
-    #[error(transparent)]
-    Injected(#[from] Injected),
+fn config_bounce_fee(config: &EthConfig) -> U256 {
+    let config = config.bounce_fee.as_deref().unwrap_or(DEFAULT_BOUNCE_FEE);
+    Amount::from_str(&config)
+        .ok()
+        .and_then(|a| taler_to_eth(&a).ok())
+        .expect("config value BOUNCE_FEE is no a valid ethereum amount")
 }
 
-pub type LoopResult<T> = Result<T, LoopError>;
-
 fn main() {
     common::log::init();
 
     let path = std::env::args().nth(1).unwrap();
     let config = load_eth_config(Some(&path));
 
+    let init_confirmation = 
config.confirmation.unwrap_or(DEFAULT_CONFIRMATION);
     let state: &'static WireState = Box::leak(Box::new(WireState {
-        confirmation: AtomicU16::new(config.confirmation),
+        confirmation: AtomicU16::new(init_confirmation),
+        max_confirmations: init_confirmation * 2,
         address: eth_payto_addr(&config.payto).unwrap(),
+        bounce_fee: config_bounce_fee(&config),
         config,
     }));
 
     let rpc_worker = 
auto_reconnect_rpc(state.config.core.data_dir.clone().unwrap(), state.address);
+    let rpc_analysis =
+        auto_reconnect_rpc(state.config.core.data_dir.clone().unwrap(), 
state.address);
     let rpc_watcher =
         auto_reconnect_rpc(state.config.core.data_dir.clone().unwrap(), 
state.address);
 
     let db_watcher = auto_reconnect_db(state.config.core.db_url.clone());
+    let db_analysis = auto_reconnect_db(state.config.core.db_url.clone());
     let db_worker = auto_reconnect_db(state.config.core.db_url.clone());
 
-    std::thread::spawn(move || watcher(rpc_watcher, db_watcher));
+    named_spawn("watcher", move || watcher(rpc_watcher, db_watcher));
+    named_spawn("analysis", move || {
+        analysis(rpc_analysis, db_analysis, state)
+    });
 
     worker(rpc_worker, db_worker, state);
 }
diff --git a/eth-wire/src/rpc.rs b/eth-wire/src/rpc.rs
index 8c96898..1221fae 100644
--- a/eth-wire/src/rpc.rs
+++ b/eth-wire/src/rpc.rs
@@ -22,7 +22,7 @@
 use common::{log::log::error, reconnect::AutoReconnect, url::Url};
 use ethereum_types::{Address, H256, U256, U64};
 use serde::de::DeserializeOwned;
-use serde_json::{error::Category, Value};
+use serde_json::error::Category;
 use std::{
     fmt::Debug,
     io::{self, BufWriter, ErrorKind, Read, Write},
diff --git a/makefile b/makefile
index 0544e84..61c3ff1 100644
--- a/makefile
+++ b/makefile
@@ -25,5 +25,7 @@ test_eth: install
        test/eth/reconnect.sh
        test/eth/stress.sh
        test/eth/reorg.sh
+       test/eth/hell.sh
+       test/eth/analysis.sh
 
 test: install test_gateway test_eth test_btc
\ No newline at end of file
diff --git a/test/conf/taler_btc_bump.conf b/test/conf/taler_btc_bump.conf
index f8a99c5..137869d 100644
--- a/test/conf/taler_btc_bump.conf
+++ b/test/conf/taler_btc_bump.conf
@@ -1,5 +1,5 @@
 [taler]
-CURRENCY = BTC
+CURRENCY      = BTC
 
 [exchange]
 BASE_URL      = http://test.com
diff --git a/test/conf/taler_btc_lifetime.conf 
b/test/conf/taler_btc_lifetime.conf
index c490e72..77db531 100644
--- a/test/conf/taler_btc_lifetime.conf
+++ b/test/conf/taler_btc_lifetime.conf
@@ -1,5 +1,5 @@
 [taler]
-CURRENCY = BTC
+CURRENCY      = BTC
 
 [exchange]
 BASE_URL      = http://test.com
diff --git a/test/eth/analysis.sh b/test/eth/analysis.sh
new file mode 100644
index 0000000..55b7ba9
--- /dev/null
+++ b/test/eth/analysis.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+## Test eth-wire ability to learn and protect itself from blockchain behavior
+
+set -eu
+
+source "${BASH_SOURCE%/*}/../common.sh"
+SCHEMA=eth.sql
+CONFIG=taler_eth.conf
+
+echo  "----- Setup -----"
+echo "Load config file"
+load_config
+echo "Start database"
+setup_db
+echo "Start ethereum node"
+init_eth
+echo "Start second ethereum node"
+init_eth2
+echo "Start eth-wire"
+eth_wire
+echo "Start gateway"
+gateway
+echo ""
+
+echo  "----- Learn from reorg -----"
+
+echo "Loose second ethereum node"
+eth_deco
+
+echo -n "Making wire transfer to exchange:"
+$WIRE_UTILS deposit $CLIENT $WIRE 0.00 42
+next_eth # Trigger eth-wire
+check_balance_eth 999580000 420000
+echo " OK"
+
+echo -n "Perform fork and check eth-wire hard error:"
+gateway_up
+eth_fork 5
+check_balance_eth 1000000000 0
+gateway_down
+echo " OK"
+
+echo -n "Recover orphaned transactions:"
+next_eth 6 # More block needed to confirm
+check_balance_eth 999580000 420000
+gateway_up
+echo " OK"
+
+echo "Loose second bitcoin node"
+eth_deco
+
+echo -n "Making wire transfer to exchange:"
+$WIRE_UTILS deposit $CLIENT $WIRE 0.00 42
+next_eth # Trigger eth-wire
+check_balance_eth 999160000 840000
+echo " OK"
+
+echo -n "Perform fork and check eth-wire learned from previous attack:"
+gateway_up
+eth_fork 5
+check_balance_eth 999580000 420000
+gateway_up
+echo " OK"
+
+echo "All tests passed!"
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]