aboutsummaryrefslogtreecommitdiff
path: root/test/functional
AgeCommit message (Collapse)Author
2018-12-13Merge #14805: tests: Support calling add_nodes more than onceWladimir J. van der Laan
98a1846b00d9c3076d6dcd96244fae6f923e26a0 tests: Support calling add_nodes more than once (Steven Roose) Pull request description: Ran into this while writing [a multi-chain test for Elements](https://github.com/ElementsProject/elements/pull/458) where I call this method more than once. Tree-SHA512: f2d698fcb560552aa5d81a4c3fbf40b7269b228b34d85a118291649ef83f8c0a30cd82a28d418237b55893bcecd538046b704e64a4d8a41f2c0aef8033dc83e5
2018-12-13Merge #14926: test: consensus: Check that final transactions are validWladimir J. van der Laan
aaaa8eb1edba2a28916d5da6001d421c1b1b253b test: consensus: Check that final transactions are valid (MarcoFalke) fae3617d79deee73dd375dc3ea5f4204a74420c5 test: Correctly deserialize without witness (MarcoFalke) Pull request description: There is no check that checks that final transactions are valid, i.e. the consensus rules could be changed (accidentally) with none of the tests failing. Tree-SHA512: 48f4c24bfcc525ddbc1bfe8c37131953b464823428c1f7a278ba6d98b98827b6b84a8eb2b33396bfb5b8cc4012b7cc1cd771637f405ea20beddae001c22aa290
2018-12-13Merge #14884: Travis: enforce Python 3.4 support through linterWladimir J. van der Laan
31926ee8cfc73501524dfa0fef2ccbaa786d6a00 [test] functional framework: add CScript hex() for Python 3.4 (Sjors Provoost) 74ce32683199b987e45eb16f0320ae392ff10edc [test] Travis: enforce Python 3.4 support in functional tests (Sjors Provoost) Pull request description: The minimum supported version of Python is 3.4 according to [dependencies.md](https://github.com/bitcoin/bitcoin/blob/master/doc/dependencies.md). This PR makes the Travis linter use this version in order to catch accidental use of modern syntax. Tree-SHA512: 71b2c102be72b135a8ba049378d66875760f20a04a657102a399240c5c2b2ddbdfa7d5ab4c0c0242ecc3259e0ee8eb2273f331bc5eb824f4ae4c3cc58aea37ac
2018-12-13Merge #14903: tests: Handle ImportError explicitly, improve comparisons ↵Wladimir J. van der Laan
against None c9ba253f4f5d675d7736d24c1167229d0898ef1a Add E711 to flake8 check (Daniel Ingram) 17b55202dae8d6e21d2490de89b345c55f7694c0 Compare to None with is/is not (Daniel Ingram) 1b89074ae27ce123adbeed57343deaef13c14f81 Change '== None' to 'is None' (Daniel Ingram) 16d293772365d57cc1a279d5ad0fa6f44b12ed54 Handle exception as ImportError (Daniel Ingram) Pull request description: Tree-SHA512: aa5875ea3d9ac47ac898545ff023b511042cd377ea0c4594074daae119f3d4f3fc295721aad94a732a907086ecb32bce19a8eed38adf479f12663c4e8944f721
2018-12-12[test] functional framework: add CScript hex() for Python 3.4Sjors Provoost
test/functional/wallet_importmulti.py failed with: AttributeError: 'CScript' object has no attribute 'hex'
2018-12-11Merge #14886: [tests] Refactor importmulti testsMarcoFalke
ee3b21dccb [tests] Add docstring for wallet_importmulti.py (John Newbery) fbdba40594 [tests] add test_address method to wallet_import.py (John Newbery) fd3a02c381 [tests] add test_importmulti method to wallet_import.py (John Newbery) 08a4a0f70f [tests] add get_multisig function to wallet_importmulti.py (John Newbery) 7c99614b40 [tests] add get_key function to wallet_importmulti.py (John Newbery) e5a8ea8f14 [tests] tidy up imports in wallet_importmulti.py (John Newbery) cb41ade6b1 [tests] fix flake8 warnings in wallet_importmulti.py (John Newbery) Pull request description: https://github.com/bitcoin/bitcoin/pull/14565 needs test coverage. This PR refactors wallet_importmulti.py to the following pattern: 1. Add `get_key()` and `get_multisig()` methods, which generate keys on node0 and return the priv/pubkeys and all scriptPubKey and address variants. 2. Add `test_importmulti()` method, which takes an importmulti request, sends it to node1 and tests against success and error codes/messages. 3. Add `test_address()` method, which takes an address, sends it as a getaddressinfo request to node1 and tests the values returned. This does not add any specific testing for #14565, but makes it very straightforward to add that testing: `test_importmulti()` can be easily updated to test for returned warnings, and `test_address()` can be called multiple times against the different address variants for a singlesig/multisig. Tree-SHA512: e0ae9d3436f0b4eec4f6b9bdc0f02aef49c5a16bbac319fd47b2cfcaf01d01780d7b296280e8760686a57fac63275eec09e2959d8aaeceae1b406d8eff768435
2018-12-11Merge #14857: wallet_keypool_topup.py: Test for all keypool address typesMarcoFalke
0dcac51049 wallet_keypool_topup.py: Test for all keypool address types (Gregory Sanders) Pull request description: To protect against regressions if key scanning is changed. Tree-SHA512: d1c4bb033bafd97203a3f68fb262a501442be947907d67902f0391fbdec39c095196403c7675e602806cc68d7e2d1f552ab339a58346162379978d06dad1c4bb
2018-12-11test: consensus: Check that final transactions are validMarcoFalke
2018-12-11test: Correctly deserialize without witnessMarcoFalke
2018-12-10[tests] Add docstring for wallet_importmulti.pyJohn Newbery
Adds a docstring describing the new importmulti test.
2018-12-10[tests] add test_address method to wallet_import.pyJohn Newbery
Adds a new test_address method for testing the imported addresses.
2018-12-10[tests] add test_importmulti method to wallet_import.pyJohn Newbery
Adds a new test_importmulti method for testing the importmulti RPC method.
2018-12-10[tests] add get_multisig function to wallet_importmulti.pyJohn Newbery
Adds a new get_multisig function which generates a new multisig and returns the public keys, private keys and all script and address types.
2018-12-10[tests] add get_key function to wallet_importmulti.pyJohn Newbery
Adds a new get_key function which generates a new key and returns the public key, private key and all script and address types.
2018-12-10Compare to None with is/is notDaniel Ingram
2018-12-07Merge #14788: tests: Possible fix the permission error when the tests open ↵MarcoFalke
the cookie file d6b3790d1a tests: check readability of cookie file (Chun Kuan Lee) Pull request description: This PR would wait until the `.cookie` file is readable Possible fix no. 5 `PermissionError` in #14446 Tree-SHA512: e7055c7ca26a6eadbbe19e4eef08ffee61cd17de79b30af2f0d090f0ad81ca24815e3c7e034e5e30d47c580bb0b221b3955e9ff2fcec2274fbf7b9232ab0cdc7
2018-12-07Merge #14795: test: allows test_runner command line to receive parameters ↵MarcoFalke
for each test 5c40e7b91a test: allows test_runner command line to receive parameters for each test (marcoagner) Pull request description: Fixes #14791. Seems to address the asked behaviour in a simple way, but could address more if a more complex behaviour is found to be needed (e.g. call `rpc_bind --ipv4` without the ".py" and have it added). Tree-SHA512: d7e21dd0ada36dd97dac71196bb97702a92986b181beb3753e37e3294b899fb65129aff5f9a45fe92b06fbf7c74e605ccb87a422f874f7a85d30401f4c2228c8
2018-12-06rpc: Avoid creating non-standard raw transactionsMarcoFalke
2018-12-06[tests] tidy up imports in wallet_importmulti.pyJohn Newbery
2018-12-06[tests] fix flake8 warnings in wallet_importmulti.pyJohn Newbery
2018-12-06Merge #14670: http: Fix HTTP server shutdownWladimir J. van der Laan
28479f926f21f2a91bec5a06671c60e5b0c55532 qa: Test bitcond shutdown (João Barbosa) 8d3f46ec3938e2ba17654fecacd1d2629f9915fd http: Remove timeout to exit event loop (João Barbosa) e98a9eede2fb48ff33a020acc888cbcd83e24bbf http: Remove unnecessary event_base_loopexit call (João Barbosa) 6b13580f4e3842c11abd9b8bee7255fb2472b6fe http: Unlisten sockets after all workers quit (João Barbosa) 18e968581697078c36a3c3818f8906cf134ccadd http: Send "Connection: close" header if shutdown is requested (João Barbosa) 02e1e4eff6cda0bfc24b455a7c1583394cbff6eb rpc: Add wait argument to stop (João Barbosa) Pull request description: Fixes #11777. Reverts #11006. Replaces #13501. With this change the HTTP server will exit gracefully, meaning that all requests will finish processing and sending the response, even if this means to wait more than 2 seconds (current time allowed to exit the event loop). Another small change is that connections are accepted even when the server is stopping, but HTTP requests are rejected. This can be improved later, especially if chunked replies are implemented. Briefly, before this PR, this is the order or events when a request arrives (RPC `stop`): 1. `bufferevent_disable(..., EV_READ)` 2. `StartShutdown()` 3. `evhttp_del_accept_socket(...)` 4. `ThreadHTTP` terminates (event loop exits) because there are no active or pending events thanks to 1. and 3. 5. client doesn't get the response thanks to 4. This can be verified by applying ```diff // Event loop will exit after current HTTP requests have been handled, so // this reply will get back to the client. StartShutdown(); + MilliSleep(2000); return "Bitcoin server stopping"; } ``` and checking the log output: ``` Received a POST request for / from 127.0.0.1:62443 ThreadRPCServer method=stop user=__cookie__ Interrupting HTTP server ** Exited http event loop Interrupting HTTP RPC server Interrupting RPC tor: Thread interrupt Shutdown: In progress... torcontrol thread exit Stopping HTTP RPC server addcon thread exit opencon thread exit Unregistering HTTP handler for / (exactmatch 1) Unregistering HTTP handler for /wallet/ (exactmatch 0) Stopping RPC RPC stopped. Stopping HTTP server Waiting for HTTP worker threads to exit msghand thread exit net thread exit ... sleep 2 seconds ... Waiting for HTTP event thread to exit Stopped HTTP server ``` For this reason point 3. is moved right after all HTTP workers quit. In that moment HTTP replies are queued in the event loop which keeps spinning util all connections are closed. In order to trigger the server side close with keep alive connections (implicit in HTTP/1.1) the header `Connection: close` is sent if shutdown was requested. This can be tested by ``` bitcoind -regtest nc localhost 18443 POST / HTTP/1.1 Authorization: Basic ... Content-Type: application/json Content-Length: 44 {"jsonrpc": "2.0","method":"stop","id":123} ``` Summing up, this PR: - removes explicit event loop exit — event loop exits once there are no active or pending events - changes the moment the listening sockets are removed — explained above - sends header `Connection: close` on active requests when shutdown was requested which is relevant when it's a persistent connection (default in HTTP 1.1) — libevent is aware of this header and closes the connection gracefully - removes event loop explicit break after 2 seconds timeout Tree-SHA512: 4dac1e86abe388697c1e2dedbf31fb36a394cfafe5e64eadbf6ed01d829542785a8c3b91d1ab680d3f03f912d14fc87176428041141441d25dcb6c98a1e069d8
2018-12-04Merge #14861: tests: Modify rpc_bind to conform to #14532 behaviour.Wladimir J. van der Laan
f3cf95ffd tests: Modify rpc_bind to conform to #14532 behaviour. (Carl Dong) Pull request description: Fixes: https://github.com/bitcoin/bitcoin/issues/14792 Tree-SHA512: 5ee63a06c92dae5406515e9e483188309b82e07b760f363d8c8ec46a42fe5f75f88724759b0ac8ef596ee28a135626e0582f575855c5dfec2fbfff2249a109f7
2018-12-04Merge #14733: P2P: Make peer timeout configurable, speed up very slow test ↵Wladimir J. van der Laan
and ensure correct code path tested. 48b37db50 make peertimeout a debug argument, remove error message translation (Zain Iqbal Allarakhia) 8042bbfbf p2p: allow p2ptimeout to be configurable, speed up slow test (Zain Iqbal Allarakhia) Pull request description: **Summary:** 1. _Primary_: Adds a `debug_only=true` flag for peertimeout, defaults to 60 sec., the current hard-coded setting. 2. _Secondary_: Drastically speeds up `p2p_timeout.py` test. 3. _Secondary_: Tests that the correct code path is being tested by adding log assertions to the test. **Rationale:** - P2P timeout was hard-coded: make it explicitly specified and configurable, instead of a magic number. - Addresses #13518; `p2p_timeout.py` takes 4 sec. to run instead of 61 sec. - Makes `p2p_timeout.py` more explicit. Previously, we relied on a comment to inform us of the timeout amount being tested. Now it is specified directly in the test via passing in the new arg; `-peertimeout=3`. - Opens us up to testing more P2P scenarios; oftentimes slow tests are the reason we don't test. **Locally verified changes:** _With Proposed Change (4.7 sec.):_ ``` $ time ./test/functional/p2p_timeouts.py 2018-11-19T00:04:19.077000Z TestFramework (INFO): Initializing test directory /tmp/testhja7g2n7 2018-11-19T00:04:23.479000Z TestFramework (INFO): Stopping nodes 2018-11-19T00:04:23.683000Z TestFramework (INFO): Cleaning up /tmp/testhja7g2n7 on exit 2018-11-19T00:04:23.683000Z TestFramework (INFO): Tests successful real 0m4.743s ``` _Currently on master (62.8 sec.):_ ``` $ time ./test/functional/p2p_timeouts.py 2018-11-19T00:06:10.948000Z TestFramework (INFO): Initializing test directory /tmp/test6mo6k21h 2018-11-19T00:07:13.376000Z TestFramework (INFO): Stopping nodes 2018-11-19T00:07:13.631000Z TestFramework (INFO): Cleaning up /tmp/test6mo6k21h on exit 2018-11-19T00:07:13.631000Z TestFramework (INFO): Tests successful real 1m2.836s ``` _Error message demonstrated for new argument `-peertimeout`:_ ``` $ ./bitcoind -peertimeout=-5 ... Error: peertimeout cannot be configured with a negative value. ``` Tree-SHA512: ff7a244ebea54c4059407bf4fb86465714e6a79cef5d2bcaa22cfe831a81761aaf597ba4d5172fc2ec12266f54712216fc41b5d24849e5d9dab39ba6f09e3a2a
2018-12-04Merge #14816: Add CScriptNum decode python implementation in functional suiteWladimir J. van der Laan
2012d4df2 Add CScriptNum decode python implementation in functional suite (Gregory Sanders) Pull request description: I needed this for reasons and thought it'd be good to upsteam it. Tree-SHA512: 6ea89fa2a5f5a7759ba722f2b4ed5cd6423ebfff4e83ac8b8b5c935e6aa479684e626c5f41fa020816d2a9079a99af5564e30808594d5c13e3b51ec9b474926d
2018-12-03tests: Modify rpc_bind to conform to #14532 behaviour.Carl Dong
- Even when rpcallowip is specified, only bind localhost - Explicitly bind in run_allowip_test
2018-12-03wallet_keypool_topup.py: Test for all keypool address typesGregory Sanders
2018-11-30Merge #14845: [tests] Add wallet_balance.pyMarcoFalke
c1825b9d39 [tests] Add wallet_balance.py (John Newbery) Pull request description: Adds a test specifically to test the wallet's getbalance and getunconfirmedbalance RPCs. `wallet_basic.py` is too large and should be broken down into more focused test cases. I wrote `wallet_balance.py` to test the changes in #14602. Offering as a PR in case people think it's more generally useful. Tree-SHA512: 573ae8faf377df3d87d5112870b40690efb285fc5578fff8acc2ac1a0e4625ae65d3dfa8abbac577c87bec015038f425833783fa09f014f87906e8d098ed30d7
2018-11-30Merge #14380: fix assert crash when specified change output spend size is ↵MarcoFalke
unknown 0fb2e69815 CreateTransaction: Assume minimum p2sh-p2wpkh spend size for unknown change (Gregory Sanders) b06483c96a Remove stale comment in CalculateMaximumSignedInputSize (Gregory Sanders) Pull request description: This is triggered anytime a fundraw type call(psbt or legacy) is used with a change output address that the wallet doesn't know how to sign for. This regression was added in 6a34ff5335786615771ca423134a484b04831c4e since BnB coin selection actually cares about this. The fix is to assume the smallest typical spend, a P2SH-P2WPKH, which is calculated using a "prototype" dummy signature flow. Future work could generalize this infrastructure to get estimated sizes of inputs for a variety of types. I also removed a comment which I believe is stale and misleading. Tree-SHA512: c7e2be189e524f81a7aa4454ad9370cefba715e3781f1e462c8bab77e4d27540191419029e3ebda11e3744c0703271e479dcd560d05e4d470048d9633e34da16
2018-11-30Merge #14683: tests: better combine_logs.py behaviorMarcoFalke
4aabadbf44 tests: have combine_logs default to most recent test dir (James O'Beirne) Pull request description: Have `combine_logs.py` default to the most recent test directory if no argument is provided. This allows you to avoid an annoying copy-paste when iterating on a failing test, since you can do something like ```sh alias testlogs='./test/functional/combine_logs.py -c | less' ./test/functional/some_test.py # fails testlogs ``` Tree-SHA512: 919642ab09c314888a23c9491963b35b9da87e60deb740d1d5e816444aa9bdda5e519dc8ca131669f2d563167ef5f5abb14e22f20f47bf8362915ed578181846
2018-11-30[tests] Add wallet_balance.pyJohn Newbery
Adds a test specifically to test the wallet's getbalance and getunconfirmedbalance RPCs.
2018-11-29tests: have combine_logs default to most recent test dirJames O'Beirne
2018-11-29Add CScriptNum decode python implementation in functional suiteGregory Sanders
2018-11-28p2p: allow p2ptimeout to be configurable, speed up slow testZain Iqbal Allarakhia
2018-11-28Merge #14819: Bugfix: test/functional/mempool_accept: Ensure oversize ↵MarcoFalke
transaction is actually oversize 29aeed1734 Bugfix: test/functional/mempool_accept: Ensure oversize transaction is actually oversize (Luke Dashjr) Pull request description: Simply integer dividing results in an acceptable size if the limit isn't an exact multiple of the input size. Use math.ceil to ensure the transaction is always oversize. (This issue can be triggered by changing the address style used.) Tree-SHA512: e45062b0e8a3e9cb08e9dac5275b68d86e4377b460f1b3b995944090a055b0542a6986826312ec0e223369838094e42e20d8614b5c2bab9975b9a6f749295b21
2018-11-27Merge #14794: tests: Add AddressSanitizer (ASan) Travis buildMarcoFalke
6541d59ddc Add LSan suppression warnings (practicalswift) ff7212ec32 Add ASan Travis build (practicalswift) ebd3bf2590 Make test p2p_invalid_messages.py pass: Allow for expected Travis ASAN memory increase (practicalswift) Pull request description: Add ASan Travis build. Tree-SHA512: b9712aaf0c9112b637b6ef0c5d93961863dcbecaf31d9561eb09258a61540fb31d2c8ecae86518a82763279e4aa6cac266cd352c2b2507df0335c0199f8b3d78
2018-11-27Merge #14477: Add ability to convert solvability info to descriptorPieter Wuille
109699dd33 Add release notes (Pieter Wuille) b65326b562 Add matching descriptors to scantxoutset output + tests (Pieter Wuille) 16203d5df7 Add descriptors to listunspent and getaddressinfo + tests (Pieter Wuille) 9b2a25b13f Add tests for InferDescriptor and Descriptor::IsSolvable (Pieter Wuille) 225bf3e3b0 Add Descriptor::IsSolvable() to distinguish addr/raw from others (Pieter Wuille) 4d78bd93b5 Add support for inferring descriptors from scripts (Pieter Wuille) Pull request description: This PR adds functionality to convert a script to a descriptor, given a `SigningProvider` with the relevant information about public keys and redeemscripts/witnessscripts. The feature is exposed in `listunspent`, `getaddressinfo`, and `scantxoutset` whenever these calls are applied to solvable outputs/addresses. This is not very useful on its own, though when we add RPCs to import descriptors, or sign PSBTs using descriptors, these strings become a compact and standalone way of conveying everything necessary to sign an output (excluding private keys). Unit tests and rudimentary RPC tests are included (more relevant tests can be added once RPCs support descriptors). Fixes #14503. Tree-SHA512: cb36b84a3e0200375b7e06a98c7e750cfaf95cf5de132cad59f7ec3cbd201f739427de0dc108f515be7aca203652089fbf5f24ed283d4553bddf23a3224ab31f
2018-11-27Merge #14813: qa: Add wallet_encryption error testsMarcoFalke
fa739d4bd7 qa: Add wallet_encryption error tests (MarcoFalke) Pull request description: The errors for empty passphrases are the help text of the RPC call, which is not very specific. Replace that with proper RPC errors and test them. Tree-SHA512: 3137e0f8f2e42a1f8ab1eeb57c99052557725f6f85139ff48c24acc8f3cf4087802de5216f3ce97375b291d21bddb7cd1379a6f280166136a306a0c9663bbd42
2018-11-27Bugfix: test/functional/mempool_accept: Ensure oversize transaction is ↵Luke Dashjr
actually oversize Simply integer dividing results in an acceptable size if the limit isn't an exact multiple of the input size. Use math.ceil to ensure the transaction is always oversize.
2018-11-26Make test p2p_invalid_messages.py pass: Allow for expected Travis ASAN ↵practicalswift
memory increase
2018-11-26qa: Add wallet_encryption error testsMarcoFalke
2018-11-26qa: clean up assert_memory_usage_stable utilityJames O'Beirne
2018-11-26qa: fix p2p_invalid_messages on macOSJames O'Beirne
2018-11-24tests: check readability of cookie fileChun Kuan Lee
2018-11-23test: allows test_runner command line to receive parameters for each testmarcoagner
2018-11-23qa: Test bitcond shutdownJoão Barbosa
2018-11-22Merge #14777: tests: Add regtest for JSON-RPC batch callsMarcoFalke
3d2c7d6f94 Add regtest for JSON-RPC batch calls. (Daniel Kraft) Pull request description: This adds a new regtest file `interface_rpc.py`, containing a test for batch JSON-RPC requests. Those were previously not tested at all. Tests for basic requests are not really necessary, as those are used anyway in lots of other regtests. The existing `interface_http.py` file is more about the underlying HTTP connection, so adding a new interface file for the JSON-RPC specific things makes sense. Tree-SHA512: 7c7576004c8474e23c98f4bf25fb655328ba6bb73ea06744ebee1c0ffbb26bc132e621ae52955d51dab0803b322f8d711667626a777ac9b26003339c2484502f
2018-11-21Add regtest for JSON-RPC batch calls.Daniel Kraft
This adds a new regtest file 'interface_rpc.py', containing a test for batch JSON-RPC requests. Those were previously not tested at all. Tests for basic requests are not really necessary, as those are used anyway in lots of other regtests. The existing interface_http.py file is more about the underlying HTTP connection, so adding a new interface file for the JSON-RPC specific things makes sense.
2018-11-21Merge #14708: Warn unrecognised sections in the config fileWladimir J. van der Laan
3fb09b9889665a24b34f25e9d1385a05058a28b7 Warn unrecognized sections in the config file (Akio Nakamura) Pull request description: This PR intends to resolve #14702. In the config file, sections are specified by square bracket pair "[]"$, or included in the option name itself which separated by a period"(.)". Typicaly, [testnet] is not a correct section name and specified options in that section are ignored but user cannot recognize what is happen. So, add some log-warning messages if unrecognized section names are present in the config file after checking section only args. note: Currentry, followings are out of scope of this PR. 1) Empty section name or option name can describe. e.g. [] , .a=b, =c 2) Multiple period characters can exist in the section name and option name. e.g. [c.d.e], [..], f.g.h.i=j, ..=k Tree-SHA512: 2cea02a0525feb40320613989a75cd7b7b1bd12158d5e6f3174ca77e6a25bb84425dd8812f62483df9fc482045c7b5402d69bc714430518b1847d055a2dc304b
2018-11-21tests: Support calling add_nodes more than onceSteven Roose
2018-11-21Merge #14719: qa: Check specific reject reasons in feature_blockWladimir J. van der Laan
fa7da0617c814aeb06d5c70c4bb8e18c79fb8725 qa: Check specific reject reasons in feature_block (MarcoFalke) Pull request description: There are some consensus checks that are essentially turned off because we never send the block, but only the header. It happens that the header was sufficient to determine the invalidity of the block according to our consensus rules in those cases. Fix that by forcing the full block on the node unsolicited. Tree-SHA512: a5534318370367ea8de07d853de7e845c8f5637cd6d5457e932a9555af26cc212625e443c00c93586d556cc770f301248e7cabd68131a37791ae91706e7e40b2