diff options
100 files changed, 719 insertions, 3479 deletions
diff --git a/contrib/devtools/lint-python.sh b/contrib/devtools/lint-python.sh index 9303fcc8ef..e2c9d775a6 100755 --- a/contrib/devtools/lint-python.sh +++ b/contrib/devtools/lint-python.sh @@ -6,5 +6,58 @@ # # Check for specified flake8 warnings in python files. -# F401: module imported but unused -flake8 --ignore=B,C,E,F,I,N,W --select=F401 . +# E112 expected an indented block +# E113 unexpected indentation +# E115 expected an indented block (comment) +# E116 unexpected indentation (comment) +# E125 continuation line with same indent as next logical line +# E131 continuation line unaligned for hanging indent +# E133 closing bracket is missing indentation +# E223 tab before operator +# E224 tab after operator +# E271 multiple spaces after keyword +# E272 multiple spaces before keyword +# E273 tab after keyword +# E274 tab before keyword +# E275 missing whitespace after keyword +# E304 blank lines found after function decorator +# E306 expected 1 blank line before a nested definition +# E502 the backslash is redundant between brackets +# E702 multiple statements on one line (semicolon) +# E703 statement ends with a semicolon +# E714 test for object identity should be "is not" +# E721 do not compare types, use "isinstance()" +# E741 do not use variables named "l", "O", or "I" +# E742 do not define classes named "l", "O", or "I" +# E743 do not define functions named "l", "O", or "I" +# F401 module imported but unused +# F402 import module from line N shadowed by loop variable +# F404 future import(s) name after other statements +# F406 "from module import *" only allowed at module level +# F407 an undefined __future__ feature name was imported +# F601 dictionary key name repeated with different values +# F602 dictionary key variable name repeated with different values +# F621 too many expressions in an assignment with star-unpacking +# F622 two or more starred expressions in an assignment (a, *b, *c = d) +# F631 assertion test is a tuple, which are always True +# F701 a break statement outside of a while or for loop +# F702 a continue statement outside of a while or for loop +# F703 a continue statement in a finally block in a loop +# F704 a yield or yield from statement outside of a function +# F705 a return statement with arguments inside a generator +# F706 a return statement outside of a function/method +# F707 an except: block as not the last exception handler +# F811 redefinition of unused name from line N +# F812 list comprehension redefines 'foo' from line N +# F822 undefined name name in __all__ +# F823 local variable name … referenced before assignment +# F831 duplicate argument name in function definition +# W292 no newline at end of file +# W504 line break after binary operator +# W601 .has_key() is deprecated, use "in" +# W602 deprecated form of raising exception +# W603 "<>" is deprecated, use "!=" +# W604 backticks are deprecated, use "repr()" +# W605 invalid escape sequence "x" + +flake8 --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E271,E272,E273,E274,E275,E304,E306,E502,E702,E703,E714,E721,E741,E742,E743,F401,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F822,F823,F831,W292,W504,W601,W602,W603,W604,W605 . diff --git a/contrib/gitian-build.sh b/contrib/gitian-build.sh index 631fba9089..d334c1642f 100755 --- a/contrib/gitian-build.sh +++ b/contrib/gitian-build.sh @@ -47,7 +47,7 @@ Options: -j Number of processes to use. Default 2 -m Memory to allocate in MiB. Default 2000 --kvm Use KVM instead of LXC ---setup Set up the Gitian building environment. Uses KVM. If you want to use lxc, use the --lxc option. Only works on Debian-based systems (Ubuntu, Debian) +--setup Set up the Gitian building environment. Uses LXC. If you want to use KVM, use the --kvm option. Only works on Debian-based systems (Ubuntu, Debian) --detach-sign Create the assert file for detached signing. Will not commit anything. --no-commit Do not commit anything to git -h|--help Print this help message diff --git a/contrib/gitian-keys/README.md b/contrib/gitian-keys/README.md index 4b0b7a2615..a9339c8bda 100644 --- a/contrib/gitian-keys/README.md +++ b/contrib/gitian-keys/README.md @@ -1,16 +1,26 @@ -PGP keys -======== +## PGP keys of Gitian builders and Developers -This folder contains the public keys of developers and active contributors. +The keys.txt contains the public keys of Gitian builders and active developers. The keys are mainly used to sign git commits or the build results of Gitian builds. -You can import the keys into gpg as follows. Also, make sure to fetch the -latest version from the key server to see if any key was revoked in the -meantime. +The most recent version of each pgp key can be found on most pgp key servers. + +Fetch the latest version from the key server to see if any key was revoked in +the meantime. +To fetch the latest version of all pgp keys in your gpg homedir, ```sh -gpg --import ./*.pgp gpg --refresh-keys ``` + +To fetch keys of Gitian builders and active developers, feed the list of +fingerprints of the primary keys into gpg: + +```sh +while read fingerprint keyholder_name; do gpg --keyserver hkp://subset.pool.sks-keyservers.net --recv-keys ${fingerprint}; done < ./keys.txt +``` + +Add your key to the list if you provided Gitian signatures for two major or +minor releases of Bitcoin Core. diff --git a/contrib/gitian-keys/achow101-key.pgp b/contrib/gitian-keys/achow101-key.pgp deleted file mode 100644 index 030fd5cf3c..0000000000 --- a/contrib/gitian-keys/achow101-key.pgp +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -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 -Khvd4+XHE/ecjLOPvLweAg== -=+hz7 ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/aschildbach-key.pgp b/contrib/gitian-keys/aschildbach-key.pgp Binary files differdeleted file mode 100644 index df06e19fa4..0000000000 --- a/contrib/gitian-keys/aschildbach-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/bluematt-key.pgp b/contrib/gitian-keys/bluematt-key.pgp Binary files differdeleted file mode 100644 index 2389d4657f..0000000000 --- a/contrib/gitian-keys/bluematt-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/btcdrak-key.pgp b/contrib/gitian-keys/btcdrak-key.pgp Binary files differdeleted file mode 100644 index f00dc729d5..0000000000 --- a/contrib/gitian-keys/btcdrak-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/cdecker-key.pgp b/contrib/gitian-keys/cdecker-key.pgp Binary files differdeleted file mode 100644 index 928a74b315..0000000000 --- a/contrib/gitian-keys/cdecker-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/centaur1-key.pgp b/contrib/gitian-keys/centaur1-key.pgp deleted file mode 100644 index 71a42e5148..0000000000 --- a/contrib/gitian-keys/centaur1-key.pgp +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -mQENBFTjy20BCAC7q/tpPQ9tdEALpDqe8kpVAT5ysOJDLDeFEE1J5O8NuDFuibiN -XYkb2nAt4Vdr23in9z0LAiTSgr7znndnab/rOSn6pXbXQfLTHrSnAeClTHVQVPSq -m5kNg1vWvNxFtIpZ/fGsc6LLmIHxdgeLn+NOpvNx7RzF/N5ctX51vMxMUeDq3daZ -tLneJVRj5tXHRJcjW62cyiNFasYAZ3JC8wjwzr0SOndc7kygbEVCTWNkTAGd1Lax -KSJW6TjhBPK7j+RljS5nfx/Tf+OG4AoA7/53593YL7Shfx8rwWVIeF4nS6efFnuf -eIj+aS5haGyFvNgw8DE7QUCrPiUxeA8wuXu7ABEBAAG0H2NlbnRhdXIgPGNlbnRh -dXJAcGhvbmVib29rLmNvbT6JATgEEwECACIFAlTjy20CGwMGCwkIBwMCBhUIAgkK -CwQWAgMBAh4BAheAAAoJEP+V+qlxaXQF8r4IAKnE8D9AOTdM/YvYxpCeI6ndEUUs -8NcotpbIBJ67vr1Dsot7Ee0PrmIYOiInA+T81lPUDecJYrnemVefhquiyJ5VJ4/d -z2zUKBfxjeOsj/PHgcowVxMco8fNEWQa2fZX6X8RVADIsUnIIwpRFVUcbssK/3xJ -k46vjWwYNQywht/ZgFBesOgywyz5GozmwrK6TixJxKk8M69GFz2fHhJjp1bxDZuk -Rs3YmWeOcCasoJ6GbvIboKQSPHGyEOCqIuiBL63YMa0n1FU0ooDteNZ04eRinIhc -fo9JC66fQrUFn8CmmRTtdZOrZ/efYjQtfLAunCkzSM3p6DE9u4Y7d8E5Ar65AQ0E -VOPLbQEIANhxtouZuQmw+k89toBWXw75s+csxKHKZuhw8QntaFyFYq3IOnIeV1sK -PRENkWsqDInjEM8k9eZ6pnS11EQ1rrFffss+mprTbL3I4S489tJETYZKHrmmox7h -ustRi5eXBEmGeKW0mqpb/9r4okpTaIfs+EJ4C9jj0ghWkqU0acyzanJiUY/0R46F -vPfGfHnhZ5TAl3eiL0H2JkF6taG8K1XOLemahdZHE9wJh0ZFWnDDkA1l6j2rtYga -jEi/ucOp5GkmumxbFiVgponDBqBpsscRrCV6SbZs9gz3dQNgqe5A3CKGZRuVCY6s -djRJelgqCF5+dV0fAT0oF3C/3E5KAgcAEQEAAYkBHwQYAQIACQUCVOPLbQIbDAAK -CRD/lfqpcWl0BUSxCACjEFwQSHcfZINWD+KdNMayxyHQlBwsEDX+xQkgnn+/Q3hW -9VI3SSSfFV3ustlUa3IaNHwuWzsrSqG6mLG47LAQ6vPAWVh723gVCpyJf42Oms/e -qeyn0f/PT/6RuNMXQeHbfddmRp4PFjyKOms5Bmf3oi4t4JSvOS4yABBBKzhDQYC9 -e+qv6Y1sDYpSiCxstQLzIHKiB5bfZ8Szfk09EyyLdqLGkiB0MFhHoXWwQxKiLVc+ -xNFj2a/jw0rQVgN5DZgHBWU5WqvS5CWIczi+2S9MFI26iBhCn3urZToaaQ/DObqC -qmekFrJ/GOj5vB1Mm014lWjG2X3EovLZ1XkgWI7W -=vtNZ ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/cfields-key.pgp b/contrib/gitian-keys/cfields-key.pgp deleted file mode 100644 index 6b0bd240ba..0000000000 --- a/contrib/gitian-keys/cfields-key.pgp +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -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 -MrD0ofsytfy1LQ== -=DE4h ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/devrandom-key.pgp b/contrib/gitian-keys/devrandom-key.pgp Binary files differdeleted file mode 100644 index 71898127ba..0000000000 --- a/contrib/gitian-keys/devrandom-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/erkmos.pgp b/contrib/gitian-keys/erkmos.pgp Binary files differdeleted file mode 100644 index 9d3f060627..0000000000 --- a/contrib/gitian-keys/erkmos.pgp +++ /dev/null diff --git a/contrib/gitian-keys/fanquake-key.pgp b/contrib/gitian-keys/fanquake-key.pgp deleted file mode 100644 index 9c03ff4522..0000000000 --- a/contrib/gitian-keys/fanquake-key.pgp +++ /dev/null @@ -1,63 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG/MacGPG2 v2.0.26 - -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 -XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg== -=3o2I ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/gavinandresen-key.pgp b/contrib/gitian-keys/gavinandresen-key.pgp Binary files differdeleted file mode 100644 index f81f44e874..0000000000 --- a/contrib/gitian-keys/gavinandresen-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/jl2012-key.pgp b/contrib/gitian-keys/jl2012-key.pgp deleted file mode 100644 index b8aad7fd88..0000000000 --- a/contrib/gitian-keys/jl2012-key.pgp +++ /dev/null @@ -1,105 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Comment: GPGTools - https://gpgtools.org - -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 -yj9YmZZSRRQ2dujg81sLQ9CrO7WB3IGpwh+4lHQ= -=1irw ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/jonasschnelli-key.pgp b/contrib/gitian-keys/jonasschnelli-key.pgp deleted file mode 100644 index 3831eaea11..0000000000 --- a/contrib/gitian-keys/jonasschnelli-key.pgp +++ /dev/null @@ -1,110 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1
-
-mQINBFSBrDIBEACrZEqObmtlTf7fOKttE39qqisFfMg0VeEPS37uETMGYsgTEvzv
-kfMsXCGsGFLQ78XsHqUeW4uQrtpJH3nUP/Sua1Q12K3lNKTSvVQyEpKoPJwXZahp
-jm6GA1ApDxZ/KlmxyobR3X0urnMYNZobl5IKJXlxoKGl4OkGNeFlh42pCXZDnR9n
-1Y17ZcDdybkWcqPbDAz8ilOQcFMhDBFg3Di3IVMAaDZP1uwWFb5vx60YB5NhkOpF
-nZUH09NJx/7u7QdGPSHOdzW4Xo1HUYtYNDkdOvgZtxpbYEFIaBtVBURMUGwAFagA
-3a6qaGnCBWEQftyISLiqcKqKqXudOg/cLa1CAiQFkz+IBhY9BCGDRnB8Dcae6EGI
-Djt2lqZTuMSiheTWeNFMGBioHfPLedcwae8KflrIBC+hNS4ay6HJdIc03WMQ4JKK
-At8Y8CRLym30/RlqZ2v8CHYqg9Ddlz3+g5JkRKaJTQwFRcX46/tAX+I2NZ8Ra1ea
-rF5cRHuCk/oaw5ZXYhj4zJO74rjAoSewAARlrTMSM541atJU1u6aWT7rNiF9QKIj
-i8vEufUxN0YfdmvDD3OXwbO7GnfWXS4sPklFIRACp+Y4ib+QnRY0/qGE0yh3RAG4
-r/dyIQ1m3z7Pc9eyPKAhE4S7SxAwoR4yOqQ5NAfZXgFuqWzkW51gkQgGzQARAQAB
-tCtKb25hcyBTY2huZWxsaSA8am9uYXMuc2NobmVsbGlAaW5jbHVkZTcuY2g+iQI+
-BBMBAgAoBQJUgawyAhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
-CRAicOMMUic59iKUD/93DF04C3lptLjtrhyd4wgpBMJV8yzagGyG+Wk0UR7elQw4
-F1MIvEtIFpuGrcnNfKcqeGGmnnKFTeBjkmgcYvej2fW9XlRA1HgIS0t0ttDv8uVX
-vy1xVj1qISB+17EiftxJjCOl2pZFEVpLQ7sSgqnVRMsCS45ag6rioGxtq1j3ifQN
-TENnJWhzOXvwzZhLgsyWLjeYvTDbzfAQLpZFowAMibOwu6ObCkn4dhaW+lI3AnPu
-76pLsrOljqGvXes6o2d28vjqMrlmsz2xVEJ4bnRPUbLv3bUl6t+19XpiMj94ZCZX
-/kvepzSNAs+aYvoldFn0/8haU5wIDXO/zgXSlm4KnhaDf1zutVq/Ng6TGb66mZKc
-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
-S5rowLE=
-=ZVPf
------END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file diff --git a/contrib/gitian-keys/jtimon-key.pgp b/contrib/gitian-keys/jtimon-key.pgp Binary files differdeleted file mode 100644 index 88d0de1503..0000000000 --- a/contrib/gitian-keys/jtimon-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/keys.txt b/contrib/gitian-keys/keys.txt new file mode 100644 index 0000000000..47da725b74 --- /dev/null +++ b/contrib/gitian-keys/keys.txt @@ -0,0 +1,29 @@ +617C90010B3BD370B0AC7D424BB42E31C79111B8 Akira Takizawa +152812300785C96444D3334D17565732E08E5E41 Andrew Chow +E944AE667CF960B1004BC32FCA662BE18B877A60 Andreas Schildbach +07DF3E57A548CCFB7530709189BBB8663E2E65CE Matt Corallo (BlueMatt) +912FD3228387123DC97E0E57D5566241A0295FA9 BtcDrak +C519EBCF3B926298946783EFF6430754120EC2F4 Christian Decker (cdecker) +F20F56EF6A067F70E8A5C99FFF95FAA971697405 centaur +C060A6635913D98A3587D7DB1C2491FFEB0EF770 Cory Fields +BF6273FAEF7CC0BA1F562E50989F6B3048A116B5 Dev Random +9A1689B60D1B3CCE9262307A2F40A9BF167FBA47 Erik Mossberg (erkmos) +D35176BE9264832E4ACA8986BF0792FBE95DC863 fivepiece +E777299FC265DD04793070EB944D35F9AC3DB76A Michael Ford +01CDF4627A3B88AAE4A571C87588242FBE38D3A8 Gavin Andresen +D3CC177286005BB8FF673294C5242A1AB3936517 jl2012 +32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC Jonas Schnelli +4B4E840451149DD7FB0D633477DFAB5C3108B9A8 Jorge Timon +71A3B16735405025D447E8F274810B012346C9A6 Wladimir J. van der Laan +E463A93F5F3117EEDE6C7316BD02942421F4889F Luke Dashjr +B8B3F1C0E58C15DB6A81D30C3648A882F4316B9B Marco Falke +CA03882CB1FC067B5D3ACFE4D300116E1C875A3D MeshCollider +9692B91BBF0E8D34DFD33B1882C5C009628ECF0C Michagogo +37EC7D7B0A217CDB4B4E007E7FAB114267E4FA04 Peter Todd +D62A803E27E7F43486035ADBBCD04D8E9CCCAC2A Paul Rabahy +D762373D24904A3E42F33B08B9A408E71DAAC974 Pieter Wuille (Location: Leuven, Belgium) +133EAC179436F14A5CF1B794860FEB804E669320 Pieter Wuille +ED9BDF7AD6A55E232E84524257FF9BDBCC301009 Sjors Provoost +77E72E69DA7EE0A148C06B21B34821D4944DE5F7 Nils Schneider +79D00BAC68B56D422F945A8F8E3A8F3247DBCBBF Willy Ko +AEC1884398647C47413C1C3FB1179EB7347DC10D Warren Togami diff --git a/contrib/gitian-keys/laanwj-key.pgp b/contrib/gitian-keys/laanwj-key.pgp Binary files differdeleted file mode 100644 index eed232a872..0000000000 --- a/contrib/gitian-keys/laanwj-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/luke-jr-key.pgp b/contrib/gitian-keys/luke-jr-key.pgp Binary files differdeleted file mode 100644 index a2d34e75e1..0000000000 --- a/contrib/gitian-keys/luke-jr-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/marcofalke-key.pgp b/contrib/gitian-keys/marcofalke-key.pgp deleted file mode 100644 index ee626500a4..0000000000 --- a/contrib/gitian-keys/marcofalke-key.pgp +++ /dev/null @@ -1,69 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -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 -=GC3s ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/meshcollider-key.pgp b/contrib/gitian-keys/meshcollider-key.pgp deleted file mode 100644 index 20963e7e25..0000000000 --- a/contrib/gitian-keys/meshcollider-key.pgp +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -gb52/WPhR6CJQ2/7y3Uj7u8sPNpb7BGI -=as33 ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/michagogo-key.pgp b/contrib/gitian-keys/michagogo-key.pgp deleted file mode 100644 index 47bc404554..0000000000 --- a/contrib/gitian-keys/michagogo-key.pgp +++ /dev/null @@ -1,59 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -mQENBFGeqJ4BCADb7SI3/+q93gIvN0AGRg9Mtz73OLIOzCHeeoyn+tp7JcYNzxkQ -9lfeXiEfn72Sh8gHkLtLIqr7HlIMo8DxSS8JPRVjlJGkNyAW4SeEwN2wNa5OV8k0 -N4jBa9a1csFyCyrEkPKvkUpBkQDvNXjNxyEhHwyZqPanKxy6NXIHOJji8ObOMQXI -T9HwJrpjRth3u4uKG968JBTEyAXAmkt0Zidl1Ykgzcedk4mJSE9uZCW8DjSv2wML -XcQz8+dYsoskT3KRdkowLHxAfj1BNyNc1+rKLghliM5vSQWi+Lbhi1Bxh4sY1UwA -lKnAGqrnAGyIvCtkwTq5QI6ufF2ZY44bvVgpABEBAAG0IU1pY2hhZ29nbyA8bWlj -aGFnb2dvQHNlcnZlci5mYWtlPokBOAQTAQIAIgUCUZ6ongIbAwYLCQgHAwIGFQgC -CQoLBBYCAwECHgECF4AACgkQgsXACWKOzwzMUAgAuqUmK10xE5C3lUym2f72z0t6 -a2NM5Wfjr9//Y1/okC36C5XAMEtN2UwckPzzJ5p5D5y5yzwfZq5Jd8Py29VQIMsV -7FbC1a0H3D+bCyX+JJ6FAmUbnWOQ/+mydYc74RvD8iwjePNT6kziZNv6dMGctJTl -0alwjtQYgyGkeYKnIxbcyjHX/IawLUrunb/6mSKun87T8+NM/omfFCTc3l8TakpM -0wyNYRiUkIfUBvB8sDUU3A80qKN/hqRKvlFu3+/kMiAc9ZYQrbmsB+sYWdmM+4zw -8NBw3yuYzWyPuoa4PR5ZmS9F11WLMR5vTRCdLudAqYsWu3LtV6vAIvlOUa2LMLRg -TWljaGFnb2dvIChSZWdpc3RlcmVkIG5pY2sgbWljaGFnb2dvIG9uIGZyZWVub2Rl -IGFzIG9mIE9jdG9iZXIgMTIsIDIwMTMpIDxtaWNoYWdvZ29Ac2VydmVyLmZha2U+ -iQE4BBMBAgAiBQJSWarzAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCC -xcAJYo7PDA7nB/91wAiaMlU5nHLUu0anhNQbGvUdFgKK1zO90S5KzUdJcY438jcS -UJW1az8l9U9JBRIfPRYVhz/Z1TAJ+dCzD7D8BXHFeGEr0zNOh87ly9aB5du7dpN2 -oSBD6wLcJpqxt4h+XjSS2CX98/2ZIJxXENE2KySaTXP39Xl3eNwvJTUBA4XlcMey -J8KMp/IERli4H0O7vRyLgu3yYpUArTqAonzG1g2lfB35PQJfeInrRSniQ336otnZ -A8qwJ63kfUtWVDRz0g1fnvtiLGPivDJaI5hyIaUeJPaXU1+sg7YNroDu60o2NGZh -F+0IjHlvRfzzA+F9Vw38rpSqR3BmCdjf6Sv3iQEcBBABAgAGBQJSWa9/AAoJEH+r -EUJn5PoE/hgH/1T2dAthVucA/hzY0nl4SMjbg+dzNlYBq00Qwx8DRKVjk5et8+kY -oPI3DGILcr+ELnxNekeMv9WQBBtJanUh1K5ohZ6ohoR7lG18LXf5HCdspflB5Me6 -LMA6iMryEP6gIs9GFuoGe2YQavm58YrkqhcPu34dGN7kdurfEXLvDfVlh5ZbKCsP -Gyd7Pbz04SpqykgK1udiTsLVjc70Xhv+jAMqeaCugDX6TLEwjVmZH/xsyKk2Uh3V -Oib5FXADAtKH+vSqqhFpXrw7R/NaBzvCbas8l61DFHiUg1/bo8vsV8MtGcyZmzXJ -C5Gm0njtGOil/g7JF9siUrpxs9Yyt/h+T2W0W01pY2hhZ29nbyAoVXNlciBhY2Nv -dW50IG1pY2hhZ29nbyBvbiBHaXRodWIgYXMgb2YgT2N0b2JlciAxMiwgMjAxMykg -PG1pY2hhZ29nb0BzZXJ2ZXIuZmFrZT6JATcEEwECACIFAlJZqxkCGwMGCwkIBwMC -BhUIAgkKCwQWAgMBAh4BAheAAAoJEILFwAlijs8M+1AH+IU78ARblqTnJeSl0iWH -mEsg4IBK30Q6/exDAcqOEm1Yc171uw2WnGmIvPYOQqxrRTvj3LoQ816dU6jrj6vY -s+XX0R2hxy7ILh17D/3UKnHcddu7rmc7pNEqZeBXaMughqQaPOWkAIe52+qK5tsl -sWllzTYE4jo29uZ3dAtDcKEJjBo/pIXnu1GOslE1+V4X1H9WDlwrS/JXHzyDQAjt -maPR+3gNesDanhrRmrnT3ZXW2ZVd3vGBibhia8PWUhU1uwOH23ySWXncgsHH0Zad -UMjd4w3YliZP/mLn2ghAxHB70IO7lgAgN3HYZeFoufP3pcK440A+CezfQiRcjHl/ -oIkBHAQQAQIABgUCUlmvfwAKCRB/qxFCZ+T6BOq9CACItsrUZPKGeWSTkMHknMrV -K5vxIXJVCBb+Tppc0Q/J5p4EkW/RFhTwIP2zw8NLDKMh5oO9md4LXhvfIZkqQJFo -6ZtLa3Vf+Kj7uyxezBo4QHA+G7tDsRGaMKVrEMiyLCwS1+hg9VaNzsf7zmQW7mYE -vTLMHp3cVaSU7Mh2Dl8rnAaM/DpTUZQwZ+32Qrb/Z4HSa4f278iqoFpjEbBE2KCr -vT5yEVvpCZ4lwSgA2a+uTlRTvVV6NA/kpsxU64tmhuEOjy+ToDqJ8wv4mqvWZxMv -C6OhfVaXBy3U9gG8aQV0ffXGs+TbCtv8ApHd6E1/AVk0oyZGJaBVrEl688bBIWd/ -uQENBFGeqJ4BCADFmgR7oEGkFFB5qXnuNYFq1nUGDAh0dLNtAD3J6EMxUZEXdmp+ -DQHJw6/eDRQaG9EbjNZheycbVUoI8K2Y/Z268HQueGuIEIJv6cZYXoXdWCbDD4fn -HMNUX2wNlpDqWxb7PNUEtfU9hI3gmHGlr5OiEh3iV06uiZg4n2rbWPbj45m5LJzv -wpCrUA+pLcl9Xjw2cajaSTjdXHk9gvXTCo6s2ZS3/3Q4l+xuzZp1MGNzPQHASMKs -wecSJKkYg6W8I5WsVlPd9a8oQCc/Nfz7BPw31MRVR/SF5FAMqaXx5uLwghVdHB2i -cLURsOtJlCfP8W06gB7yS+MH45Jq/oxBRiJBABEBAAGJAR8EGAECAAkFAlGeqJ4C -GwwACgkQgsXACWKOzwwT4wgAy6ICcnBZ9l2jSu+ldy57F6jf5kpKZgB9NV8V2mMA -NeY1wMQ4VTVpU4t3s4E2LYtGNJNkPQVHbt1Pf4dGPasvMPaHMamgwgyqgYixqs0x -D5PdKzVrfnjwTTr/ZAFdccSPmvy5/hbY0geQ/+mzdbL07+xaT58JIoG5nySDKhmC -VeOvhDZtXMVAhEWBDPEgh/H9sEuBgMgZrzfE1j3q802qiXeQs6WtadWlQ1RN9Iq1 -ZzIi6u9/BifEIRI0pO/WwKOZdXLTemFUoakoe7uT3A74N96t0G9LZVihYbEoO+Pc -5IaHPBV5VLeR3TB1LnnjHVf/Fwi8cnGy50kNWjcbMyEDag== -=jyQ4 ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/petertodd-key.pgp b/contrib/gitian-keys/petertodd-key.pgp deleted file mode 100644 index 5ee82a6f7e..0000000000 --- a/contrib/gitian-keys/petertodd-key.pgp +++ /dev/null @@ -1,1901 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -BSGsRbgvDNIR6RczbQ3j53l5j7ReYKP1yLnPwiNC3noPewqGephy6gH3BjYCtYZt -Vq4+OeNgCLi5fhy1xNCeqto6qQlbms7hw5YKB/x12QnsdgxGV9guuKYiJEOG37A0 -qdmYOBkHt3TfZWlLCDVRaHvb30eGSKS01aHmK4pJLAFYVgLw/ggBjegj6AxdnpT5 -NQM9uWCfwZ2qa3vBPaw7FYhjcB/nSvpZ9I4dC1F3lffLucgpg73p6OO5aU6w952M -hGDMKBGovbG2hvIaqs1RwaKZNtZZcBCXfIsQnGU11LYs/3w8cSyxWE/35HlveXW6 -+YBXHIaY8nrJCQHwLlmRj7w1RXVODBy75iUd6mYURPZyadpVfTKIpFkddIFPLKPl -6QkByMAno4dWS/p/2/xek9zBnhUhBjiQ+F9+rbF0K5LswiMK/BwzB8UXOXeueZXH -H1vDCDOBzrDit8bgxJy8j2YGT2Vq7ThMnhSLLC3hRcWJAz+0rSJ51OxWLS3CQGgQ -lmMOc2Wmz+K7JKvat3eZesBTQEZre6MpxXiebna53RnK/jFlEiqeZqPDWfry81ew -qzDnWaQ/m43L0V8QVVeJBLEEEgECAJsFAlGVbM6UGmh0dHA6Ly93d3cuamVuc2Vy -YXQuZGUvZmlsZXMvb3BlbnBncC9BNEZGMjI3OS1jZXJ0LXBvbGljeS0yMDEzLTA1 -LTE3LnR4dD9zaGE1MTJzdW09OGM4NTgyZjI1Mjk5MjRkZDY5Mjk3Yjc0YzM0MGEw -YTI5YTFjMWQ3NWIxODFiZmY2MDJmZGRkNzllN2YwNDk2NAAKCRBOH3mapP8ieSuD -H/90vmcaUOrfHXiDON3WzGU9lkk2K5GEauttX6p2gRRhzTqy47zUl5Wu8KWetkft -XOf/4yhPwDyFzCElArReLBg0gM4vgCAH+jeZqSWcMvgv9M11cA8rSF7aRLdpPfR6 -m4RwS8niwpvInNG4DNCQxqZqSBB6XDyrtmjJP6PNhJD6Nd24nMzImyJ7QB1JrSjK -lk539GS7fgEhhrBh5nKhVlvzzusvAc7MKysUCMduQrRYbkWQxw41OdIlIZMc6ErC -SGEEKgrVB4xFZR2DNTd93PDggjHTtvXKnydCZC1XL94qvvHMmSagXfk76QwtHBG8 -099QR60buDGLnZvyDbR7H5ts7UPbIwIRWA0v/p7hhT9PRRLLVuK1oLUa1gEN/IAf -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 -peBNXREPb4kkfF+RpT7HWD0u+i6sWb5+Yzt+vuRip7JkVu+7FDefLJ6ke0nEu6xJ -+HbAmZznOjnAg3o8M+XD9NIJT8Z5yB+ikQ3AZuZ1bJfNC85++oKGq14xJSvcA/4f -hLdGNmj05ijBMYLsdzDL+Wkdl/69sultxs4nD6mhlw2epZtiw5qj4dgbzz7p6O78 -3pZgXBvy5UFxgxx8hZsjDAayodfyebFNSLXC06uVjafFbtbQZc83UfJAxwaW0jF6 -cl0n7nquGPk1TNMVCHOd9VNCdhPlFJHctUbIv0+HNrzgWCrmN1JzP4BJZsIK/Oqs -j1SoFdGwxRWpSNwgO3WJASIEEAECAAwFAlKOadAFAwASdQAACgkQlxC4m8pXrXz8 -wQgAj0li8ga7DxoPNue6DzfKUbXw/LqjZUgs+d/MlHiEXS9hEMBDKLAnpDVIwSQl -Ldu7UvanjpWK5UVj4jTMnNKjJXHRlFc1WBRrehOFej6tob//cd3czFKDG+IewnQX -OLI7TA3uP5rg9PikGJOUW7wHUwunBdQl9XpLJe2XIhR7BAC4ppYl14OLDXM87f4J -grEDv8po/xdY+s2ysI31g8/v8mg2ROromZ12HMrsirqyVb+dyNFxcQi9U9ZC6h8V -00G4+duTjJt8YpQ/DYybVpMmVa40ePV+Z113OFZn9JdKs3p0kSi8csyLyItyJ62K -c3/yfspKE3ZDrd+FVJ/VJXUIXohGBBARAgAGBQJTGOluAAoJEHc3YWR7U2QV/1AA -n1bPtu6ZiSp+10U6yMmEvc9jWGlbAJ9tSDXgb9k3bFr1scJJ5kBsFJLGJYkCHAQQ -AQoABgUCUp+JYAAKCRCkTD3TpUjY4lRZEACqIACFZ0JHma1seks08qGrOYAIJxd7 -VS7Pgk4w8/kYaoXePs+F2Liaevnd06aCytJBxa32yR9fsgoPwoF2I4tRMCBn68Sn -lw/te9SU7M9Prrf8Rq02gEO7a2kqAH6ZNcUHdQDw2U0Rj4ArnZkHUh2Ey4TJwVUc -tZzeXxlpgqYRTBLNaJyyBP53N8A+nHtpcqJYdxDYMMdTYVNs8epvRMcRfO/dWnnR -lnco1ptge3cwm7E1/zX96/7GTPDwvtWseo0PF9W6wbaWTNm3c71iDXJbNbcVWdFt -BEJZBhHzciyN3sysHEI6IwGzmmpAKpQJ2foXpYhxy1LuHBT3kW7dq/mOnr1zyjkI -eLSK4eqiWzIAePoJfeQUbWkUIAdSSCYXTNAb9dV0rdkn8vZRZvVS+suHDQgMYtMu -pq3Ne5nJCVwrmfnzBj8WVKkPgShMgro26z6bFVIQX2dv8B7EXIEbut3DNeySZiaX -YoMZRADPHhwO9BLhFwllSEW0uHIZSbPWkQu4e5cbvMPc1PhIB07lcPSP3VKXNSEF -62zX6r1puKT04WHiwOZgeW2iGlIvGINawkhD4q0mGl2gsmD9dUEpkskAKKQI1BIn -v1qxGbXYZ3mZpStf+w7FIDOOA6pQao/h8yLkcZ6K2Bya22vp48pAlT4oEyvm3GpA -1X9/4W7wqG2EZYkBIgQQAQIADAUCUviNcAUDABJ1AAAKCRCXELibyletfIlwB/4v -gUDitIgIRGSNt+g+Gl74DezowmbhEQZTRPJH1Uqs2nCr23ESZb+8ROGnY1yYiC9e -jfpAabE6dPdfHqZq1XHo9je/LKq0zvaOWa+VKUScpQH1LsFM6K9W0lWtUwkFtZPZ -eGHvYVgMoZvyq8CG433LOl3vuV2XMiEH4Qorq90INCugf0Hm/fXfw2x9632NlMb8 -dcw2J+4bEMYabBdyd4eTMw8MhutcmD1iWP2D4GDcf3wHLxALM/rmVyHMCQ/fEYp/ -ST1T0tiIS+UIEs2pZ4DtN6NWMlJWiu6BY4ZObSsiiEN/5HyX0uEqujAgQ3SN5UZ8 -oDA16dec1OOhoEZ1phxHiQIcBBABCAAGBQJTLdxQAAoJEGC0MXHYul9Bl7AP/0k9 -d6JtKAllAkACankmXWjNdzgqDJMES9rqiSITn3e5l0Yz6L9O62E6jg6j6qD8YAu8 -qxBcHNMjbfV4EjXxxFVvM9yEcdLWogrJzQ/ZTvOaiPKq3QMX908/g7gCTsjp4zWt -p34mfDK8SelWAvboTbNEXZIQe8YlR17Wf4/DGeJOMFihmF159D8sikXV5k/EMUXs -L3MB/m8MfDcHumAOfZiUhmIILXhlT3cCw0AOkJ97/u2eqlM6C7t5fLGC5k9tM1Aj -A73s8bKBor1Hxjlct19o54/EpzmtLjg/UVdJJyXhvAFPxXay/Ucf4Kjf0gUNGWNq -QJYWPINBDjZmPPvhFHniitgGFNT/kaP4HnmDRUPT1gGTzAlbVSMknBp7HKxKui+E -HTrd6+UCh8ichYTGaKhq1yCMNjCC1FTqbLbY2o30pRn7LCQodWwvHZb+H/3LOmA7 -ok2IM7SlGYfLZAQ/Aj9UguCab1H+YaGZV6x/SSIVwXtQURN+c1Cr2JVtkfEI3dzi -bx81TStOh6zWlhLVYYlorYM11kv1dMpOljokNAsdfOyNbtEI8C5M9Bt/VuCGYscj -UA8gq2WX+u1Q6Afxdg8jGK2sMxZF2iiJ+fG0qvLX0Z/WIS5jQxhMA6cdrXnJ5687 -HpXDmlaUg9kdoEohKdLH7Gg6w1NWYFz+m2tb2gnkiQEcBBABAgAGBQJTPNquAAoJ -EPYiSHm2lQsiBcYH/RdlC+JjtI+QJLvupWv3SvwATvDYat1FqqHze7Qp9WHfWrph -SvXZBLKZ/ZzBUtzYLLAV3LP0Y6ZSCLuFTUfAkoqTm8E0ucKjjW5alFgSbPrCdY9D -eH+eu33uZbD+TRkEmzCDPoFay6xL7ONMBD71JgW+g9Ztz90hz2xZGo76163LRX80 -lqJVuM2ECgC/VWbcyfcYO23FcwEb0UUAznPvh+dapXCl7cHgvSMXlUwUCqhQclnp -/NPyMkUessmV8O5wOM36pkVG37oJpyoDSHEORELdX7NE47+X2iyA/k3WGOQ0BJQB -47FJZMcVfbigK/9zhrvPlGiI82FYmjFno4FaUhWJASIEEAECAAwFAlM3HCcFAwAS -dQAACgkQlxC4m8pXrXwQLAgAvbu9U9o0nRAk8ZTDTIap7s3cch1lw5nTOZFhWl1A -ncPAYiEz0BLqS7YBeWpKKr38sbVuvpgXBo4vpEpRIY4b7TUp4ydYJMTry8XeErrZ -M4my0bySels7CZxowsiaLoonTwceMD6OtE2WKa/4gSxMsLy4nWLxViJ+0ZDkGUJG -vChC1z1QUKz4A8+huD+1c79HbNm+TEXx5vRsYHesVaIypbSr0KxP67RTySTSaNPk -bOt4jFZ5b9HamQywDpScsN7elSNSVGVJPvCmlEUFP49eDxFhoDd8cFAZuqljT8Ch -cinkvo/by/bZ9vTbP7GltloXtgKJfmrNWddzV8zOC+W5CYkBmQQTAQIAgwIbAwIe -AQIXgAUJCG4soF4UgAAAAAAVAEBibG9ja2hhc2hAYml0Y29pbi5vcmcwMDAwMDAw -MDAwMDAwMDAwMTFkOWY2OTMxZTY1ZjgxNGM2ZjNiMjIxNzM2YjBjNDVmMjVlMDM2 -NWEzZDE1NmZhBQJTPx1GBQsJCAcDBRUICgkLAhYAAAoJEH+rEUJn5PoE+QcH/jdh -L8CN3KyejH7hJJc61bLiudILA1viZ0YI90UeoyCqzb0QAlA/teJd7Ieu+f1+kX84 -5rgICRYGZj3p8HJIzc+q2pDhlYYlB3u5fP/U0WiS6PzuMVvHEo7ifW56M67cDh/+ -bxbNszMnMaYErZfPL/43Orad5lpSPjvwxCFDD6WAQ17qAORg/dBv1rj7vtVBFvMg -C5Sp09BdsotN1rlDyvv4SyuCK2IHvup2BEh+3tXLm5DnuoDu8C8jdCgOzRxqA1n4 -QYH+ITl2DLWD9LrDgFIAEUOuWA2M24ck/OSSKTpQw1YxSTC8f3OppYGjwVdW4uyR -vvr97s8q9ONuEIyl3DaJAZwEEAECAAYFAlM/F5YACgkQIuNMkI8Cy6Jq2wwAlLGW -sUgLsXCDdzH/moB2XOqB42cSxUAq1Y9TASdyvWs6mUsmvWib7JuyP663JvFIEq/6 -IkgiNSVKf+P+Se90+loz5dk55we2/bEjUTk3WC0yFvuGPr95wU3v3dQieD9Hj58k -x43k0uFzzNDFt2Z/ZoxDxstqkUgDoi9Fvo4sBCL9iih+ZRnrxZvoFDDp9bHuVeYG -mxfikzx/PfiuOXDy0GV9b+EUYjoFIGf0CDoKu1LxVAndAB8QY2Z3v7QztNOJdhQh -Be4i7vCjUBwJ9n/9KKgC4BZ6kpmFDTDFj+/YUMti+XO0N7LxDGKRbXD7bLNB5QLW -2DLzYg5gRN1+atzyj3Sixcc8zgm2chp/v2GgJ3gKQz9CEyKZVX8eT2iJFQxUISjD -3obbl3+KIDfQnahv2WUSs9ncWtAq/jGz79uQzwsT6BKsxppFaELPRWyUZnjRtI4M -nPwYmXae/u9IB3nDfk/s2Vq7L96ZYBMnnnygJQpen59mIAs/ZA3lvdud2LggiQIc -BBABAgAGBQJTPybMAAoJEIJpXKCOp5VTbVgP/1KaEAPrhvDBaItMEm5uyu8nk+bC -U0ak2cj2b+QukTeAhtrkj1sa78TD/KKjAPcMSMxWJNyypC5+mT0/qlVhbxYd6TZs -WW6jR/XjCvPbzSyEeUnt7R7SngpjfyRC93fr+oT0ukFLf13fYL5vhtd72S29oifz -GG+/ik62sSJqW2imCTPVNoviR61xIZ92G2Q43QZMBPADWJbHH0Lo/YhbxcPeInxs -JYeTF8kO/yUTGiO1CWHx83gmVWgtw/IB+99iFC0M0tZPBajh1aK4KwwTw/WGVW9O -VINm6S6Niw0UEvE474e5P47fz9KL/15A/JYqxpbowJSJkdE1RYPf8TP+AIOPhSky -JiZ0YKWDbAZjKsn4ySA9TrkeQ80WZeaJlLS4p0QP18W/KRKUWcry690dkfMJkNCA -OAb+mW6c9sLFAUcQtraCryTaTKmbSFUU8Pklfi5FqIEC7MxIsMY0KfuiDYi6hVzT -EAwgmcENkcOXEl10pLuXtKA3oNT34elI88sBaNGtSmsVCVN1ItmxGIxtl/unlD/H -BmZ6gB7fmX9NXbi68R+3pqSM+RKahIDbcg5KoEuFkMMzUkzmgIaXlMyFG7WDxPI8 -mZ9+dN9THddQ14TP1EP3tWRNHZZ8wNm8y5OL5+Lr7OUSR32rMDBKQ36o6JRsIwQs -IphQUzrgVZun5n7tiQIcBBABCAAGBQJTInByAAoJEMIYUlgZ94RRCPAP/iGwt33v -vnei1XL7YU8lsQ2JqyBspoW29ZCXSpnSmSSUE1CoybdAaa7tTxufTvCJtqUQPLXV -Wu0oFFHwdLEm/NGOEpN0aFKj9p3u7b8Rlw2sUm/a/7Q4eyXrWhv4/JpnoIN7Cq4w -vI7tiXE45I8Vpzsx9G7qqMgGy2YRUOP3s9WBbLqFf23AvU/EFW2A+HBvmuTsEl7/ -VlVi5o+B8QuQDXiEBkuOLdErWzQYTtJWBNEl5DpeJKvTZdC90jBP3jgtA9AvCVrj -QBabrENezzTF29OwYVVuCoP6tvIRhyePoQt11guT8vi2q4oYgwiKhmR0ZAaaYfIX -p4zPkgSCmyhcjkwRq/KAyPhemWcQUddrWRpkiRZ1j1Dii699m6LSqX7uISjRaGNW -TE6RGseTNNMT8X15BLpa0EZ+hML0cVFzU92WCNyMcZMx9z6+oi2ntqGkF/CQk+VV -q4I1ZciJzdaVStT7KNUjLt/vQlqfZbUzw7P7kG8Q6iqRRzkK0yDgEKHpxsZkGoeo -H9Di+sb8RxpS+QlCI3I2jMcC9EWflhGtxe94ucbA98drM6ZMxzEAj5E59nXoD/K2 -i8PVVfRSd2rDLL7lL56PlNZpz1HXeH86kGXRzIucM1JlabM3I+GVpZCTucFiGkFa -AxJYEIwNOMz47beP2/4J9ttOiZ7Ex4/HQ6QziQEcBBABCAAGBQJTg5KEAAoJEO0a -ZQcAABARPI4IAJTM0C9eXIYJUCmf4RAk3rsMjVeVIWAIyLXlUCpkmYKqiRWlH9Wo -OOsTm9zstxFqSM6ZNX6eE3ZxMyXbZsGYahGbHoWqVYbavZzXwYDiJrCM7PLEQAW6 -qW/Wx8/9aZKKnoIQirPU3KZmhbjs6q7sl6Ze/J4emTJm+fLUx+P6o55jgt24uopo -kCCZnu7uouPgvWy66b+JCEPz6zzSIBQv50YU13IigydzqQhkGCjFl+I3P4qTJ6wO -8I151BvpaL04AsKWRk+IrCMjMmpXK6WMGpQjdqKqza1pdvNK3JGOUGJ7mtw5vRwC -38EXVznmrmg54skilHeQkOLV8UN3bzmySx2JASIEEAECAAwFAlNaDqoFAwASdQAA -CgkQlxC4m8pXrXyUPgf/daLzMlwjTlmMqtXMcgOWLR7CZesMQIuC+KrKur8uD1oG -EQxKjk5XPz/ByIQc3p+Y7/sxSH3fFYPI8+InuvDjbJQXmWOWvOMU+0w5aNg5HK/e -kpqG1t5323a+DBWI2ui+npQwXplVjRPH1PrXuDgQnUvxG1+xy/cWCA38mFPyRpHM -YbDdLuF4qyH3Ff93JwEXNcPO51UGtWxDSjMPAK71OA3m6AvVH6kTa+FM+GiPCcza -3+W4oloGqiSbYI09m29mhF4E/593ZlJ7eViRbHUBT6e41cfycivKx0yXR2Q7I78y -U9ujA1nyydyeQPKEBDojykUl45tiCGEFUkWtgJjkB4kCHAQQAQIABgUCU4itMwAK -CRC8I2NW0Evc1swAD/9OY6ThJqOJpeMaQVVIWx5Ik1YmhFu+9G2nrJZF/c7RQI96 -2ugbnVG3ZbOjFM2hcOnE+OFl0LJJjrtNfhqc4o5n+HPv0ysr7M0N6vgegH1JN8nU -iVkiepfE2GYkUK5NkzWMB2BRfJs7JXeYteZ0Cq0Y5xn8SUFYlJZZ3ml/Z2vatcom -4fpxvkLMG/cZdzR666BVWbmQuC2Wk2taW4uV75VyN8bI20z9uAYMszKGNX0JWJqc -GbYLEfmlmu3hD6NiuX7LL61gVXc5wjP0DOa8abwAyn751peaCKs9OAsxXPg4wOuh -4rY/5dC0pfA8G53bCadDiZqG9vPKP/p6WtoY62YL21wVZmXupNiVeIDCopAEwIkv -SS1JQvQY1474VFRhHein6JC7csZfH37XjjlnknI6vQAunhccKPa8ko5Evu8eSxsX -EoX1xAxYVFiu/I8SdYKGWMz0Yy4c9LMAW/Ou/OdcPRRbDroAj9VEYsPyhuQrT1kE -Y4YJCeRBOK7ZpaG5IFoOP7lgX0hcK6VWGHnbvOnF8+NeuryIFQBoSV7maNhDYSav -USmzwi9gjZFnp6CR/hnH20lauHvwzTp2cGBGS+UMHfI0yN46L+Jjo1r9dUboqmR/ -kZxYQd3nlqEJBYW/7eiED/stf/E02NHW9QXs2ZfHOiDdDZMIFbjaAhg1YuYDRokC -HAQQAQIABgUCU8KMsQAKCRCDgslcKQI9+WwdD/9V40Q++4vtud893RDMucMHfRso -lnkI2QN83qL5tpEHnQFnWMuSlu1GELObZ6QyNdarWHvW4TvDe7dbF6HssAaK+P3B -oZvvCxk7qQa789DW7RBkaaovW5dKyW2V3e8hXJrDl4aKXK2amzpBkX02kXz3ZB8I -/+GUnoZZIHAlNYm/6lkMbCQBfIdqPukuJNlXjR8vdPZ8uLVJO2VdtctP2nTfaIxS -QTDuD+7YLw5BWrGEXSkKBuvTILttgMmZpbfNy9nkejvB9NtlaneZwOqzUZjDuijB -TzuMX5tqD2FYkQgwOTXQOSZzyi8OdPKVS1+/wOY5Ryo1jEkAyzDUfEEXLNk5GHGv -MfTqcxPB9CUh/rIN94KiI+jL6nfBDShnhuCZlNtzADtNy9nunBt71CBIWSIPYz2H -7rdN+KFCPmP9n9FNT3Bx+esN9Zc+YxLZ/Tv3aGaxdgifYR6cLjeiM8+4KY7dg4+i -Bnj2nuknqkVQGTLDDfC36OlWj5+cBTUOso3ThcGlwhRsD1QtstVkh1zrfsnEd6Bl -ZZPafAtsqtphBEnWobBevon60nOKXn2WX1uTNJMvVkj+3G2/RJOGz6JMUU7NXLfD -LyCL9LNUcSss/gkqn9MTb3NyYJfHj5fbH/Ha4pIeV7mmoOZu9eSCMQOo/9Uo+Q19 -xgppySgscGwyVFJIoIkBHAQQAQIABgUCU66hKQAKCRB0VcXjwM3OuW1bB/46KjAd -XmRP88iW6r5kNrexv9vN+xFl+p3wLnhEC/Zc/SiE3fgRjanUf1U5RBYvtHXmqIfZ -jyFo1lJQq0egQkfhyCsXTvsmsupH8Bkw6SnWFCryXbg3MCTICbbrNuE1tAH1ESSC -/H2iZUKoAppLRrZh+ZK4EifyPOjO5QkkRLSZ22GH5w6hvvny7vrhrDbwL+PNSXwb -KTieb24Hp6lRLUS6JiyDmC488rC4/oNKfr+f+i5tajy/rGJWm7is9Ctz78AqPhy6 -PdKKcexkZ/0TOyycolSzAI/OLDE2KqhdmW0MmBHxxsTkRMzlwIoIpOV2JnXqRNOh -lwHnBHzQi11tWiHliQEcBBABAgAGBQJTt9mIAAoJEN1A8liqzgHpaJoIAKittxrh -HwDkZAGDjUpHaJTpMqTh5VVTawwewQv5M8OCIaCWcL0tyF2VkXyWMDJ6CQA7Ei3A -cXYU0QYJJN0+m2ZT9/P90LQs5ptKCfdgc8wMk4mW85D6ZxT2qo70vH2S8/c8akvD -BFsYGsFRiAZIaxr4alBFRadBW1B60Rg2DUFbNmH30yct6rhLpUIaeSln1oY2x7Kr -qTP9r7dMM6HV4+wr9Z5NwZHChrX+GEC6+m4HKTK3WTDTmuiHtEPFcE1xX7XGlQTm -S4Ny/n5GI3NPV1ci+zC+gJpn8gzgCdI7fs5PkcjRyhn+IZvRuxfG95ooTQ/5DcQw -BWmmtgcan5Wy4O2JARwEEAECAAYFAlO5FPYACgkQ6sXr8HqpwqPIJQf/UddOpOXU -Ur5AkWei/3+XMJTF6LLqdDzPRRH95IoL40sn+l22FahSq6zcbEi3ktFf5vIj0vlv -u2k5bVUKShXMilye32ddeITv2DNisuRYHkY7pHL1kMvdFu1CiuCH0pZYHIaBI+Cb -NmcpoY5RB4dl4WiwtAxyjz7l+ytWzq7qWAjBgUDtXhQojT7sG7gg9TZ7GMpwRgWu -BFFGNYifzApT6IZkxWh6Rq/DhvlS5jcqfF70pDrO5ZYJbbpb7mjtEf/qwEIAvTvw -VCua1yynn5RGAQQxOuxHYi8IiwiKEx77HviNRYIs11jbjGFQyJQYK/EkQDjsPMQy -AzUVFQjWPzkcMIkBHAQQAQgABgUCU67DBwAKCRCfMYAseWQvJVOMB/sF5wN+K6db -rC4u5A6Kq86wXya5TQfk8E/pOleNKVNoiBuAEi2xNfK0aNfmXJORjJEUY8LCuC4h -VI5Di6K+UpbpauuKIzJvZdp29yXs827wZwudRHDlwJFlRv7cW3Eg1s5TJPIVPZgd -mpjgofkv92ceO2LMG84V3Gpn9n5zEE2WPmRi3bULyJqJeFqe/Vf9m4xI4ZyocYlV -Wzj8Zh2LkQkQ/bmx8xiHYtns3IhXriFY789kxvzHKC8PbW0NxQf6nOjL2aSpHLgD -DXmFCWAIDf3pfGsKQp0OntyeGNCnTBRmJjH67ltDe2AgNLnLud1XSOTokgU0uO9y -KV4kWoem6zO3iQEcBBABCAAGBQJTvv2uAAoJEELoaioR9I02fZsH/3tOpaptnALZ -q+Nfe39YZECz0+W9LFnTr9lsC17QXBu94lh3U4p/SXIhEb+BsOKiBp4L6qe0wzmS -GJNbP0V/zRvQ3wT0XCYYlW69SOY7vBGwUbF1zpRHZhD6/UUXiH24SAL31EVsSAwS -zdJ6A2SIaLvn/b4OG2CJXVC5/YdXdzvPwoYDb3Av+drTppAm4gfwzSQRy8mcmZ7t -SzbC1ZXgZjJkRFsnA5WhGF4YzAGo50lq9TAlO3zCkYCduhMjC4eE1yCxU6P+8Xgo -CTentqODwUHaxcdWY/NZ7OuIoC7sBdHUc+NHyGVP/d34hh59sasuEx7lDTOtfSG0 -cylIdZM+3EiJAhwEEAECAAYFAlO6xH8ACgkQogy+sgAMZRXYLBAAo3MvO3yCD3gW -v5mNPSpC1KrmpcIrIu7gUDEgv0YY6C5mezeRXwpLiPNZPeewg+glW6qr13nRBlPi -ZaIQN5JRNDESPkTBC4k5c+QiV38zcqlggkzCv9sMP25wxoayI26w0GlO3/X0wsVZ -k8/x+corjT5ZAeT/9Go1ZUGyn3hYVp8voxbZoOfJYTOtLXjQ1i0JrDulxp3DxrCE -8OGMIVGpzejOxQPNLciEUtq1NN9QESHpXTaonTWjP8ubT019fO+qIl8Uy1h/ElzA -ztTZq2gDuQ7//xQJ4R8DbDP7j0Qggpsm2Hso/Rg5ruSiX+1qBF+COhm16Dl7zoxR -IO9+5RpanXm7g0qBcALCuIn2aQOMTtB9bA59I7fXsBMv4OuHr3bpxbcktqA1BpHz -y4K7r98opgGpfZb1YyiEw6pAaW/VwQoV/cEQsqopuSmSngXtvFtXLPqAMkODi4Wd -S6/YySiEUkKdpe72jHamZUQwWrXc0CQ0M+YONXlLizOVDGCHj+itHx/jqsA5KGnZ -1X6/UqpwZLBlIJyO3JSXEjofIN0u7CyYspQZRpowhJA7EuGYCTCff5BJ/FWvM0yV -Tk7yw1LXYvSbGWMWvwdbExADiWY4Nd60lVxFkopID+jqVF4ggCdGtSPMpzEZvdx3 -RnaCJS7A0Bq5zGKbf6or5u1XL9tf5tCJAhwEEwECAAYFAlO2mOMACgkQFtVCxJ1n -Uejg4hAAg6WtMSU2pFsgEHr5rXHlQ4d0SKSsEPgFV7Fi5Rr/PtZQahJ5o9xVNg1o -kW84KipiFJaPH5dzBkRjcZ2CaN/61jlK8DNXg7+ApIXWy/blcRhR6lc1fYW/jerE -5QU2ImTUSxKGUYT/2HCCdsRBk2EWYBbk5uDL+h6KWnY5ZY03bmazYvEdw0/AtC5/ -VtpQbdw4TUvssu2cBXUnoijMffXmETZvNuhGmyVf7uy/Ha8PDAAQR38UJkLjytDJ -hmdKNQ0pk8yzQ3z0lxjM00p/kmtv6LFRVvC36u9NmeNsmo8vY+WdeRWEM4mEhD8m -pVT30Sp1LLpNuObkwzqH+vw5ejHh+NKpV2zSWQXl1MqGBc/kVqH7bM8PQff5SOfo -d1eO5wUX1Xm5tdwnpvdfMc9tTosVouOWsf+sITyhwtvnr1Ph5pjbfHeyrEKHh7pR -JkhOPd/CS8sUI3VKNe0mzhvydCljCfq/pcfBcJxrKr6JhCo0NRihhqL6IM6YFYqE -WP6dBT7aXtxAeOhkn5/oHmVmthhuCwHC2Q9fGNwaiYmnYGBCDYS+AOo4rbMy2IKM -kyqVgK6b6/wT8RHGJaz69MrZvuotx6Nsy+UaV6Ce0MDVNvWN0vo2SgzqPNDWq5yJ -TnhbUbXxd7ZdlDc0y88jVDKyfi/BvsUe8u2uWrYOROiYl+NlCXSJBBwEEAEIAAYF -AlO5Y+wACgkQrs71RuyLAmARpx//Xu2RFWxxhBSmX04zkINjZiEdmz0LPfr9Tby7 -Skppefe0k/s/t3EyRCHAjI6UOFeI3zpb1Dojez0bLrCqv++++t7Q2jbBPa0GjCI1 -pMVPz+nJPrfZSOkUpgzbH0CDOCrcQMFGyAka3L54sC1AcDye8Un/4pcBZ/fWd70f -hbNtlSKqjXmpI6rouT4uowxSKQzje5fwzqsJZbZcYWyAeAfRdkCiT1Gf44J9sxMo -9vQ4BrSUkXwEa9pR9fROxcDDCjsHMXgL+Fi5oYR9OfVUOxUz5TGWAuxNg7Mv1QBV -taMjLAYXZHRrHqSBaHWDmhT3DDzGRTEjrlvSjtgwxI10Gbk40bLpL5BIlxT5Bhc5 -pNcDnrVQiZ1h2CTc6hpCmwPP3FC6iOEqAcCH5OMnFIgNEb+1/cuY9f3HgcbXAX9r -o53K0cuCnpuUfdR2um7648wngK4amzMkOMbo0qFPMuPz2VxsHjcjWbKmZiQKFaEx -jCyPmGvKEI38JAh8BC+rJE4Eng/zS99rlTOeEGnGxgJaeEP8nmbrj1BgNyvXUsPZ -LXItD9vmG+xu6+9x5shG6Q2LRRYx5NT6CD18u70pqPUsulrmWZohlyz/ikJnMvy/ -StLGiBFSWIawWraJMl+3Hba1U7eFL61qi9ZfJzrraKY06OtckboqCvs/7ixWg8Jb -xaHGKbz97GVzd40rufoD7U5dJfeqOBzRrOro4DcTRFRitzslaPedzGaPWQVt+JJ/ -tqlmHsS55X8rmsdR51+Td84DDG2tqoNzWVrVPRwyWxvYAdO5ZNU8l6C6HhOqEUea -+WtGWxzK6XqrkcmGlFKvCYd67+1eoHFhq7+SlAyqIqGH9HVhEJhvrpOUJSH6Eh1j -B0wELOESdE4h1DO86lQnCAfS99ATIiG6gLI2tbUU5/HagVotMGDB82Xfva0JhJYG -2d4Xcluu8276H0RZaQFtsDF9WRvvEH1DpR2XTZ5Eh+TxCI5gDiTZU3eIl2bHfirn -qpkCPR73FRJBrUMXbbcqO9DFGFPoscfLLrkkmkI+ovUUGjrXN/SI7Wki6rHEcqhG -FkWEyLEJ87LBZrB8ZzSH2DA/PnhbMeEY6/2N6F9LhFJWT8NLtEOuH+0KaD6MwHae -+3hrjdhvpVhlyDfT3jerPRHdvkgZJEJyZ8hTvmqsms9WWuuiHwtXZ1reRPRYio2h -lr145esKKwQKKI7z1qTpl5sT9m4FCUxtv8oB5tzoBJxo7gkV+06Gho18HXTX4nJu -2Q/ZzWW2mHtBJimajXNVmBgxJcgv2vnFnQl4l4nKgcAmrSVY8xyGNFJQ5yZMyKnv -k1297hDnXO/erG9VOu/x+4vyvym4d2dWJU6G1bT4/QcjXi/YXIkCHAQQAQoABgUC -U8UOYQAKCRBeOpO01N3NixXXD/4mk0TGtdT3HhrwstIA492xmTOnudt6wCHP8s9l -LwdiirLWIVhA6f+kBFVAZufiS0QGeY3gfMmuhcJwEyhBjTgsfE03SW663dQwRj0y -aQYuzJGMxORkUMi3r3URRXQVdCigcjYUzaGYzXzUef82LH24eyNDBaiJrCo8s+Gt -pqUuAyLJ3kxaCxjMCyxZfBMPzUBheLd9c0NDmBRSuaAVwyqXlavh6E6vSY2Y/syC -3YLvqDWif0XJg5sJUBCwf7Ju6gFGrN/h7wy4up6SIoLVwR1prU1fZWaIw1X0mxSy -zTtox6AsCZgWn/AjDx6zaEHrvV6RQxyVUUN/AmlfH3WYIAJNOOSll8fwIcIEtnWl -9TlrE4uJySCydZXPUa/+zTk0AvKWuaN2E7DyRvk6fV/4dNb+4pnQPUz0o+FQjy7P -Wf2R/eK5a46svLVl1l/TchW0IW+D52RrIPsQRMHz9W34F8vvTx6NpARIzMTXQMDa -59Pu3tBOmZA97Wl7ZfwRXqUVIYwf80B+zmAF//DWe7zkLoGrJPis9/ZGrgNpL+i5 -Cy+D4sy4OZfKveEMWfl0S6TpG5VbvmEOxa9RRbMut/SaqQBxQIV2/gRYH6x1injW -dwAZ8mPgHCOLXDY4Oregj8f9te4MaSgHrYbM++BjSmtGu18ibgePMsE9nB/kJDBi -yhqy+4kCHAQTAQoABgUCU8WCwgAKCRCDZQG+nyenI3RaD/wIlMHp4pu47UD4Ey8n -Mqonl2OxwycHhI+n+gbl+F5k52ZaKQ/by7u8dXIuBGpgckVWBSGN21tyiU4fXiyb -x5riII7NkXB0iZfpC17qE5VWLC/GIPo/e8aT3LDFVe/0oNbfCldRa5cmN4HIwIXl -VSHB7dXUqIskjpJAc+FfEXJqs42GamQQgP8PqV5VvNLxzWv4ioUD7R8usk5ZyvsP -WvtkJTqnw9nCI78zs+iGkYrBpqAbC4ICmkDXWRJOimcXSXtlxzZxh6/+9X63Du8r -LXaKFYgzqlj/NWkNTU1kTZq67HrymOlzQNUNOIzpe4+Z2sg2qEAQ9KeWeRXQbWbb -uvF/O9rcxIR8s0Lwd7OFFTcDaU91HRSSVQRgC6oT4IByZkPjEjwrZwJhPPJNk7Op -hSu5li9iZvlB8gM1HFHtHozDl00HZ/EN2yGAUwU2uz6eneszQh72lbyzGZLprgB2 -O4WlmTb6wlJ9nWYl8V/FKge56keUDJueGa+fmQ3rTA3nGdUyE9kWpAvEuoasrV6W -WFSTLOFudPDxGI9d8Kg8SrwMYdDxm96Dj7fZLOlw/1seOQm1AJuHXlaPqefG8rFM -cVr7tdB6VSPrAtmF2uqCkomHzhlrvSbKzCz9xu2Ibe0/2FPX/ZLyz3zzYL2hH8Lp -mVIHOH5KLoGNydTwLZyGgyz4X4kBIgQQAQIADAUCU8QtCwUDABJ1AAAKCRCXELib -yletfDFHB/9Rg/GopXG6njxhcBcCUEGGwakRltV/TOqXem3zcVu3CeEPGt4oVqw+ -BTpyNc4WwPmYwlpsAldMQjqVA0ZfbKy+EWFUGTnMBxkfVIPSNagrYOAtwe6qKHUe -uBWfY54INC1gTzeSlkzdTo+vXjLDQv7JE1gIeurkhDkIWlUx+8qsfNx+JnEMuhZt -O/uUddbxJCw5/TWqP/sdbVpj++K2A33qshwLZC45ImyHKWXSMEtDf8vzxd/JTghq -Jg3VWrtSAtsuDm9vi7pkVGMRHa81J9A+bIBLymTZcdLx6snoV5+tJPZ6LuL8tjhK -x95VZ+pwvgMQJbMOW1P9QG8vaOHIm3NYiQEiBBABAgAMBQJT1fnPBQMAEnUAAAoJ -EJcQuJvKV618essH/R4hivDd6XuQi3AbmumF6WmTuFRvwX059UflrMw0XnB5NOa1 -tY04OvEYyeB4Xd5JeZX1c4M1lhgfEVY6Nf+k9E59oSii3JBlDy68pT+zm5GvKMWr -hweNqGgZ5bytrgzWRFICkUqt5GAsRZK3iPLpk1Alh5vBMlEcWMlRxpjm0qo4Smhf -T6mbWXAenMVbfU8nb+feX3QIaNwi98X7VqW8uQkbJeVtXWGr+y0nhqNhMF7p9+OE -2aETLqrrV6T6cnvsXVCDkbjdZN7/k6Nz7+vljkNMgotkiaMOq0lTp4N/Zym9dH6m -4YUu1vOh+lzN9rXNPjQdvxeNe0t1n1M9WN5gT9aJAhwEEAECAAYFAlK0eNgACgkQ -hvvFGwuj4WSQGhAAvAq9Retogx1daVFgJNO/TOVdjHjGKwJJ283zN68BC3HRlXmj -yDDHC0D3/Wevw2pZhlWUqMYTgEOjWVVqeZeePx6Oqs/NAkAqM1+K75WifF7ccZPP -5VWGapcZ2vTT0wghr4w2wFdnoaWBZ/NEaP1AZXcqHT4LkGX/Z93PLMqeXAoGkA1a -LKcdLIlDL6ZPfVplMNlox+YQ+KprpiyvAkM/iwyPOPJvhdV7d92hFLL0xrf1dgBZ -NV6STeKfVwqpeM8O5V+hUpGJU2GsxbuKjb2tqwbFblsPHTSz7Vs/CxSZgApH7YOe -ybHHfRxM/8ucCVsWtSVpCWUz7DvBkGLlW5atRU19Wsl3HhJ3dap//k7qqpt7vANW -iILtwH5Z2qy7qVrzcMvLzUKDCctzSJmoUvsq/mCQoWz5XA2wcVbbONrxw1qny50X -ha8WI75lK/PBQxw+yAaUVH4yr7g08p7+Hqa69VCR+ihSQv8heTluMfZxsezeBpkw -fEJMTrZC6j8R5or9D3vGd8AFX7tLjETpzctJx2757UHmY+QRyDwdog0laLzjRLgk -bf+FQUOSNnIdfp+l9sGGxln7Lqyh7VTW3IrkDEIl8XsAdGCdxmRorErG9Z03qpL8 -v32/3MhkQoUcQOIyz/DbQWe3V+aajrZj/isIZoa5hMdJbOs0X1A1AlrQjT+JAhwE -EAECAAYFAlPadngACgkQi+chBy4YZL5pGQ//TL87RzgzJYDVhCVCIWkc+PH+9L/3 -UFu9MrmFN//ks3amHJCErWPlMMDww+3uHwBS8Dv95MlQsojFDj57XaJDyv+xABpJ -00DlQiMasVX8NKvYJ8XOavf0oTza9NRbcJQOoBcaZSj1MR2D/QD+xO+on/zPiA4I -F4+rUKdJ0W3nmPvguGbUDehncM5cnhwOeRjnDOEY3qyvq1qcGUgRQGHmWQdb9MPq -pU7ltuwlu2vfGqZgroPm7YOjQUFeTSXNWUMXW7y/W6L0c8PwgJ1jx9e5InqRTo5m -t1p/a0lkVgSY4Q5k8BMe7GSYYfKQ+bLtB/aZ6pm/HLdjTrR+4DjhLC+q853IiBK3 -flCtIGX/DqseC/SWzsE5InQ6PO/KUUGNvQ5OeoL7C8eWtudYdtnwU462RwRXYZvR -2/WpH1DoTMhis+PfHn8jZ6oms7532AN6OsMgShPRNI7xxKaxQQAG4DULCOUT4hV+ -lDEzWIGeQoP+Y+XWrmPkiwszmkk+FbZ5rb0t8o7OUQ7lqB/I6mFKy7JzC3ISKUog -c/nUw2D1i+1ebmnQxEYTKavLWqfVvKDkY+ITE2HJKTkzQ0saZTQYIhyge7BDmn7o -hRIZ5GQtr/ZMfBDkr1xUR8xaBKXEsGcLn3gC1y/pJyq4mt4EVQEThKHR1LqLgib1 -v2LgVIwe5QvSTUGJAhwEEwEKAAYFAlQAyCUACgkQluKhvoHUeqKSShAAijtxj0Az -Zi6o/EYgrWZcQy6ZuKSX5O1INDAIitP/PTYBk4vy1/pMVwDgOJnYabaeB79En5f5 -yfInaGKzdwwcfX35T3Co/a/WwGoa2RTQ8SESM4uFfXj7g+e31bhH6RWk+hOxJDlV -rvs1L33tcT/tuxr8vl8pIo/zQiX8erfgxOelBSqJbsxA+tj5ASlh5Oziu+uyCguP -fhhEz+Kmhg4iWYsKdZbhzgGruA7uyoVVaY01ssknq749RblGGG6/bcdvJbjwMbJz -ZFVNWjCx1S+vrjsGIyI+xTEDSuNgUUGhAZP06NXtdaPnmVXmUfCthc07ky+S73O6 -XHQX2CfUxEdYtwWcIR2AjDoSVtnFbOcoNaLpBgWkSLf7RGOU6ddTTTgFB0VH6l+J -JCOJk9uq/nVmUimKZmkfTdlSduQLK8YlQt7jDE5Os3pWi1ndAtXzDSyAaxYDsmmM -Yu420WSclLJeRyngIIFRjuMfkE5yQ4/XJLY04RakucKYEy/Ifi8PdsszPCPJ2w4c -4YkOM67RGc+9y0FnHYRIhv6LakGl6072jmLcIHCzkmoubQPv/9e4lZKDM1YpciaF -USwxk/Bceoy8JO8lylKvixXfakHMTmYd5RnJRXHaMw9oHzuIMLMXcFo/2Z7tSMU4 -VqkcxRlIGUxllzdzbyuEKDcsBYMydfjAdtGJAhwEEAECAAYFAlQR7H4ACgkQ4eSy -oShroyNU8g//UWIwig7aKTBiL0vdeE2UnhKOzvwYUGt7yr1SWTEjiW5WVg7Fd7dU -wxkg3rqpFVp1blixup6DJihTbBaz2sn8RaCa5k83HX/V7tB/cp29W0Iq7M41DZmi -ihA15t98iJ0DWPURxo+cRNjVogrOF/xANjY49E4sp1jbvfMH1bKtJkknDJaD5q3C -CktbgtcEoC0P5KU2jf357biJKUgvHtr32gp4qtjjkZSzg9u0knkjetqMusxmzv4q -cPsDY/Ov5Xy7UV73ep3wlZX/Ghx7XAahUJ1fk834v5j9Jbtnb9MXakhwqhRoAZmq -qy7bGY7yGI47E3r/ugmNTsUwT74IFiNkYN0GABr4J5dlxSQLoe6nc6iUuMQ1K86w -mzYtgbqYRtKvMxYfKNQyLR5Q1tFo3tVWiQWjDdgznUCvdFIF9ZMrxsNKvJa/i4yx -CPUPm3qqApleFZPMtR4OyNEgBSQBjzV02hEo/PtZQ+qm3Y1spj7Llmrcszl8g1Gk -gb7LBG8uJYb83jVOaQnW2TJzrM8x/OJCAnDq9FDAq8IHCjBSK1cLgqjshfWjY0pD -wSm3XubFWff52hjNVp1sNT92JmwPG1+vt7aywH5ScKxxyyjgcEitReamJoiKVK/r -eRAAe0HhEhR1Ly4bKQ7bL9sobc2quyPfB+ql5/brRUnQhWlHfzRG9nuJASIEEAEC -AAwFAlQ6KzcFAwASdQAACgkQlxC4m8pXrXx85QgAlsdERxQtdrK4PXAp/0J/uaMR -vUatM9Bt2CqD3KIhHtrjhuPJnXzu8T7Gy2qSKuGlBKnsIIUYdtjGwa/Muclro6Hr -5zVj1Dnhk9kRdm9+iuTZL5QoJkChM0kjuY3/IutyvZC6y6V8tzQAr5crgbIczCbQ -PElhh4qobPhez5achWz4tGMiQ41fhxi4ZRk2/V1tpFr+XQ8KnPLv05pw+nn4emvQ -j2EwosOFJX+z/882JOcaLVhf2UefPtaZBOUvKST2LuKOvgR6Kal7On79di4fTlpq -hOFog70FlBhy7X/k8Ofc7WhkRRJaO3U5dlwJo2tAurfCgEBwg2btexzCxwWkbYkC -HAQTAQoABgUCVFammAAKCRDo4ni6j1yKEcYXD/97wyRb1cMbV5MXIxjesYghtt8A -MKp7Yn/PSid+pNZlaeDUPyFn6IDKxnloQFnm06kXhLIsZRJXaWtKI1r9U5agPye9 -OxBuK/a3jwXbWyRuEEiuSzNy0C8rWh+vkpIwmE7VRRa9IPuupcUuhHr8l6yHz69D -z4qXj8Hs8haSuYAueo+BcPzPFZq/cx3xhb+pRMo2TGl1k52Dg37P7rGHCI4bRDoU -snaK3RkzYnnq6zbOsZgdrvmnFXCGgMdeME7WIxnmMF+ZoMtQpR6uPZFdiimKIk/R -6i3LOwy+B8PFQme2mmHh1ksc8WUyWNFeGu3p/qEWPOsYo27xYoj3PXDwg2xirEjY -ddaqSZF7/y4kzXMMln2tQ1kFLdylSmAiT3dAaEuxvfaJVFXTroHvsUPF5ZwWKDfU -Y46ctahUQk7bvlDEF+LF8KvwS5zzV/wWyyIDINyoGe3fJH7xH5DA/YwXzCtME5kO -Sxln1q0FK+4GxRBg0w6sqYpycc9wZvrj46oz6Zmco3g22xD9pLkNpdYaB+I1SdQZ -3fPv5wh0AEffvl2EUxPRxd3rKyBaVudGk4NSMgj7lCcmBgjoPCkxaiomZldw0cAI -NXnANmP6rUbZkxksZp+hcTltvAqeJl165NEBLv02c3AnjatgNxu+ING/dhTFBILR -FO4vi17p2/pnf2Vw8okCHAQQAQIABgUCVIXkmwAKCRBXJYbejhNFJMy7EACPlffi -CRTKSitdRPb8K/7qj2knl+9jRjXgCQS2Is+cD+mjdGuKPtrDHV/uB3yc6a83dlrw -zibgk34V8d/dmQCnM2lULQnApXXoTLzBrwR1fQ4EAOWLmhrYdfIQ6cKPzKjCu0HY -1kKBGEx+HSeNfx/c2d9AjscC5AMoIMcCCsCRZWfa8CeWJkxNCFQvtIkJdl0OYT82 -m1VFVTNNaLT4Z2jKeCV9odKCCqixJnIFmQLKvrFDUZ1UbsHqys9nrbxS/jPrpKfA -XvEPKZjLqlNGnQvdRjae8WbmMl/qfhqttGGTBgw1DynNls/uLk5yJx1jBRI8TBiK -Ph9KMyc4ces59QWdKcMAx2VRUbF/1BOVVudaFdABAzLs7KAJSQrUPA6nVh/LYoWm -zlCJrekQTAw5Mz2YctldAcu6V8AdGkzPB8xW0SbDQTCVSgQQSUOJJKkf9hvdKZC2 -I43OKxSD3r9oW5s3jciVBRWPjNw4APlSDo/cA58q1qDXL8/7XuqEYz7YSugDx/xf -YCQQaXqaOdlT681fjdZG61Bpb/UXfclEXU5CHVYs2Q+CJgP6Q6n3hUoKlI1mBrEY -3XNocHOWtHr14B+gVSlU3vPHRqaXwUfhF2nLRac5E4KDl+LWyJ5WqFwl/TyDpSN5 -ZGB49JxYdd5hyUFvafeVjeIQk/QM8dxy6fvc1okCSAQSAQoAMgUCVJnpmCsaaHR0 -cDovL3d3dy5oZWFkc3Ryb25nLmRlL2tleXNpZ25pbmctcG9saWN5AAoJEOzpIdqG -O5X341YP/0AFeqUGu/DX/ZOypiuDSvgu4fFbErICGsmGOx/I7Z/UZxJIIy8MAXAS -QQ7xeV7xuMf2o+kxkSIaxrV6PaiOtyDlYW2T8jMGdzpSAxwqGMoT06CMY/6gmxuY -gB/BPcxTouQBrpRdb86JydXJTOFpwjSDel7wX5BKtxezYy941/6wrPyCCANt7Ys9 -WfC/ZT4JJOeVMC9r3C/qY+ZFioUzxwLGuYmIksp7u3mN92U7Ieurb7GBJU9zA0os -k+6fGDsYvdb6kMgBgIgAQLSRe8zOACN0GDrfCnwStivLmNgkaGTdMLbgordm6wKF -FQfJHyvFYm9wwlP64WG3ZYW1F/eriKu9HAlQOMTM85oDF/IWUC+QbSnlD+BDYg+J -bIruvP6Im+qnSMeBP0w+jEFgX+mHfpOh1VCWEQcruGIqO0PjMG9v3oJQ/SBA9EKD -YODUtP3xvOc2MVvawevkrbSbWsly6oVwEcMtvceFBG9/lNC6RZelOfOJVgXpMoTI -5zRoHaQUB7DDeeylUB47fQ4mu4KtmvGqyc5LHe1WM8VJbopteYdzY2md67cvj76a -L3JGvxZxxnihFdHIfvByb/8IeH7qZS92a6N3LyIs/xX5UMnQb+JyZIVtsBwytpgA -IaTJ5FTHktf09HtAH79Pm1Inz1lHy3Z8KsEvcDREZvp+WnF+pA+7iQEcBBABAgAG -BQJTvaraAAoJEAPPSgqzx5pjzfcIAJJKUzlxdHOWxuoXf1zMdqYYbheU8uzB9zW1 -8SEmqkB4hThvR1wKn6+k9MjXS0RWrV+2KETKQCibVXnrXxhzGQMdoFEYkBovtBSh -b9B8rQRdzorpixWF86JTnGKV5B2YIuZ0yK/QxFhDVlwKgpsPtULtIjZvXcSzUmK/ -tB8aqlBJZGXoa0mSI0AqaheI5n3bkCFIycnVWzH9FxVFI6F2ELhRDlIK00dA1bEo -Wj/+nAMbBxrQy/ROfjjM7sB7ENy8NLwai0NB1qLfR2UYDgisbPaLGzAjUOzc92tv -Z7E70wUnJEKVJ64/KiZaDOOxmILKakZISJXDuoWXw2deT3Ul1C6JASIEEAECAAwF -AlSjCY8FAwASdQAACgkQlxC4m8pXrXyQrwf9EU9cleqkzKURvWGCWaXxUHW5QBeC -B2XFBtg9Qmp76++Ymlx2EPJWjkbpSq41d3PsiuYx3WLDaiV4pZvOvVfYOPRBw8GC -dt6Ub2DVXZfDtd6r7gEG6TpqW6z6jZZrra5Q/Rd1hSxeXmMniM23bJL1MuMvTncV -jX71mQr1oVP/i8rTGRDgp9w/0txkWV5mKUMfnDmMLLWgfRGNOQqoQCBKGwd2GoiZ -dIDYoWBVwCS00xK29POtdIYgcqLH5FQwIPn81DXP3pCOiaZO3Sc7C+W8X0WmeGLS -y2baMTuahIMIAbDMRsPjbEHOp7wlZ/d4LO7MfNHUb09kpmKJ1Yyycdhg6okBIgQQ -AQIADAUCVLTUmQUDABJ1AAAKCRCXELibyletfPY6B/9sYWNf0hyNJ6h3s7afwm8Y -TZlsWqtYRYrMk2DYJHR9HkfrL8yN0IornIRnPUw4JKqCVz9u1IUgjyRs6kriwn2I -VekVQEcLejOvZvit3dv83kV3SKnJLo0GhaiMfG5u1YZDhXEv9F0ttG8wQEPyduIG -xIU92atvl0L3hnzL50KuhsAYefzQf2BOihuaYh02T6BO9QPrkD2TbsqmfeJ7CsoY -QIkidk47gBvSDy40tJAd3JNe/0QgL4WMIaPm8HMzvmbTVpsN4px1Rqwlnl4SAB6a -Klv53/t4MuFVeX6rmEf7BPgWRFaDJSEjYlWJffpDM7xWik2bHIZc8gM67Te+bhgC -iQEiBBABAgAMBQJUxqCrBQMAEnUAAAoJEJcQuJvKV6189oAIAIwWUtzMWZBF+fHy -n7eBKXSEeXe7yojBZa8X34K6qDMEbM2zBha8giHHCZjFbxZS/hh2j9YNCBZ/sP2+ -29w0GcO0JDXNyJPqsxDVnSZ0hWCNec30adxS9E2+HcAFc0K3CDiggfoB3aYtVdqZ -AXSeyqHIlpN0Edl9Smyvhhz+75T4ETugB0aQQ5Mf5REaEg/AOzXewDpAcnC+ymVk -Yqq9ZIZYFMYiZgFJbGaHF60BuR6bMD7aPF1/LJNETXpENvoWsiEpnzALp/GohWf9 -CIo4Fu4xCyg17r5NUsg9+6flmCOT3eR/7XLLzyiPu9WbWHXbgdpP6uBTZuEfdrK4 -5jefQ32JAhwEEgECAAYFAlL673MACgkQwICDq15+pAokfRAAhx890VG++EEp2v+s -EF43qEOh7RjVXlC7gaJv/9Tpwrh/gON0a74m2ymsxSKOIpi/s1uwc6l1mc/kuSEW -rHa5FABtYla7l4ORfcR1b4hRfALwjbiAXC8J+aTRlkaFPWj6OMzhgKcCT3nEzQxK -2bL8ZO/rDzagM7NDN88lQxNFHnPlecr4fba+ffk19jrqwOCphu0iusI8HxkwJiwH -ROf4LmalY3MGFSqfQIoaJu5zhDjpppalDmjO2l8tscV6+r3i5byZqN2dkQQ3XsOk -Do0k54v4BmMTwXp24oB7tV6DvWHqffijRNZpYYJTKeAsbbJJSICNEklWREJx4NcE -1tfXZQbjubOQH9AWjpkTub0A/Sv8hIaWFHRKAx97JeyNoAsYr8rrKxf8CI31Rjbk -PEbHu+1xWKrmff84bi2J/J1+zsNcjk/+cegNjwCQYOrnOx1RTN389AhjZ7hV8QNT -W5Czh1T9J1Re4AQupQbV5jeWV2jeZLZOM7J3Ef9YWtIQARO2BIFem5yHPnfObdP9 -fFpGkzp9S615AfK/XKDy7fsOG/PAZd+PLazZRp8bR04a/gnos8oq+ZbYcl+Cky3d -kFM8DvUaF810HPlAGWvCSeLNmARMBAuP2GbnuClUf6yPD2FAv0h/HvGe0mPjZ0UM -Ku8GSJ5GWTntqPJ+LxCRuXOdj42JAjkEEwECACMFAlOv4MgcGmh0dHA6Ly9vdHRv -ZHYuY29tL3NpZ3BvbGljeQAKCRAjutNRyRa2fX3VD/wJ0hJPbrhO9lGSRmzmLjN9 -OqLRqxVVuupdB0ZtVoEhB5JXOxjj49fu23bK/z/fWNR6ZuOpnaXeTwnaC0SEcv+T -K9yHEkcIWWs10h6Wmj+Ab4XwvmaMdzKb0GigUT5RcqvOaTlKtrzUOd83UQzG4a+G -uXdRD4RAAH1iAqs4mp8qVNQgvGE+s0t+6OIEXv3BihHKBSppyM3x885z7xfALLdD -IQZfYTX9xx/1eMtoNuMfvcZni+pdzhpchNy61wTb5Cf2+U9KosMOtSTdKkCFMyUB -ETOrmLXIbc3OZ7+UOa5whyaZ8VQQrnqWq+WftAOTiWPpxG/DsrY1+utzhaYjFA8Y -8l01I9JlKh9LRThQjGrYDx817NSUqStHZUUCy06QgBWCw/G//UkmytODmBSQZfqV -9iAdcKR4ni3tgWzD60WSsGodwslpkcbPZw1b6qjzSRc+HLJpJNFi9k7qwH4Cb+AH -NNdIhWwOszWhNKw/Fiw6LEfCrP/O51uWafueQQ0F7MMvxj9MKbHwoUOX5BFImqm1 -6SfrV9t4ad+8NZ095gwAJxQTUdwRiAV1UuXwZwhIc+DoYnWTQ/m+WVdtk/Wc3pie -0qkgcr4WvHiLBt3yjeGuyS1OXjBXs+hd7vjj5j6boVWWUt4eQVBKkoeW66akV10c -nya86EAdMdcR2/hvVVOvNIkBIgQQAQIADAUCUyX3XQUDABJ1AAAKCRCXELibylet -fIiICACrqngenwN7p5ii1tmJN4eyMk++Sz9GVqSvEOFBFRwfZdZXTd6d4Sr4doVm -Sa4M592BPpYZ3eU1xd0fvveBj8pYXmdJCOeTvt2lOjpjjh++9fTlPnrOhHacW1Na -OjsFcAyWTug37nXq1yegShlVCo2/bDl0z/Cj3kL0W/Ck/hzyzpVUPdrpFeEPrDC5 -so2P8t10e4bb8STA6hLkMYEyjVftDQs2N0ml/48CCH9MpuduNXHjSjXMS/GXFNC6 -8w1eRluVmCsNoITqH37Tkj6+BUhyo0IluxxvsCrOUuOwmvvTHwZ6C2EObTtUphPQ -/Yy/6Z2jPB0exvTt6MrnhUQm7WsAiQEiBBABAgAMBQJU2QImBQMAEnUAAAoJEJcQ -uJvKV618jUYH/iRhR3OvceP+/ebyypdmtVGnBXTcyWZVDaztva6gg1TBoHK8wzId -OLoEmD3wQZ9EBDuZywRGnHrgWlof/WMnhk4ZuheZeVFTgA5RO8E+IquIhcrkFBep -Fl8LN3bFxJ8L+s50cgFVG8e0BG6dfqf8IW4M82bs+A6fwrji8u3rbjuuhXvG9R7d -+fegF8nEazE29ykdg/pwDGsAefyGYWhNuRF/wZoNI9GiQUHmtsmRCUIHRuaGSZ5l -eYjFChoyHh/W/GG00JI8OdL/jOh8Do82HmEDSDYmtx9/2/T3ieNhcxyllcUHeahn -Uln6cHwEuFI0bzin+P0927cwxOEUtXDYYpiJASIEEAECAAwFAlTqOAcFAwASdQAA -CgkQlxC4m8pXrXz50QgAoxezroOZ3HL+tejY+gRr/5LsOQgc//CdlDCOVkldPNX3 -LMl/I8RQytSepgPF4pxc4g8l+WWvhNp+no6z/TiiRm4kMHm4Y2PcXQ2YX335f7wR -vcDZpUijYP6YbvDUwyg3IuKU+WlHO5ggOlDpoctTr6c6+z5gJsmy9ZxAkQyK7ZHB -K4tilZ4jdUarL2orpiSQEnlfgV+zjP6maZygb85MBoR/2HQ3vI9ot9XI9ueSvR77 -RGdo+6bsvf+RUhEdrC/SHyX04mWvaB/xzYHpxk7rUfAES8A+vrkupzJ4lxnWIKXp -cERo4l7pvfJRiAAvpLXSG2X2I0+oXwd3n6/OBG2ZBokBIgQQAQIADAUCVQ0a3AUD -ABJ1AAAKCRCXELibyletfOOlB/93RjbZ+aSwsRTKjtyFf19XJSzS0RIQL6U50KcT -3mrBNe7MLtt2S2exY1rbPCJUkkU2o82pxsrKg1D3sHIiP6dSkN5RiTTXWz5aFQs/ -fV0BihNvICYAkh/1BvL39T21a/cJqExvcG3JqBN6lb2NhbS6CwrRVop63wzVMDJ9 -VPUWHxkeTb+vm1Ucpc4+Lenuwq9rAliglxjJjghs7JxdReI4Mb1NEfbp/1mcKUEx -lLhZMhmUSDo7lcmQ4jpRPvuWOHpdM9d6ZMDGvNQrpzTVVlcpGLKzfwUibNfQS4+d -C4CweBhiQwjRHEoGYxpRqUhvtkuwloZfR2VoGdNDvmwbEfMSiQEcBBMBAgAGBQJU -rjxmAAoJEDzYwH8LXOFOWPwIAIlL4BdP6UUCqktIiVtFpHpcLdwJoElOOlxmpWen -tQH8yNVrHdHaHgNzG5KMQNK/9RUvVeOQZX4g0/a11/GvwcY5pKNVSD1Jev4GSthf -585s6DyEGV/ptBYLLDFtSZdwttN+psNjCW3nk8cWY3cV0xZ6rOq22nz42puv9Q51 -TnaxBZk5kjROOetXQapW02twdC4k9tXLzuxjZ5w4zul9j0DFvXXIENHRMZVQDODr -e9SkkzfvYyhqLMB5hFMZK7bnY6LvtWWM+aLZRa1B/j+thWwhM0JnCyKtqOXS8sGK -rfpj7et2f66fi+i2yNhk/UBBHGwNlhYkeZG+ovcWTAtRjdGJASIEEAECAAwFAlQX -PQ4FAwASdQAACgkQlxC4m8pXrXyvNQgAq8NazgIJu3cuGoIkel7tDAdPjFtQuznc -pARNRSwVyG2jdZHOrNf76AoZK0NIqcenuKVyLe/o/U9+P4ufbBPajqnhSqEiu4f0 -mk1TWoJxWC2jW+Ew2ZLNu0adtoAqBE+FDCieAObUKF++4cxiU4r5npilADucQ4Fy -UGLTA5RUQy4j9w0rQJ4xCAhzxBT/SiULlKQgEpj2XdOOiHSMS76fbIkw991L8ECN -/1DiNDAzbExE2BwS0WwPb3KUiT0ookS91Q2i6mWaJbCa4iJUvK3i2YTxPpFb4N2e -YmCCvKMLT4RC/2JQlUSjEozMImdYbFh1c0snzXmRatWK9THyyFuXx9HTt9O1ARAA -AQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAQBIAEgAAP/bAEMAEAsMDgwKEA4N -DhIREBMYKRsYFhYYMiQmHik7ND49OjQ5OEFJXlBBRVlGODlSb1NZYWRpamk/T3N7 -cmZ6XmdpZf/bAEMBERISGBUYMBsbMGVDOUNlZWVlZWVlZWVlZWVlZWVlZWVlZWVl -ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZf/AABEIASAA8AMBIgACEQEDEQH/ -xAAaAAACAwEBAAAAAAAAAAAAAAADBAABAgUG/8QAMBAAAgIBBAAGAQMFAAIDAAAA -AQIAAxEEEiExBRMiQVFhcRQygQYjQpGhFbEzUsH/xAAYAQEBAQEBAAAAAAAAAAAA -AAAAAQIDBP/EAB8RAQEBAQADAAIDAAAAAAAAAAABEQISITFBUQMiMv/aAAwDAQAC -EQMRAD8AyohAJSiEUTyuy1E2BIomgIRAJoCWBLAgQCXiSXAmJJckCSSSZgSSZZ1X -kkCZ8+v2YQCyTC2ofcTW4QLkkEuVEkxJJAkmJckDOJWJuTEKGRMkQuJREgERMkQp -EwRAERFr+RG2EXuEirUQiiZUTYEqNATYEoCaAgSalS4ElypCcQixMPYqD1HEV1Wq -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 -U2SsTgUAXL3GANeTM4N/XzzPXokCHAQQAQgABgUCUy3cVAAKCRBgtDFx2LpfQac8 -D/4kXKRRhtT8U+ViibJHXE8/MpGIqF373wbfs2y9S3D+kd/JOxC6ibnev2b+Wq29 -qdMk6BcyUaVzP0dxcnJj2CygYl2RD5dfIp8PzSilTHNfXGbJr9xPTcAjamXhUoJZ -p8/C1ODwf2y11EB8CLDVVZmqgtxUOJNfh6is3cfzbYF8O2CX9ai5x9UykV9g//// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -/////////////////////////////////////////////4kBHAQTAQIABgUCVK48 -ZgAKCRA82MB/C1zhTgoVB/9j6/khep6CXjyIoghxycm/4qhuCs2M8kM6G1B2W0sv -lkaeqha+A96lCS43YoaRWkto2k496rrHfoC5f/8Vb36nQS7hd59DYANbtr5KJzwf -yYsP/7+bkaiuC1E5SqmHjFiYYe7enQWdrcbsDfj420ScL9t2P0gO3vKJ5S8m7hkc -a4OdCmYJkdaYxJcHK7BC4vkJmbxfnmmyGJaEPP/oxNCeZiyL37Y62N4DqCQpDj5C -Ngk5w93+6H4oI8CIMzWEQZt9bZ2k9ipGobYhaLgVk5UMWkVJ8CuZESCgHLCuz7hG -gDoDmXTnz3zbp038QPusF9zb307DEsWq7XwJB33/ljm4uQENBE+Xo6MBCADB0197 -HdK48SqvipyPB49vlzfP6KHfcACZCg1JTqOt8KRJFwTP3PTi/GJuUvt4io1UVG29 -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 -IemulKZaOJ7LLNmKTjOZnj12+S76emwpNEduQajYMDXPtHnc1FpF2jo4tfOQBO5h -7z+UJzsGPO9O0pkYPxO3h/RS12R3uyvVE8Ej0w/8wiPFA29QgGf3zBRJ6GK2rAV+ -N/qhlMnE0agSy2+cmZzPDe33gtjLVZ7YmVp0YxbKa35DtvukhliGKH1cqkLKUt6Y -ytvzuckpEQPEtI/7KTYmCfaT2hlOo7uSfGn9FtV0xzlcVy0dMk24xKllyeyeennJ -jOuudVo5CQFRssnBDbkBDQRTG+drAQgAlo+QtN3XwYnuaRheTFnOLD7h9XBqZapO -DwqQbod7MXZqp4jEfGqfQKleL0Xs9Dh5I66Hhwr9GIuciVSQbSEcqBEznHJGM6n1 -ssG662b5a+W3WC11SUGpuZJOUgOEHVLgVqSe7td8w8bFD841kfPXRTYmtNgzki/K -RK7FFR1M5C5fBaQb7KGH/Cj/jUKKS9EwrMTW4jQxdcz881MFOGLM9hB4MCRXv+W4 -yUGqXurvFaEvYzVrYF1XNJFHheQ0Iw5GNUGxk0+F01kTBRNjJ+fnu/G/rIkHUYAc -E3VHqsd1l6NStMwn2o2a+po/xeS3CIdxsRBx4NYepBrZdRjUrRzNiQARAQABiQGE -BBgBCABuBQJTG+drXhSAAAAAABUAQGJsb2NraGFzaEBiaXRjb2luLm9yZzAwMDAw -MDAwMDAwMDAwMDBmNGY1YmEzMzQ3OTFhNDEwMjkxN2U0ZDNmMjJmNmFkN2YyYzRm -MTVkOTczMDdmZTICGyAFCQlmAYAACgkQf6sRQmfk+gTTNwf/XK8IGaPMASckFU1c -EHM8ruYAC4b1wzzAY2733geJJlIMd4pYVhPWcczwMozc2AWJrhHzMS6Ho/r+FmAQ -H+s0csYdhw0hL8w60bPXHSWu9wu6zlUJEY8G4pKjisEokYY7Aje/oEGfg8KJLHXA -hYrPauW++O/NFCZ6ZNimFf40JRSjSUGzTKuBYW0/25dfV017De1XZvD+Qd198CfA -9ojvBP2Rn7PYQkCMYA7xsViNz+tD0eC+BRdyO0cffCzoOOHHXy/1KSOnCry+JReA -jnpviOsUyfY2bqGsmOpxyo5VfZ3OoHOOV7nucBEmQojuhl/xvU+Lc2airaR6UIAm -jWDWrrkBjQRTG+GcAQwAk8T4liMdVQMjh6WFsmY38lEGu5FxirVSrMKjVQAq52XO -l0I2jc6zTdqzyinW0sEswcQhmkTANzCspaU2kIBr/QVbdtPxPakwysV3RsqHPlAI -rVQIdBU7ENnE9uzRzJtZfc5m+buknQ3MBjMdXlAceO4w7i+uhu5zXW4tSVwgKzhU -uy1IexvK7ni4EZHzsOAarFbZpHozUqNZol7ALJrWkpQWqjuJZEIN0vefgSf3AV/r -vGFlbI/PwEWDZlYlwDV9scuHRqqu0S1LArcLDmf78vnnclZYVUNl2kaVgRKmu2ra -CWCSctmkyC5rqM9Xj+6B0ZVxhXReqfCnRn06Zwf7WwJuMWMfbAfZjDbksIMgKWpT -/8UrH2RrI/6b4w5hXa7/C8zp8H109f7xcRgdLyj748P0bsrrVSfUWxMP+XRRGPY0 -4spkhNUVFlYc2BroIRXS+REKuI5WfWnUeSNWfAqbexaHRSgQQIydN2qp2sSxAe6Q -FE3aXZyCHC4DMqIlUml7ABEBAAGJA7IEGAEIAG4FAlMb4ZxeFIAAAAAAFQBAYmxv -Y2toYXNoQGJpdGNvaW4ub3JnMDAwMDAwMDAwMDAwMDAwMGY0ZjViYTMzNDc5MWE0 -MTAyOTE3ZTRkM2YyMmY2YWQ3ZjJjNGYxNWQ5NzMwN2ZlMgIbAgUJCWYBgAI4CRB/ -qxFCZ+T6BMFsIAQZAQgAlQUCUxvhnF4UgAAAAAAVAEBibG9ja2hhc2hAYml0Y29p -bi5vcmcwMDAwMDAwMDAwMDAwMDAwZjRmNWJhMzM0NzkxYTQxMDI5MTdlNGQzZjIy -ZjZhZDdmMmM0ZjE1ZDk3MzA3ZmUyLxSAAAAAABUAEXBrYS1hZGRyZXNzQGdudXBn -Lm9yZ3BldGVAcGV0ZXJ0b2Qub3JnAAoJEGJeboN5AaHKDGcL/R3/aZoKC3OgtAkb -o2g/ykbMt8pIko2cofAB/3zwl1p2qvwO3QV/vTVt6y4uEPEHItaFLiKTSH2KpTVl -YflOh4M2/LXwXQmOiixpyDY3w42R6AZqY4g6q2SLDpNQLWaxVOerPgvDpSkIbcwH -j8Fvai3Mrxtr2J+Jq3KW6TQnW9m5G/j4SqmQ2sRfkl6EEHiGcZp7pbKkE+qYGsmV -HEirfCjlf03N3c7zcs6Nic9AEq2ghcnLwRAqmyRU59wOvIHlbQtnpJ9TI2zaOp2n -U+4wOVkdolzN6TfPPLwATXsUFlQRS0ygarQXF4ifZ55MGZ56pc3GOR6fEH0FaUbr -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 -=BHZ+ ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/prab-key.pgp b/contrib/gitian-keys/prab-key.pgp deleted file mode 100644 index 0870c88b9b..0000000000 --- a/contrib/gitian-keys/prab-key.pgp +++ /dev/null @@ -1,81 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 - -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 -RFdDYRHByRDDL1I= -=dOwX ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/sipa-key.pgp b/contrib/gitian-keys/sipa-key.pgp Binary files differdeleted file mode 100644 index a1930ddee9..0000000000 --- a/contrib/gitian-keys/sipa-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/sjors-key.pgp b/contrib/gitian-keys/sjors-key.pgp deleted file mode 100644 index 2b5acc82aa..0000000000 --- a/contrib/gitian-keys/sjors-key.pgp +++ /dev/null @@ -1,76 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mQINBFWSwMoBEADG31O8+ex+xpgzVKQgF4iVRE5uBPT0+GM6FnwqIIhXVKiBLQh8 -YDhhgk6joh+vsLrFzKZ9kXwoiHN8y/AiNCQ0xjAUdpznD5xvHAaGIAlT/sodRNT+ -869WgT9G1uiVp0P4ucEeilmhCn9o51LqkS3roXkj0ec52b1pslUl2WKdu1ZD+Bj4 -3/oVZm7mmjkDwl0RHJQmqlK0bunq0jlVlgH5sdQfmLbCZaq3LhVPf73zt5qHH+J6 -ZbU7A4cqm2eN5SyH+Nno+cq3+vXmvVI+x/jPe/dPDCXaGWf5fWI/Lbk/mMP7JAl1 -6X44CN+hZHUnNuzeZt2/ROWZ0s0JJcjQkSe9noUQedjBAHX82s886vsFzOHvDtul -EuV/XAjUlkhMbhZkZaIq9ucqHmUBI4+OcFEIbbKc9TrKtJe+CYuWTNlomVk/iFr8 -zSm/S64NiqKi/BeQGgcsDZIaJDYfDP83esOOaaxFswHnJNtHnU1PwntrJtXft0dK -ydtlQZ6r96SYxLDTeGfC2SNk0zbnKAGvjj04vzQeN+JSRZ75tNKmgdbJdNL8wvPh -879TpCwMhNDvSRG+YqCe6whaJV76a+Doxg48HCJYaj6bnRn41/QGJEyL31I8l/7S -YsLLmAEbqwG7erYi7WZS3cRrGJI8RwohGMZf7yraqoaOgMKmtE/Sq0tLtwARAQAB -tCNTam9ycyBQcm92b29zdCA8c2pvcnNAc3Byb3Zvb3N0Lm5sPokCQAQTAQoAKgIb -AwUJB4YfgAULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAUCWWXcoAIZAQAKCRBX/5vb -zDAQCeYJD/47XDMfEMg4g4spo7k92XsNkvjlAhWvvxd+kxow/V8c64WQXody32FZ -HRSmK8dVjf9mIJMKkX4lpKpim7cQxsdTcorcdu+yk4TK+Wah61vsMhbSSllfHs1U -+q8jYMGnXTD+CY0aeTMrTfJcR2yN98jmNSWIL1qWmJ51RSTL6BQKb6eYtR7pWRkW -uMR6oFC09Db4fiKa4zhH81+/t0g+6pMY391gSluaS+OfNqGORCo+/IdG5IDzh5Vp -f19qXjd5oMsZQf6/P4b4XUktgl8RVRcNzdYGoXpcd8LpeHtEOh5I93ODmCwqd67b -YDlhDNN7iGhPndPEF6P4CNO/rXLPCZyMhRyt1dflu0KPCr+0AgR31cdhH/p7eCyj -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 -N5Ug -=80Es ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/tcatm-key.pgp b/contrib/gitian-keys/tcatm-key.pgp Binary files differdeleted file mode 100644 index baaec76b8c..0000000000 --- a/contrib/gitian-keys/tcatm-key.pgp +++ /dev/null diff --git a/contrib/gitian-keys/willyko-key.pgp b/contrib/gitian-keys/willyko-key.pgp deleted file mode 100644 index a3b58ad994..0000000000 --- a/contrib/gitian-keys/willyko-key.pgp +++ /dev/null @@ -1,85 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -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 -=PVBi ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-keys/wtogami-key.pgp b/contrib/gitian-keys/wtogami-key.pgp deleted file mode 100644 index e0f6c4c5fd..0000000000 --- a/contrib/gitian-keys/wtogami-key.pgp +++ /dev/null @@ -1,131 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.13 (GNU/Linux) - -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 -=icdI ------END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 28068a7523..2790ef4acd 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -124,7 +124,7 @@ def main(): g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n') g.write(' *\n') g.write(' * Each line contains a 16-byte IPv6 address and a port.\n') - g.write(' * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.\n') + g.write(' * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.\n') g.write(' */\n') with open(os.path.join(indir,'nodes_main.txt'),'r') as f: process_nodes(g, f, 'pnSeed6_main', 8333) diff --git a/doc/build-osx.md b/doc/build-osx.md index 3e243933c8..2b84c7cc2c 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -90,23 +90,6 @@ Other commands: ./src/bitcoin-cli --help # Outputs a list of command-line options. ./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. -Using Qt Creator as IDE ------------------------- -You can use Qt Creator as an IDE, for bitcoin development. -Download and install the community edition of [Qt Creator](https://www.qt.io/download/). -Uncheck everything except Qt Creator during the installation process. - -1. Make sure you installed everything through Homebrew mentioned above -2. Do a proper ./configure --enable-debug -3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project -4. Enter "bitcoin-qt" as project name, enter src/qt as location -5. Leave the file selection as it is -6. Confirm the "summary page" -7. In the "Projects" tab select "Manage Kits..." -8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler -9. Select LLDB as debugger (you might need to set the path to your installation) -10. Start debugging with Qt Creator - Notes ----- diff --git a/doc/build-windows.md b/doc/build-windows.md index 9e0e66e522..8d4afdc817 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -102,11 +102,9 @@ Note that for WSL the Bitcoin Core source path MUST be somewhere in the default example /usr/src/bitcoin, AND not under /mnt/d/. If this is not the case the dependency autoconf scripts will fail. This means you cannot use a directory that located directly on the host Windows file system to perform the build. -The next three steps are an example of how to acquire the source in an appropriate way. +Acquire the source in the usual way: - cd /usr/src - sudo git clone https://github.com/bitcoin/bitcoin.git - sudo chmod -R a+rw bitcoin + git clone https://github.com/bitcoin/bitcoin.git Once the source code is ready the build steps are below. @@ -132,11 +130,9 @@ Note that for WSL the Bitcoin Core source path MUST be somewhere in the default example /usr/src/bitcoin, AND not under /mnt/d/. If this is not the case the dependency autoconf scripts will fail. This means you cannot use a directory that located directly on the host Windows file system to perform the build. -The next three steps are an example of how to acquire the source in an appropriate way. +Acquire the source in the usual way: - cd /usr/src - sudo git clone https://github.com/bitcoin/bitcoin.git - sudo chmod -R a+rw bitcoin + git clone https://github.com/bitcoin/bitcoin.git Then build using: diff --git a/doc/release-process.md b/doc/release-process.md index 0f8dadfd1a..430a5a7ed3 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -137,10 +137,7 @@ Build output expected: ### Verify other gitian builders signatures to your own. (Optional) -Add other gitian builders keys to your gpg keyring, and/or refresh keys. - - gpg --import bitcoin/contrib/gitian-keys/*.pgp - gpg --refresh-keys +Add other gitian builders keys to your gpg keyring, and/or refresh keys: See `../bitcoin/contrib/gitian-keys/README.md`. Verify the signatures diff --git a/src/addrman.h b/src/addrman.h index 172cb5f45b..38da754afb 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -59,7 +59,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*(CAddress*)this); + READWRITE(*static_cast<CAddress*>(this)); READWRITE(source); READWRITE(nLastSuccess); READWRITE(nAttempts); diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 1214b548cf..a60d3b3b6d 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -35,7 +35,7 @@ std::string HelpMessageCli() std::string strUsage; strUsage += HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); - strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); + strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)"), BITCOIN_CONF_FILENAME)); strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory")); strUsage += HelpMessageOpt("-getinfo", _("Get general information from the remote server. Note that unlike server-side RPC calls, the results of -getinfo is the result of multiple non-atomic requests. Some entries in the result may represent results from different states (e.g. wallet balance may be as of a different block from the chain state reported)")); AppendParamsHelpMessages(strUsage); @@ -198,6 +198,7 @@ static void http_error_cb(enum evhttp_request_error err, void *ctx) class BaseRequestHandler { public: + virtual ~BaseRequestHandler() {} virtual UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) = 0; virtual UniValue ProcessReply(const UniValue &batch_in) = 0; }; diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 89dd8549b9..a04258fd40 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -24,44 +24,6 @@ void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp) strUsage += HelpMessageOpt("-testnet", _("Use the test chain")); } -/** - * Main network - */ -class CBaseMainParams : public CBaseChainParams -{ -public: - CBaseMainParams() - { - nRPCPort = 8332; - } -}; - -/** - * Testnet (v3) - */ -class CBaseTestNetParams : public CBaseChainParams -{ -public: - CBaseTestNetParams() - { - nRPCPort = 18332; - strDataDir = "testnet3"; - } -}; - -/* - * Regression test - */ -class CBaseRegTestParams : public CBaseChainParams -{ -public: - CBaseRegTestParams() - { - nRPCPort = 18443; - strDataDir = "regtest"; - } -}; - static std::unique_ptr<CBaseChainParams> globalChainBaseParams; const CBaseChainParams& BaseParams() @@ -73,11 +35,11 @@ const CBaseChainParams& BaseParams() std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain) { if (chain == CBaseChainParams::MAIN) - return std::unique_ptr<CBaseChainParams>(new CBaseMainParams()); + return MakeUnique<CBaseChainParams>("", 8332); else if (chain == CBaseChainParams::TESTNET) - return std::unique_ptr<CBaseChainParams>(new CBaseTestNetParams()); + return MakeUnique<CBaseChainParams>("testnet3", 18332); else if (chain == CBaseChainParams::REGTEST) - return std::unique_ptr<CBaseChainParams>(new CBaseRegTestParams()); + return MakeUnique<CBaseChainParams>("regtest", 18443); else throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index b4d2bb4f08..2cb860380e 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -24,9 +24,10 @@ public: const std::string& DataDir() const { return strDataDir; } int RPCPort() const { return nRPCPort; } -protected: - CBaseChainParams() {} + CBaseChainParams() = delete; + CBaseChainParams(const std::string& data_dir, int rpc_port) : nRPCPort(rpc_port), strDataDir(data_dir) {} +private: int nRPCPort; std::string strDataDir; }; diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 2b102c464f..6e2b3c34a2 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -5,7 +5,7 @@ * AUTOGENERATED by contrib/seeds/generate-seeds.py * * Each line contains a 16-byte IPv6 address and a port. - * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. + * IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x13,0x05,0x7f}, 8333}, diff --git a/src/core_read.cpp b/src/core_read.cpp index 4ccb967087..6a8308f869 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -33,14 +33,14 @@ CScript ParseScript(const std::string& s) if (op < OP_NOP && op != OP_RESERVED) continue; - const char* name = GetOpName((opcodetype)op); + const char* name = GetOpName(static_cast<opcodetype>(op)); if (strcmp(name, "OP_UNKNOWN") == 0) continue; std::string strName(name); - mapOpNames[strName] = (opcodetype)op; + mapOpNames[strName] = static_cast<opcodetype>(op); // Convenience: OP_ADD and just ADD are both recognized: boost::algorithm::replace_first(strName, "OP_", ""); - mapOpNames[strName] = (opcodetype)op; + mapOpNames[strName] = static_cast<opcodetype>(op); } } diff --git a/src/httpserver.cpp b/src/httpserver.cpp index a022d220e0..36db530c82 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -73,34 +73,13 @@ private: std::deque<std::unique_ptr<WorkItem>> queue; bool running; size_t maxDepth; - int numThreads; - - /** RAII object to keep track of number of running worker threads */ - class ThreadCounter - { - public: - WorkQueue &wq; - explicit ThreadCounter(WorkQueue &w): wq(w) - { - std::lock_guard<std::mutex> lock(wq.cs); - wq.numThreads += 1; - } - ~ThreadCounter() - { - std::lock_guard<std::mutex> lock(wq.cs); - wq.numThreads -= 1; - wq.cond.notify_all(); - } - }; public: explicit WorkQueue(size_t _maxDepth) : running(true), - maxDepth(_maxDepth), - numThreads(0) + maxDepth(_maxDepth) { } - /** Precondition: worker threads have all stopped - * (call WaitExit) + /** Precondition: worker threads have all stopped (they have been joined). */ ~WorkQueue() { @@ -119,7 +98,6 @@ public: /** Thread function */ void Run() { - ThreadCounter count(*this); while (true) { std::unique_ptr<WorkItem> i; { @@ -141,13 +119,6 @@ public: running = false; cond.notify_all(); } - /** Wait for worker threads to exit */ - void WaitExit() - { - std::unique_lock<std::mutex> lock(cs); - while (numThreads > 0) - cond.wait(lock); - } }; struct HTTPPathHandler @@ -449,6 +420,7 @@ bool UpdateHTTPServerLogging(bool enable) { std::thread threadHTTP; std::future<bool> threadResult; +static std::vector<std::thread> g_thread_http_workers; bool StartHTTPServer() { @@ -460,8 +432,7 @@ bool StartHTTPServer() threadHTTP = std::thread(std::move(task), eventBase, eventHTTP); for (int i = 0; i < rpcThreads; i++) { - std::thread rpc_worker(HTTPWorkQueueRun, workQueue); - rpc_worker.detach(); + g_thread_http_workers.emplace_back(HTTPWorkQueueRun, workQueue); } return true; } @@ -486,7 +457,10 @@ void StopHTTPServer() LogPrint(BCLog::HTTP, "Stopping HTTP server\n"); if (workQueue) { LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); - workQueue->WaitExit(); + for (auto& thread: g_thread_http_workers) { + thread.join(); + } + g_thread_http_workers.clear(); delete workQueue; workQueue = nullptr; } @@ -525,7 +499,7 @@ struct event_base* EventBase() static void httpevent_callback_fn(evutil_socket_t, short, void* data) { // Static handler: simply call inner handler - HTTPEvent *self = ((HTTPEvent*)data); + HTTPEvent *self = static_cast<HTTPEvent*>(data); self->handler(); if (self->deleteWhenTriggered) delete self; diff --git a/src/init.cpp b/src/init.cpp index 5e81e05f49..b28baba779 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -165,6 +165,7 @@ void Interrupt() InterruptRPC(); InterruptREST(); InterruptTorControl(); + InterruptMapPort(); if (g_connman) g_connman->Interrupt(); } @@ -191,7 +192,7 @@ void Shutdown() #ifdef ENABLE_WALLET FlushWallets(); #endif - MapPort(false); + StopMapPort(); // Because these depend on each-other, we make sure that neither can be // using the other before destroying them. @@ -213,7 +214,7 @@ void Shutdown() if (fFeeEstimatesInitialized) { - ::feeEstimator.FlushUnconfirmed(::mempool); + ::feeEstimator.FlushUnconfirmed(); fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME; CAutoFile est_fileout(fsbridge::fopen(est_path, "wb"), SER_DISK, CLIENT_VERSION); if (!est_fileout.IsNull()) @@ -336,7 +337,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-blockreconstructionextratxn=<n>", strprintf(_("Extra transactions to keep in memory for compact block reconstructions (default: %u)"), DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN)); if (showDebug) strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY)); - strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); + strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)"), BITCOIN_CONF_FILENAME)); if (mode == HMM_BITCOIND) { #if HAVE_DECL_DAEMON @@ -348,7 +349,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize)); } strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); - strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)"), DEFAULT_DEBUGLOGFILE)); + strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf(_("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)"), DEFAULT_DEBUGLOGFILE)); if (showDebug) strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER)); strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup")); @@ -362,7 +363,7 @@ std::string HelpMessage(HelpMessageMode mode) -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); strUsage += HelpMessageOpt("-persistmempool", strprintf(_("Whether to save the mempool on shutdown and load on restart (default: %u)"), DEFAULT_PERSIST_MEMPOOL)); #ifndef WIN32 - strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), BITCOIN_PID_FILENAME)); + strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)"), BITCOIN_PID_FILENAME)); #endif strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " @@ -500,7 +501,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcauth=<userpw>", _("Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcbind=<addr>[:port]", _("Bind to given address to listen for JSON-RPC connections. This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)")); - strUsage += HelpMessageOpt("-rpccookiefile=<loc>", _("Location of the auth cookie (default: data dir)")); + strUsage += HelpMessageOpt("-rpccookiefile=<loc>", _("Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)")); strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort())); strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); @@ -545,7 +546,8 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex std::string strCmd = gArgs.GetArg("-blocknotify", ""); if (!strCmd.empty()) { boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free } } @@ -1425,6 +1427,9 @@ bool AppInitMain() pcoinsTip.reset(); pcoinsdbview.reset(); pcoinscatcher.reset(); + // new CBlockTreeDB tries to delete the existing file, which + // fails if it's still open from the previous loop. Close it first: + pblocktree.reset(); pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset)); if (fReset) { @@ -1645,12 +1650,19 @@ bool AppInitMain() // Wait for genesis block to be processed { WaitableLock lock(cs_GenesisWait); - while (!fHaveGenesis) { - condvar_GenesisWait.wait(lock); + // We previously could hang here if StartShutdown() is called prior to + // ThreadImport getting started, so instead we just wait on a timer to + // check ShutdownRequested() regularly. + while (!fHaveGenesis && !ShutdownRequested()) { + condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500)); } uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait); } + if (ShutdownRequested()) { + return false; + } + // ********************************************************* Step 11: start node int chain_active_height; @@ -1664,12 +1676,14 @@ bool AppInitMain() LogPrintf("nBestHeight = %d\n", chain_active_height); if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) - StartTorControl(threadGroup, scheduler); + StartTorControl(); - Discover(threadGroup); + Discover(); // Map ports with UPnP - MapPort(gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)); + if (gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)) { + StartMapPort(); + } CConnman::Options connOptions; connOptions.nLocalServices = nLocalServices; diff --git a/src/net.cpp b/src/net.cpp index 5f4c0eecab..201914685c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -297,7 +297,7 @@ CNode* CConnman::FindNode(const CNetAddr& ip) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if ((CNetAddr)pnode->addr == ip) { + if (static_cast<CNetAddr>(pnode->addr) == ip) { return pnode; } } @@ -308,7 +308,7 @@ CNode* CConnman::FindNode(const CSubNet& subNet) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if (subNet.Match((CNetAddr)pnode->addr)) { + if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) { return pnode; } } @@ -330,7 +330,7 @@ CNode* CConnman::FindNode(const CService& addr) { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if ((CService)pnode->addr == addr) { + if (static_cast<CService>(pnode->addr) == addr) { return pnode; } } @@ -370,7 +370,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo return nullptr; // Look for an existing connection - CNode* pnode = FindNode((CService)addrConnect); + CNode* pnode = FindNode(static_cast<CService>(addrConnect)); if (pnode) { LogPrintf("Failed to open new connection, already connected\n"); @@ -398,7 +398,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo // Also store the name we used to connect in that CNode, so that future FindNode() calls to that // name catch this early. LOCK(cs_vNodes); - CNode* pnode = FindNode((CService)addrConnect); + CNode* pnode = FindNode(static_cast<CService>(addrConnect)); if (pnode) { pnode->MaybeSetAddrName(std::string(pszDest)); @@ -559,7 +559,7 @@ void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t ba { LOCK(cs_vNodes); for (CNode* pnode : vNodes) { - if (subNet.Match((CNetAddr)pnode->addr)) + if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) pnode->fDisconnect = true; } } @@ -1431,7 +1431,7 @@ void CConnman::ThreadSocketHandler() } else if (!pnode->fSuccessfullyConnected) { - LogPrintf("version handshake timeout from %d\n", pnode->GetId()); + LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId()); pnode->fDisconnect = true; } } @@ -1459,6 +1459,8 @@ void CConnman::WakeMessageHandler() #ifdef USE_UPNP +static CThreadInterrupt g_upnp_interrupt; +static std::thread g_upnp_thread; void ThreadMapPort() { std::string port = strprintf("%u", GetListenPort()); @@ -1509,35 +1511,29 @@ void ThreadMapPort() std::string strDesc = "Bitcoin " + FormatFullVersion(); - try { - while (true) { + do { #ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); #else - /* miniupnpc 1.6 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); #endif - if(r!=UPNPCOMMAND_SUCCESS) - LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); - else - LogPrintf("UPnP Port Mapping successful.\n"); - - MilliSleep(20*60*1000); // Refresh every 20 minutes - } - } - catch (const boost::thread_interrupted&) - { - r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); - LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); - freeUPNPDevlist(devlist); devlist = nullptr; - FreeUPNPUrls(&urls); - throw; + if(r!=UPNPCOMMAND_SUCCESS) + LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port, port, lanaddr, r, strupnperror(r)); + else + LogPrintf("UPnP Port Mapping successful.\n"); } + while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); + + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); + LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); + freeUPNPDevlist(devlist); devlist = nullptr; + FreeUPNPUrls(&urls); } else { LogPrintf("No valid UPnP IGDs found\n"); freeUPNPDevlist(devlist); devlist = nullptr; @@ -1546,27 +1542,39 @@ void ThreadMapPort() } } -void MapPort(bool fUseUPnP) +void StartMapPort() { - static std::unique_ptr<boost::thread> upnp_thread; + if (!g_upnp_thread.joinable()) { + assert(!g_upnp_interrupt); + g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort))); + } +} - if (fUseUPnP) - { - if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - } - upnp_thread.reset(new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort))); +void InterruptMapPort() +{ + if(g_upnp_thread.joinable()) { + g_upnp_interrupt(); } - else if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - upnp_thread.reset(); +} + +void StopMapPort() +{ + if(g_upnp_thread.joinable()) { + g_upnp_thread.join(); + g_upnp_interrupt.reset(); } } #else -void MapPort(bool) +void StartMapPort() +{ + // Intentionally left blank. +} +void InterruptMapPort() +{ + // Intentionally left blank. +} +void StopMapPort() { // Intentionally left blank. } @@ -1965,7 +1973,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai } if (!pszDest) { if (IsLocal(addrConnect) || - FindNode((CNetAddr)addrConnect) || IsBanned(addrConnect) || + FindNode(static_cast<CNetAddr>(addrConnect)) || IsBanned(addrConnect) || FindNode(addrConnect.ToStringIPPort())) return; } else if (FindNode(std::string(pszDest))) @@ -2121,7 +2129,7 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b return true; } -void Discover(boost::thread_group& threadGroup) +void Discover() { if (!fDiscover) return; @@ -37,10 +37,6 @@ class CScheduler; class CNode; -namespace boost { - class thread_group; -} // namespace boost - /** Time between pings automatically sent out for latency probing and keepalive (in seconds). */ static const int PING_INTERVAL = 2 * 60; /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ @@ -441,8 +437,10 @@ private: friend struct CConnmanTest; }; extern std::unique_ptr<CConnman> g_connman; -void Discover(boost::thread_group& threadGroup); -void MapPort(bool fUseUPnP); +void Discover(); +void StartMapPort(); +void InterruptMapPort(); +void StopMapPort(); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 3cf96be61a..bf9307727a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -750,7 +750,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) } // Requires cs_main. -void Misbehaving(NodeId pnode, int howmuch) +void Misbehaving(NodeId pnode, int howmuch, const std::string& message) { if (howmuch == 0) return; @@ -761,12 +761,13 @@ void Misbehaving(NodeId pnode, int howmuch) state->nMisbehavior += howmuch; int banscore = gArgs.GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD); + std::string message_prefixed = message.empty() ? "" : (": " + message); if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) { - LogPrintf("%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior); + LogPrint(BCLog::NET, "%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed); state->fShouldBan = true; } else - LogPrintf("%s: %s peer=%d (%d -> %d)\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior); + LogPrint(BCLog::NET, "%s: %s peer=%d (%d -> %d)%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed); } @@ -1225,10 +1226,10 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } // release cs_main - if (it != pfrom->vRecvGetData.end()) { + if (it != pfrom->vRecvGetData.end() && !pfrom->fPauseSend) { const CInv &inv = *it; - it++; if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK || inv.type == MSG_WITNESS_BLOCK) { + it++; ProcessGetBlockData(pfrom, consensusParams, inv, connman, interruptMsgProc); } } @@ -1260,8 +1261,7 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac for (size_t i = 0; i < req.indexes.size(); i++) { if (req.indexes[i] >= block.vtx.size()) { LOCK(cs_main); - Misbehaving(pfrom->GetId(), 100); - LogPrintf("Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->GetId()); + Misbehaving(pfrom->GetId(), 100, strprintf("Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->GetId())); return; } resp.txn[i] = block.vtx[req.indexes[i]]; @@ -1318,8 +1318,8 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve uint256 hashLastBlock; for (const CBlockHeader& header : headers) { if (!hashLastBlock.IsNull() && header.hashPrevBlock != hashLastBlock) { - Misbehaving(pfrom->GetId(), 20); - return error("non-continuous headers sequence"); + Misbehaving(pfrom->GetId(), 20, "non-continuous headers sequence"); + return false; } hashLastBlock = header.GetHash(); } @@ -1338,7 +1338,9 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve if (state.IsInvalid(nDoS)) { LOCK(cs_main); if (nDoS > 0) { - Misbehaving(pfrom->GetId(), nDoS); + Misbehaving(pfrom->GetId(), nDoS, "invalid header received"); + } else { + LogPrint(BCLog::NET, "peer=%d: invalid header received\n", pfrom->GetId()); } if (punish_duplicate_invalid && mapBlockIndex.find(first_invalid_header.GetHash()) != mapBlockIndex.end()) { // Goal: don't allow outbound peers to use up our outbound @@ -1374,7 +1376,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve // etc), and not just the duplicate-invalid case. pfrom->fDisconnect = true; } - return error("invalid header received"); + return false; } } @@ -1783,8 +1785,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if (vAddr.size() > 1000) { LOCK(cs_main); - Misbehaving(pfrom->GetId(), 20); - return error("message addr size() = %u", vAddr.size()); + Misbehaving(pfrom->GetId(), 20, strprintf("message addr size() = %u", vAddr.size())); + return false; } // Store the new addresses @@ -1859,8 +1861,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if (vInv.size() > MAX_INV_SZ) { LOCK(cs_main); - Misbehaving(pfrom->GetId(), 20); - return error("message inv size() = %u", vInv.size()); + Misbehaving(pfrom->GetId(), 20, strprintf("message inv size() = %u", vInv.size())); + return false; } bool fBlocksOnly = !fRelayTxes; @@ -1920,8 +1922,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if (vInv.size() > MAX_INV_SZ) { LOCK(cs_main); - Misbehaving(pfrom->GetId(), 20); - return error("message getdata size() = %u", vInv.size()); + Misbehaving(pfrom->GetId(), 20, strprintf("message getdata size() = %u", vInv.size())); + return false; } LogPrint(BCLog::NET, "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->GetId()); @@ -2323,9 +2325,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr int nDoS; if (state.IsInvalid(nDoS)) { if (nDoS > 0) { - LogPrintf("Peer %d sent us invalid header via cmpctblock\n", pfrom->GetId()); LOCK(cs_main); - Misbehaving(pfrom->GetId(), nDoS); + Misbehaving(pfrom->GetId(), nDoS, strprintf("Peer %d sent us invalid header via cmpctblock\n", pfrom->GetId())); } else { LogPrint(BCLog::NET, "Peer %d sent us invalid header via cmpctblock\n", pfrom->GetId()); } @@ -2411,8 +2412,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr ReadStatus status = partialBlock.InitData(cmpctblock, vExtraTxnForCompact); if (status == READ_STATUS_INVALID) { MarkBlockAsReceived(pindex->GetBlockHash()); // Reset in-flight state in case of whitelist - Misbehaving(pfrom->GetId(), 100); - LogPrintf("Peer %d sent us invalid compact block\n", pfrom->GetId()); + Misbehaving(pfrom->GetId(), 100, strprintf("Peer %d sent us invalid compact block\n", pfrom->GetId())); return true; } else if (status == READ_STATUS_FAILED) { // Duplicate txindexes, the block is now in-flight, so just request it @@ -2539,8 +2539,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr ReadStatus status = partialBlock.FillBlock(*pblock, resp.txn); if (status == READ_STATUS_INVALID) { MarkBlockAsReceived(resp.blockhash); // Reset in-flight state in case of whitelist - Misbehaving(pfrom->GetId(), 100); - LogPrintf("Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom->GetId()); + Misbehaving(pfrom->GetId(), 100, strprintf("Peer %d sent us invalid compact block/non-matching block transactions\n", pfrom->GetId())); return true; } else if (status == READ_STATUS_FAILED) { // Might have collided, fall back to getdata now :( @@ -2602,8 +2601,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr unsigned int nCount = ReadCompactSize(vRecv); if (nCount > MAX_HEADERS_RESULTS) { LOCK(cs_main); - Misbehaving(pfrom->GetId(), 20); - return error("headers message size = %u", nCount); + Misbehaving(pfrom->GetId(), 20, strprintf("headers message size = %u", nCount)); + return false; } headers.resize(nCount); for (unsigned int n = 0; n < nCount; n++) { @@ -2864,7 +2863,7 @@ static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman* connman) CNodeState &state = *State(pnode->GetId()); for (const CBlockReject& reject : state.rejects) { - connman->PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, (std::string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock)); + connman->PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, std::string(NetMsgType::BLOCK), reject.chRejectCode, reject.strRejectReason, reject.hashBlock)); } state.rejects.clear(); diff --git a/src/net_processing.h b/src/net_processing.h index 4f2b8935f4..b534ef01c3 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -79,6 +79,6 @@ struct CNodeStateStats { /** Get statistics from node state */ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); /** Increase a node's misbehavior score. */ -void Misbehaving(NodeId nodeid, int howmuch); +void Misbehaving(NodeId nodeid, int howmuch, const std::string& message=""); #endif // BITCOIN_NET_PROCESSING_H diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 81f72879f4..4f231d73c8 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -522,17 +522,17 @@ unsigned short CService::GetPort() const bool operator==(const CService& a, const CService& b) { - return (CNetAddr)a == (CNetAddr)b && a.port == b.port; + return static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) && a.port == b.port; } bool operator!=(const CService& a, const CService& b) { - return (CNetAddr)a != (CNetAddr)b || a.port != b.port; + return static_cast<CNetAddr>(a) != static_cast<CNetAddr>(b) || a.port != b.port; } bool operator<(const CService& a, const CService& b) { - return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port); + return static_cast<CNetAddr>(a) < static_cast<CNetAddr>(b) || (static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) && a.port < b.port); } bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const diff --git a/src/netbase.cpp b/src/netbase.cpp index d51277c495..5be3fe34f8 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -572,7 +572,7 @@ bool HaveNameProxy() { bool IsProxy(const CNetAddr &addr) { LOCK(cs_proxyInfos); for (int i = 0; i < NET_MAX; i++) { - if (addr == (CNetAddr)proxyInfo[i].proxy) + if (addr == static_cast<CNetAddr>(proxyInfo[i].proxy)) return true; } return false; diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 9142f3706d..79b450e3e6 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -981,16 +981,17 @@ bool CBlockPolicyEstimator::Read(CAutoFile& filein) return true; } -void CBlockPolicyEstimator::FlushUnconfirmed(CTxMemPool& pool) { +void CBlockPolicyEstimator::FlushUnconfirmed() { int64_t startclear = GetTimeMicros(); - std::vector<uint256> txids; - pool.queryHashes(txids); LOCK(cs_feeEstimator); - for (auto& txid : txids) { - removeTx(txid, false); + size_t num_entries = mapMemPoolTxs.size(); + // Remove every entry in mapMemPoolTxs + while (!mapMemPoolTxs.empty()) { + auto mi = mapMemPoolTxs.begin(); + removeTx(mi->first, false); // this calls erase() on mapMemPoolTxs } int64_t endclear = GetTimeMicros(); - LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n",txids.size(), (endclear - startclear)*0.000001); + LogPrint(BCLog::ESTIMATEFEE, "Recorded %u unconfirmed txs from mempool in %gs\n", num_entries, (endclear - startclear)*0.000001); } FeeFilterRounder::FeeFilterRounder(const CFeeRate& minIncrementalFee) diff --git a/src/policy/fees.h b/src/policy/fees.h index 96a842b7a1..5f69e989c1 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -223,7 +223,7 @@ public: bool Read(CAutoFile& filein); /** Empty mempool transactions on shutdown to record failure to confirm for txs still in mempool */ - void FlushUnconfirmed(CTxMemPool& pool); + void FlushUnconfirmed(); /** Calculation of highest target that estimates are tracked for */ unsigned int HighestTargetTracked(FeeEstimateHorizon horizon) const; diff --git a/src/primitives/block.h b/src/primitives/block.h index 612a9fa203..5d6d44ac76 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -86,14 +86,14 @@ public: CBlock(const CBlockHeader &header) { SetNull(); - *((CBlockHeader*)this) = header; + *(static_cast<CBlockHeader*>(this)) = header; } ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*(CBlockHeader*)this); + READWRITE(*static_cast<CBlockHeader*>(this)); READWRITE(vtx); } diff --git a/src/protocol.h b/src/protocol.h index aaeb90eee2..42eb57e4f0 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -346,8 +346,8 @@ public: READWRITE(nTime); uint64_t nServicesInt = nServices; READWRITE(nServicesInt); - nServices = (ServiceFlags)nServicesInt; - READWRITE(*(CService*)this); + nServices = static_cast<ServiceFlags>(nServicesInt); + READWRITE(*static_cast<CService*>(this)); } // TODO: make private (improves encapsulation) diff --git a/src/qt/README.md b/src/qt/README.md new file mode 100644 index 0000000000..7ffea98170 --- /dev/null +++ b/src/qt/README.md @@ -0,0 +1,95 @@ +This directory contains the BitcoinQT graphical user interface (GUI). It uses the cross platform framework [QT](https://www1.qt.io/developers/). + +The current precise version for QT 5 is specified in [qt.mk](/depends/packages/qt.mk). QT 4 is also supported (see [#8263](https://github.com/bitcoin/bitcoin/issues/8263)). + +## Compile and run + +See build instructions ([OSX](/doc/build-osx.md), [Windows](/doc/build-windows.md), [Unix](/doc/build-unix.md), etc). + +To run: + +```sh +./src/qt/bitcoin-qt +``` + +## Files and directories + +### forms + +Contains [Designer UI](http://doc.qt.io/qt-5.9/designer-using-a-ui-file.html) files. They are created with [Qt Creator](#use-qt-Creator-as IDE), but can be edited using any text editor. + +### locale + +Contains translations. They are periodically updated. The process is described [here](/doc/translation_process.md). + +### res + +Resources such as the icon. + +### test + +Tests. + +### bitcoingui.(h/cpp) + +Represents the main window of the Bitcoin UI. + +### \*model.(h/cpp) + +The model. When it has a corresponding controller, it generally inherits from [QAbstractTableModel](http://doc.qt.io/qt-5/qabstracttablemodel.html). Models that are used by controllers as helpers inherit from other QT classes like [QValidator](http://doc.qt.io/qt-5/qvalidator.html). + +ClientModel is used by the main application `bitcoingui` and several models like `peertablemodel`. + +### \*page.(h/cpp) + +A controller. `:NAMEpage.cpp` generally includes `:NAMEmodel.h` and `forms/:NAME.page.ui` with a similar `:NAME`. + +### \*dialog.(h/cpp) + +Various dialogs, e.g. to open a URL. Inherit from [QDialog](http://doc.qt.io/qt-4.8/qdialog.html). + +### paymentserver.(h/cpp) + +Used to process BIP21 and BIP70 (see https://github.com/bitcoin/bitcoin/pull/11622) payment URI / requests. Also handles URI based application switching (e.g. when following a bitcoin:... link from a browser). + +### walletview.(h/cpp) + +Represents the view to a single wallet. + +### Other .h/cpp files + +* UI elements like BitcoinAmountField, which inherit from QWidget. +* `bitcoinstrings.cpp`: automatically generated +* `bitcoinunits.(h/cpp)`: BTC / mBTC / etc handling +* `callback.h` +* `guiconstants.h`: UI colors, app name, etc +* `guiutil.h`: several helper functions +* `macdockiconhandler.(h/cpp)` +* `macdockiconhandler.(h/cpp)`: display notifications in OSX + +## Contribute + +See [CONTRIBUTING.md](/CONTRIBUTING.md) for general guidelines. Specifically for QT: + +* don't change `local/bitcoin_en.ts`; this happens [automatically](/doc/translation_process.md#writing-code-with-translations) + +## Using Qt Creator as IDE + +You can use Qt Creator as an IDE. This is especially useful if you want to change +the UI layout. + +Download and install the community edition of [Qt Creator](https://www.qt.io/download/). +Uncheck everything except Qt Creator during the installation process. + +Instructions for OSX: + +1. Make sure you installed everything through Homebrew mentioned in the [OSX build instructions](/docs/build-osx.md) +2. Use `./configure` with the `--enable-debug` flag +3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project +4. Enter "bitcoin-qt" as project name, enter src/qt as location +5. Leave the file selection as it is +6. Confirm the "summary page" +7. In the "Projects" tab select "Manage Kits..." +8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler +9. Select LLDB as debugger (you might need to set the path to your installation) +10. Start debugging with Qt Creator (you might need to the executable to "bitcoin-qt" under "Run", which is where you can also add command line arguments) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index b26d99a20a..e4c088d379 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -388,7 +388,6 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown())); - pollShutdownTimer->start(200); } void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) @@ -515,14 +514,16 @@ void BitcoinApplication::initializeResult(bool success) window, SLOT(message(QString,QString,unsigned int))); QTimer::singleShot(100, paymentServer, SLOT(uiReady())); #endif + pollShutdownTimer->start(200); } else { - quit(); // Exit main loop + Q_EMIT splashFinished(window); // Make sure splash screen doesn't stick around during shutdown + quit(); // Exit first main loop invocation } } void BitcoinApplication::shutdownResult() { - quit(); // Exit main loop after shutdown finished + quit(); // Exit second main loop invocation after shutdown finished } void BitcoinApplication::handleRunawayException(const QString &message) @@ -705,7 +706,7 @@ int main(int argc, char *argv[]) if (BitcoinCore::baseInitialize()) { app.requestInitialize(); #if defined(Q_OS_WIN) && QT_VERSION >= 0x050000 - WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(QObject::tr(PACKAGE_NAME)), (HWND)app.getMainWinId()); + WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely...").arg(QObject::tr(PACKAGE_NAME)), static_cast<HWND>(app.getMainWinId())); #endif app.exec(); app.requestShutdown(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index afd90a3bc6..4e868b7c17 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -599,7 +599,7 @@ void BitcoinGUI::createTrayIconMenu() #else // Note: On Mac, the dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); - dockIconHandler->setMainWindow((QMainWindow *)this); + dockIconHandler->setMainWindow(static_cast<QMainWindow*>(this)); trayIconMenu = dockIconHandler->dockMenu(); #endif @@ -922,13 +922,13 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned buttons = QMessageBox::Ok; showNormalIfMinimized(); - QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this); + QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this); int r = mBox.exec(); if (ret != nullptr) *ret = r == QMessageBox::Ok; } else - notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message); + notificator->notify(static_cast<Notificator::Class>(nNotifyIcon), strTitle, message); } void BitcoinGUI::changeEvent(QEvent *e) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index acb3f2346f..8d2e5619e0 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -142,7 +142,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge if (settings.contains("nCoinControlMode") && !settings.value("nCoinControlMode").toBool()) ui->radioTreeMode->click(); if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder")) - sortView(settings.value("nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value("nCoinControlSortOrder").toInt())); + sortView(settings.value("nCoinControlSortColumn").toInt(), (static_cast<Qt::SortOrder>(settings.value("nCoinControlSortOrder").toInt()))); } CoinControlDialog::~CoinControlDialog() @@ -428,7 +428,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) if (amount > 0) { - CTxOut txout(amount, (CScript)std::vector<unsigned char>(24, 0)); + CTxOut txout(amount, static_cast<CScript>(std::vector<unsigned char>(24, 0))); txDummy.vout.push_back(txout); fDust |= IsDust(txout, ::dustRelayFee); } @@ -519,7 +519,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Never create dust outputs; if we would, just add the dust to the fee. if (nChange > 0 && nChange < MIN_CHANGE) { - CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0)); + CTxOut txout(nChange, static_cast<CScript>(std::vector<unsigned char>(24, 0))); if (IsDust(txout, ::dustRelayFee)) { nPayFee += nChange; diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 82db28d586..e7326d3f7a 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -24,7 +24,7 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event) else if (event->key() == Qt::Key_Escape) // press esc -> close dialog { event->ignore(); - CoinControlDialog *coinControlDialog = (CoinControlDialog*)this->parentWidget(); + CoinControlDialog *coinControlDialog = static_cast<CoinControlDialog*>(this->parentWidget()); coinControlDialog->done(QDialog::Accepted); } else diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 558d4f108c..edf1c29ea1 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -101,7 +101,7 @@ QFont fixedPitchFont() #endif } -// Just some dummy data to generate an convincing random-looking (but consistent) address +// Just some dummy data to generate a convincing random-looking (but consistent) address static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47}; // Generate a dummy address with invalid CRC, starting with the network prefix. diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 4ade88d843..909be1c264 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -315,7 +315,12 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in break; case MapPortUPnP: // core option - can be changed on-the-fly settings.setValue("fUseUPnP", value.toBool()); - MapPort(value.toBool()); + if (value.toBool()) { + StartMapPort(); + } else { + InterruptMapPort(); + StopMapPort(); + } break; case MinimizeOnClose: fMinimizeOnClose = value.toBool(); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 1227e340ce..871822ccb4 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -351,7 +351,7 @@ void SendCoinsDialog::on_sendButton_clicked() SendConfirmationDialog confirmationDialog(tr("Confirm send coins"), questionString.arg(formatted.join("<br />")), SEND_CONFIRM_DELAY, this); confirmationDialog.exec(); - QMessageBox::StandardButton retval = (QMessageBox::StandardButton)confirmationDialog.result(); + QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result()); if(retval != QMessageBox::Yes) { diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index fa3bd18d5a..5df1282f73 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -38,7 +38,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) float fontFactor = 1.0; float devicePixelRatio = 1.0; #if QT_VERSION > 0x050100 - devicePixelRatio = ((QGuiApplication*)QCoreApplication::instance())->devicePixelRatio(); + devicePixelRatio = static_cast<QGuiApplication*>(QCoreApplication::instance())->devicePixelRatio(); #endif // define text to place diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index fa43ab750a..88f8f463bc 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -322,7 +322,7 @@ void TransactionView::chooseWatchonly(int idx) if(!transactionProxyModel) return; transactionProxyModel->setWatchOnlyFilter( - (TransactionFilterProxy::WatchOnlyFilter)watchOnlyWidget->itemData(idx).toInt()); + static_cast<TransactionFilterProxy::WatchOnlyFilter>(watchOnlyWidget->itemData(idx).toInt())); } void TransactionView::changedSearch() diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 4d7e977fcb..541114e5fe 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -695,7 +695,7 @@ bool WalletModel::bumpFee(uint256 hash) questionString.append("</td></tr></table>"); SendConfirmationDialog confirmationDialog(tr("Confirm fee bump"), questionString); confirmationDialog.exec(); - QMessageBox::StandardButton retval = (QMessageBox::StandardButton)confirmationDialog.result(); + QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result()); // cancel sign&broadcast if users doesn't want to bump the fee if (retval != QMessageBox::Yes) { diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index 1e7a76efc0..e11a72899d 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -56,7 +56,7 @@ bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pM void WinShutdownMonitor::registerShutdownBlockReason(const QString& strReason, const HWND& mainWinId) { typedef BOOL (WINAPI *PSHUTDOWNBRCREATE)(HWND, LPCWSTR); - PSHUTDOWNBRCREATE shutdownBRCreate = (PSHUTDOWNBRCREATE)GetProcAddress(GetModuleHandleA("User32.dll"), "ShutdownBlockReasonCreate"); + PSHUTDOWNBRCREATE shutdownBRCreate = static_cast<PSHUTDOWNBRCREATE>(GetProcAddress(GetModuleHandleA("User32.dll"), "ShutdownBlockReasonCreate")); if (shutdownBRCreate == nullptr) { qWarning() << "registerShutdownBlockReason: GetProcAddress for ShutdownBlockReasonCreate failed"; return; diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index b88c1bccd5..99c1242d8a 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -114,7 +114,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "pruneblockchain", 0, "height" }, { "keypoolrefill", 0, "newsize" }, { "getrawmempool", 0, "verbose" }, - { "estimatefee", 0, "nblocks" }, { "estimatesmartfee", 0, "conf_target" }, { "estimaterawfee", 0, "conf_target" }, { "estimaterawfee", 1, "threshold" }, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index c22d0ac377..69d0d12e86 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -201,7 +201,6 @@ UniValue getmininginfo(const JSONRPCRequest& request) " \"pooledtx\": n (numeric) The size of the mempool\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" " \"warnings\": \"...\" (string) any network and blockchain warnings\n" - " \"errors\": \"...\" (string) DEPRECATED. Same as warnings. Only shown when bitcoind is started with -deprecatedrpc=getmininginfo\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmininginfo", "") @@ -219,11 +218,7 @@ UniValue getmininginfo(const JSONRPCRequest& request) obj.push_back(Pair("networkhashps", getnetworkhashps(request))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("chain", Params().NetworkIDString())); - if (IsDeprecatedRPCEnabled("getmininginfo")) { - obj.push_back(Pair("errors", GetWarnings("statusbar"))); - } else { - obj.push_back(Pair("warnings", GetWarnings("statusbar"))); - } + obj.push_back(Pair("warnings", GetWarnings("statusbar"))); return obj; } @@ -772,43 +767,8 @@ UniValue submitblock(const JSONRPCRequest& request) UniValue estimatefee(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() != 1) - throw std::runtime_error( - "estimatefee nblocks\n" - "\nDEPRECATED. Please use estimatesmartfee for more intelligent estimates." - "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" - "confirmation within nblocks blocks. Uses virtual transaction size of transaction\n" - "as defined in BIP 141 (witness data is discounted).\n" - "\nArguments:\n" - "1. nblocks (numeric, required)\n" - "\nResult:\n" - "n (numeric) estimated fee-per-kilobyte\n" - "\n" - "A negative value is returned if not enough transactions and blocks\n" - "have been observed to make an estimate.\n" - "-1 is always returned for nblocks == 1 as it is impossible to calculate\n" - "a fee that is high enough to get reliably included in the next block.\n" - "\nExample:\n" - + HelpExampleCli("estimatefee", "6") - ); - - if (!IsDeprecatedRPCEnabled("estimatefee")) { - throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee is deprecated and will be fully removed in v0.17. " - "To use estimatefee in v0.16, restart bitcoind with -deprecatedrpc=estimatefee.\n" - "Projects should transition to using estimatesmartfee before upgrading to v0.17"); - } - - RPCTypeCheck(request.params, {UniValue::VNUM}); - - int nBlocks = request.params[0].get_int(); - if (nBlocks < 1) - nBlocks = 1; - - CFeeRate feeRate = ::feeEstimator.estimateFee(nBlocks); - if (feeRate == CFeeRate(0)) - return -1.0; - - return ValueFromAmount(feeRate.GetFeePerK()); + throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee was removed in v0.17.\n" + "Clients should use estimatesmartfee."); } UniValue estimatesmartfee(const JSONRPCRequest& request) @@ -986,7 +946,7 @@ static const CRPCCommand commands[] = { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} }, - { "util", "estimatefee", &estimatefee, {"nblocks"} }, + { "hidden", "estimatefee", &estimatefee, {} }, { "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} }, { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index c11dda22c4..e772f56534 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -262,9 +262,6 @@ UniValue createmultisig(const JSONRPCRequest& request) std::string msg = "createmultisig nrequired [\"key\",...]\n" "\nCreates a multi-signature address with n signature of m keys required.\n" "It returns a json object with the address and redeemScript.\n" - "DEPRECATION WARNING: Using addresses with createmultisig is deprecated. Clients must\n" - "transition to using addmultisigaddress to create multisig addresses with addresses known\n" - "to the wallet before upgrading to v0.17. To use the deprecated functionality, start bitcoind with -deprecatedrpc=createmultisig\n" "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" "2. \"keys\" (string, required) A json array of hex-encoded public keys\n" @@ -297,15 +294,8 @@ UniValue createmultisig(const JSONRPCRequest& request) if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) { pubkeys.push_back(HexToPubKey(keys[i].get_str())); } else { -#ifdef ENABLE_WALLET - CWallet* const pwallet = GetWalletForJSONRPCRequest(request); - if (IsDeprecatedRPCEnabled("createmultisig") && EnsureWalletIsAvailable(pwallet, false)) { - pubkeys.push_back(AddrToPubKey(pwallet, keys[i].get_str())); - } else -#endif throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\nNote that from v0.16, createmultisig no longer accepts addresses." - " Clients must transition to using addmultisigaddress to create multisig addresses with addresses known to the wallet before upgrading to v0.17." - " To use the deprecated functionality, start bitcoind with -deprecatedrpc=createmultisig", keys[i].get_str())); + " Users must use addmultisigaddress to create multisig addresses with addresses known to the wallet.", keys[i].get_str())); } } diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index ddc1bb6232..cdd2e67a69 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -72,9 +72,7 @@ static fs::path GetAuthCookieFile(bool temp=false) if (temp) { arg += ".tmp"; } - fs::path path(arg); - if (!path.is_complete()) path = GetDataDir() / path; - return path; + return AbsPathForConfigVal(fs::path(arg)); } bool GenerateAuthCookie(std::string *cookie_out) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 00e73675b4..fdd5cdad31 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -692,7 +692,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request) "\nArguments:\n" "1. \"hexstring\" (string, required) The transaction hex string\n" - "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n" + "2. \"prevtxs\" (string, optional) A json array of previous dependent transaction outputs\n" " [ (json array of json objects, or 'null' if none provided)\n" " {\n" " \"txid\":\"id\", (string, required) The transaction id\n" diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e12329be76..4dad6b44c5 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -104,7 +104,7 @@ enum // SCRIPT_VERIFY_MINIMALIF = (1U << 13), - // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed + // Signature(s) must be empty vector if a CHECK(MULTI)SIG operation failed // SCRIPT_VERIFY_NULLFAIL = (1U << 14), diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index d0dd272550..35d794b983 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -13,16 +13,13 @@ typedef std::vector<unsigned char> valtype; -unsigned int HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore) +static bool HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore) { - unsigned int nResult = 0; - for (const valtype& pubkey : pubkeys) - { + for (const valtype& pubkey : pubkeys) { CKeyID keyID = CPubKey(pubkey).GetID(); - if (keystore.HaveKey(keyID)) - ++nResult; + if (!keystore.HaveKey(keyID)) return false; } - return nResult; + return true; } isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion sigversion) @@ -140,7 +137,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& } } } - if (HaveKeys(keys, keystore) == keys.size()) + if (HaveKeys(keys, keystore)) return ISMINE_SPENDABLE; break; } diff --git a/src/script/ismine.h b/src/script/ismine.h index b54879cc15..c1338c3a8e 100644 --- a/src/script/ismine.h +++ b/src/script/ismine.h @@ -29,7 +29,7 @@ enum isminetype typedef uint8_t isminefilter; /* isInvalid becomes true when the script is found invalid by consensus or policy. This will terminate the recursion - * and return a ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as + * and return ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as * different SIGVERSION may have different network rules. Currently the only use of isInvalid is indicate uncompressed * keys in SIGVERSION_WITNESS_V0 script, but could also be used in similar cases in the future */ diff --git a/src/script/script.h b/src/script/script.h index bedf5f9be5..591777672e 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -568,7 +568,7 @@ public: pc += nSize; } - opcodeRet = (opcodetype)opcode; + opcodeRet = static_cast<opcodetype>(opcode); return true; } diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 09442b7f9f..f8a1347c31 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -92,11 +92,11 @@ [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a010047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], -["As above, but using a OP_1"], +["As above, but using an OP_1"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], -["As above, but using a OP_1NEGATE"], +["As above, but using an OP_1NEGATE"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index a845083636..7e39ec7599 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -23,11 +23,11 @@ [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a01ff47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], -["As above, but using a OP_1"], +["As above, but using an OP_1"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], -["As above, but using a OP_1NEGATE"], +["As above, but using an OP_1NEGATE"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 12f113655a..5d6f781404 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test) const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); const Consensus::Params &mainnetParams = chainParams->GetConsensus(); for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { - uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i); + uint32_t bitmask = VersionBitsMask(mainnetParams, static_cast<Consensus::DeploymentPos>(i)); // Make sure that no deployment tries to set an invalid bit. BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask); @@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test) // activated soft fork could be later changed to be earlier to avoid // overlap.) for (int j=i+1; j<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; j++) { - if (VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)j) == bitmask) { + if (VersionBitsMask(mainnetParams, static_cast<Consensus::DeploymentPos>(j)) == bitmask) { BOOST_CHECK(mainnetParams.vDeployments[j].nStartTime > mainnetParams.vDeployments[i].nTimeout || mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout); } diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index c45b5dac0d..717d1cf7e5 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -133,7 +133,7 @@ TorControlConnection::~TorControlConnection() void TorControlConnection::readcb(struct bufferevent *bev, void *ctx) { - TorControlConnection *self = (TorControlConnection*)ctx; + TorControlConnection *self = static_cast<TorControlConnection*>(ctx); struct evbuffer *input = bufferevent_get_input(bev); size_t n_read_out = 0; char *line; @@ -178,7 +178,7 @@ void TorControlConnection::readcb(struct bufferevent *bev, void *ctx) void TorControlConnection::eventcb(struct bufferevent *bev, short what, void *ctx) { - TorControlConnection *self = (TorControlConnection*)ctx; + TorControlConnection *self = static_cast<TorControlConnection*>(ctx); if (what & BEV_EVENT_CONNECTED) { LogPrint(BCLog::TOR, "tor: Successfully connected!\n"); self->connected(*self); @@ -725,13 +725,13 @@ fs::path TorController::GetPrivateKeyFile() void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg) { - TorController *self = (TorController*)arg; + TorController *self = static_cast<TorController*>(arg); self->Reconnect(); } /****** Thread ********/ static struct event_base *gBase; -static boost::thread torControlThread; +static std::thread torControlThread; static void TorControlThread() { @@ -740,7 +740,7 @@ static void TorControlThread() event_base_dispatch(gBase); } -void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) +void StartTorControl() { assert(!gBase); #ifdef WIN32 @@ -754,7 +754,7 @@ void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) return; } - torControlThread = boost::thread(boost::bind(&TraceThread<void (*)()>, "torcontrol", &TorControlThread)); + torControlThread = std::thread(std::bind(&TraceThread<void (*)()>, "torcontrol", &TorControlThread)); } void InterruptTorControl() diff --git a/src/torcontrol.h b/src/torcontrol.h index 20514f7bbf..2be6701fa5 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -13,7 +13,7 @@ extern const std::string DEFAULT_TOR_CONTROL; static const bool DEFAULT_LISTEN_ONION = true; -void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler); +void StartTorControl(); void InterruptTorControl(); void StopTorControl(); diff --git a/src/txdb.h b/src/txdb.h index 3edeb4648e..2fc69e563b 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -46,7 +46,7 @@ struct CDiskTxPos : public CDiskBlockPos template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*(CDiskBlockPos*)this); + READWRITE(*static_cast<CDiskBlockPos*>(this)); READWRITE(VARINT(nTxOffset)); } diff --git a/src/txmempool.h b/src/txmempool.h index d6f8e7094b..c6a1bf08ce 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -241,15 +241,18 @@ public: /** \class CompareTxMemPoolEntryByScore * - * Sort by score of entry ((fee+delta)/size) in descending order + * Sort by feerate of entry (fee/size) in descending order + * This is only used for transaction relay, so we use GetFee() + * instead of GetModifiedFee() to avoid leaking prioritization + * information via the sort order. */ class CompareTxMemPoolEntryByScore { public: bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { - double f1 = (double)a.GetModifiedFee() * b.GetTxSize(); - double f2 = (double)b.GetModifiedFee() * a.GetTxSize(); + double f1 = (double)a.GetFee() * b.GetTxSize(); + double f2 = (double)b.GetFee() * a.GetTxSize(); if (f1 == f2) { return b.GetTx().GetHash() < a.GetTx().GetHash(); } @@ -379,8 +382,9 @@ public: * * mapTx is a boost::multi_index that sorts the mempool on 4 criteria: * - transaction hash - * - feerate [we use max(feerate of tx, feerate of tx with all descendants)] + * - descendant feerate [we use max(feerate of tx, feerate of tx with all descendants)] * - time in mempool + * - ancestor feerate [we use min(feerate of tx, feerate of tx with all unconfirmed ancestors)] * * Note: the term "descendant" refers to in-mempool transactions that depend on * this one, while "ancestor" refers to in-mempool transactions that a given diff --git a/src/util.cpp b/src/util.cpp index 80eed24ffd..6738bbc6e4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <util.h> +#include <fs.h> #include <chainparamsbase.h> #include <random.h> @@ -188,11 +189,7 @@ static void DebugPrintInit() fs::path GetDebugLogPath() { fs::path logfile(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); - if (logfile.is_absolute()) { - return logfile; - } else { - return GetDataDir() / logfile; - } + return AbsPathForConfigVal(logfile); } bool OpenDebugLog() @@ -624,11 +621,7 @@ void ClearDatadirCache() fs::path GetConfigFile(const std::string& confPath) { - fs::path pathConfigFile(confPath); - if (!pathConfigFile.is_complete()) - pathConfigFile = GetDataDir(false) / pathConfigFile; - - return pathConfigFile; + return AbsPathForConfigVal(fs::path(confPath), false); } void ArgsManager::ReadConfigFile(const std::string& confPath) @@ -663,9 +656,7 @@ void ArgsManager::ReadConfigFile(const std::string& confPath) #ifndef WIN32 fs::path GetPidFile() { - fs::path pathPidFile(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME)); - if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; - return pathPidFile; + return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME))); } void CreatePidFile(const fs::path &path, pid_t pid) @@ -936,3 +927,8 @@ int64_t GetStartupTime() { return nStartupTime; } + +fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific) +{ + return fs::absolute(path, GetDataDir(net_specific)); +} diff --git a/src/util.h b/src/util.h index 277b4c66af..05138a9bfe 100644 --- a/src/util.h +++ b/src/util.h @@ -191,6 +191,16 @@ bool OpenDebugLog(); void ShrinkDebugFile(); void runCommand(const std::string& strCommand); +/** + * Most paths passed as configuration arguments are treated as relative to + * the datadir if they are not absolute. + * + * @param path The path to be conditionally prefixed with datadir. + * @param net_specific Forwarded to GetDataDir(). + * @return The normalized path. + */ +fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true); + inline bool IsSwitchChar(char c) { #ifdef WIN32 diff --git a/src/validation.cpp b/src/validation.cpp index 698ef9181d..371460a6f0 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -547,8 +547,10 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool const CTransaction& tx = *ptx; const uint256 hash = tx.GetHash(); AssertLockHeld(cs_main); - if (pfMissingInputs) + LOCK(pool.cs); // mempool "read lock" (held through GetMainSignals().TransactionAddedToMempool()) + if (pfMissingInputs) { *pfMissingInputs = false; + } if (!CheckTransaction(tx, state)) return false; // state filled in by CheckTransaction @@ -581,8 +583,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // Check for conflicts with in-memory transactions std::set<uint256> setConflicts; - { - LOCK(pool.cs); // protect pool.mapNextTx for (const CTxIn &txin : tx.vin) { auto itConflicting = pool.mapNextTx.find(txin.prevout); @@ -623,15 +623,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool } } } - } { CCoinsView dummy; CCoinsViewCache view(&dummy); LockPoints lp; - { - LOCK(pool.cs); CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool); view.SetBackend(viewMemPool); @@ -670,8 +667,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool if (!CheckSequenceLocks(tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) return state.DoS(0, false, REJECT_NONSTANDARD, "non-BIP68-final"); - } // end LOCK(pool.cs) - CAmount nFees = 0; if (!Consensus::CheckTxInputs(tx, state, view, GetSpendHeight(view), nFees)) { return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state)); @@ -768,7 +763,6 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // If we don't hold the lock allConflicting might be incomplete; the // subsequent RemoveStaged() and addUnchecked() calls don't guarantee // mempool consistency for us. - LOCK(pool.cs); const bool fReplacementTransaction = setConflicts.size(); if (fReplacementTransaction) { @@ -1188,7 +1182,8 @@ static void AlertNotify(const std::string& strMessage) safeStatus = singleQuote+safeStatus+singleQuote; boost::replace_all(strCmd, "%s", safeStatus); - boost::thread t(runCommand, strCmd); // thread runs free + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free } static void CheckForkWarningConditions() @@ -1689,9 +1684,9 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para int32_t nVersion = VERSIONBITS_TOP_BITS; for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { - ThresholdState state = VersionBitsState(pindexPrev, params, (Consensus::DeploymentPos)i, versionbitscache); + ThresholdState state = VersionBitsState(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i), versionbitscache); if (state == THRESHOLD_LOCKED_IN || state == THRESHOLD_STARTED) { - nVersion |= VersionBitsMask(params, (Consensus::DeploymentPos)i); + nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i)); } } @@ -2581,9 +2576,6 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams& SyncWithValidationInterfaceQueue(); } - if (ShutdownRequested()) - break; - const CBlockIndex *pindexFork; bool fInitialDownload; { @@ -2630,6 +2622,13 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams& } if (nStopAtHeight && pindexNewTip && pindexNewTip->nHeight >= nStopAtHeight) StartShutdown(); + + // We check shutdown only after giving ActivateBestChainStep a chance to run once so that we + // never shutdown before connecting the genesis block during LoadChainTip(). Previously this + // caused an assert() failure during shutdown in such cases as the UTXO DB flushing checks + // that the best block hash is non-null. + if (ShutdownRequested()) + break; } while (pindexNewTip != pindexMostWork); CheckBlockIndex(chainparams.GetConsensus()); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 0b021f9fe0..03fb824e7a 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -71,6 +71,28 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } +bool GetWalletAddressesForKey(CWallet * const pwallet, const CKeyID &keyid, std::string &strAddr, std::string &strLabel) +{ + bool fLabelFound = false; + CKey key; + pwallet->GetKey(keyid, key); + for (const auto& dest : GetAllDestinationsForKey(key.GetPubKey())) { + if (pwallet->mapAddressBook.count(dest)) { + if (!strAddr.empty()) { + strAddr += ","; + } + strAddr += EncodeDestination(dest); + strLabel = EncodeDumpString(pwallet->mapAddressBook[dest].name); + fLabelFound = true; + } + } + if (!fLabelFound) { + strAddr = EncodeDestination(GetDestinationForKey(key.GetPubKey(), g_address_type)); + } + return fLabelFound; +} + + UniValue importprivkey(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); @@ -729,12 +751,13 @@ UniValue dumpwallet(const JSONRPCRequest& request) for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { const CKeyID &keyid = it->second; std::string strTime = EncodeDumpTime(it->first); - std::string strAddr = EncodeDestination(keyid); + std::string strAddr; + std::string strLabel; CKey key; if (pwallet->GetKey(keyid, key)) { file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime); - if (pwallet->mapAddressBook.count(keyid)) { - file << strprintf("label=%s", EncodeDumpString(pwallet->mapAddressBook[keyid].name)); + if (GetWalletAddressesForKey(pwallet, keyid, strAddr, strLabel)) { + file << strprintf("label=%s", strLabel); } else if (keyid == masterKeyID) { file << "hdmaster=1"; } else if (mapKeyPool.count(keyid)) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 9364d18d30..261d9b37f5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1192,10 +1192,6 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n" " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n" "}\n" - "\nResult (DEPRECATED. To see this result in v0.16 instead, please start bitcoind with -deprecatedrpc=addmultisigaddress).\n" - " clients should transition to the new output api before upgrading to v0.17.\n" - "\"address\" (string) A bitcoin address associated with the keys.\n" - "\nExamples:\n" "\nAdd a multisig address from 2 addresses\n" + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + @@ -1238,11 +1234,6 @@ UniValue addmultisigaddress(const JSONRPCRequest& request) CTxDestination dest = pwallet->AddAndGetDestinationForScript(inner, output_type); pwallet->SetAddressBook(dest, strAccount, "send"); - // Return old style interface - if (IsDeprecatedRPCEnabled("addmultisigaddress")) { - return EncodeDestination(dest); - } - UniValue result(UniValue::VOBJ); result.pushKV("address", EncodeDestination(dest)); result.pushKV("redeemScript", HexStr(inner.begin(), inner.end())); @@ -1794,8 +1785,6 @@ UniValue listtransactions(const JSONRPCRequest& request) // the user could have gotten from another RPC command prior to now pwallet->BlockUntilSyncedToCurrentChain(); - LOCK2(cs_main, pwallet->cs_wallet); - std::string strAccount = "*"; if (!request.params[0].isNull()) strAccount = request.params[0].get_str(); @@ -1817,20 +1806,25 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwallet->wtxOrdered; - - // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { - CWalletTx *const pwtx = (*it).second.first; - if (pwtx != nullptr) - ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter); - CAccountingEntry *const pacentry = (*it).second.second; - if (pacentry != nullptr) - AcentryToJSON(*pacentry, strAccount, ret); + LOCK2(cs_main, pwallet->cs_wallet); + + const CWallet::TxItems & txOrdered = pwallet->wtxOrdered; - if ((int)ret.size() >= (nCount+nFrom)) break; + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != nullptr) + ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != nullptr) + AcentryToJSON(*pacentry, strAccount, ret); + + if ((int)ret.size() >= (nCount+nFrom)) break; + } } + // ret is newest to oldest if (nFrom > (int)ret.size()) @@ -2190,14 +2184,14 @@ UniValue abandontransaction(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() != 1) + if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( "abandontransaction \"txid\"\n" "\nMark in-wallet transaction <txid> as abandoned\n" "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n" "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n" "It only works on transactions which are not included in a block and are not currently in the mempool.\n" - "It has no effect on transactions which are already conflicted or abandoned.\n" + "It has no effect on transactions which are already abandoned.\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "\nResult:\n" @@ -2205,6 +2199,7 @@ UniValue abandontransaction(const JSONRPCRequest& request) + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); + } ObserveSafeMode(); @@ -3257,8 +3252,8 @@ UniValue bumpfee(const JSONRPCRequest& request) "If the change output is not big enough to cover the increased fee, the command will currently fail\n" "instead of adding new inputs to compensate. (A future implementation could improve this.)\n" "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n" - "By default, the new fee will be calculated automatically using estimatefee.\n" - "The user can specify a confirmation target for estimatefee.\n" + "By default, the new fee will be calculated automatically using estimatesmartfee.\n" + "The user can specify a confirmation target for estimatesmartfee.\n" "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n" "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n" "returned by getnetworkinfo) to enter the node's mempool.\n" diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index f39471b871..161372784b 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -676,18 +676,24 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) BOOST_CHECK_EQUAL(list.begin()->second.size(), 2); // Lock both coins. Confirm number of available coins drops to 0. - std::vector<COutput> available; - wallet->AvailableCoins(available); - BOOST_CHECK_EQUAL(available.size(), 2); + { + LOCK2(cs_main, wallet->cs_wallet); + std::vector<COutput> available; + wallet->AvailableCoins(available); + BOOST_CHECK_EQUAL(available.size(), 2); + } for (const auto& group : list) { for (const auto& coin : group.second) { LOCK(wallet->cs_wallet); wallet->LockCoin(COutPoint(coin.tx->GetHash(), coin.i)); } } - wallet->AvailableCoins(available); - BOOST_CHECK_EQUAL(available.size(), 0); - + { + LOCK2(cs_main, wallet->cs_wallet); + std::vector<COutput> available; + wallet->AvailableCoins(available); + BOOST_CHECK_EQUAL(available.size(), 0); + } // Confirm ListCoins still returns same result as before, despite coins // being locked. list = wallet->ListCoins(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2b8019395c..513819606b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -34,7 +34,6 @@ #include <future> #include <boost/algorithm/string/replace.hpp> -#include <boost/thread.hpp> std::vector<CWalletRef> vpwallets; /** Transaction fee set by the user */ @@ -976,7 +975,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) if (!strCmd.empty()) { boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free } return true; @@ -1078,7 +1078,7 @@ bool CWallet::TransactionCanBeAbandoned(const uint256& hashTx) const { LOCK2(cs_main, cs_wallet); const CWalletTx* wtx = GetWalletTx(hashTx); - return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain() <= 0 && !wtx->InMempool(); + return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain() == 0 && !wtx->InMempool(); } bool CWallet::AbandonTransaction(const uint256& hashTx) @@ -1094,7 +1094,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) auto it = mapWallet.find(hashTx); assert(it != mapWallet.end()); CWalletTx& origtx = it->second; - if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { + if (origtx.GetDepthInMainChain() != 0 || origtx.InMempool()) { return false; } @@ -2198,111 +2198,109 @@ CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount, const int nMinDepth, const int nMaxDepth) const { + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); + vCoins.clear(); + CAmount nTotal = 0; + for (const auto& entry : mapWallet) { - LOCK2(cs_main, cs_wallet); + const uint256& wtxid = entry.first; + const CWalletTx* pcoin = &entry.second; - CAmount nTotal = 0; + if (!CheckFinalTx(*pcoin->tx)) + continue; - for (const auto& entry : mapWallet) - { - const uint256& wtxid = entry.first; - const CWalletTx* pcoin = &entry.second; + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + continue; - if (!CheckFinalTx(*pcoin->tx)) - continue; + int nDepth = pcoin->GetDepthInMainChain(); + if (nDepth < 0) + continue; - if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) - continue; + // We should not consider coins which aren't at least in our mempool + // It's possible for these to be conflicted via ancestors which we may never be able to detect + if (nDepth == 0 && !pcoin->InMempool()) + continue; - int nDepth = pcoin->GetDepthInMainChain(); - if (nDepth < 0) - continue; + bool safeTx = pcoin->IsTrusted(); + + // We should not consider coins from transactions that are replacing + // other transactions. + // + // Example: There is a transaction A which is replaced by bumpfee + // transaction B. In this case, we want to prevent creation of + // a transaction B' which spends an output of B. + // + // Reason: If transaction A were initially confirmed, transactions B + // and B' would no longer be valid, so the user would have to create + // a new transaction C to replace B'. However, in the case of a + // one-block reorg, transactions B' and C might BOTH be accepted, + // when the user only wanted one of them. Specifically, there could + // be a 1-block reorg away from the chain where transactions A and C + // were accepted to another chain where B, B', and C were all + // accepted. + if (nDepth == 0 && pcoin->mapValue.count("replaces_txid")) { + safeTx = false; + } - // We should not consider coins which aren't at least in our mempool - // It's possible for these to be conflicted via ancestors which we may never be able to detect - if (nDepth == 0 && !pcoin->InMempool()) - continue; + // Similarly, we should not consider coins from transactions that + // have been replaced. In the example above, we would want to prevent + // creation of a transaction A' spending an output of A, because if + // transaction B were initially confirmed, conflicting with A and + // A', we wouldn't want to the user to create a transaction D + // intending to replace A', but potentially resulting in a scenario + // where A, A', and D could all be accepted (instead of just B and + // D, or just A and A' like the user would want). + if (nDepth == 0 && pcoin->mapValue.count("replaced_by_txid")) { + safeTx = false; + } - bool safeTx = pcoin->IsTrusted(); - - // We should not consider coins from transactions that are replacing - // other transactions. - // - // Example: There is a transaction A which is replaced by bumpfee - // transaction B. In this case, we want to prevent creation of - // a transaction B' which spends an output of B. - // - // Reason: If transaction A were initially confirmed, transactions B - // and B' would no longer be valid, so the user would have to create - // a new transaction C to replace B'. However, in the case of a - // one-block reorg, transactions B' and C might BOTH be accepted, - // when the user only wanted one of them. Specifically, there could - // be a 1-block reorg away from the chain where transactions A and C - // were accepted to another chain where B, B', and C were all - // accepted. - if (nDepth == 0 && pcoin->mapValue.count("replaces_txid")) { - safeTx = false; - } + if (fOnlySafe && !safeTx) { + continue; + } - // Similarly, we should not consider coins from transactions that - // have been replaced. In the example above, we would want to prevent - // creation of a transaction A' spending an output of A, because if - // transaction B were initially confirmed, conflicting with A and - // A', we wouldn't want to the user to create a transaction D - // intending to replace A', but potentially resulting in a scenario - // where A, A', and D could all be accepted (instead of just B and - // D, or just A and A' like the user would want). - if (nDepth == 0 && pcoin->mapValue.count("replaced_by_txid")) { - safeTx = false; - } + if (nDepth < nMinDepth || nDepth > nMaxDepth) + continue; - if (fOnlySafe && !safeTx) { + for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) { + if (pcoin->tx->vout[i].nValue < nMinimumAmount || pcoin->tx->vout[i].nValue > nMaximumAmount) continue; - } - if (nDepth < nMinDepth || nDepth > nMaxDepth) + if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint(entry.first, i))) continue; - for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) { - if (pcoin->tx->vout[i].nValue < nMinimumAmount || pcoin->tx->vout[i].nValue > nMaximumAmount) - continue; - - if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint(entry.first, i))) - continue; - - if (IsLockedCoin(entry.first, i)) - continue; - - if (IsSpent(wtxid, i)) - continue; + if (IsLockedCoin(entry.first, i)) + continue; - isminetype mine = IsMine(pcoin->tx->vout[i]); + if (IsSpent(wtxid, i)) + continue; - if (mine == ISMINE_NO) { - continue; - } + isminetype mine = IsMine(pcoin->tx->vout[i]); - bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO); - bool fSolvableIn = (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO; + if (mine == ISMINE_NO) { + continue; + } - vCoins.push_back(COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx)); + bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO); + bool fSolvableIn = (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO; - // Checks the sum amount of all UTXO's. - if (nMinimumSumAmount != MAX_MONEY) { - nTotal += pcoin->tx->vout[i].nValue; + vCoins.push_back(COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx)); - if (nTotal >= nMinimumSumAmount) { - return; - } - } + // Checks the sum amount of all UTXO's. + if (nMinimumSumAmount != MAX_MONEY) { + nTotal += pcoin->tx->vout[i].nValue; - // Checks the maximum number of UTXO's. - if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) { + if (nTotal >= nMinimumSumAmount) { return; } } + + // Checks the maximum number of UTXO's. + if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) { + return; + } } } } @@ -2320,11 +2318,11 @@ std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const // avoid adding some extra complexity to the Qt code. std::map<CTxDestination, std::vector<COutput>> result; - std::vector<COutput> availableCoins; - AvailableCoins(availableCoins); LOCK2(cs_main, cs_wallet); + AvailableCoins(availableCoins); + for (auto& coin : availableCoins) { CTxDestination address; if (coin.fSpendable && diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a4684c2935..fefe415bb1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -408,7 +408,7 @@ public: mapValue["timesmart"] = strprintf("%u", nTimeSmart); } - READWRITE(*(CMerkleTx*)this); + READWRITE(*static_cast<CMerkleTx*>(this)); std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev READWRITE(vUnused); READWRITE(mapValue); diff --git a/test/README.md b/test/README.md index b59c8db4e5..b522c4469a 100644 --- a/test/README.md +++ b/test/README.md @@ -33,13 +33,13 @@ The ZMQ functional test requires a python ZMQ library. To install it: Individual tests can be run by directly calling the test script, eg: ``` -test/functional/replace-by-fee.py +test/functional/feature_rbf.py ``` or can be run through the test_runner harness, eg: ``` -test/functional/test_runner.py replace-by-fee.py +test/functional/test_runner.py feature_rbf.py ``` You can run any combination (incl. duplicates) of tests by calling: diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 68453e50f4..e1263414bd 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -3,39 +3,47 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test fee estimation code.""" +from decimal import Decimal +import random -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, COIN +from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_greater_than, + assert_greater_than_or_equal, + connect_nodes, + satoshi_round, + sync_blocks, + sync_mempools, +) # Construct 2 trivial P2SH's and the ScriptSigs that spend them # So we can create many transactions without needing to spend # time signing. -redeem_script_1 = CScript([OP_1, OP_DROP]) -redeem_script_2 = CScript([OP_2, OP_DROP]) -P2SH_1 = CScript([OP_HASH160, hash160(redeem_script_1), OP_EQUAL]) -P2SH_2 = CScript([OP_HASH160, hash160(redeem_script_2), OP_EQUAL]) +REDEEM_SCRIPT_1 = CScript([OP_1, OP_DROP]) +REDEEM_SCRIPT_2 = CScript([OP_2, OP_DROP]) +P2SH_1 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_1), OP_EQUAL]) +P2SH_2 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_2), OP_EQUAL]) # Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2 -SCRIPT_SIG = [CScript([OP_TRUE, redeem_script_1]), CScript([OP_TRUE, redeem_script_2])] - -global log +SCRIPT_SIG = [CScript([OP_TRUE, REDEEM_SCRIPT_1]), CScript([OP_TRUE, REDEEM_SCRIPT_2])] def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment): - """ - Create and send a transaction with a random fee. + """Create and send a transaction with a random fee. + The transaction pays to a trivial P2SH script, and assumes that its inputs are of the same form. The function takes a list of confirmed outputs and unconfirmed outputs and attempts to use the confirmed list first for its inputs. It adds the newly created outputs to the unconfirmed list. - Returns (raw transaction, fee) - """ + Returns (raw transaction, fee).""" + # It's best to exponentially distribute our random fees # because the buckets are exponentially spaced. # Exponentially distributed from 1-128 * fee_increment - rand_fee = float(fee_increment)*(1.1892**random.randint(0,28)) + rand_fee = float(fee_increment) * (1.1892 ** random.randint(0, 28)) # Total fee ranges from min_fee to min_fee + 127*fee_increment fee = min_fee - fee_increment + satoshi_round(rand_fee) tx = CTransaction() @@ -50,95 +58,69 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee total_in += t["amount"] tx.vin.append(CTxIn(COutPoint(int(t["txid"], 16), t["vout"]), b"")) if total_in <= amount + fee: - raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in)) - tx.vout.append(CTxOut(int((total_in - amount - fee)*COIN), P2SH_1)) - tx.vout.append(CTxOut(int(amount*COIN), P2SH_2)) + raise RuntimeError("Insufficient funds: need %d, have %d" % (amount + fee, total_in)) + tx.vout.append(CTxOut(int((total_in - amount - fee) * COIN), P2SH_1)) + tx.vout.append(CTxOut(int(amount * COIN), P2SH_2)) # These transactions don't need to be signed, but we still have to insert # the ScriptSig that will satisfy the ScriptPubKey. for inp in tx.vin: inp.scriptSig = SCRIPT_SIG[inp.prevout.n] txid = from_node.sendrawtransaction(ToHex(tx), True) - unconflist.append({ "txid" : txid, "vout" : 0 , "amount" : total_in - amount - fee}) - unconflist.append({ "txid" : txid, "vout" : 1 , "amount" : amount}) + unconflist.append({"txid": txid, "vout": 0, "amount": total_in - amount - fee}) + unconflist.append({"txid": txid, "vout": 1, "amount": amount}) return (ToHex(tx), fee) -def split_inputs(from_node, txins, txouts, initial_split = False): - """ - We need to generate a lot of inputs so we can generate a ton of transactions. +def split_inputs(from_node, txins, txouts, initial_split=False): + """Generate a lot of inputs so we can generate a ton of transactions. + This function takes an input from txins, and creates and sends a transaction which splits the value into 2 outputs which are appended to txouts. Previously this was designed to be small inputs so they wouldn't have - a high coin age when the notion of priority still existed. - """ + a high coin age when the notion of priority still existed.""" + prevtxout = txins.pop() tx = CTransaction() tx.vin.append(CTxIn(COutPoint(int(prevtxout["txid"], 16), prevtxout["vout"]), b"")) - half_change = satoshi_round(prevtxout["amount"]/2) - rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000") - tx.vout.append(CTxOut(int(half_change*COIN), P2SH_1)) - tx.vout.append(CTxOut(int(rem_change*COIN), P2SH_2)) + half_change = satoshi_round(prevtxout["amount"] / 2) + rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000") + tx.vout.append(CTxOut(int(half_change * COIN), P2SH_1)) + tx.vout.append(CTxOut(int(rem_change * COIN), P2SH_2)) # If this is the initial split we actually need to sign the transaction # Otherwise we just need to insert the proper ScriptSig - if (initial_split) : + if (initial_split): completetx = from_node.signrawtransaction(ToHex(tx))["hex"] - else : + else: tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]] completetx = ToHex(tx) txid = from_node.sendrawtransaction(completetx, True) - txouts.append({ "txid" : txid, "vout" : 0 , "amount" : half_change}) - txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change}) + txouts.append({"txid": txid, "vout": 0, "amount": half_change}) + txouts.append({"txid": txid, "vout": 1, "amount": rem_change}) -def check_estimates(node, fees_seen, max_invalid, print_estimates = True): - """ - This function calls estimatefee and verifies that the estimates - meet certain invariants. - """ - all_estimates = [ node.estimatefee(i) for i in range(1,26) ] - if print_estimates: - log.info([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]]) - delta = 1.0e-6 # account for rounding error - last_e = max(fees_seen) - for e in [x for x in all_estimates if x >= 0]: - # Estimates should be within the bounds of what transactions fees actually were: - if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen): +def check_estimates(node, fees_seen, max_invalid): + """Call estimatesmartfee and verify that the estimates meet certain invariants.""" + + delta = 1.0e-6 # account for rounding error + last_feerate = float(max(fees_seen)) + all_smart_estimates = [node.estimatesmartfee(i) for i in range(1, 26)] + for i, e in enumerate(all_smart_estimates): # estimate is for i+1 + feerate = float(e["feerate"]) + assert_greater_than(feerate, 0) + + if feerate + delta < min(fees_seen) or feerate - delta > max(fees_seen): raise AssertionError("Estimated fee (%f) out of range (%f,%f)" - %(float(e), min(fees_seen), max(fees_seen))) - # Estimates should be monotonically decreasing - if float(e)-delta > last_e: + % (feerate, min(fees_seen), max(fees_seen))) + if feerate - delta > last_feerate: raise AssertionError("Estimated fee (%f) larger than last fee (%f) for lower number of confirms" - %(float(e),float(last_e))) - last_e = e - valid_estimate = False - invalid_estimates = 0 - for i,e in enumerate(all_estimates): # estimate is for i+1 - if e >= 0: - valid_estimate = True - if i >= 13: # for n>=14 estimatesmartfee(n/2) should be at least as high as estimatefee(n) - assert(node.estimatesmartfee((i+1)//2)["feerate"] > float(e) - delta) + % (feerate, last_feerate)) + last_feerate = feerate + if i == 0: + assert_equal(e["blocks"], 2) else: - invalid_estimates += 1 - - # estimatesmartfee should still be valid - approx_estimate = node.estimatesmartfee(i+1)["feerate"] - answer_found = node.estimatesmartfee(i+1)["blocks"] - assert(approx_estimate > 0) - assert(answer_found > i+1) - - # Once we're at a high enough confirmation count that we can give an estimate - # We should have estimates for all higher confirmation counts - if valid_estimate: - raise AssertionError("Invalid estimate appears at higher confirm count than valid estimate") - - # Check on the expected number of different confirmation counts - # that we might not have valid estimates for - if invalid_estimates > max_invalid: - raise AssertionError("More than (%d) invalid estimates"%(max_invalid)) - return all_estimates - + assert_greater_than_or_equal(i + 1, e["blocks"]) class EstimateFeeTest(BitcoinTestFramework): def set_test_params(self): @@ -151,7 +133,7 @@ class EstimateFeeTest(BitcoinTestFramework): which we will use to generate our transactions. """ self.add_nodes(3, extra_args=[["-maxorphantx=1000", "-whitelist=127.0.0.1"], - ["-blockmaxsize=17000", "-maxorphantx=1000", "-deprecatedrpc=estimatefee"], + ["-blockmaxsize=17000", "-maxorphantx=1000"], ["-blockmaxsize=8000", "-maxorphantx=1000"]]) # Use node0 to mine blocks for input splitting # Node1 mines small blocks but that are bigger than the expected transaction rate. @@ -160,7 +142,6 @@ class EstimateFeeTest(BitcoinTestFramework): # Node2 is a stingy miner, that # produces too small blocks (room for only 55 or so transactions) - def transact_and_mine(self, numblocks, mining_node): min_fee = Decimal("0.00001") # We will now mine numblocks blocks generating on average 100 transactions between each block @@ -169,14 +150,14 @@ class EstimateFeeTest(BitcoinTestFramework): # resorting to tx's that depend on the mempool when those run out for i in range(numblocks): random.shuffle(self.confutxo) - for j in range(random.randrange(100-50,100+50)): - from_index = random.randint(1,2) + for j in range(random.randrange(100 - 50, 100 + 50)): + from_index = random.randint(1, 2) (txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo, self.memutxo, Decimal("0.005"), min_fee, min_fee) tx_kbytes = (len(txhex) // 2) / 1000.0 - self.fees_per_kb.append(float(fee)/tx_kbytes) + self.fees_per_kb.append(float(fee) / tx_kbytes) sync_mempools(self.nodes[0:3], wait=.1) - mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"] + mined = mining_node.getblock(mining_node.generate(1)[0], True)["tx"] sync_blocks(self.nodes[0:3], wait=.1) # update which txouts are confirmed newmem = [] @@ -191,10 +172,6 @@ class EstimateFeeTest(BitcoinTestFramework): self.log.info("This test is time consuming, please be patient") self.log.info("Splitting inputs so we can generate tx's") - # Make log handler available to helper functions - global log - log = self.log - # Start node0 self.start_node(0) self.txouts = [] @@ -210,13 +187,13 @@ class EstimateFeeTest(BitcoinTestFramework): # Use txouts to monitor the available utxo, since these won't be tracked in wallet reps = 0 while (reps < 5): - #Double txouts to txouts2 - while (len(self.txouts)>0): + # Double txouts to txouts2 + while (len(self.txouts) > 0): split_inputs(self.nodes[0], self.txouts, self.txouts2) while (len(self.nodes[0].getrawmempool()) > 0): self.nodes[0].generate(1) - #Double txouts2 to txouts - while (len(self.txouts2)>0): + # Double txouts2 to txouts + while (len(self.txouts2) > 0): split_inputs(self.nodes[0], self.txouts2, self.txouts) while (len(self.nodes[0].getrawmempool()) > 0): self.nodes[0].generate(1) @@ -235,7 +212,7 @@ class EstimateFeeTest(BitcoinTestFramework): self.fees_per_kb = [] self.memutxo = [] - self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting + self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting self.log.info("Will output estimates for 1/2/3/6/15/25 blocks") for i in range(2): diff --git a/test/functional/p2p_fingerprint.py b/test/functional/p2p_fingerprint.py index 93ef73e25e..516ce8555b 100755 --- a/test/functional/p2p_fingerprint.py +++ b/test/functional/p2p_fingerprint.py @@ -4,7 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test various fingerprinting protections. -If an stale block more than a month old or its header are requested by a peer, +If a stale block more than a month old or its header are requested by a peer, the node should pretend that it does not have it to avoid fingerprinting. """ diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py index d6f25158ef..90183474bb 100755 --- a/test/functional/rpc_deprecated.py +++ b/test/functional/rpc_deprecated.py @@ -4,24 +4,24 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test deprecation of RPC calls.""" from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_raises_rpc_error class DeprecatedRpcTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True - self.extra_args = [[], ["-deprecatedrpc=estimatefee", "-deprecatedrpc=createmultisig"]] + self.extra_args = [[], []] def run_test(self): - self.log.info("estimatefee: Shows deprecated message") - assert_raises_rpc_error(-32, 'estimatefee is deprecated', self.nodes[0].estimatefee, 1) - - self.log.info("Using -deprecatedrpc=estimatefee bypasses the error") - self.nodes[1].estimatefee(1) - - self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses") - assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) - self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + # This test should be used to verify correct behaviour of deprecated + # RPC methods with and without the -deprecatedrpc flags. For example: + # + # self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses") + # assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()]) + # self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + # + # There are currently no deprecated RPC methods in master, so this + # test is currently empty. + pass if __name__ == '__main__': DeprecatedRpcTest().main() diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index 5f7a0586e0..6b9c9c15b7 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -223,8 +223,8 @@ class RawTransactionsTest(BitcoinTestFramework): assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[2].fundrawtransaction, rawtx, {'change_type': None}) assert_raises_rpc_error(-5, "Unknown change type", self.nodes[2].fundrawtransaction, rawtx, {'change_type': ''}) rawtx = self.nodes[2].fundrawtransaction(rawtx, {'change_type': 'bech32'}) - tx = self.nodes[2].decoderawtransaction(rawtx['hex']) - assert_equal('witness_v0_keyhash', tx['vout'][rawtx['changepos']]['scriptPubKey']['type']) + dec_tx = self.nodes[2].decoderawtransaction(rawtx['hex']) + assert_equal('witness_v0_keyhash', dec_tx['vout'][rawtx['changepos']]['scriptPubKey']['type']) ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # @@ -676,7 +676,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}), self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee, "subtractFeeFromOutputs": [0]})] - dec_tx = [self.nodes[3].decoderawtransaction(tx['hex']) for tx in result] + dec_tx = [self.nodes[3].decoderawtransaction(tx_['hex']) for tx_ in result] output = [d['vout'][1 - r['changepos']]['value'] for d, r in zip(dec_tx, result)] change = [d['vout'][r['changepos']]['value'] for d, r in zip(dec_tx, result)] diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index c2ca7c70b8..92126ef4b7 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -186,7 +186,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[0].generate(1) self.sync_all() - #THIS IS A INCOMPLETE FEATURE + #THIS IS AN INCOMPLETE FEATURE #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index f8d66def64..a5e66bd959 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -99,7 +99,9 @@ class BitcoinTestFramework(): PortSeed.n = self.options.port_seed - os.environ['PATH'] = self.options.srcdir + ":" + self.options.srcdir + "/qt:" + os.environ['PATH'] + os.environ['PATH'] = self.options.srcdir + os.pathsep + \ + self.options.srcdir + os.path.sep + "qt" + os.pathsep + \ + os.environ['PATH'] check_json_precision() @@ -148,10 +150,11 @@ class BitcoinTestFramework(): self.log.info("Note: bitcoinds were not stopped and may still be running") if not self.options.nocleanup and not self.options.noshutdown and success != TestStatus.FAILED: - self.log.info("Cleaning up") - shutil.rmtree(self.options.tmpdir) + self.log.info("Cleaning up {} on exit".format(self.options.tmpdir)) + cleanup_tree_on_exit = True else: self.log.warning("Not cleaning up dir %s" % self.options.tmpdir) + cleanup_tree_on_exit = False if success == TestStatus.PASSED: self.log.info("Tests successful") @@ -164,6 +167,8 @@ class BitcoinTestFramework(): self.log.error("Hint: Call {} '{}' to consolidate all logs".format(os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + "/../combine_logs.py"), self.options.tmpdir)) exit_code = TEST_EXIT_FAILED logging.shutdown() + if cleanup_tree_on_exit: + shutil.rmtree(self.options.tmpdir) sys.exit(exit_code) # Methods to override in subclass test scripts. diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index c670878d68..0cf3424c71 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -268,7 +268,7 @@ def main(): if args.help: # Print help for test_runner.py, then print help of the first script (with args removed) and exit. parser.print_help() - subprocess.check_call([(config["environment"]["SRCDIR"] + '/test/functional/' + test_list[0].split()[0])] + ['-h']) + subprocess.check_call([sys.executable, os.path.join(config["environment"]["SRCDIR"], 'test', 'functional', test_list[0].split()[0]), '-h']) sys.exit(0) check_script_list(config["environment"]["SRCDIR"]) @@ -312,7 +312,7 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove if len(test_list) > 1 and jobs > 1: # Populate cache try: - subprocess.check_output([tests_dir + 'create_cache.py'] + flags + ["--tmpdir=%s/cache" % tmpdir]) + subprocess.check_output([sys.executable, tests_dir + 'create_cache.py'] + flags + ["--tmpdir=%s/cache" % tmpdir]) except subprocess.CalledProcessError as e: sys.stdout.buffer.write(e.output) raise @@ -342,7 +342,7 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove print('\n============') print('{}Combined log for {}:{}'.format(BOLD[1], testdir, BOLD[0])) print('============\n') - combined_logs, _ = subprocess.Popen([os.path.join(tests_dir, 'combine_logs.py'), '-c', testdir], universal_newlines=True, stdout=subprocess.PIPE).communicate() + combined_logs, _ = subprocess.Popen([sys.executble, os.path.join(tests_dir, 'combine_logs.py'), '-c', testdir], universal_newlines=True, stdout=subprocess.PIPE).communicate() print("\n".join(deque(combined_logs.splitlines(), combined_logs_len))) print_results(test_results, max_len_name, (int(time.time() - time0))) @@ -412,7 +412,7 @@ class TestHandler: tmpdir_arg = ["--tmpdir={}".format(testdir)] self.jobs.append((t, time.time(), - subprocess.Popen([self.tests_dir + test_argv[0]] + test_argv[1:] + self.flags + portseed_arg + tmpdir_arg, + subprocess.Popen([sys.executable, self.tests_dir + test_argv[0]] + test_argv[1:] + self.flags + portseed_arg + tmpdir_arg, universal_newlines=True, stdout=log_stdout, stderr=log_stderr), diff --git a/test/functional/wallet_abandonconflict.py b/test/functional/wallet_abandonconflict.py index 14964438af..8fb860cd7e 100755 --- a/test/functional/wallet_abandonconflict.py +++ b/test/functional/wallet_abandonconflict.py @@ -8,11 +8,12 @@ descendants as abandoned which allows their inputs to be respent. It can be used to replace "stuck" or evicted transactions. It only works on transactions which are not included in a block and are not currently in the mempool. It has - no effect on transactions which are already conflicted or abandoned. + no effect on transactions which are already abandoned. """ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * + class AbandonConflictTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 @@ -28,6 +29,11 @@ class AbandonConflictTest(BitcoinTestFramework): sync_mempools(self.nodes) self.nodes[1].generate(1) + # Can not abandon non-wallet transaction + assert_raises_rpc_error(-5, 'Invalid or non-wallet transaction id', lambda: self.nodes[0].abandontransaction(txid='ff' * 32)) + # Can not abandon confirmed transaction + assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', lambda: self.nodes[0].abandontransaction(txid=txA)) + sync_blocks(self.nodes) newbalance = self.nodes[0].getbalance() assert(balance - newbalance < Decimal("0.001")) #no more than fees lost diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 2cd4127854..f621d41b4e 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -231,13 +231,16 @@ def test_unconfirmed_not_spendable(rbf_node, rbf_node_address): assert_equal([t for t in rbf_node.listunspent(minconf=0, include_unsafe=False) if t["txid"] == bumpid], []) # submit a block with the rbf tx to clear the bump tx out of the mempool, - # then call abandon to make sure the wallet doesn't attempt to resubmit the - # bump tx, then invalidate the block so the rbf tx will be put back in the - # mempool. this makes it possible to check whether the rbf tx outputs are + # then invalidate the block so the rbf tx will be put back in the mempool. + # This makes it possible to check whether the rbf tx outputs are # spendable before the rbf tx is confirmed. block = submit_block_with_tx(rbf_node, rbftx) - rbf_node.abandontransaction(bumpid) + # Can not abandon conflicted tx + assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', lambda: rbf_node.abandontransaction(txid=bumpid)) rbf_node.invalidateblock(block.hash) + # Call abandon to make sure the wallet doesn't attempt to resubmit + # the bump tx and hope the wallet does not rebroadcast before we call. + rbf_node.abandontransaction(bumpid) assert bumpid not in rbf_node.getrawmempool() assert rbfid in rbf_node.getrawmempool() diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py index 77f90ffb81..5e943d048d 100755 --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -20,6 +20,7 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old): found_script_addr = 0 found_addr_chg = 0 found_addr_rsv = 0 + witness_addr_ret = None hd_master_addr_ret = None for line in inputfile: # only read non comment lines @@ -47,7 +48,14 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old): # count key types for addrObj in addrs: - if addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label=": + if addrObj['address'] == addr.split(",")[0] and addrObj['hdkeypath'] == keypath and keytype == "label=": + # a labled entry in the wallet should contain both a native address + # and the p2sh-p2wpkh address that was added at wallet setup + if len(addr.split(",")) == 2: + addr_list = addr.split(",") + # the entry should be of the first key in the wallet + assert_equal(addrs[0]['address'], addr_list[0]) + witness_addr_ret = addr_list[1] found_addr += 1 break elif keytype == "change=1": @@ -63,7 +71,7 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old): found_script_addr += 1 break - return found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret + return found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret, witness_addr_ret class WalletDumpTest(BitcoinTestFramework): @@ -83,6 +91,8 @@ class WalletDumpTest(BitcoinTestFramework): tmpdir = self.options.tmpdir # generate 20 addresses to compare against the dump + # but since we add a p2sh-p2wpkh address for the first pubkey in the + # wallet, we will expect 21 addresses in the dump test_addr_count = 20 addrs = [] for i in range(0,test_addr_count): @@ -101,12 +111,13 @@ class WalletDumpTest(BitcoinTestFramework): result = self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.unencrypted.dump") assert_equal(result['filename'], os.path.abspath(tmpdir + "/node0/wallet.unencrypted.dump")) - found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_unenc = \ + found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_unenc, witness_addr_ret = \ read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, script_addrs, None) assert_equal(found_addr, test_addr_count) # all keys must be in the dump assert_equal(found_script_addr, 2) # all scripts must be in the dump assert_equal(found_addr_chg, 50) # 50 blocks where mined assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys + assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key #encrypt wallet, restart, unlock and dump self.nodes[0].node_encrypt_wallet('test') @@ -116,12 +127,13 @@ class WalletDumpTest(BitcoinTestFramework): self.nodes[0].keypoolrefill() self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.encrypted.dump") - found_addr, found_script_addr, found_addr_chg, found_addr_rsv, _ = \ + found_addr, found_script_addr, found_addr_chg, found_addr_rsv, _, witness_addr_ret = \ read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, script_addrs, hd_master_addr_unenc) assert_equal(found_addr, test_addr_count) assert_equal(found_script_addr, 2) assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now assert_equal(found_addr_rsv, 90*2) + assert_equal(witness_addr_ret, witness_addr) # Overwriting should fail assert_raises_rpc_error(-8, "already exists", self.nodes[0].dumpwallet, tmpdir + "/node0/wallet.unencrypted.dump") diff --git a/test/util/bitcoin-util-test.py b/test/util/bitcoin-util-test.py index 64e826ad0b..30bd13d0dc 100755 --- a/test/util/bitcoin-util-test.py +++ b/test/util/bitcoin-util-test.py @@ -44,7 +44,7 @@ def main(): # Add the format/level to the logger logging.basicConfig(format=formatter, level=level) - bctester(os.path.join(env_conf["SRCDIR"], "test/util/data"), "bitcoin-util-test.json", env_conf) + bctester(os.path.join(env_conf["SRCDIR"], "test", "util", "data"), "bitcoin-util-test.json", env_conf) def bctester(testDir, input_basename, buildenv): """ Loads and parses the input file, runs all tests and reports results""" |