3

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 by Steve Myers.

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.
    – Ava Chow
    Commented Jun 12, 2022 at 17:11

1 Answer 1

3

I was able to successfully get electrs to change a transaction from confirmed to unconfirmed by using a second mining node, as suggested by Murch 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
2
  • Weird that it wouldn't work just with one block longer. Thanks for the comprehensive write-up.
    – Murch
    Commented Jun 12, 2022 at 23:54
  • 1
    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. :-) Commented Jun 13, 2022 at 5:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.