Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions contrib/signet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Contents
========
This directory contains tools related to Signet, both for running a Signet yourself and for using one.

The `args.sh` script is a helper script used by the other scripts and should not be invoked directly.

getcoins.sh
===========

A script to call a faucet to get Signet coins.

Syntax: `getcoins.sh [--help] [--cmd=<bitcoin-cli path>] [--faucet=<faucet URL>] [--addr=<signet bech32 address>] [--password=<faucet password>] [--] [<bitcoin-cli args>]`

* `--cmd` lets you customize the bitcoin-cli path. By default it will look for it in the PATH, then in `../../src/`
* `--faucet` lets you specify which faucet to use; the faucet is assumed to be compatible with https://github.com/kallewoof/bitcoin-faucet
* `--addr` lets you specify a Signet address; by default, the address must be a bech32 address. This and `--cmd` above complement each other (i.e. you do not need `bitcoin-cli` if you use `--addr`)
* `--password` lets you specify a faucet password; this is handy if you are in a classroom and set up your own faucet for your students; (above faucet does not limit by IP when password is enabled)

If using the default network, invoking the script with no arguments should be sufficient under normal
circumstances, but if multiple people are behind the same IP address, the faucet will by default only
accept one claim per day. See `--password` above.

issuer.sh
=========

A script to regularly issue Signet blocks.

Syntax: `issuer.sh <idle time> [--help] [--cmd=<bitcoin-cli path>] [--] [<bitcoin-cli args>]`

* `<idle time>` is a time in seconds to wait between each block generation
* `--cmd` lets you customize the bitcoin-cli path. By default it will look for it in the PATH, then in `../../src/`

Signet, just like other bitcoin networks, uses proof of work alongside the block signature; this
includes the difficulty adjustment every 2016 blocks.
The `<idle time>` exists to allow you to maintain a relatively low difficulty over an extended period
of time. E.g. an idle time of 540 means your node will end up spending roughly 1 minute grinding
hashes for each block, and wait 9 minutes after every time.

mkblock.sh
==========

A script to generate one Signet block.

Syntax: `mkblock.sh <bitcoin-cli path> [<bitcoin-cli args>]`

This script is called by the other block issuing scripts, but can be invoked independently to generate
1 block immediately.

secondary.sh
============

A script to act as backup generator in case the primary issuer goes offline.

Syntax: `secondary.sh <trigger time> <idle time> [--cmd=<bitcoin-cli path>] [<bitcoin-cli args>]`

* `<trigger time>` is the time in seconds that must have passed since the last block was seen for the secondary issuer to kick into motion
* `<idle time>` is the time in seconds to wait after generating a block, and should preferably be the same as the idle time of the main issuer

Running a Signet network, it is recommended to have at least one secondary running in a different
place, so it doesn't go down together with the main issuer.
57 changes: 57 additions & 0 deletions contrib/signet/addtxtoblock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

import sys
import os
import argparse

# dirty hack but makes CBlock etc available
sys.path.append('/'.join(os.getcwd().split('/')[:-2]) + '/test/functional')

from test_framework.messages import ( # noqa: E402
CBlock,
CTransaction,
FromHex,
ToHex,
)

from test_framework.blocktools import add_witness_commitment # noqa: E402

def main():

# Parse arguments and pass through unrecognised args
parser = argparse.ArgumentParser(add_help=False,
usage='%(prog)s [addtxtoblock options] [bitcoin block file] [tx file] [fee]',
description=__doc__,
epilog='''Help text and arguments:''',
formatter_class=argparse.RawTextHelpFormatter)
_, unknown_args = parser.parse_known_args()

if len(unknown_args) != 3:
print("Need three arguments (block file, tx file, and fee)")
sys.exit(1)

[blockfile, txfile, feestr] = unknown_args

with open(blockfile, "r", encoding="utf8") as f:
blockhex = f.read().strip()
with open(txfile, "r", encoding="utf8") as f:
txhex = f.read().strip()

fee = int(feestr)

block = CBlock()
FromHex(block, blockhex)

tx = CTransaction()
FromHex(tx, txhex)

block.vtx[0].vout[0].nValue += fee
block.vtx.append(tx)
add_witness_commitment(block)
print(ToHex(block))

if __name__ == '__main__':
main()
55 changes: 55 additions & 0 deletions contrib/signet/args.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C

args="-signet"
eoc=

command -v bitcoin-cli > /dev/null \
&& bcli="bitcoin-cli" \
|| bcli="$(dirname $0)/../../src/bitcoin-cli"

if [ "$VARCHECKS" = "" ]; then
VARCHECKS='if [ "$varname" = "cmd" ]; then bcli=$value;'
fi

# compatibility; previously the bitcoin-cli path was given as first argument
if [[ "$1" != "" && "${1:$((${#1}-11))}" = "bitcoin-cli" ]]; then
echo "using $1 as bcli"
bcli=$1
shift
fi

for i in "$@"; do
if [ $eoc ]; then
args="$args $i"
elif [ "$i" = "--" ]; then
# end of commands; rest into args for bitcoin-cli
eoc=1
continue
elif [ "${i:0:2}" = "--" ]; then
# command
j=${i:2}
if [ "$j" = "help" ]; then
>&2 echo -e $HELPSTRING
exit 1
fi
export varname=${j%=*}
export value=${j#*=}
eval $VARCHECKS '
else
>&2 echo "unknown parameter $varname (from \"$i\"); for help, type: $0 --help"
exit 1
fi'
else
# arg
args="$args $i"
fi
done

if ! [ -e "$bcli" ]; then
command -v "$bcli" >/dev/null 2>&1 || { echo >&2 "error: unable to find bitcoin-cli binary: $bcli"; exit 1; }
fi
74 changes: 74 additions & 0 deletions contrib/signet/forker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C

#
# Take the hex formatted line separated transactions in reorg-list.txt where every even transaction is put into the even set, and every odd transaction is put into the odd set.
# That is, transactions on line 1, 3, 5, 7, ... go into the odd set, and transactions on line 2, 4, 6, 8, ... go into the even set.
#
# - Generate two blocks A and B, where A contains all or some of the odd set, and B contains the corresponding even set.
# - Sign, grind, and broadcast block A
# - Wait a random amount of time (1-10 mins)
# - Invalidate block A
# - Sign, grind, and broadcast block B
#

bcli=$1
shift

function log()
{
echo "- $(date +%H:%M:%S): $*"
}

if [ ! -e "reorg-list.txt" ]; then
echo "reorg-list.txt not found"
exit 1
fi

# get address for coinbase output
addr=$($bcli "$@" getnewaddress)

# create blocks A and B
$bcli "$@" getnewblockhex $addr > $PWD/block-a
cp block-a block-b

odd=1
while read -r line; do
if [ "$line" = "" ]; then continue; fi
echo $line > tx
if [ $odd -eq 1 ]; then blk="block-a"; else blk="block-b"; fi
./addtxtoblock.py $blk tx 100 > t # note: we are throwing away all fees above 100 satoshis for now; should figure out a way to determine fees
mv t $blk
(( odd=1-odd ))
done < reorg-list.txt

rm reorg-list.txt

log "mining block A (to-orphan block)"
while true; do
$bcli "$@" signblock $PWD/block-a > signed-a
blockhash_a=$($bcli "$@" grindblock $PWD/signed-a 1000000000)
if [ "$blockhash_a" != "false" ]; then break; fi
done
log "mined block with hash $blockhash_a"
(( waittime=RANDOM%570 ))
(( waittime=30+waittime ))
log "waiting for $waittime s"
sleep $waittime
log "invalidating $blockhash_a"
$bcli "$@" invalidateblock $blockhash_a

log "mining block B (replace block)"
while true; do
$bcli "$@" signblock $PWD/block-b > signed-b
blockhash_b=$($bcli "$@" grindblock $PWD/signed-b 1000000000)
if [ "$blockhash_b" != "false" ]; then break; fi
done

echo "mined $blockhash_b"
echo "cleaning up"
rm block-b signed-b block-a signed-a
Loading