20c9e03554 gui: Call setWalletActionsEnabled(true) only for the first wallet (Hennadii Stepanov)
Pull request description:
On master (a78742830a) there is a bug:
- open an encrypted wallet; please note that the "Encrypt Wallet..." menu item is disabled that is expected:
![Screenshot from 2020-08-03 12-38-37](https://user-images.githubusercontent.com/32963518/89169084-70060c80-d586-11ea-86b9-05ef38d08f41.png)
- then open any other wallet; note that the "Encrypt Wallet..." menu item gets enabled that is wrong:
![Screenshot from 2020-08-03 12-42-36](https://user-images.githubusercontent.com/32963518/89169385-d68b2a80-d586-11ea-9813-a533a847e098.png)
This PR fixes this bug.
ACKs for top commit:
jonasschnelli:
Tested ACK 20c9e03554 - I could reproduce the issue on master and have verify that this PR fixes it.
achow101:
ACK 20c9e03554
Tree-SHA512: 2c9ab94bde8c4f413b0a95c05bf3a1a29f5910e0f99d6639a11dd77758c78af25b060b3fecd78117066ef15b113feb79870bc1347cc04289da915c00623e5787
56a461f727 wallet: fix buffer over-read in SQLite file magic check (Sebastian Falbesoner)
Pull request description:
Looking at our new SQLite database code, I noticed that there is a potential problem in the method `IsSQLiteFile()`: If there is no terminating zero within the first 16 bytes of the file, the `magic` buffer would be over-read in the `std::string` constructor for `magic_str`. Fixed by using the "from buffer" variant of the string ctor (that also takes a size) rather than the "from c-string" variant (see http://www.cplusplus.com/reference/string/string/string/).
The behaviour can be reproduced by the following steps:
* Creating a file of at least 512 bytes in size (to pass the minimum size check) that doesn't contain zero bytes in the magic area, e.g. simply:
`$ python3 -c "print('A'*512)" > /tmp/corrupt_wallet`
* Showing content and size of the `magic_str` string in case the magic check fails
* Create a simple unit test that simply calls `IsSQLiteFile` with the corrupt wallet file
* Run the unit test and see the random gibberish output of `magic_str` after 16 `A`s :-)
Or, TLDR variant, just get the branch https://github.com/theStack/bitcoin/tree/reproduce_sqlite_magic_overread, compile unit Tests and run the script `./reproduce_sqlite_magic_overread.sh`.
Note that this is the minimal diff, probably it would be better to avoid `std::string` at all in this case and just use `memcmp`, strings that include null bytes are pretty confusing.
ACKs for top commit:
promag:
Code review ACK 56a461f727.
practicalswift:
ACK 56a461f72796ca60de28e78f144741eb1a4f5213: patch looks correct
achow101:
ACK 56a461f727
Tree-SHA512: a7aadd4d38eb92337e6281df2980f4bde744dbb6cf112b9cd0f2cab8772730e302db9123a8fe7ca4e7e844c47e68957487adb2bed4518c40b4bed6a69d7922b4
fa299ac273 test: Speed up wallet_resendwallettransactions test with mockscheduler RPC (MarcoFalke)
Pull request description:
Also fixes#20143
ACKs for top commit:
guggero:
ACK fa299ac2
Tree-SHA512: 024ced4aa5f5c266e24fd0583d47b45b19c2a6ae25a06fabeacaa0ac996eec0c45f11cc34b2df17d01759b78ed31a991aa86978aafcc76cb0017382f601bf85a
fa5a91a352 test: Fix typo (one tx is enough) in p2p_feefilter (MarcoFalke)
fa3af2c0d3 test: Fix intermittent issue in p2p_feefilter (MarcoFalke)
Pull request description:
Fixes:
```
Traceback (most recent call last):
File "test/functional/test_framework/test_framework.py", line 126, in main
self.run_test()
File "test/functional/p2p_feefilter.py", line 63, in run_test
self.test_feefilter()
File "test/functional/p2p_feefilter.py", line 117, in test_feefilter
txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00020000'), from_node=node1)['wtxid'] for _ in range(3)]
File "test/functional/p2p_feefilter.py", line 117, in <listcomp>
txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00020000'), from_node=node1)['wtxid'] for _ in range(3)]
File "test/functional/test_framework/wallet.py", line 63, in send_self_transfer
txid = from_node.sendrawtransaction(tx_hex)
File "test/functional/test_framework/coverage.py", line 47, in __call__
return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
File "test/functional/test_framework/authproxy.py", line 146, in __call__
raise JSONRPCException(response['error'], status)
test_framework.authproxy.JSONRPCException: bad-txns-inputs-missingorspent (-25)
ACKs for top commit:
guggero:
ACK fa5a91a3
Tree-SHA512: 51d885753f72e1c91c4580709c15bdab60ff8c9d6f9bcb6db78a560e7e4dd7f76ce23add3303b374174afa3f11f74aa61db189a90c68d7f7655b15e64f51ed96
5aadd4be18 Convert amounts from float to decimal (Prayank)
Pull request description:
> decimal is preferred in accounting applications
https://docs.python.org/3.8/library/decimal.html
Decimal type saves an exact value so better than using float.
~~3 variables declared with type as 'Decimal' in [test/functional/mempool_accept.py](https://github.com/bitcoin/bitcoin/blob/master/test/functional/mempool_accept.py): fee, fee_expected, output_amount~~
~~Not required to convert to string anymore for using the above variables as decimal~~
+ fee, fee_expected, output_amount
~~+ 8 decimal places~~
+ Using value of coin['amount'] as decimal and removed 'int'
+ Removed unnecessary parentheses
+ Remove str() and use quotes
Fixes https://github.com/bitcoin/bitcoin/issues/20011
ACKs for top commit:
guggero:
ACK 5aadd4be18
Tree-SHA512: 5877cf3837e5b65bec0fc8909de141a720bfa02a747513e21d20f3c41ec0cfecc524d2c347a96596b0a1a97900da2acf08b799f26b11d537e4dcddc6ce45f38e
If there is no terminating zero within the 16 magic bytes, the buffer would be
over-read in the std::string constructor. Fixed by using the "from buffer"
variant of the ctor (that also takes a size) rather than the "from c-string"
variant.
fa5f46600f test: Fix rpc_net intermittent issue (MarcoFalke)
Pull request description:
Without the sync, the nodes might generate blocks at the same height and thus never be able to sync
ACKs for top commit:
practicalswift:
ACK fa5f46600fb98f1b35346bedc1a66c9019d01114: patch looks correct
Tree-SHA512: 21255795c2121c71fc620beb766855e57c7af94a668331d1b625665e22eb4b485a2b5c3ad2bb9a7042744f3c3e49c71251bcec41ba25bca03fd54aae32968a3a
+ fee, fee_expected, output_amount
+ Using value of coin['amount'] as decimal and removed 'int'
+ Removed unnecessary parentheses
+ Remove str() and use quotes
fa4074b395 Show name, format and if uses descriptors in bitcoin-wallet tool (Jonas Schnelli)
Pull request description:
ACKs for top commit:
MarcoFalke:
ACK fa4074b395
jonatack:
re-ACK fa4074b395
Tree-SHA512: cf6ee96ff21532fc4b0ba7a0fdfdc1fa485c9b1495447350fe65cd0bd919e0e0280613933265cdee069b8c29ccf015ac374535a70cac3d4fb89f4d08b3a03519
3c7d9ab8c8 test: Move (dis)?connect_nodes globals into TestFramework as helpers (Elliott Jin)
4b16c61461 scripted-diff: test: Replace uses of (dis)?connect_nodes global (Prayank)
be386840d4 test: Replace use of (dis)?connect_nodes globals (Elliott Jin)
Pull request description:
`util.py` defines global helper functions `connect_nodes` and `disconnect_nodes`; however, these functions are confusing because they take a node and an index (instead of two indexes).
The `TestFramework` object has enough context to convert from `i` to `self.nodes[i]`, so we can replace all instances of `connect_nodes(self.nodes[a], b)` with `self.connect_nodes(a, b)`. Similarly, we can replace instances of `disconnect_nodes`.
The approach taken in this PR builds on #19945 but uses a scripted-diff for the majority of the changes.
Fixes: #19821
ACKs for top commit:
MarcoFalke:
ACK 3c7d9ab8c8
guggero:
ACK 3c7d9ab8
Tree-SHA512: e027092748602904abcd986d7299624c8754c3236314b6d8e392e306741c212f266c2207e385adfb194f67ae6559a585ee7b15d639b1d65c4651dbf503e5931a
2d5793c016 Bugfix: chainparams: Add missing (disabled) Taproot deployment for Signet (Luke Dashjr)
Pull request description:
Is there a way we can trigger compiler warnings if a deployment is undefined?
ACKs for top commit:
decryp2kanon:
utACK 2d5793c016
MarcoFalke:
review ACK 2d5793c016
Tree-SHA512: 135cefae0f8dc552b0f682c2b87cabca7a4716290a36410a55968850e803a5049234e3cc597c8ef8d7917ae5d5ea3fb851e160df171b6793114c6bc01c5ea3e7
-BEGIN VERIFY SCRIPT-
# max-depth=0 excludes test/functional/test_framework/...
FILES=$(git grep -l --max-depth 0 "connect_nodes" test/functional)
# Replace (dis)?connect_nodes(self.nodes[a], b) with self.(dis)?connect_nodes(a, b)
sed -i 's/\b\(dis\)\?connect_nodes(self\.nodes\[\(.*\)\]/self.\1connect_nodes(\2/g' $FILES
# Remove imports in the middle of a line
sed -i 's/\(dis\)\?connect_nodes, //g' $FILES
sed -i 's/, \(dis\)\?connect_nodes//g' $FILES
# Remove imports on a line by themselves
sed -i '/^\s*\(dis\)\?connect_nodes,\?$/d' $FILES
sed -i '/^from test_framework\.util import connect_nodes$/d' $FILES
-END VERIFY SCRIPT-
Co-authored-by: Elliott Jin <elliott.jin@gmail.com>
A later scripted-diff commit replaces the majority of uses, which all
follow this pattern:
(dis)?connect_nodes(self.nodes[a], b)
This commit replaces the few "special cases".
624bab00dd test: add coverage for getwalletinfo format field (Jon Atack)
5e737a0092 rpc, wallet: Expose database format in getwalletinfo (João Barbosa)
Pull request description:
Support for sqlite based wallets was added in #19077. This PR adds the `format` key in `getwalletinfo` response, that can be `bdb` or `sqlite`.
ACKs for top commit:
jonatack:
Tested ACK 624bab00dd
laanwj:
Code review ACK 624bab00dd.
MarcoFalke:
doesn't hurt ACK 624bab00dd
hebasto:
ACK 624bab00dd, tested on Linux Mint 20 (x86_64).
meshcollider:
utACK 624bab00dd
Tree-SHA512: a81f8530f040f6381d33e073a65f281993eccfa717424ab6e651c1203cbaf27794dcb7175570459e7fdaa211565bc060d0a3ecbe70d2b6f9c49b8d5071e4441c
c8abbc9d1f p2p: declare Announcement::m_state as uint8_t, add getter/setter (Jon Atack)
Pull request description:
Change `Announcement::m_state` in `tx_request.cpp` from type `State` to `uint8_t` and add a getter and setter for the conversion to/from `State`. This should silence these travis ci gcc compiler warnings:
```
txrequest.cpp:73:21: warning: ‘{anonymous}::Announcement::m_state’ is
too small to hold all values of ‘enum class {anonymous}::State’
State m_state : 3;
^
```
The gcc warnings are based on the maximum value held by the underlying uint8_t enumerator type, even though the intention of the bitfield declaration is the maximum declared enumerator value. They have apparently been silenced in gcc 8.4+ and 9.3+ according to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
ACKs for top commit:
sipa:
utACK c8abbc9d1f
ajtowns:
ACK c8abbc9d1f -- quick code review
hebasto:
ACK c8abbc9d1f, tested on Bionic (x86_64, gcc 7.5.0):
Tree-SHA512: 026721dd7a78983a72da77638d3327d2b252bef804e489278a852f000046c028d6557bbd6c2b4cea391d4e01f9264a1be842d502047cb90b2997cc37bee59e61
fa38093bee doc: Merge release notes (MarcoFalke)
Pull request description:
Now that all features are merged, open release notes editing at the wiki
https://github.com/bitcoin-core/bitcoin-devwiki/wiki/0.21.0-Release-Notes-Draft
ACKs for top commit:
fanquake:
ACK fa38093bee
Tree-SHA512: ced161a2fcb0366a77a05b020c8dd65a0cf0a0de17b8260bbca9b5833ed370f92b1b81116bfc59b83380bf28b55d8963c628cf13a0cad603e5c823341b446065
fa48405ef8 Warn on unknown rw_settings (MarcoFalke)
Pull request description:
Log a warning to debug log if unknown settings are encountered. This should probably only ever happen when the software is upgraded.
Something similar is already done for the command line and config file. See:
* test: Add test for unknown args #16234 (commit fa7dd88b71)
ACKs for top commit:
ryanofsky:
Code review ACK fa48405ef8. Looks good and I could see this being helpful for debugging. Thanks for taking suggestions
Tree-SHA512: cec7d88adf84fa0a842f56b26245157736eb50df433db951e622ea07fd145b899822b24cdab1d8b36c066415ce4f0ef09b493fa8a8d691532822a59c573aafa7
76bbcc414f test: Fix -Wunused-function warning if configured --without-libs (Hennadii Stepanov)
Pull request description:
On master (80c8a02f1b) compiling with gcc:
```
$ ./configure --without-libs
$ make clean && make
...
test/script_tests.cpp:1369:23: warning: ‘CScriptWitness script_tests::ScriptWitnessFromJSON(const UniValue&)’ defined but not used [-Wunused-function]
1369 | static CScriptWitness ScriptWitnessFromJSON(const UniValue& univalue)
| ^~~~~~~~~~~~~~~~~~~~~
test/script_tests.cpp:1357:28: warning: ‘std::vector<CTxOut> script_tests::TxOutsFromJSON(const UniValue&)’ defined but not used [-Wunused-function]
1357 | static std::vector<CTxOut> TxOutsFromJSON(const UniValue& univalue)
| ^~~~~~~~~~~~~~
test/script_tests.cpp:1350:28: warning: ‘CMutableTransaction script_tests::TxFromHex(const string&)’ defined but not used [-Wunused-function]
1350 | static CMutableTransaction TxFromHex(const std::string& str)
| ^~~~~~~~~
...
```
This change is move-only (nice to review with `git diff --color-moved`).
ACKs for top commit:
practicalswift:
ACK 76bbcc414f3001b16ac0101f738ed0b3e6f1a372: diff looks correct
fanquake:
ACK 76bbcc414f - verified that this fixes the warnings. As mentioned can be reviewed with `git diff HEAD~ --color-moved=dimmed_zebra`.
Tree-SHA512: 7799ac190d1e3f15e38b36cfcd1f8d138be80cab6c6cfad8f7828e07deffc2037d52f1d967f7f233a3a8ed74eee184f5275076c2f364c3e363c77a1f40aa5030
bd5215103e random: fixes read buffer resizing in RandAddSeedPerfmon (Ethan Heilman)
Pull request description:
As shown below when resizing the read buffer `vData` `std::max((vData.size() * 3) / 2, nMaxSize)` is used. This means that the buffer size immediately jumps to `nMaxSize`. I believe the intend of this code is to grow the buffer size through several steps rather than immediately resize it to the max size.
```cpp
std::vector<unsigned char> vData(250000, 0);
long ret = 0;
unsigned long nSize = 0;
const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
while (true) {
nSize = vData.size();
ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize);
if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
break;
vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
}
```
vData always starts at size 250,000 and nMaxSize is always 10,000,000 so the first time this line is reached:
```cpp
vData.resize(std::max((vData.size() * 3) / 2, nMaxSize));
```
the effect will always be to resize vData to nMaxSize. Then because the loop terminates when vData.size >= 10,000,000 only one resize operation will take place.
To fix this issue we replace `std::min` with `std::max`
This PR also adds a comment clarifying the behavior of this function the first time it is called.
ACKs for top commit:
fanquake:
ACK bd5215103e - thanks for taking a look at this Ethan. Swapping from `std::max` to `std::min` here certainly seems correct.
Tree-SHA512: 7c65f700e5bbe44bc2f1ffdcdc99ec19c542894c95b5ee9791facd09d02afae88d1f8f35af129719e4860db94bc790856e7adb1d218a395381e7c2913b95f1d0
95fedd33a2 refactor: Clean up -Wlogical-op warning (maskoficarus)
Pull request description:
This is a quick patch that fixes#19912 . This change prevents a -Wlogical-op warning that occurs because we're treating a const int value as a boolean. There's no sense checking if a non-zero constant has a value, so I've removed the check.
#18836 also addresses the same warning, but has a larger scope and will require more review. This pull request will act as a patch to prevent this compile warning until 18836 is merged.
ACKs for top commit:
MarcoFalke:
review ACK 95fedd33a2
hebasto:
ACK 95fedd33a2, tested on Linux Mint 20 (x86_64):
Tree-SHA512: 13a9d7f7cb472f4c22a01ca2f9771a75267ff769bdae9d0dc6b2c7f3b05369f6dfa859be2b172b39c15ede6c44cddf556380b3565e42850faa65ccd3fe6e175b
da0988daf1 scripted-diff: rename vRecvGetData (Neha Narula)
ba951812ec Guard vRecvGetData (now in net processing) with its own mutex (Neha Narula)
2d9f2fca43 Move vRecvGetData to net processing (Neha Narula)
673247b58c Lock before checking if orphan_work_set is empty; indicate it is guarded (Neha Narula)
8803aee668 Move m_orphan_work_set to net_processing (Neha Narula)
9c47cb29f9 [Rename only] Rename orphan_work_set to m_orphan_work_set. (Neha Narula)
Pull request description:
Add annotations to guard `vRecvGetData` and `orphan_work_set` and fix up places where they were accessed without a lock. There is no current data race because they happen to be accessed by only one thread, but this might not always be the case.
Original discussion: https://github.com/bitcoin/bitcoin/pull/18861#discussion_r451778445
ACKs for top commit:
MarcoFalke:
review ACK da0988daf1🐬
jnewbery:
Code review ACK da0988daf1
hebasto:
ACK da0988daf1, I have reviewed the code and it looks correct, I agree it can be merged.
Tree-SHA512: 31cadd319ddc9273a87e77afc4db7339fd636e816b5e742eba5cb32927ac5cc07a672b2268d2d38a75a0f1b17d93836adab9acf7e52f26ea9a43f54efa57257e
b128b56672 test: add logging for mining_getblocktemplate_longpoll.py (Sebastian Falbesoner)
8ee3536b2b test: remove unused helpers random_transaction(), make_change() and gather_inputs() (Sebastian Falbesoner)
fddce7e199 test: use MiniWallet for mining_getblocktemplate_longpoll.py (Sebastian Falbesoner)
Pull request description:
This PR enables one more of the non-wallet functional tests (mining_getblocktemplate_longpoll.py) to be run even with the Bitcoin Core wallet disabled by using the new MiniWallet instead, as proposed in #20078. Also adds missing log messages for the subtests.
This was the only functional test that used the `random_transaction` helper in `test_framework/util.py`, hence it is removed, together with other helpers (`make_change` and `gather_inputs`) that were again only used by `random_transaction`.
ACKs for top commit:
MarcoFalke:
ACK b128b56672
Tree-SHA512: 09a5fa7b0f5976a47040f7027236d7ec0426d5a4829a082221c4b5fae294470230e89ae3df0bca0eea26833162c03980517f5cc88761ad251c3df4c4a49bca46
51365674e8 script: Make ComputeEntrySchnorr and ComputeEntryECDSA const to clarify contract (practicalswift)
Pull request description:
Make `ComputeEntrySchnorr` and `ComputeEntryECDSA` `const` to clarify contract.
ACKs for top commit:
benthecarman:
ACK 51365674e8
theStack:
ACK 51365674e8👌
sipa:
utACK 51365674e8
Tree-SHA512: 0f7a72bf6df7a97d21045ead9db398d2a9527c358aeeb894dec34a5386da4cc316e2f3326716e960ef8aa47bf73b99d1f92bb6d45dfa7871c84624bcad8a79f1
fa68755364 contrib: Fix gen_key_io_test_vectors.py imports (MarcoFalke)
Pull request description:
The script currently fails with
```
Traceback (most recent call last):
File "./gen_key_io_test_vectors.py", line 18, in <module>
from segwit_addr import bech32_encode, decode, convertbits, CHARSET
ImportError: cannot import name 'decode' from 'segwit_addr'
```
Fix that.
Also, unrelated cleanup to use the `bytearray.hex()` method instead of importing a library. https://docs.python.org/3.5/library/stdtypes.html#bytes.hex
ACKs for top commit:
theStack:
tested ACK fa68755364
Tree-SHA512: 45ff7d710de3d0ef5ac6d91543cff0edff6189d2cd00b0f8889f4361e66ef1825f12aea9e71d62038c14a7a531bfc95ffe9a1df83b85aa7f3dd666df07a6be81
to silence these Travis CI GCC compiler warnings:
txrequest.cpp:73:21: warning: ‘{anonymous}::Announcement::m_state’ is
too small to hold all values of ‘enum class {anonymous}::State’
State m_state : 3;
^
The warnings are based on the maximum value held by the underlying uint8_t
enumerator type, though the intention of the bitfield declaration is the
maximum declared enumerator value.
The warning been silenced in GCC 8.4+ and 9.3+ according to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414
0d9d2a1f7c Only update the updateSmartFeeLabel once in sync (Jonas Schnelli)
Pull request description:
Calling `updateSmartFeeLabel` and therefore `estimateSmartFee` is pointless during IBD.
GUI freezes appear because `estimateSmartFee` competes with `processBlock` for the `m_cs_fee_estimator` lock leading to multiple seconds of blocking the GUI thread in `updateSmartFeeLabel`.
ACKs for top commit:
ryanofsky:
Code review ACK 0d9d2a1f7c. Clever fix. Didn't test but I remember I could reproduce the startup issue easily before by putting a sleep in estimateSmartFee.
promag:
Code review ACK 0d9d2a1f7c.
hebasto:
ACK 0d9d2a1f7c, tested on Linux Mint 20 (x86_64) with `QT_FATAL_WARNINGS=1` and `-debug=qt`.
Tree-SHA512: 85ec2266f06ddd7b523e24d2a462f10ed965d5b4d479005263056f81b7fe49996e1568dafb84658af406e9202ed3bfa846d59c10bb951e0f97cee230e30fafd5
d438d609cd QA: Use GBT to get block versions correct (Luke Dashjr)
1df2cd1c8f QA: blocktools: Accept block template to create_block (Luke Dashjr)
Pull request description:
The goal here is to decouple unrelated tests from the details of block versions.
Currently, these tests are forcing specific versions of blocks for no real reason.
ACKs for top commit:
fjahr:
re-ACK d438d609cd
benthecarman:
ACK d438d60
Tree-SHA512: 523b1cd4dac8d65c88432e126ce7f60df96ca4b94f7ecc8e83ba4ffbade23e2afe7055fdf586ce3c195a533f2004e63fff83add4267b39473a581c9f1c6d5340
1d22300b99 Address functional test nits (Pieter Wuille)
5669642a0b docs: mention BIPs 340-342 in doc/bips.md (Pieter Wuille)
Pull request description:
This addresses some nits in the tests, and adds entries for BIP 340-342 to doc/bips.md.
ACKs for top commit:
fanquake:
ACK 1d22300b99
benthecarman:
ACK 1d22300b99
Tree-SHA512: ad8f937dc6a34db86c585f65beb80e7eceda1822d9a20c86346a319908870381062856d0b95b42049a2791317a038c77fbcbf896c9f4aaa7318e4864b7fcf7a4
3333077823 rpc: Adjust witness-tx deserialize error message (MarcoFalke)
cccc752569 rpc: Properly deserialize txs with witness before signing (MarcoFalke)
Pull request description:
Signing a transaction can only happen when the transaction has inputs. A transaction with inputs can always be deserialized as witness-transaction. If `try_no_witness` decoding is attempted, this will lead to rare intermittent failures.
Fixes#18803
ACKs for top commit:
achow101:
ACK 3333077823
ajtowns:
ACK 3333077823
Tree-SHA512: 73f8a5cdfe03fb0e68908d2fa09752c346406f455694a020ec0dd1267ef8f0a583b8e84063ea74aac127106dd193b72623ca6d81469a94b3f5b3c766ebf2c42b