wallet: warn against accidental unsafe older() import
BIP 379 allows height and time locks that have no consensus meaning in BIP 68 / BIP 112. This is used by some protocols like Lightning to encode extra data, but is unsafe when used unintentionally. E.g. older(65536) is equivalent to older(1). This commit emits a warning when importing such a descriptor. It introduces a helper ForEachNode to traverse all miniscript nodes.
This commit is contained in:
7 files changed
+138
-1
No files matched your search
@@ -22,6 +22,7 @@ from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.blocktools import COINBASE_MATURITY
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.descriptors import descsum_create
|
||||
from test_framework.script import SEQUENCE_LOCKTIME_TYPE_FLAG
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
@@ -58,6 +59,7 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
if 'warnings' in result[0]:
|
||||
observed_warnings = result[0]['warnings']
|
||||
assert_equal("\n".join(sorted(warnings)), "\n".join(sorted(observed_warnings)))
|
||||
self.log.debug(result)
|
||||
assert_equal(result[0]['success'], success)
|
||||
if error_code is not None:
|
||||
assert_equal(result[0]['error']['code'], error_code)
|
||||
@@ -783,5 +785,40 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
assert_equal(w_multipath.getrawchangeaddress(address_type="bech32"), w_multisplit.getrawchangeaddress(address_type="bech32"))
|
||||
assert_equal(sorted(w_multipath.listdescriptors()["descriptors"], key=lambda x: x["desc"]), sorted(w_multisplit.listdescriptors()["descriptors"], key=lambda x: x["desc"]))
|
||||
|
||||
self.log.info("Test older() safety")
|
||||
|
||||
for flag in [0, SEQUENCE_LOCKTIME_TYPE_FLAG]:
|
||||
self.log.debug("Importing a safe value always works")
|
||||
safe_value = (65535 | flag)
|
||||
self.test_importdesc(
|
||||
{
|
||||
'desc': descsum_create(f"wsh(and_v(v:pk([12345678/0h/0h]{xpub}/*),older({safe_value})))"),
|
||||
'active': True,
|
||||
'range': [0, 2],
|
||||
'timestamp': 'now'
|
||||
},
|
||||
success=True
|
||||
)
|
||||
|
||||
self.log.debug("Importing an unsafe value results in a warning")
|
||||
unsafe_value = safe_value + 1
|
||||
desc = descsum_create(f"wsh(and_v(v:pk([12345678/0h/0h]{xpub}/*),older({unsafe_value})))")
|
||||
expected_warning = (
|
||||
f"time-based relative locktime: older({unsafe_value}) > (65535 * 512) seconds is unsafe"
|
||||
if flag == SEQUENCE_LOCKTIME_TYPE_FLAG
|
||||
else f"height-based relative locktime: older({unsafe_value}) > 65535 blocks is unsafe"
|
||||
)
|
||||
self.test_importdesc(
|
||||
{
|
||||
'desc': desc,
|
||||
'active': True,
|
||||
'range': [0, 2],
|
||||
'timestamp': 'now'
|
||||
},
|
||||
success=True,
|
||||
warnings=[expected_warning],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ImportDescriptorsTest(__file__).main()
|
||||
Reference in new issue
Block a user