diff options
| -rw-r--r-- | README.md | 131 | ||||
| -rw-r--r-- | src/main_gui.cpp | 19 |
2 files changed, 121 insertions, 29 deletions
| @@ -62,6 +62,17 @@ added a per-block signature-operation cap. A node on an older build will accept | |||
| 62 | blocks that current nodes reject, which puts it on a different chain without any | 62 | blocks that current nodes reject, which puts it on a different chain without any |
| 63 | warning. | 63 | warning. |
| 64 | 64 | ||
| 65 | Two more reasons, both measured rather than theorised: | ||
| 66 | |||
| 67 | - **Before 1.2.13** a node closed a disconnected peer's socket twice and left the | ||
| 68 | closed handle in its `select()` set, where it made `select()` fail on every | ||
| 69 | iteration. The node then spent its socket loop in an error path instead of | ||
| 70 | reading its peers. Two nodes side by side on the same machine, same network: | ||
| 71 | the one without the fix held 11 peers, the one with it held 21. | ||
| 72 | - **Before 1.2.11** a long-running Windows node accumulated sockets it never | ||
| 73 | released — 1262 of them in 26 hours on one machine, each holding an ephemeral | ||
| 74 | port. | ||
| 75 | |||
| 65 | Your wallet and chain data live in `%APPDATA%\Bitflash` (Windows) or | 76 | Your wallet and chain data live in `%APPDATA%\Bitflash` (Windows) or |
| 66 | `~/.bitflash` (Linux) and are shared by every version, so upgrading is just | 77 | `~/.bitflash` (Linux) and are shared by every version, so upgrading is just |
| 67 | replacing the binary. Never delete that directory to "fix" something without a | 78 | replacing the binary. Never delete that directory to "fix" something without a |
| @@ -69,10 +80,47 @@ backup — it holds your keys. | |||
| 69 | 80 | ||
| 70 | --- | 81 | --- |
| 71 | 82 | ||
| 72 | ## Backing up your wallet | 83 | ## Your wallet: the phrase and the file |
| 84 | |||
| 85 | Since 1.2.12 a wallet can hold twelve words that rebuild it. Since 1.2.13 those | ||
| 86 | words also cover the address the window shows you. **Both still matter** — the | ||
| 87 | phrase and the file back up different things, and the difference is where people | ||
| 88 | lose money. | ||
| 89 | |||
| 90 | ### The recovery phrase | ||
| 91 | |||
| 92 | ``` | ||
| 93 | bitflash -newphrase # create it, show it once, exit | ||
| 94 | bitflash -restorephrase="twelve words here" # rebuild a wallet from it | ||
| 95 | ``` | ||
| 96 | |||
| 97 | `-newphrase` installs a BIP32 seed, derives the wallet's key pool and default | ||
| 98 | receiving address from it, and prints the words once. It refuses if a phrase | ||
| 99 | already exists: replacing one silently would strand every coin on addresses the | ||
| 100 | written-down words no longer describe. | ||
| 101 | |||
| 102 | `-restorephrase` installs the seed and walks forward in batches of a hundred | ||
| 103 | addresses, rescanning the chain after each and stopping when a whole batch turns | ||
| 104 | up nothing. `-restoredepth=N` looks further. `-showderived=N` lists the addresses | ||
| 105 | a phrase produces, so you can check one before trusting it. | ||
| 106 | |||
| 107 | The same two operations are in the window, under **Wallet Safety**. | ||
| 108 | |||
| 109 | **The words are printed to the terminal and nowhere else** — never to | ||
| 110 | `debug.log`, which is the file people are routinely asked to attach to an issue. | ||
| 73 | 111 | ||
| 74 | Two things about this wallet will cost you money if you do not know them. Both | 112 | **What the phrase does not cover.** Keys that existed *before* the seed was |
| 75 | are consequences of the 0.1.0 wallet format, and neither is obvious. | 113 | installed are random. They are not derived from it and they do not come back |
| 114 | from the words. The wallet names such an address `Your Address (created before | ||
| 115 | the recovery phrase)` so you can tell them apart. This is why file backups still | ||
| 116 | matter. | ||
| 117 | |||
| 118 | > **If you created a phrase on 1.2.12, run `-restorephrase` with the same twelve | ||
| 119 | > words.** That release installed the seed but left the visible address and the | ||
| 120 | > key pool random, so the wallet went on handing out addresses the words cannot | ||
| 121 | > reproduce while the window said a phrase existed. Restoring repairs it. | ||
| 122 | |||
| 123 | ### The file | ||
| 76 | 124 | ||
| 77 | **Copying `wallet.dat` on its own is not a backup.** Berkeley DB ties the file | 125 | **Copying `wallet.dat` on its own is not a backup.** Berkeley DB ties the file |
| 78 | to the environment in the `database/` subdirectory beside it, so a lone | 126 | to the environment in the `database/` subdirectory beside it, so a lone |
| @@ -88,20 +136,26 @@ It loads the wallet, writes the copy, and exits without starting the node. If | |||
| 88 | you would rather copy by hand, shut the node down first and take the **whole** | 136 | you would rather copy by hand, shut the node down first and take the **whole** |
| 89 | data directory, not just `wallet.dat`. | 137 | data directory, not just `wallet.dat`. |
| 90 | 138 | ||
| 91 | **Every backup is still a snapshot, but it now has a safety margin.** The wallet | 139 | A file backup covers what a phrase cannot: keys from before the seed, and any |
| 92 | keeps a pool of 100 pre-generated keys. A backup contains those keys, so it | 140 | key the wallet acquired by import. It also has a margin of its own — the wallet |
| 93 | covers the next 100 mining rewards or receive addresses the node hands out after | 141 | keeps a pool of 100 pre-generated keys, so a backup covers the next 100 mining |
| 94 | the backup. That makes a normal backup much safer than the original 0.1.0 | 142 | rewards or receive addresses. Take a fresh one after mining for a while, after |
| 95 | wallet, where the very next block could land on a key the backup did not have. | 143 | creating many receive addresses, and before moving the wallet to another machine. |
| 144 | |||
| 145 | The GUI has a **Backup Wallet** button and a **Wallet Safety** view, which fills | ||
| 146 | the key pool before writing the backup. | ||
| 96 | 147 | ||
| 97 | It is not a seed phrase. Heavy use can drain the key pool, and deterministic | 148 | ### Finding coins the wallet never recorded |
| 98 | wallet restore is still tracked in [#47](https://github.com/Bitflash-sh/bitflash/issues/47). | 149 | |
| 99 | Back up again after mining for a while, after creating many receive addresses, | 150 | ``` |
| 100 | and before moving the wallet to another machine. | 151 | bitflash -rescan |
| 152 | ``` | ||
| 101 | 153 | ||
| 102 | The GUI has a **Backup Wallet** button and a **Wallet Safety** view. Use that if | 154 | Walks the chain for coins a key of yours owns but the wallet has no record of — |
| 103 | you do not want to run the command by hand; it fills the key pool before writing | 155 | after importing keys, or after restoring a file from another machine. |
| 104 | the backup. | 156 | `-importwallet` runs this automatically. A scan asked for with no chain data |
| 157 | loaded is refused rather than reported as "no transactions found", which reads | ||
| 158 | as a verdict to somebody who has just lost a wallet. | ||
| 105 | 159 | ||
| 106 | ### When wallet.dat itself will not open | 160 | ### When wallet.dat itself will not open |
| 107 | 161 | ||
| @@ -153,28 +207,48 @@ xmrig -a rx/0 -o POOL_BTF_ADDRESS -u YOUR_BTF_ADDRESS -p x | |||
| 153 | ## Headless / server mode | 207 | ## Headless / server mode |
| 154 | 208 | ||
| 155 | ```bash | 209 | ```bash |
| 156 | ./bitflash /nogui # node only | 210 | ./bitflash -nogui # node only |
| 157 | ./bitflash /nogui /gen # node + solo mining | 211 | ./bitflash -nogui -gen # node + solo mining |
| 158 | ./bitflash /nogui /gen /operator # pool operator | 212 | ./bitflash -nogui -gen -operator # pool operator |
| 159 | ./bitflash /nogui /gen /participant=POOL_BTF_ADDRESS # mine to pool | 213 | ./bitflash -nogui -gen -participant=POOL_BTF_ADDRESS # mine to pool |
| 160 | ``` | 214 | ``` |
| 161 | 215 | ||
| 162 | Mining is off unless you pass `/gen` — it is not remembered between restarts, so | 216 | Every option takes `-` or `/`. **Under MSYS2 use the `-` form** — the shell |
| 163 | put the flag in whatever starts the node rather than enabling it in the window. | 217 | rewrites a leading slash into a path before the node ever sees it. |
| 218 | |||
| 219 | **The mining mode is remembered between restarts** since 1.2.11, so a node that | ||
| 220 | was mining comes back mining. A `-gen`, `-operator` or `-participant` flag always | ||
| 221 | wins over what was stored, and the log says on every start which of the two | ||
| 222 | decided. Passing the flag anyway is the safe habit: it survives a wallet that | ||
| 223 | came from an older build. | ||
| 164 | 224 | ||
| 165 | Other options worth knowing: | 225 | Other options worth knowing: |
| 166 | 226 | ||
| 167 | ```bash | 227 | ```bash |
| 168 | /datadir=PATH # wallet and chain data elsewhere | 228 | -datadir=PATH # wallet and chain data elsewhere |
| 169 | /port=N # P2P listen port, default 8433 | 229 | -port=N # P2P listen port, default 8433 |
| 170 | /debug # verbose log; without it debug.log is nearly silent | 230 | -debug # verbose log; without it debug.log is nearly silent |
| 171 | /help # full list | 231 | -help # full list |
| 172 | ``` | 232 | ``` |
| 173 | 233 | ||
| 174 | `/port` plus `/datadir` is what lets two nodes share one machine. Both are | 234 | `-port` plus `-datadir` is what lets two nodes share one machine. Both are |
| 175 | needed — the data directory takes an exclusive lock, so a second node pointed at | 235 | needed — the data directory takes an exclusive lock, so a second node pointed at |
| 176 | the same one will refuse to start. | 236 | the same one will refuse to start. |
| 177 | 237 | ||
| 238 | ### When something looks wrong | ||
| 239 | |||
| 240 | **Menu > Diagnostics**, and the same report in `debug.log` every ten minutes: | ||
| 241 | peers held against peers `select()` is actually watching, blocks received and how | ||
| 242 | many arrived without a parent, the proof-of-work mode with the live miner thread | ||
| 243 | count, sockets by the part of the program that opened them, and per peer how long | ||
| 244 | since the last message each way. There is a copy button — if you open an issue, | ||
| 245 | paste that. | ||
| 246 | |||
| 247 | It exists because every hard problem in this project so far was found from | ||
| 248 | *outside* the node: sockets read over WMI from another machine, memory compared | ||
| 249 | against a number in a README, a `grep` over somebody's log. In each case the node | ||
| 250 | knew and had no way to say so. | ||
| 251 | |||
| 178 | As a systemd service: | 252 | As a systemd service: |
| 179 | 253 | ||
| 180 | ```ini | 254 | ```ini |
| @@ -183,7 +257,7 @@ Description=Bitflash node | |||
| 183 | After=network.target | 257 | After=network.target |
| 184 | 258 | ||
| 185 | [Service] | 259 | [Service] |
| 186 | ExecStart=/opt/bitflash/bitflash /nogui /gen /operator | 260 | ExecStart=/opt/bitflash/bitflash -nogui -gen -operator |
| 187 | Restart=always | 261 | Restart=always |
| 188 | User=bitcoin | 262 | User=bitcoin |
| 189 | WorkingDirectory=/opt/bitflash | 263 | WorkingDirectory=/opt/bitflash |
| @@ -225,7 +299,7 @@ Relays are the meeting points that let nodes behind NAT connect to each other. M | |||
| 225 | 299 | ||
| 226 | ```bash | 300 | ```bash |
| 227 | sudo bash relay/install-bitflash-relay.sh 8434 | 301 | sudo bash relay/install-bitflash-relay.sh 8434 |
| 228 | ./bitflash /nogui /announcerelay=YOUR_PUBLIC_IP:8434 | 302 | ./bitflash -nogui -announcerelay=YOUR_PUBLIC_IP:8434 |
| 229 | ``` | 303 | ``` |
| 230 | 304 | ||
| 231 | Relays forward encrypted bytes and cannot read or modify traffic. | 305 | Relays forward encrypted bytes and cannot read or modify traffic. |
| @@ -265,6 +339,7 @@ Installs deps via pacman, produces `Bitflash-*-windows.zip`. | |||
| 265 | | Addressing | `.btf` rendezvous — see the caveats above | | 339 | | Addressing | `.btf` rendezvous — see the caveats above | |
| 266 | | Premine | None | | 340 | | Premine | None | |
| 267 | | Pool server | Built-in — `.btf` rendezvous only | | 341 | | Pool server | Built-in — `.btf` rendezvous only | |
| 342 | | Wallet recovery | Twelve-word phrase (BIP39 + BIP32), plus file backup | | ||
| 268 | 343 | ||
| 269 | The halving interval is the number most people get wrong coming from Bitcoin. | 344 | The halving interval is the number most people get wrong coming from Bitcoin. |
| 270 | Same 210,000 blocks, but at two minutes instead of ten, so it arrives in about | 345 | Same 210,000 blocks, but at two minutes instead of ten, so it arrives in about |
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index c9e7dee..32fcdef 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -40,6 +40,12 @@ static string argval2(int argc, char* argv[], const char* keySlash, const char* | |||
| 40 | return argval(argc, argv, keyDash); | 40 | return argval(argc, argv, keyDash); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | // The real printf, not the one util.h remaps to OutputDebugStringF. Help that | ||
| 44 | // goes to debug.log is help nobody asked for: `-help` printed a full page into | ||
| 45 | // the data directory and returned 0 with an empty terminal, which reads as a | ||
| 46 | // command that does nothing. Same reason walletcmd.cpp undefines it. | ||
| 47 | #undef printf | ||
| 48 | |||
| 43 | static void PrintUsage() | 49 | static void PrintUsage() |
| 44 | { | 50 | { |
| 45 | printf("Bitflash command-line options\n"); | 51 | printf("Bitflash command-line options\n"); |
| @@ -50,7 +56,7 @@ static void PrintUsage() | |||
| 50 | printf(" /debug\n"); | 56 | printf(" /debug\n"); |
| 51 | printf(" /gen\n"); | 57 | printf(" /gen\n"); |
| 52 | printf(" /nogui or /daemon\n"); | 58 | printf(" /nogui or /daemon\n"); |
| 53 | printf(" /selftest=wallet-keypool\n"); | 59 | printf(" /selftest=wallet-keypool or /selftest=wallet-hd\n"); |
| 54 | printf("\n"); | 60 | printf("\n"); |
| 55 | printf("Mining mode:\n"); | 61 | printf("Mining mode:\n"); |
| 56 | printf(" /operator\n"); | 62 | printf(" /operator\n"); |
| @@ -84,12 +90,18 @@ static void PrintUsage() | |||
| 84 | printf(" wallet that has none, show it once, exit)\n"); | 90 | printf(" wallet that has none, show it once, exit)\n"); |
| 85 | printf(" /restorephrase=\"WORDS\" (rebuild this wallet from a phrase and scan\n"); | 91 | printf(" /restorephrase=\"WORDS\" (rebuild this wallet from a phrase and scan\n"); |
| 86 | printf(" the chain for its coins, then exit)\n"); | 92 | printf(" the chain for its coins, then exit)\n"); |
| 93 | printf(" /restoredepth=N (with /restorephrase: derive at least N\n"); | ||
| 94 | printf(" addresses before giving up)\n"); | ||
| 95 | printf(" /showderived=N (list the first N addresses a phrase\n"); | ||
| 96 | printf(" produces, without installing it)\n"); | ||
| 87 | printf(" /rescan (walk the chain for coins this wallet owns\n"); | 97 | printf(" /rescan (walk the chain for coins this wallet owns\n"); |
| 88 | printf(" but never recorded, then exit)\n"); | 98 | printf(" but never recorded, then exit)\n"); |
| 89 | printf("\n"); | 99 | printf("\n"); |
| 90 | printf("Each option also accepts '-' instead of '/'.\n"); | 100 | printf("Each option also accepts '-' instead of '/'.\n"); |
| 91 | } | 101 | } |
| 92 | 102 | ||
| 103 | #define printf OutputDebugStringF | ||
| 104 | |||
| 93 | static void ParseStartupArguments(int argc, char* argv[]) | 105 | static void ParseStartupArguments(int argc, char* argv[]) |
| 94 | { | 106 | { |
| 95 | if (arg(argc,argv,"/datadir") || arg(argc,argv,"-datadir")) | 107 | if (arg(argc,argv,"/datadir") || arg(argc,argv,"-datadir")) |
| @@ -221,6 +233,11 @@ int main(int argc, char* argv[]) | |||
| 221 | if (arg(argc,argv,"/help") || arg(argc,argv,"-help") || | 233 | if (arg(argc,argv,"/help") || arg(argc,argv,"-help") || |
| 222 | arg(argc,argv,"--help") || arg(argc,argv,"/?")) | 234 | arg(argc,argv,"--help") || arg(argc,argv,"/?")) |
| 223 | { | 235 | { |
| 236 | // Without this the help prints into nothing. A -mwindows binary starts | ||
| 237 | // with no console, so every one of those printfs went nowhere and the | ||
| 238 | // one command whose entire job is to tell you something told you | ||
| 239 | // nothing at all -- exit code 0, not a byte of output. | ||
| 240 | AttachTerminal(); | ||
| 224 | PrintUsage(); | 241 | PrintUsage(); |
| 225 | return 0; | 242 | return 0; |
| 226 | } | 243 | } |