commit 4855a6ec05351a697de9f10be1597eaa8a726c0a
parent effa824a4de6f09a999a578f30ba3e341d380b31
Author: Antoine A <>
Date: Wed, 23 Mar 2022 21:36:38 +0100
dirty fix for eth tests and other improvements
Diffstat:
9 files changed, 94 insertions(+), 112 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -454,9 +454,9 @@ dependencies = [
[[package]]
name = "deadpool-postgres"
-version = "0.10.1"
+version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46ff1451a33b8b31b15eedcf5401dbbb28606caed4fa94d20487eb3fac2ebd04"
+checksum = "c668a58063c6331e3437e3146970943ad82b1b36169fd979bb2645ac2088209a"
dependencies = [
"deadpool",
"log",
@@ -817,9 +817,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "hyper"
-version = "0.14.17"
+version = "0.14.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd"
+checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
dependencies = [
"bytes",
"futures-channel",
@@ -975,9 +975,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.14"
+version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
dependencies = [
"cfg-if",
]
@@ -1789,9 +1789,9 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.7"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
dependencies = [
"itoa 1.0.1",
"libc",
@@ -1801,9 +1801,9 @@ dependencies = [
[[package]]
name = "time-macros"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
+checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
[[package]]
name = "tiny-keccak"
diff --git a/README.md b/README.md
@@ -48,9 +48,11 @@ Depolymerizer require:
We expect you to have already have written a [configuration](#configuration) and
that PostgreSQL and the node (bitcoind or geth) is configured and running.
-We will use `btc-wire` in command, but you can use `eth-wire` interchangeably to depolymerize Ethereum.
+We will use `btc-wire` in command, but you can use `eth-wire` interchangeably to
+depolymerize Ethereum.
-If you want to use a specific configuration file, you can add `-c CONF_PATH` to every command.
+If you want to use a specific configuration file, you can add `-c CONF_PATH` to
+every command.
#### Database initialization
@@ -60,13 +62,15 @@ btc-wire initdb
#### Wallet initialization
-Depolymerization uses an encrypted wallet, so you need to provide a password in the environment variable `PASSWORD`.
+Depolymerization uses an encrypted wallet, so you need to provide a password in
+the environment variable `PASSWORD`.
```
btc-wire initwallet
```
-You then need to update your configuration with the provided `PAYTO` config value.
+You then need to update your configuration with the provided `PAYTO` config
+value.
#### Start depolymerization
@@ -74,7 +78,8 @@ You then need to update your configuration with the provided `PAYTO` config valu
btc-wire
```
-You also need to run the wire gateway `wire-gateway`. It can run from another user as long it can access the database and the configuration file.
+You also need to run the wire gateway `wire-gateway`. It can run from another
+user as long it can access the database and the configuration file.
## Configuration
@@ -231,9 +236,9 @@ You can have an additional context:
Instrumentation test documentation can be founded in the
[instrumentation](instrumentation/README.md) directory.
-### Unit test
+### Local test
-Unit test require additional binaries. The following binaries must be in the
+Local test require additional binaries. The following binaries must be in the
local user PATH:
- `pg_ctl` and `psql` from PostgreSQL
diff --git a/btc-wire/src/main.rs b/btc-wire/src/main.rs
@@ -110,6 +110,7 @@ fn init(config: Option<PathBuf>, init: Init) -> LoopResult<()> {
rpc.load_wallet(WIRE_WALLET_NAME).ok();
// Load previous address
+ // TODO Use address label instead of the database ?
let prev_addr = db.query_opt("SELECT value FROM state WHERE name = 'addr'", &[])?;
let addr = if let Some(row) = prev_addr {
sql_addr(&row, 0)
@@ -158,6 +159,7 @@ fn run(config: Option<PathBuf>) {
Network::Regtest => "regtest",
};
info!("Running on {} chain", chain_name);
+ // TODO Check wire wallet own config PAYTO address
let rpc_watcher = auto_rpc_common(state.btc_config.clone());
let rpc_analysis = auto_rpc_common(state.btc_config.clone());
diff --git a/btc-wire/src/rpc.rs b/btc-wire/src/rpc.rs
@@ -47,7 +47,7 @@ pub fn auto_rpc_wallet(config: BitcoinConfig, wallet: &'static str) -> AutoRpcWa
let mut rpc = Rpc::wallet(config, wallet)
.map_err(|err| error!("connect RPC: {}", err))
.ok()?;
- rpc.load_wallet(wallet).ok();
+ rpc.load_wallet(wallet).ok();
rpc.unlock_wallet(&password())
.map_err(|err| error!("connect RPC: {}", err))
.ok()?;
diff --git a/docs/report.tex b/docs/report.tex
@@ -16,14 +16,23 @@
\affil{Bern University of Applied Sciences}
\date{\today}
-\DeclareAcronym{dlt}{
+\DeclareAcronym{DLT}{
short=DLT,
long=Distributed Ledger,
}
-\DeclareAcronym{dos}{
+\DeclareAcronym{DOS}{
short=DOS,
long=Denial of service,
}
+\DeclareAcronym{BIP}{
+ short=BIP,
+ long=Bitcoin Improvement Proposal,
+}
+\DeclareAcronym{RPC}{
+short=RPC,
+long=Remote Procedure Call
+}
+
\begin{document}
@@ -69,7 +78,7 @@ At the heart of these currencies is a blockchain. A blockchain is an append-only
\subsection{Consensus}
-The blockchain itself is just a storage system. To make it a \acf{dlt}, it needs a peer-to-peer network to share its changes. But also a way for participants (nodes) to agree on a single state of the chain, to reach consensus in a network where nodes can be malicious and have an economic interest in deceiving others. There are many ways to create such consensus, but only two of them interest us: proof of work and proof of stake.
+The blockchain itself is just a storage system. To make it a \acf{DLT}, it needs a peer-to-peer network to share its changes. But also a way for participants (nodes) to agree on a single state of the chain, to reach consensus in a network where nodes can be malicious and have an economic interest in deceiving others. There are many ways to create such consensus, but only two of them interest us: proof of work and proof of stake.
% DLT definition ?
@@ -83,7 +92,7 @@ Another problem is that miners are incentivized to invest more and more computin
\subsubsection*{Proof of stake}
-This mechanism replaces the use of computing power with the stacking of money. Validators (who replace miners) stake large sums of money to be randomly selected to validate blocks. In case of malicious behavior, the stacked money is burned by other validators.
+This mechanism replaces the use of computing power with the stacking of money. Validators (who replace miners) stake large sums of money to be allowed to verified blocks and be randomly selected to create them. In case of malicious behavior, the stacked money is burned by other validators.
The effectiveness and security of this mechanism have yet to be proven, but Ethereum plans to adopt it in the summer of 2022.
@@ -97,7 +106,7 @@ These decentralized consensus mechanisms lead to the creation of competing block
\subsection{Mining incentive}
-A minimum amount of mining power is required for the cryptocurrency to work. Without new blocks, there can be no new transaction. The more mining power and diversity (different miners), the more resistant the \ac{dlt} is to attacks. Since mining is an expensive process, cryptocurrencies must incentivize it by offering rewards to miners.
+A minimum amount of mining power is required for the cryptocurrency to work. Without new blocks, there can be no new transaction. The more mining power and diversity (different miners), the more resistant the \ac{DLT} is to attacks. Since mining is an expensive process, cryptocurrencies must incentivize it by offering rewards to miners.
Rewards are of two kinds:
\begin{itemize}
@@ -125,19 +134,19 @@ GNU Taler is an electronic payment system implemented as free software. We provi
\end{figure}
-\subsubsection*{Exchange}
+\paragraph*{Exchange}
The exchange is the payment service provider for financial transactions between customers and merchants. The exchange holds money as a reserve for anonymous digital coins.
-\subsubsection*{Customer}
-A customer can withdraw coins from the exchange and store them in his electronic wallet. These coins can then be spent at a merchant.
+\paragraph*{Customer}
+Customers can withdraw coins from the exchange and store them in their electronic wallets. These coins can then be spent at a merchant.
-\subsubsection*{Merchant}
-A merchant accepts coins in exchange for goods and services. The merchant can then deposit these coins at the exchange to receive money in return.
+\paragraph*{Merchant}
+Merchants accept coins in exchange for goods and services. They can then deposit these coins at the exchange to receive money in return.
-\subsubsection*{Auditor}
+\paragraph*{Auditor}
Auditors monitor the behaviour of the exchanges to ensure that exchanges operate correctly. They are typically operated by financial regulators.
-\subsubsection*{Settlement layer}
+\paragraph*{Settlement layer}
The settlement layer provides finality for wire transfers that allow customers to deposit money and merchant to withdraw money from Taler. It is typically provided by banks. The goal of this project is to use blockchains as a settlement layer to support blockchain-based cryptocurrencies.
\subsection{Blockchain settlement layer}
@@ -149,7 +158,7 @@ The settlement layer provides finality for wire transfers that allow customers t
\caption{Blockchain settlement layer with Depolymerizer}
\end{figure}
-Depolymerizer serves as a middleware between GNU taler and cryptocurrencies \ac{dlt}. Customers can send money to the Depolymerizer using an on-chain transaction to get coins that they can use in off-chain transactions. Using the Depolymerizer, Taler exchanges can materialize coins back into the blockchain.
+Depolymerizer serves as a middleware between GNU taler and cryptocurrencies \ac{DLT}. Customers can send money to the Depolymerizer using an on-chain transaction to get coins that they can use in off-chain transactions. Using the Depolymerizer, Taler exchanges can materialize coins back into the blockchain.
Off-chain transactions have many advantages over on-chain transactions. At the cost of putting trust in exchange operators or auditors, you can have fast and low cost transactions with instant confirmation (ms). GNU Taler offers linear scalability that can solve blockchain throughput limitation and, by not relying on Proof of Work, has a much lower ecological impact. GNU Taler does not sacrifice privacy either; it provides privacy when it can and transparency when it has to (regulation: avoid tax evasion and money laundering).
@@ -296,13 +305,13 @@ Ethereum is designed around the concept of smart contracts. Logging inside a sma
\subsection{Friendly behavior on format error}
-When we receive a transaction without any metadata or with an incompatible format (bogus wallet), we want to return the money to its owner (bounce). However, this is dangerous because we have created a potential attack loophole as anyone can now make Depolymerizer do a transaction, by sending a malformed transaction. Depolymerizer takes a bounce fee to make a potential \acs{dos} attack too costly and charges the recipient the transaction fee to ensure it can not lose money on a bounce.
+When we receive a transaction without any metadata or with an incompatible format (bogus wallet), we want to return the money to its owner (bounce). However, this is dangerous because we have created a potential attack loophole as anyone can now make Depolymerizer do a transaction, by sending a malformed transaction. Depolymerizer takes a bounce fee to make a potential \acs{DOS} attack too costly and charges the recipient the transaction fee to ensure it can not lose money on a bounce.
\clearpage
\section{Architecture}
-Each cryptocurrency uses a different \ac{dlt} with its own format and rules, which evolve over time. We do not want to manage the \ac{dlt} logic ourselves, nor do we want to rely on third-party dependencies to implement their support properly and be maintained. The simplest solution is to rely on the official clients and communicate with them via RPC.
+Each cryptocurrency uses a different \ac{DLT} with its own format and rules, which evolve over time. We do not want to manage the \ac{DLT} logic ourselves, nor do we want to rely on third-party dependencies to implement their support properly and be maintained. The simplest solution is to rely on the official clients and communicate with them via \acs{RPC}.
\begin{figure}[hb]
\begin{center}
@@ -311,9 +320,9 @@ Each cryptocurrency uses a different \ac{dlt} with its own format and rules, whi
\caption{Depolymerizer architecture}
\end{figure}
-While some parts of Depolymerizer are \ac{dlt} specific, much of the logic is common and we want to reuse it. We have a Wire Gateway component that implements the Taler HTTP API to enable communication with Taler exchanges. Each supported cryptocurrency has its specific adapter to communicate with the official full node client via RPC. The Wire Gateway module and the \ac{dlt} adapter use a common database to store transactions and communicate with notifications.
+While some parts of Depolymerizer are \ac{DLT} specific, much of the logic is common and we want to reuse it. We have a Wire Gateway component that implements the Taler HTTP API to enable communication with Taler exchanges. Each supported cryptocurrency has its specific adapter to communicate with the official full node client via \acs{RPC}. The Wire Gateway module and the \ac{DLT} adapter use a common database to store transactions and communicate with notifications.
-\subsection{\acs{dlt} adapter}
+\subsection{\acs{DLT} adapter}
The DTL adapter uses an event-based architecture with three distinct loops.
@@ -327,21 +336,21 @@ The analysis loop waits for new blocks and then analyzes the behavior of the blo
\paragraph*{Worker}
-The worker loop waits for new blocks or transaction requests (from the Wire Gateway API). When one of these events occurs, it first reconciles the local database with the \ac{dlt}, then triggers requested debits, re-issues blocked debits and bounces malformed credits.
+The worker loop waits for new blocks or transaction requests (from the Wire Gateway API). When one of these events occurs, it first reconciles the local database with the \ac{DLT}, then triggers requested debits, re-issues blocked debits and bounces malformed credits.
\subsection{Worker loop in detail}
-\subsubsection*{\acs{dlt} reconciliation}
+\subsubsection*{\acs{DLT} reconciliation}
-During a \ac{dlt} reconciliation, we first list all new transactions and any transactions that have been removed in a reorganization since the last reconciliation. If any previously confirmed debits have been removed without being reinserted into another block, we notify the Wire Gateway to cease activity and wait for the next block in hopes of recovering them. All newly confirmed debits and successful credits are registered in the database.
+During a \ac{DLT} reconciliation, we first list all new transactions and any transactions that have been removed in a reorganization since the last reconciliation. If any previously confirmed debits have been removed without being reinserted into another block, we notify the Wire Gateway to cease activity and wait for the next block in hopes of recovering them. All newly confirmed debits and successful credits are registered in the database.
\subsubsection*{Reconciliation inconsistency}
-When we issue a transaction (debit or bounce), it is possible for the database or \ac{dlt} request to fail. Since a \ac{dlt} request does not mean that the cryptocurrency transaction was not successful, and since the database may not record a successful transaction, it is possible to have an inconsistency between the DLT and the database where a successful transaction is not recorded as such. This is very problematic because we must perform each transaction once.
+When we issue a transaction (debit or bounce), it is possible for the database or \ac{DLT} request to fail. Since a \ac{DLT} request does not mean that the cryptocurrency transaction was not successful, and since the database may not record a successful transaction, it is possible to have an inconsistency between the DLT and the database where a successful transaction is not recorded as such. This is very problematic because we must perform each transaction once.
-This is also problematic because, even if we used a status machine state in the database to detect this inconsistency, the only way to resolve it is to make another \ac{dlt} reconciliation, which is slow and does not play well with database locking.
+This is also problematic because, even if we used a status machine state in the database to detect this inconsistency, the only way to resolve it is to make another \ac{DLT} reconciliation, which is slow and does not play well with database locking.
-Since we know that blockchain-based cryptocurrencies have low throughput, we do not need parallel worker loops to stay synchronized. Therefore, we can use a cross-process locking mechanism to ensure that only one working loop is running at a time. Then, when a database or \ac{dlt} request error occurs, we can restart the loop, which will start by performing a \ac{dlt} reconciliation that will recover all successful unregistered transactions.
+Since we know that blockchain-based cryptocurrencies have low throughput, we do not need parallel worker loops to stay synchronized. Therefore, we can use a cross-process locking mechanism to ensure that only one working loop is running at a time. Then, when a database or \ac{DLT} request error occurs, we can restart the loop, which will start by performing a \ac{DLT} reconciliation that will recover all successful unregistered transactions.
\clearpage
@@ -359,7 +368,7 @@ When some merchants wanted to allow instant payments with Bitcoin, they chose to
This becomes problematic when you want to make a legitimate replacement, to unstuck a transaction by increasing its transaction fee for example. At the same time, it is always dangerous to give an easy way to attackers and scammers to change the content of a pending transaction.
-A solution has been adopted in BIP 125 \cite{BIP125}. It is now possible to encode the replaceability of a bitcoin transaction when creating it. This allows it to be replaced by a new transaction within certain rules: you cannot send less money to existing recipients and you must pay a replacement fee as a countermeasure to a \acs{dos} attack.
+A solution has been adopted in \acs{BIP} 125 \cite{BIP125}. It is now possible to encode the replaceability of a bitcoin transaction when creating it. This allows it to be replaced by a new transaction within certain rules: you cannot send less money to existing recipients and you must pay a replacement fee as a countermeasure to a \acs{DOS} attack.
\clearpage
@@ -427,7 +436,7 @@ Taler is a modular project where each module communicates through HTTP API. The
The wire API only supports the Basic HTTP Authentication method and it has to be optional. Making it optional can lead to security issues by misconfiguration. If the default behavior in case of missing configuration is to deactivate authentication, a typo could lead to an exposed API. We made the authentication method configuration mandatory to make its deactivation explicit.
-\subsection*{OOM \acs{dos}}
+\subsection*{OOM DOS}
A common Denial Of Service attack consists of sending many requests with huge bodies to saturate a server memory and, in the worst case, create an Out Of Memory error. To be resilient against such attacks we only read body after request authentication, to prevent any person without authorization to access the API to perform such attacks.
diff --git a/eth-wire/src/bin/eth-wire-utils.rs b/eth-wire/src/bin/eth-wire-utils.rs
@@ -84,21 +84,14 @@ enum Cmd {
wire_addr: String,
wire: u64,
},
- /// Add a peer
- Connect {
- /// peer datadir
- datadir: PathBuf,
- },
- /// Remove a peer
- Disconnect {
- /// peer datadir
- datadir: PathBuf,
- },
/// Abandon all unconfirmed transaction
Abandon {
/// sender address
from: String,
},
+ Export {
+ path: String,
+ },
}
fn main() {
@@ -216,34 +209,6 @@ fn main() {
}
}
}
- Cmd::Connect { datadir } => {
- let mut peer = Rpc::new(datadir).unwrap();
- let mut enode = peer.node_info().unwrap().enode;
- // Replace ip with localhost because it is broken
- enode.set_host(Some("127.0.0.1")).unwrap();
- assert!(rpc.add_peer(&enode).unwrap());
- let start = Instant::now();
- while rpc.count_peer().unwrap() == 0 {
- if start.elapsed() > Duration::from_secs(60) {
- panic!("Connect timeout");
- }
- std::thread::sleep(Duration::from_secs(5))
- }
- }
- Cmd::Disconnect { datadir } => {
- let mut peer = Rpc::new(datadir).unwrap();
- let mut enode = peer.node_info().unwrap().enode;
- // Replace ip with localhost because it is broken
- enode.set_host(Some("127.0.0.1")).unwrap();
- assert!(rpc.remove_peer(&enode).unwrap());
- let start = Instant::now();
- while rpc.count_peer().unwrap() != 0 {
- if start.elapsed() > Duration::from_secs(60) {
- panic!("Disconnect timeout");
- }
- std::thread::sleep(Duration::from_secs(5))
- }
- }
Cmd::Abandon { from } => {
let from = H160::from_str(&from).unwrap();
rpc.unlock_account(&from, &passwd).ok();
@@ -261,5 +226,9 @@ fn main() {
.unwrap();
}
}
+ Cmd::Export { path } => {
+ std::fs::remove_file(&path).ok();
+ assert!(rpc.export_chain(&path).unwrap())
+ }
}
}
diff --git a/eth-wire/src/rpc.rs b/eth-wire/src/rpc.rs
@@ -316,7 +316,7 @@ pub trait RpcClient {
/* ----- Account management ----- */
- /// List registered acount
+ /// List registered account
fn list_accounts(&mut self) -> Result<Vec<Address>> {
self.call("personal_listAccounts", &EMPTY)
}
@@ -326,7 +326,7 @@ pub trait RpcClient {
self.call("personal_newAccount", &[passwd])
}
- /// Unlock an existinf acount
+ /// Unlock an existing account
fn unlock_account(&mut self, account: &Address, passwd: &str) -> Result<bool> {
self.call("personal_unlockAccount", &(account, passwd, 0))
}
@@ -348,7 +348,7 @@ pub trait RpcClient {
r => r,
}
}
-
+
/// Get block by hash
fn block(&mut self, hash: &H256) -> Result<Option<Block>> {
match self.call("eth_getBlockByHash", &(hash, &true)) {
@@ -361,7 +361,7 @@ pub trait RpcClient {
fn pending_transactions(&mut self) -> Result<Vec<Transaction>> {
self.call("eth_pendingTransactions", &EMPTY)
}
-
+
/// Get latest block
fn latest_block(&mut self) -> Result<Block> {
self.call("eth_getBlockByNumber", &("latest", &true))
@@ -414,20 +414,12 @@ pub trait RpcClient {
/* ----- Peer management ----- */
- /// Add peer to the peer list
- fn add_peer(&mut self, url: &Url) -> Result<bool> {
- self.call("admin_addPeer", &[url])
- }
-
- /// Remove a peer to the peer list
- fn remove_peer(&mut self, url: &Url) -> Result<bool> {
- self.call("admin_removePeer", &[url])
+ fn export_chain(&mut self, path: &str) -> Result<bool> {
+ self.call("admin_exportChain", &[path])
}
- /// Get peer count
- fn count_peer(&mut self) -> Result<u32> {
- let peers: U64 = self.call("net_peerCount", &EMPTY)?;
- Ok(peers.as_u32())
+ fn import_chain(&mut self, path: &str) -> Result<bool> {
+ self.call("admin_importChain", &[path])
}
}
diff --git a/instrumentation/README.md b/instrumentation/README.md
@@ -1,6 +1,6 @@
# Depolymerizer instrumentation test
-Unit tests running on a private development network are meant to test the good
+Local tests running on a private development network are meant to test the good
behavior in case of extreme situations but do not attest our capacity to handle
real network behavior.
@@ -17,4 +17,4 @@ tested blockchain will be determined based on the taler configuration.
If you do not want to use a persistent database for instrumentation tests, there
is a [script](../script/tmp_db.sh) to generate a temporary database similar to
-unit tests.
+local tests.
+\ No newline at end of file
diff --git a/test/common.sh b/test/common.sh
@@ -274,29 +274,35 @@ function init_eth() {
echo -e "PAYTO = payto://ethereum/$WIRE" >> $CONF
}
-# Start a seconf geth dev node connected to the first one
+# Initialize a second geth dev node
function init_eth2() {
# Initialize blockchain
$ETH_CLI2 init $DIR/genesis.json &>> log/node2.log
- # Start node
- $ETH_CLI2 --port 30305 $* &>> log/node2.log &
- sleep 1
- # Create etherbase account for mining
$ETH_CLI2 account new --password <(echo $PASSWORD) &> /dev/null
- # Connect nodes
- $WIRE_UTILS connect $WIRE_DIR2
}
+# We use the import/export chain functionality to simulate a connected node peer
+# because local network peer are not reliable
+# importChain RPC crash so we have to use the cli for now
+
# Disconnect the two nodes
function eth_deco() {
- $WIRE_UTILS disconnect $WIRE_DIR2
+ $WIRE_UTILS export $DIR/chain &>> log/node.log
+ $ETH_CLI2 import $DIR/chain &>> log/node2.log
}
# Create a fork on the second node and reconnect the two node
function eth_fork() {
- sleep 2 # Sync before fork
+ $ETH_CLI2 --port 30305 --miner.gasprice 0 &>> log/node2.log &
+ NODE2_PID="$!"
+ sleep 1
$WIRE_UTILS2 mine $RESERVE ${1:-}
- $WIRE_UTILS connect $WIRE_DIR2
+ $WIRE_UTILS2 export $DIR/chain &>> log/node2.log
+ kill $NODE2_PID
+ stop_node
+ $ETH_CLI import $DIR/chain &>> log/node.log
+ start_eth --miner.gasprice 0
+ sleep 5 # Wait for reconnect
}
# Restart an initialized geth dev node
@@ -304,9 +310,7 @@ function start_eth() {
# Start node
$ETH_CLI $* &>> log/node.log &
NODE_PID="$!"
- sleep 1
- # Try to connect nodes
- $WIRE_UTILS connect $WIRE_DIR2 &> /dev/null || true
+ sleep 2
}
function restart_eth() {