...
authoralex <[email protected]>
Tue, 28 Jun 2022 00:34:54 +0000 (17:34 -0700)
committeralex <[email protected]>
Tue, 28 Jun 2022 00:34:54 +0000 (17:34 -0700)
cold-setup
test/setup.sh
test/wallet_multisig_spend_correctness.tests.sh

index 62afaf9df05bdf52f8e2dafafe4fe09c9ac25dee..06ef97ddc94b872b06ae9f420009600614b7ab94 100755 (executable)
@@ -27,6 +27,12 @@ bitcoin_core_start() {
        log_info "bitcoin core started"
 }
 
+bitcoin_core_start_interactive() {
+       log_msg "start bitcoin core:\n\n\tbitcoind --daemonwait\n"
+
+       confirm "confirm bitcoin core started"
+}
+
 bitcoin_core_stop() {
        RUNNING=`ps -A | ( grep bitcoind > /dev/null && echo "1" ) || echo "0"`
        if [[ "$RUNNING" -eq 0 ]]; then
@@ -41,6 +47,22 @@ bitcoin_core_stop() {
        log_info "bitcoin core stopped"
 }
 
+bitcoin_core_stop_interactive() {
+       log_msg "stop bitcoin core:\n\n\tbitcoin-cli stop\n"
+}
+
+confirm() {
+       local RESULT
+       while true; do
+               read -n 1 -p "$1: [Y/n] " RESULT
+               if [[ "$RESULT" == "Y" ]]; then
+                       break;
+               fi
+               log_error "\nfailed...\n"
+       done
+       log_error "\n"
+}
+
 depends() {
        PATH="$PATH:/sbin"
 
@@ -116,10 +138,51 @@ multisig_create() {
        echo -n '", "active": true, "timestamp": "now", "internal": true}]' >> "$DUMPFILE"
 }
 
+multisig_create_interactive() {
+       log_msg "Creating multi-signature descriptors..."
+
+       log_msg "create output file 'main.descriptors':\n\n\techo -n \"wsh(sortedmulti(3,\" > main.descriptors"
+       confirm "confirm main.descriptors created"
+
+       for((i = 1; i <= $N; i++)); do
+               log_msg "added descriptors from wallet$i to main.descriptors\n\n\tbitcoin-cli -rpcwallet=wallet$i listdescriptors | jq -j '.descriptors | map(select(.desc | startswith(\"wpkh\"))) | map(select(.internal == false)) | map(.desc | ltrimstr(\"wpkh(\")) | .[] | split(\")\") | .[0]' >> main.descriptors"
+               confirm "confirm descriptors from wallet$i added to main.descriptors"
+       done
+
+       log_msg "finish formatting for main.descriptors:\n\n\techo \"))\" >> main.descriptors"
+       confirm "confirm main.descriptors file fully created"
+
+       log_msg "Use bitcoin core to get information on fully formed descriptors and output result to descriptors.txt:\n\n\tcat main.descriptors | bitcoin-cli -stdin getdescriptorinfo | jq -j '.descriptor' >> descriptors.txt"
+       confirm "confirm descriptors.txt created"
+
+       log_msg "create output file 'change.descriptors':\n\n\techo -n \"wsh(sortedmulti(3,\" > change.descriptors"
+       confirm "confirm change.descriptors created"
+
+       for((i = 1; i <= $N; i++)); do
+               log_msg "added change descriptors from wallet$i to change.descriptors\n\n\tbitcoin-cli -rpcwallet=wallet$i listdescriptors | jq -j '.descriptors | map(select(.desc | startswith(\"wpkh\"))) | map(select(.internal == true)) | map(.desc | ltrimstr(\"wpkh(\")) | .[] | split(\")\") | .[0]' >> change.descriptors"
+               confirm "confirm change descriptors from wallet$i added to change.descriptors"
+       done
+               
+       log_msg "finish formatting for change.descriptors:\n\n\techo \"))\" >> change.descriptors"
+       confirm "confirm change.descriptors file fully created"
+
+       log_msg "Format descriptors.txt to be ready to append change descriptors:\n\n\techo -n ',{\"desc\": \"' >> descriptors.txt"
+       confirm "confirm descriptors.txt formatted correctly"
+
+       log_msg "Use bitcoin core to get information on fully formed change descriptors and output result to descriptors.txt:\n\n\tcat change.descriptors | bitcoin-cli -stdin getdescriptorinfo | jq -j '.descriptor' >> descriptors.txt"
+       confirm "confirm change descriptors added to descriptors.txt"
+}
+
 network_off() {
        nmcli networking off
 }
 
+network_off_interactive() {
+       log_msg "shut off networking:\n\n\tnmcli networking off\n"
+       
+       confirm "confirm networking shut off"
+}
+
 parse_arguments() {
        # transform long options into short opts
        for arg in "$@"; do
@@ -330,6 +393,67 @@ usbs() {
        done
 }
 
+usbs_interactive() {
+       # export to usbs
+       for((i = 1; i <= $N; i++)); do
+               log_msg "insert usb drive..."
+               USB_PATH="`usb_detect`"
+               log_msg "usb drive detected at $USB_PATH"
+               confirm "use usb drive at $USB_PATH?"
+
+               log_msg "wipe filesystem on $USB_PATH\n\n\twipefs -a $USB_PATH"
+               confirm "usb drive wiped"
+
+               if [[ -n "$ENCRYPTION" ]]; then
+                       log_msg "format usb device for encryption:\n\n\tcryptsetup luksFormat --type luks2 $USB_PATH"
+                       confirm "usb drive formatted for encryption"
+
+                       log_msg "open encrypted drive:\n\n\tcryptsetup luksOpen $USB_PATH $USB_DECRYPT_NAME"
+                       confirm "usb drive opened"
+
+                       USB_PATH_PRE_DECRYPT="$USB_PATH"
+                       USB_PATH="/dev/mapper/$USB_DECRYPT_NAME"
+               fi
+               
+               log_msg "fill drive with zeros:\n\n\tdd if=/dev/zero of=$USB_PATH"
+               confirm "drive filled with zeros"
+
+               log_msg "make filesystem on usb drive:\n\n\tmkfs.ext4 $USB_PATH"
+               confirm "filesystem setup on usb drive"
+
+               log_msg "mount usb drive:\n\n\tmount $USB_PATH $USB_DIRECTORY"
+               confirm "usb drive mounted at $USB_DIRECTORY"
+
+               log_msg "dump descriptors for wallet$i:\n\n\tbitcoin-cli -named -rpcwallet=wallet$i listdescriptors private=true > wallet$i.descriptors"
+               confirm "descriptors dumped into wallet$i.descriptors"
+
+               log_msg "copy descriptors for wallet$i to $USB_DIRECTORY:\n\n\tcp wallet$i.descriptors $USB_DIRECTORY/"
+               confirm "descriptors copied to $USB_DIRECTORY"
+
+               log_msg "copy multi-signature descriptors to $USB_DIRECTORY:\n\n\tcp descriptors.txt $USB_DIRECTORY/"
+               confirm "multi-signature descriptors copied to $USB_DIRECTORY"
+
+               log_msg "verify integrity sum of copied files matches:\n\n\tb2sum wallet$i.descriptors $USB_DIRECTORY/wallet$i.descriptors descriptors.txt $USB_DIRECTORY/descriptors.txt"
+               confirm "copied files' integrity matches"
+
+               log_msg "shred wallet$i.descriptors:\n\n\tshred -u wallet$i.descriptors"
+               confirm "wallet$i.descriptors shredded"
+
+               log_msg "unmount usb drive:\n\n\tumount $USB_DIRECTORY"
+               confirm "usb drive unmounted"
+
+               if [[ -z "$ENCRYPTION" ]]; then
+                       log_msg "close encrypted drive:\n\n\tcryptsetup luksClose $USB_PATH"
+                       confirm "usb drive closed"
+
+                       USB_PATH="$USB_PATH_PRE_DECRYPT"
+               fi
+
+               log_msg "eject device:\n\n\teject $USB_PATH"
+               confirm "usb drive ejected"
+       done
+}
+
 validate_parameters() {
        if [[ "$M" -gt "$N" ]]; then
                log_error "ERROR: threshold>wallets ($M>$N)"
@@ -429,10 +553,24 @@ wallets() {
        done
 }
 
+wallets_interactive() {
+       log_msg "Creating $N wallets..."
+       for((i = 1; i <= $N; i++)); do
+               log_msg "create wallet$i:\n\tbitcoin-cli -named createwallet wallet_name=wallet$i descriptors=true\n"
+               confirm "confirm wallet$i was created"
+       done
+}
+
 wallets_clean() {
        find "$DATA_DIRECTORY" -name "wallet.dat" -exec shred -u {} \;
 }
 
+wallets_clean_interactive() {
+       log_msg "clean up wallet files:\n\n\tfind ~/.bitcoin -name \"wallet.dat\" -exec shred -u {} \;"
+
+       confirm "wallet files deleted"
+}
+
 main() {
        depends
 
@@ -461,8 +599,23 @@ main() {
 
 main_interactive() {
        log_msg "interactive mode started..."
-       log_error "ERROR: interactive mode not implemented"
-       exit 1
+       log_msg "A series of commands to fully setup a cold storage solution with be output."
+       log_msg "All commands should be run in a separate shell."
+
+       bitcoin_core_start_interactive
+
+       network_off_interactive
+
+       wallets_interactive
+       multisig_create_interactive
+
+       usbs_interactive
+
+       wallets_clean_interactive
+
+       bitcoin_core_stop_interactive
+
+       log_msg "Successfully completed setup."
 }
 
 main "$@"
index 36c6bfd47428683cc95ac7b0da58912ddcfe344e..01a3473cbf4f3267e16ff57e467e59881911d246 100644 (file)
@@ -36,7 +36,7 @@ setup_test_descriptors() {
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -47,7 +47,7 @@ setup_test_descriptors() {
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -58,7 +58,7 @@ setup_test_descriptors() {
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -69,7 +69,7 @@ setup_test_descriptors() {
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -80,7 +80,7 @@ setup_test_descriptors() {
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -91,7 +91,7 @@ setup_test_descriptors() {
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -102,7 +102,7 @@ setup_test_descriptors() {
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -113,7 +113,7 @@ setup_test_descriptors() {
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
@@ -132,7 +132,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -143,7 +143,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -154,7 +154,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -165,7 +165,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -176,7 +176,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -187,7 +187,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -198,7 +198,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -209,7 +209,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
@@ -228,7 +228,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -239,7 +239,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -250,7 +250,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -261,7 +261,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -272,7 +272,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -283,7 +283,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -294,7 +294,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -305,7 +305,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
@@ -324,7 +324,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -335,7 +335,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -346,7 +346,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -357,7 +357,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -368,7 +368,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -379,7 +379,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -390,7 +390,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -401,7 +401,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
@@ -420,7 +420,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -431,7 +431,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -442,7 +442,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -453,7 +453,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -464,7 +464,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -475,7 +475,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -486,7 +486,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -497,7 +497,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
@@ -516,7 +516,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -527,7 +527,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -538,7 +538,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -549,7 +549,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -560,7 +560,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -571,7 +571,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -582,7 +582,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -593,7 +593,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
@@ -612,7 +612,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -623,7 +623,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -634,7 +634,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -645,7 +645,7 @@ EOF
       "internal": false,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -656,7 +656,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -667,7 +667,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -678,7 +678,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     },
@@ -689,7 +689,7 @@ EOF
       "internal": true,
       "range": [
         0,
-        999
+        2999
       ],
       "next": 0
     }
index 8eb67c846ce81dcbc728c3f7384d990eb17f5958..095150fbbc064691fca854af602587cb7bfbbf19 100755 (executable)
@@ -56,7 +56,7 @@ sign() {
 }
 
 spend() {
-       local CMD="$BITCOIN_CLI -rpcwallet=live walletcreatefundedpsbt '[]' '[{\"$1\":$2}]'"
+       local CMD="$BITCOIN_CLI -rpcwallet=live -named walletcreatefundedpsbt outputs='[{\"$1\":$2}]' options='{\"subtract_fee_from_outputs\":[]}'"
        local UNSIGNED="`eval "$CMD" | jq -r '.psbt'`"
        local WALLETS=($(shuf -n "$M" -e {1..7}))
        for i in "${WALLETS[@]}"; do
@@ -166,7 +166,6 @@ assert "$EXPECTED" "$(<result)"
 ADDRESS="`$BITCOIN_CLI -rpcwallet=dummy getnewaddress`"
 for((j = 1; j<=1000; j++)); do
        spend "$ADDRESS" 0.5
-       echo "$j transactions done..."
 done
 
 eval "$BITCOIN_CLI -rpcwallet=dummy -generate 100" > /dev/null
@@ -194,10 +193,14 @@ assert "$EXPECTED" "$(<result)"
 ADDRESS="`$BITCOIN_CLI -rpcwallet=dummy getnewaddress`"
 
 spend "$ADDRESS" 100
+eval "$BITCOIN_CLI -rpcwallet=dummy -generate 100" > /dev/null
 spend "$ADDRESS" 100
+eval "$BITCOIN_CLI -rpcwallet=dummy -generate 100" > /dev/null
 spend "$ADDRESS" 100
+eval "$BITCOIN_CLI -rpcwallet=dummy -generate 100" > /dev/null
 spend "$ADDRESS" 100
-spend "$ADDRESS" 99.99758
+eval "$BITCOIN_CLI -rpcwallet=dummy -generate 100" > /dev/null
+spend "$ADDRESS" "99.99"
 
 eval "$BITCOIN_CLI -rpcwallet=dummy -generate 100" > /dev/null
 
@@ -206,7 +209,7 @@ EXPECTED='{
   "walletname": "live",
   "walletversion": 169900,
   "format": "sqlite",
-  "balance": 0.00000000,
+  "balance": 0.00599563,
   "unconfirmed_balance": 0.00000000,
   "immature_balance": 0.00000000,
   "txcount": 2005,