Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions qa/rpc-tests/p2p-versionbits-warning.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import re
import time
from test_framework.blocktools import create_block, create_coinbase

Expand All @@ -21,6 +22,10 @@
VB_TOP_BITS = 0x20000000
VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment

WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect"
WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT)
VB_PATTERN = re.compile("^Warning.*versionbit")

# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending
# p2p messages to a node, generating the messages in the main testing logic.
class TestNode(NodeConnCB):
Expand Down Expand Up @@ -65,16 +70,12 @@ def __init__(self):
self.num_nodes = 1

def setup_network(self):
self.nodes = []
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
# Open and close to create zero-length file
with open(self.alert_filename, 'w') as f:
with open(self.alert_filename, 'w') as _:
pass
self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]
self.nodes.append(start_node(0, self.options.tmpdir, self.node_options))

import re
self.vb_pattern = re.compile("^Warning.*versionbit")
self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]]
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)

# Send numblocks blocks via peer with nVersionToUse set.
def send_blocks_with_version(self, peer, numblocks, nVersionToUse):
Expand All @@ -83,7 +84,7 @@ def send_blocks_with_version(self, peer, numblocks, nVersionToUse):
block_time = self.nodes[0].getblockheader(tip)["time"]+1
tip = int(tip, 16)

for i in range(numblocks):
for _ in range(numblocks):
block = create_block(tip, create_coinbase(height+1), block_time)
block.nVersion = nVersionToUse
block.solve()
Expand All @@ -96,7 +97,7 @@ def send_blocks_with_version(self, peer, numblocks, nVersionToUse):
def test_versionbits_in_alert_file(self):
with open(self.alert_filename, 'r') as f:
alert_text = f.read()
assert(self.vb_pattern.match(alert_text))
assert(VB_PATTERN.match(alert_text))

def run_test(self):
# Setup the p2p connection and start up the network thread.
Expand All @@ -122,8 +123,10 @@ def run_test(self):
# Fill rest of period with regular version blocks
self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1)
# Check that we're not getting any versionbit-related errors in
# getinfo()
assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"]))
# get*info()
assert(not VB_PATTERN.match(self.nodes[0].getinfo()["errors"]))
assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["errors"]))
assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"]))

# 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling
# some unknown bit
Expand All @@ -132,8 +135,10 @@ def run_test(self):
# Might not get a versionbits-related alert yet, as we should
# have gotten a different alert due to more than 51/100 blocks
# being of unexpected version.
# Check that getinfo() shows some kind of error.
assert(len(self.nodes[0].getinfo()["errors"]) != 0)
# Check that get*info() shows some kind of error.
assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getinfo()["errors"])
assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["errors"])
assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"])

# Mine a period worth of expected blocks so the generic block-version warning
# is cleared, and restart the node. This should move the versionbit state
Expand All @@ -142,20 +147,21 @@ def run_test(self):
stop_node(self.nodes[0], 0)
wait_bitcoinds()
# Empty out the alert file
with open(self.alert_filename, 'w') as f:
with open(self.alert_filename, 'w') as _:
pass
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)

# Connecting one block should be enough to generate an error.
self.nodes[0].generate(1)
assert(len(self.nodes[0].getinfo()["errors"]) != 0)
assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getinfo()["errors"])
assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["errors"])
assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"])
stop_node(self.nodes[0], 0)
wait_bitcoinds()
self.test_versionbits_in_alert_file()

# Test framework expects the node to still be running...
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])

self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)

if __name__ == '__main__':
VersionBitsWarningTest().main()
4 changes: 2 additions & 2 deletions qa/rpc-tests/rpcbind_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ def run_bind_test(self, allow_ips, connect_to, addresses, expected):

def run_allowip_test(self, allow_ips, rpchost, rpcport):
'''
Start a node with rpcwallow IP, and request getinfo
Start a node with rpcallow IP, and request getnetworkinfo
at a non-localhost IP.
'''
base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips]
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args])
try:
# connect to node through non-loopback interface
node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0)
node.getinfo()
node.getnetworkinfo()
finally:
node = None # make sure connection will be garbage collected and closed
stop_nodes(self.nodes)
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ UniValue getinfo(const UniValue& params, bool fHelp)
if (fHelp || params.size() != 0)
throw runtime_error(
"getinfo\n"
"Returns an object containing various state info.\n"
"\nDEPRECATED. Returns an object containing various state info.\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method has been deprecated for years, we didn't even mention this in the help message yet? Ouch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if anyone types in help getinfo. (Otherwise no one will see the DEPRECATED warning anyway)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, people use the help system. It's the only up-to-date RPC documentation that there is, and errors are usually found quickly.

But maybe not for old calls. Of course it may make sense to mention it in the release notes as well. I don't think we ever did, but even if so a reminder probably can't hurt.

"\nResult:\n"
"{\n"
" \"version\": xxxxx, (numeric) the server version\n"
Expand Down