<p>I was able to successfully get <code>electrs</code> to change a transaction from confirmed to unconfirmed by using a second mining node, as <a href="https://twitter.com/murchandamus/status/1535657478150561794" rel="nofollow noreferrer">suggested</a> by Murch on twitter. My test setup looks like this:</p>
<p>electrum -&gt; electrs -&gt; bitcoind(1) -&gt; bitcoind(2) (generates/invalidates blocks)</p>
<p>The trick was that I had to invalidate two blocks on my mining node (2) which also removed my test transaction from the mining nodes mempool. Then I had to generate 3 more to make a new longest chain that didn't contain my test transaction. After all that then my electrs node change the transaction from confirmed to unconfirmed.</p>
<p>I don't know why electrs doesn't mark the transaction to unconfirmed when I invalidate the block on the one node it's connected to. I tried the same test with electrumx and it behaved the same way as electrs. For anyone else trying to repro this test all the gory details are below:</p>
<h2>Install electrs</h2>
<pre><code>sudo apt-get update
sudo apt-get install librocksdb-dev wget
sudo apt-get install -qqy cargo clang cmake build-essential
</code></pre>
<p>From electrs git repo being tested:</p>
<pre><code>ROCKSDB_INCLUDE_DIR=/usr/include
ROCKSDB_LIB_DIR=/usr/lib
cargo install --locked --path .
electrs --version
</code></pre>
<h2>Install bitcoind</h2>
<pre><code>BITCOIND_VERSION=22.0

wget -q https://bitcoincore.org/bin/bitcoin-core-$BITCOIND_VERSION/bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz
tar xvf bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz
mv -v bitcoin-$BITCOIND_VERSION/bin/bitcoind .
mv -v bitcoin-$BITCOIND_VERSION/bin/bitcoin-cli .
</code></pre>
<h2>Install electrum client</h2>
<pre><code>sudo apt-get install -qqy git libsecp256k1-0 python3-cryptography python3-setuptools python3-pip jq curl

git clone --recurse-submodules https://github.com/spesmilo/electrum/

python3 -m pip install -e electrum/

electrum version --offline
</code></pre>
<h2>Remove old data</h2>
<pre><code>rm -rf data/
mkdir -p data/{bitcoin1,bitcoin2,electrum,electrs}
</code></pre>
<h2>Start bitcoind node 1 and fund wallet</h2>
<pre><code>./bitcoind -version
./bitcoind -regtest -regtest -txindex=1 -datadir=data/bitcoin1 -printtoconsole=0 -fallbackfee=0.0001 &amp;
BITCOIND1_PID=$!
</code></pre>
<h2>Start and fund mining bitcoind node 2 and add to node 1</h2>
<pre><code>./bitcoind -regtest -txindex=1 -datadir=data/bitcoin2 -port=28444 -rpcport=28443 -printtoconsole=0 -fallbackfee=0.0001 &amp;
BITCOIND2_PID=$!

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 createwallet &quot;test&quot;
NODE_ADDR=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getnewaddress`
echo $NODE_ADDR

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 generatetoaddress 101 $NODE_ADDR 
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getwalletinfo

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 addnode &quot;127.0.0.1:18444&quot; &quot;add&quot;

./bitcoin-cli -regtest -datadir=data/bitcoin1 getpeerinfo
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getpeerinfo
</code></pre>
<h3>Status of bitcoind nodes</h3>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>node #</th>
<th>tip height</th>
<th>confirmed</th>
<th>mempool</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>101</td>
<td>none</td>
<td>none</td>
</tr>
<tr>
<td>2</td>
<td>101</td>
<td>none</td>
<td>none</td>
</tr>
</tbody>
</table>
</div><h2>Start electrs and electrum</h2>
<pre><code>export RUST_LOG=electrs=debug
electrs \
  --db-dir=data/electrs \
  --daemon-dir=data/bitcoin1 \
  --network=regtest \
  2&gt; data/electrs/regtest-debug.log &amp;
ELECTRS_PID=$!

electrum --regtest daemon --server localhost:60401:t -1 -vDEBUG 2&gt; data/electrum/regtest-debug.log &amp;
ELECTRUM_PID=$!

</code></pre>
<h2>Fund electrum wallet</h2>
<pre><code>electrum --regtest --wallet=data/electrum/wallet getinfo
electrum --regtest --wallet=data/electrum/wallet create --seed_type=segwit
electrum --regtest --wallet=data/electrum/wallet load_wallet
electrum --regtest --wallet=data/electrum/wallet getbalance
WALLET_ADDR1=`electrum --regtest --wallet=data/electrum/wallet getunusedaddress`
echo $WALLET_ADDR1

TX1=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 sendtoaddress $WALLET_ADDR1 1.11 &quot;test1&quot;`

./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true

electrum --regtest --wallet=data/electrum/wallet getaddresshistory $WALLET_ADDR1
electrum --regtest --wallet=data/electrum/wallet getbalance

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 generatetoaddress 1 $NODE_ADDR

./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true

electrum --regtest --wallet=data/electrum/wallet getaddresshistory $WALLET_ADDR1
electrum --regtest --wallet=data/electrum/wallet getbalance
</code></pre>
<h3>Status of bitcoind nodes</h3>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>node #</th>
<th>tip height</th>
<th>confirmed</th>
<th>mempool</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>102</td>
<td>TX1</td>
<td>none</td>
</tr>
<tr>
<td>2</td>
<td>102</td>
<td>TX1</td>
<td>none</td>
</tr>
</tbody>
</table>
</div><h3>Status of electrum wallet</h3>
<p>confirmed: 1.11</p>
<h2>Invalidate 1st block on node 2</h2>
<pre><code>TIP=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443  getbestblockhash`
echo $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 invalidateblock $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getmempoolinfo 

./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin1 getmempoolinfo 

electrum --regtest --wallet=data/electrum/wallet getbalance
</code></pre>
<h3>Status of bitcoind nodes</h3>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>node #</th>
<th>tip height</th>
<th>confirmed</th>
<th>mempool</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>102</td>
<td>TX1</td>
<td>none</td>
</tr>
<tr>
<td>2</td>
<td>101</td>
<td>none</td>
<td>TX1</td>
</tr>
</tbody>
</table>
</div><h3>Status of electrum wallet</h3>
<p>confirmed: 1.11</p>
<h2>Invalidate 2nd block on node 2</h2>
<pre><code>TIP=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getbestblockhash`
echo $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 invalidateblock $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getmempoolinfo 

./bitcoin-cli -regtest -datadir=data/bitcoin1 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin1 getmempoolinfo

electrum --regtest --wallet=data/electrum/wallet getbalance
electrum --regtest --wallet=data/electrum/wallet listunspent
</code></pre>
<h3>Status of bitcoind nodes</h3>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>node #</th>
<th>tip height</th>
<th>confirmed</th>
<th>mempool</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>102</td>
<td>TX1</td>
<td>none</td>
</tr>
<tr>
<td>2</td>
<td>100</td>
<td>none</td>
<td>none</td>
</tr>
</tbody>
</table>
</div><h3>Status of electrum wallet</h3>
<p>confirmed: 1.11</p>
<h2>Generate 3 new blocks on node 2</h2>
<pre><code>
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 generatetoaddress 3 $NODE_ADDR

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getmempoolinfo

./bitcoin-cli -regtest -datadir=data/bitcoin1 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin1 getmempoolinfo

electrum --regtest --wallet=data/electrum/wallet getbalance
</code></pre>
<h3>Status of bitcoind nodes</h3>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>node #</th>
<th>tip height</th>
<th>confirmed</th>
<th>mempool</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>103</td>
<td>none</td>
<td>TX1</td>
</tr>
<tr>
<td>2</td>
<td>103</td>
<td>none</td>
<td>none</td>
</tr>
</tbody>
</table>
</div><h3>Status of electrum wallet</h3>
<p>confirmed: 0<br />
unconfirmed: 1.11</p>
<h2>Stop daemons</h2>
<pre><code>
electrum --regtest --wallet=data/electrum/wallet stop
wait $ELECTRUM_PID

kill -INT $ELECTRS_PID
wait $ELECTRS_PID

./bitcoin-cli -regtest -datadir=data/bitcoin1 stop
wait $BITCOIND1_PID

./bitcoin-cli -regtest -datadir=data/bitcoin2 --rpcport=28443 stop
wait $BITCOIND2_PID
</code></pre>

CC BY-SA 4.0
2022-06-12T23:54:13.347Z
Weird that it wouldn't work just with one block longer. Thanks for the comprehensive write-up.
Murch
CC BY-SA 4.0
2022-06-13T05:41:33.063Z
Thanks, I agree it is strange that I couldn't do it with one node by invalidating and making a longer chain. I just tried it again to be sure and same result, electrs/electrum thinks the tx is still confirmed. A mystery for another day. :-)
Not Mandatory
CC BY-SA 4.0
2022-06-12T23:03:16.000Z
2022-06-12T23:53:44.570Z
2022-06-12T23:53:44.570Z
Not Mandatory
<blockquote>
<p>I'm trying to test the Bitcoin Dev Kit Electrum client with Electrs 0.9.1 for the case of a 1-block reorg. I use
<code>invalidateblock</code> on my single regtest bitcoind 22.0, but I don't see my
test transaction unconfirmed. Is there a better way to simulate a 1-block reorg?</p>
</blockquote>
<p>Slightly edited from this <a href="https://twitter.com/notmandatory/status/1535655719881433088" rel="nofollow noreferrer">question</a> by Steve Myers.</p>

CC BY-SA 4.0
2022-06-12T17:11:31.177Z
This sounds like an issue with electrs. I tried `invalidateblock` on my regtest node and the non-coinbase transactions in that block were put back into the mempool.
Ava Chow
<electrum><regtest><chain-reorganization><testing><invalidateblock>
How can I simulate a reorg for testing?
Murch
# How can I simulate a reorg for testing?

(Asked by: username_0 on 2022-06-11)

> I'm trying to test the Bitcoin Dev Kit Electrum client with Electrs 0.9.1 for the case of a 1-block reorg. I use
> `invalidateblock` on my single regtest bitcoind 22.0, but I don't see my
> test transaction unconfirmed. Is there a better way to simulate a 1-block reorg?

Slightly edited from this [question](https://twitter.com/username_2/status/1535655719881433088) by Steve Myers.

**Tags:** electrum, regtest, chain-reorganization, testing, invalidateblock

> **Comments:**
> **username_1**: This sounds like an issue with electrs. I tried `invalidateblock` on my regtest node and the non-coinbase transactions in that block were put back into the mempool.  

---

## 1 answers

### Answer by username_2 on 2022-06-12. Score: 4 | Accepted answer

I was able to successfully get `electrs` to change a transaction from confirmed to unconfirmed by using a second mining node, as [suggested](https://twitter.com/murchandamus/status/1535657478150561794) by username_0 on twitter. My test setup looks like this:

electrum -> electrs -> bitcoind(1) -> bitcoind(2) (generates/invalidates blocks)

The trick was that I had to invalidate two blocks on my mining node (2) which also removed my test transaction from the mining nodes mempool. Then I had to generate 3 more to make a new longest chain that didn't contain my test transaction. After all that then my electrs node change the transaction from confirmed to unconfirmed.

I don't know why electrs doesn't mark the transaction to unconfirmed when I invalidate the block on the one node it's connected to. I tried the same test with electrumx and it behaved the same way as electrs. For anyone else trying to repro this test all the gory details are below:

## Install electrs

```
sudo apt-get update
sudo apt-get install librocksdb-dev wget
sudo apt-get install -qqy cargo clang cmake build-essential

```

From electrs git repo being tested:

```
ROCKSDB_INCLUDE_DIR=/usr/include
ROCKSDB_LIB_DIR=/usr/lib
cargo install --locked --path .
electrs --version

```

## Install bitcoind

```
BITCOIND_VERSION=22.0

wget -q https://bitcoincore.org/bin/bitcoin-core-$BITCOIND_VERSION/bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz
tar xvf bitcoin-$BITCOIND_VERSION-x86_64-linux-gnu.tar.gz
mv -v bitcoin-$BITCOIND_VERSION/bin/bitcoind .
mv -v bitcoin-$BITCOIND_VERSION/bin/bitcoin-cli .

```

## Install electrum client

```
sudo apt-get install -qqy git libsecp256k1-0 python3-cryptography python3-setuptools python3-pip jq curl

git clone --recurse-submodules https://github.com/spesmilo/electrum/

python3 -m pip install -e electrum/

electrum version --offline

```

## Remove old data

```
rm -rf data/
mkdir -p data/{bitcoin1,bitcoin2,electrum,electrs}

```

## Start bitcoind node 1 and fund wallet

```
./bitcoind -version
./bitcoind -regtest -regtest -txindex=1 -datadir=data/bitcoin1 -printtoconsole=0 -fallbackfee=0.0001 &
BITCOIND1_PID=$!

```

## Start and fund mining bitcoind node 2 and add to node 1

```
./bitcoind -regtest -txindex=1 -datadir=data/bitcoin2 -port=28444 -rpcport=28443 -printtoconsole=0 -fallbackfee=0.0001 &
BITCOIND2_PID=$!

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 createwallet "test"
NODE_ADDR=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getnewaddress`
echo $NODE_ADDR

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 generatetoaddress 101 $NODE_ADDR 
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getwalletinfo

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 addnode "127.0.0.1:18444" "add"

./bitcoin-cli -regtest -datadir=data/bitcoin1 getpeerinfo
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getpeerinfo

```

### Status of bitcoind nodes

| node # | tip height | confirmed | mempool |
| --- | --- | --- | --- |
| 1 | 101 | none | none |
| 2 | 101 | none | none |

## Start electrs and electrum

```
export RUST_LOG=electrs=debug
electrs \
  --db-dir=data/electrs \
  --daemon-dir=data/bitcoin1 \
  --network=regtest \
  2> data/electrs/regtest-debug.log &
ELECTRS_PID=$!

electrum --regtest daemon --server localhost:60401:t -1 -vDEBUG 2> data/electrum/regtest-debug.log &
ELECTRUM_PID=$!

```

## Fund electrum wallet

```
electrum --regtest --wallet=data/electrum/wallet getinfo
electrum --regtest --wallet=data/electrum/wallet create --seed_type=segwit
electrum --regtest --wallet=data/electrum/wallet load_wallet
electrum --regtest --wallet=data/electrum/wallet getbalance
WALLET_ADDR1=`electrum --regtest --wallet=data/electrum/wallet getunusedaddress`
echo $WALLET_ADDR1

TX1=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 sendtoaddress $WALLET_ADDR1 1.11 "test1"`

./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true

electrum --regtest --wallet=data/electrum/wallet getaddresshistory $WALLET_ADDR1
electrum --regtest --wallet=data/electrum/wallet getbalance

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 generatetoaddress 1 $NODE_ADDR

./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true

electrum --regtest --wallet=data/electrum/wallet getaddresshistory $WALLET_ADDR1
electrum --regtest --wallet=data/electrum/wallet getbalance

```

### Status of bitcoind nodes

| node # | tip height | confirmed | mempool |
| --- | --- | --- | --- |
| 1 | 102 | TX1 | none |
| 2 | 102 | TX1 | none |

### Status of electrum wallet

confirmed: 1.11

## Invalidate 1st block on node 2

```
TIP=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443  getbestblockhash`
echo $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 invalidateblock $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getmempoolinfo 

./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin1 getmempoolinfo 

electrum --regtest --wallet=data/electrum/wallet getbalance

```

### Status of bitcoind nodes

| node # | tip height | confirmed | mempool |
| --- | --- | --- | --- |
| 1 | 102 | TX1 | none |
| 2 | 101 | none | TX1 |

### Status of electrum wallet

confirmed: 1.11

## Invalidate 2nd block on node 2

```
TIP=`./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getbestblockhash`
echo $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 invalidateblock $TIP

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getmempoolinfo 

./bitcoin-cli -regtest -datadir=data/bitcoin1 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin1 getmempoolinfo

electrum --regtest --wallet=data/electrum/wallet getbalance
electrum --regtest --wallet=data/electrum/wallet listunspent

```

### Status of bitcoind nodes

| node # | tip height | confirmed | mempool |
| --- | --- | --- | --- |
| 1 | 102 | TX1 | none |
| 2 | 100 | none | none |

### Status of electrum wallet

confirmed: 1.11

## Generate 3 new blocks on node 2

```

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 generatetoaddress 3 $NODE_ADDR

./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin2 -rpcport=28443 getmempoolinfo

./bitcoin-cli -regtest -datadir=data/bitcoin1 getblockchaininfo
./bitcoin-cli -regtest -datadir=data/bitcoin1 getrawtransaction $TX1 true
./bitcoin-cli -regtest -datadir=data/bitcoin1 getmempoolinfo

electrum --regtest --wallet=data/electrum/wallet getbalance

```

### Status of bitcoind nodes

| node # | tip height | confirmed | mempool |
| --- | --- | --- | --- |
| 1 | 103 | none | TX1 |
| 2 | 103 | none | none |

### Status of electrum wallet

confirmed: 0  
unconfirmed: 1.11

## Stop daemons

```

electrum --regtest --wallet=data/electrum/wallet stop
wait $ELECTRUM_PID

kill -INT $ELECTRS_PID
wait $ELECTRS_PID

./bitcoin-cli -regtest -datadir=data/bitcoin1 stop
wait $BITCOIND1_PID

./bitcoin-cli -regtest -datadir=data/bitcoin2 --rpcport=28443 stop
wait $BITCOIND2_PID

```

> **Comments:**
> **username_0**: Weird that it wouldn't work just with one block longer. Thanks for the comprehensive write-up.  
> **username_2**: Thanks, I agree it is strange that I couldn't do it with one node by invalidating and making a longer chain. I just tried it again to be sure and same result, electrs/electrum thinks the tx is still confirmed. A mystery for another day. :-)  

---

