forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
M-of-N-like sporks #2288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
M-of-N-like sporks #2288
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
bf41b31
support set of keys to sign spork
d449c00
several addresses support in -sporkkey
47249e5
tests for multykey sporks
6fc3998
command line option -minsporkkeys
656fad2
make spork active only after given number of signers
e327194
use signature in spork hash calculation
9724bb8
test for new and old spork messages interaction
633313c
add multikeyspork.py to integration tests
a3129eb
change test to have ability to distinguish default spork value
e8da6a5
require min spork keys number to be more than the half of the common …
187b87a
calc current spork value with majority of signers
17afe2a
set test nodes time in integration test
d51ceae
extract keyid from signed spork message directly
9ad4485
change -sporkaddr option syntax to process several addresses
4adf334
codestyle fixes
a094966
fix test comments
ea19a73
codestyle fixes
985ca1d
simplify CSporkManager::SporkValueIsActive
5c0c2ce
Calc signature hash without signature field
58da4c5
do not restore pubkey ids from cach
8aa814a
Calc different keyids to check signature because not all sporks can b…
167bf9f
codestyle fixes
d184ece
Fix CSporkManager::CheckAndRemove to use several keys
f60fbfb
codestyle fixes
8dc93fd
Correct processing of not actual spork6 value with GetSignerKeyID
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| #!/usr/bin/env python3 | ||
| # Copyright (c) 2018 The Dash Core developers | ||
| # Distributed under the MIT software license, see the accompanying | ||
| # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
|
||
| from test_framework.mininode import * | ||
| from test_framework.test_framework import BitcoinTestFramework | ||
| from test_framework.util import * | ||
| from time import * | ||
|
|
||
| ''' | ||
| multikeysporks.py | ||
|
|
||
| Test logic for several signer keys usage for spork broadcast. | ||
|
|
||
| We set 5 possible keys for sporks signing and set minimum | ||
| required signers to 3. We check 1 and 2 signers can't set the spork | ||
| value, any 3 signers can change spork value and other 3 signers | ||
| can change it again. | ||
| ''' | ||
|
|
||
|
|
||
| class MultiKeySporkTest(BitcoinTestFramework): | ||
| def __init__(self): | ||
| super().__init__() | ||
| self.num_nodes = 5 | ||
| self.setup_clean_chain = True | ||
| self.is_network_split = False | ||
|
|
||
| def setup_network(self): | ||
| self.nodes = [] | ||
|
|
||
| # secret(base58): 931wyuRNVYvhg18Uu9bky5Qg1z4QbxaJ7fefNBzjBPiLRqcd33F | ||
| # keyid(hex): 60f0f57f71f0081f1aacdd8432340a33a526f91b | ||
| # address(base58): yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa | ||
|
|
||
| # secret(base58): 91vbXGMSWKGHom62986XtL1q2mQDA12ngcuUNNe5NfMSj44j7g3 | ||
| # keyid(hex): 43dff2b09de2f904f688ec14ee6899087b889ad0 | ||
| # address(base58): yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h | ||
|
|
||
| # secret(base58): 92bxUjPT5AhgXuXJwfGGXqhomY2SdQ55MYjXyx9DZNxCABCSsRH | ||
| # keyid(hex): d9aa5fa00cce99101a4044e65dc544d1579890de | ||
| # address(base58): ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7 | ||
|
|
||
| # secret(base58): 934yPXiVGf4RCY2qTs2Bt5k3TEtAiAg12sMxCt8yVWbSU7p3fuD | ||
| # keyid(hex): 0b23935ce0bea3b997a334f6fa276c9fa17687b2 | ||
| # address(base58): ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn | ||
|
|
||
| # secret(base58): 92Cxwia363Wg2qGF1fE5z4GKi8u7r1nrWQXdtsj2ACZqaDPSihD | ||
| # keyid(hex): 1d1098b2b1f759b678a0a7a098637a9b898adcac | ||
| # address(base58): yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui | ||
|
|
||
| self.nodes.append(start_node(0, self.options.tmpdir, | ||
| ["-debug", "-sporkkey=931wyuRNVYvhg18Uu9bky5Qg1z4QbxaJ7fefNBzjBPiLRqcd33F", | ||
| "-sporkaddr=ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7", | ||
| "-sporkaddr=yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h", | ||
| "-sporkaddr=yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa", | ||
| "-sporkaddr=ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn", | ||
| "-sporkaddr=yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui", | ||
| "-minsporkkeys=3"])) | ||
| self.nodes.append(start_node(1, self.options.tmpdir, | ||
| ["-debug", "-sporkkey=91vbXGMSWKGHom62986XtL1q2mQDA12ngcuUNNe5NfMSj44j7g3", | ||
| "-sporkaddr=ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7", | ||
| "-sporkaddr=yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h", | ||
| "-sporkaddr=yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa", | ||
| "-sporkaddr=ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn", | ||
| "-sporkaddr=yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui", | ||
| "-minsporkkeys=3"])) | ||
| self.nodes.append(start_node(2, self.options.tmpdir, | ||
| ["-debug", "-sporkkey=92bxUjPT5AhgXuXJwfGGXqhomY2SdQ55MYjXyx9DZNxCABCSsRH", | ||
| "-sporkaddr=ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7", | ||
| "-sporkaddr=yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h", | ||
| "-sporkaddr=yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa", | ||
| "-sporkaddr=ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn", | ||
| "-sporkaddr=yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui", | ||
| "-minsporkkeys=3"])) | ||
| self.nodes.append(start_node(3, self.options.tmpdir, | ||
| ["-debug", "-sporkkey=934yPXiVGf4RCY2qTs2Bt5k3TEtAiAg12sMxCt8yVWbSU7p3fuD", | ||
| "-sporkaddr=ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7", | ||
| "-sporkaddr=yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h", | ||
| "-sporkaddr=yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa", | ||
| "-sporkaddr=ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn", | ||
| "-sporkaddr=yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui", | ||
| "-minsporkkeys=3"])) | ||
| self.nodes.append(start_node(4, self.options.tmpdir, | ||
| ["-debug", "-sporkkey=92Cxwia363Wg2qGF1fE5z4GKi8u7r1nrWQXdtsj2ACZqaDPSihD", | ||
| "-sporkaddr=ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7", | ||
| "-sporkaddr=yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h", | ||
| "-sporkaddr=yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa", | ||
| "-sporkaddr=ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn", | ||
| "-sporkaddr=yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui", | ||
| "-minsporkkeys=3"])) | ||
| # connect nodes at start | ||
| for i in range(0, 5): | ||
| for j in range(i, 5): | ||
| connect_nodes(self.nodes[i], j) | ||
|
|
||
| def get_test_spork_state(self, node): | ||
| info = node.spork('show') | ||
| # use InstantSend spork for tests | ||
| return info['SPORK_2_INSTANTSEND_ENABLED'] | ||
|
|
||
| def set_test_spork_state(self, node, value): | ||
| # use InstantSend spork for tests | ||
| node.spork('SPORK_2_INSTANTSEND_ENABLED', value) | ||
|
|
||
| def wait_for_test_spork_state(self, node, value): | ||
| start = time() | ||
| got_state = False | ||
| while True: | ||
| if self.get_test_spork_state(node) == value: | ||
| got_state = True | ||
| break | ||
| if time() > start + 10: | ||
| break | ||
| sleep(0.1) | ||
| return got_state | ||
|
|
||
| def run_test(self): | ||
| # check test spork default state | ||
| for node in self.nodes: | ||
| assert(self.get_test_spork_state(node) == 0) | ||
|
|
||
| set_mocktime(get_mocktime() + 1) | ||
| set_node_times(self.nodes, get_mocktime()) | ||
| # first and second signers set spork value | ||
| self.set_test_spork_state(self.nodes[0], 1) | ||
| self.set_test_spork_state(self.nodes[1], 1) | ||
| # spork change requires at least 3 signers | ||
| for node in self.nodes: | ||
| assert(not self.wait_for_test_spork_state(node, 1)) | ||
|
|
||
| # third signer set spork value | ||
| self.set_test_spork_state(self.nodes[2], 1) | ||
| # now spork state is changed | ||
| for node in self.nodes: | ||
| assert(self.wait_for_test_spork_state(node, 1)) | ||
|
|
||
| set_mocktime(get_mocktime() + 1) | ||
| set_node_times(self.nodes, get_mocktime()) | ||
| # now set the spork again with other signers to test | ||
| # old and new spork messages interaction | ||
| self.set_test_spork_state(self.nodes[2], 2) | ||
| self.set_test_spork_state(self.nodes[3], 2) | ||
| self.set_test_spork_state(self.nodes[4], 2) | ||
| for node in self.nodes: | ||
| assert(self.wait_for_test_spork_state(node, 2)) | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| MultiKeySporkTest().main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -570,6 +570,7 @@ std::string HelpMessage(HelpMessageMode mode) | |
| AppendParamsHelpMessages(strUsage, showDebug); | ||
| strUsage += HelpMessageOpt("-litemode=<n>", strprintf(_("Disable all Dash specific functionality (Masternodes, PrivateSend, InstantSend, Governance) (0-1, default: %u)"), 0)); | ||
| strUsage += HelpMessageOpt("-sporkaddr=<hex>", strprintf(_("Override spork address. Only useful for regtest and devnet. Using this on mainnet or testnet will ban you."))); | ||
| strUsage += HelpMessageOpt("-minsporkkeys=<n>", strprintf(_("Overrides minimum spork signers to change spork value. Only useful for regtest and devnet. Using this on mainnet or testnet will ban you."))); | ||
|
|
||
| strUsage += HelpMessageGroup(_("Masternode options:")); | ||
| strUsage += HelpMessageOpt("-masternode=<n>", strprintf(_("Enable the client to act as a masternode (0-1, default: %u)"), 0)); | ||
|
|
@@ -1398,13 +1399,28 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) | |
| threadGroup.create_thread(&ThreadScriptCheck); | ||
| } | ||
|
|
||
| if (!sporkManager.SetSporkAddress(GetArg("-sporkaddr", Params().SporkAddress()))) | ||
| return InitError(_("Invalid spork address specified with -sporkaddr")); | ||
| std::vector<std::string> vSporkAddresses; | ||
| if (mapMultiArgs.count("-sporkaddr")) { | ||
| vSporkAddresses = mapMultiArgs.at("-sporkaddr"); | ||
| } else { | ||
| vSporkAddresses = Params().SporkAddresses(); | ||
| } | ||
| for (const auto& address: vSporkAddresses) { | ||
| if (!sporkManager.SetSporkAddress(address)) { | ||
| return InitError(_("Invalid spork address specified with -sporkaddr")); | ||
| } | ||
| } | ||
|
|
||
| if (IsArgSet("-sporkkey")) // spork priv key | ||
| { | ||
| if (!sporkManager.SetPrivKey(GetArg("-sporkkey", ""))) | ||
| int minsporkkeys = GetArg("-minsporkkeys", Params().MinSporkKeys()); | ||
| if (!sporkManager.SetMinSporkKeys(minsporkkeys)) { | ||
| return InitError(_("Invalid minimum number of spork signers specified with -minsporkkeys")); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above, same line or braces. Also |
||
| } | ||
|
|
||
|
|
||
| if (IsArgSet("-sporkkey")) { // spork priv key | ||
| if (!sporkManager.SetPrivKey(GetArg("-sporkkey", ""))) { | ||
| return InitError(_("Unable to sign spork message, wrong key?")); | ||
| } | ||
| } | ||
|
|
||
| // Start the lightweight task scheduler thread | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bodies of an if should either be on the same line or in brackets