Browse Source

Fixed namespace creation.

Fixed mempool propagation for both old (incorrect) and new (correct) namespaces.

Version 0.16.5.4
issue_19
Just Wonder 4 years ago
parent
commit
10c5b0d0fd
  1. 2
      configure.ac
  2. 3
      depends/packages/libsodium.mk
  3. 39
      src/chainparams.cpp
  4. 1
      src/consensus/params.h
  5. 16
      src/keva/main.cpp
  6. 23
      src/script/keva.cpp
  7. 3
      src/script/keva.h
  8. 10
      src/test/keva_tests.cpp
  9. 6
      src/validation.cpp
  10. 3
      src/validation.h
  11. 4
      src/versionbits.cpp
  12. 3
      src/wallet/wallet.cpp
  13. 99
      test/functional/feature_keva_ns.py
  14. 61
      test/functional/feature_keva_ns_bug.py

2
configure.ac

@ -3,7 +3,7 @@ AC_PREREQ([2.60]) @@ -3,7 +3,7 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 16)
define(_CLIENT_VERSION_REVISION, 5)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_BUILD, 4)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2020)
define(_COPYRIGHT_HOLDERS,[The %s developers])

3
depends/packages/libsodium.mk

@ -2,7 +2,7 @@ package=libsodium @@ -2,7 +2,7 @@ package=libsodium
$(package)_version=1.0.18
$(package)_download_path=https://download.libsodium.org/libsodium/releases/
$(package)_file_name=$(package)-$($(package)_version)-stable.tar.gz
$(package)_sha256_hash=7047fc20e7692bbfa656a5df825983ad7c7640eaec3926331d14aa2ae1d542ea
$(package)_sha256_hash=51ff569103105b78b49df53a861fd0be5ed1cb1522440c84dfe63b39cfb97bd4
define $(package)_set_vars
$(package)_config_opts_mingw32+=CFLAGS="-Ofast -fomit-frame-pointer -march=pentium3 -mtune=westmere"
@ -19,4 +19,3 @@ endef @@ -19,4 +19,3 @@ endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef

39
src/chainparams.cpp

@ -122,24 +122,27 @@ public: @@ -122,24 +122,27 @@ public:
consensus.nPowTargetSpacing = 2.0 * 60; // Two minutes
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 6048; // 75% of 8064
consensus.nMinerConfirmationWindow = 8064; // nPowTargetTimespan / nPowTargetSpacing * 4
consensus.nRuleChangeActivationThreshold = 1620; // 75% of 2160
consensus.nMinerConfirmationWindow = 2160; // 3 days
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
//consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1485561600; // January 28, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = -1; // Consensus::BIP9Deployment::ALWAYS_ACTIVE
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517356801; // January 31st, 2018
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
//consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1485561600; // January 28, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = -1; // Consensus::BIP9Deployment::ALWAYS_ACTIVE
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1517356801; // January 31st, 2018
// Deployment of NsFix
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].bit = 3;
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].nStartTime = 1594771200; // 07/15/2020 @ 12:00am
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].nTimeout = 1598745600; // 08/30/2020 @ 12:00am
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000999a6a433f7");
@ -211,30 +214,33 @@ public: @@ -211,30 +214,33 @@ public:
consensus.BIP34Hash = uint256S("0xa8dbaa66a9266348f6527fe528efea73227d51938befb81d5a1521cebd319c4a"); // Genesis
consensus.BIP65Height = 1;
consensus.BIP66Height = 1;
consensus.RandomXHeight = 6030;
consensus.RandomXHeight = 3;
consensus.powLimit = uint256S("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 2.0 * 60; // Two minutes
consensus.nPowTargetSpacing = 2.0 * 60; // Two minutes
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.fPowNoRetargeting = true;
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
consensus.nMinerConfirmationWindow = 144; // nPowTargetTimespan / nPowTargetSpacing
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
//consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1483228800; // January 1, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = -1; // Consensus::BIP9Deployment::ALWAYS_ACTIVE
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517356801; // January 31st, 2018
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
//consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1483228800; // January 1, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = -1; // Consensus::BIP9Deployment::ALWAYS_ACTIVE
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1517356801; // January 31st, 2018
// Deployment of NsFix
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].bit = 3;
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].nStartTime = 1594771200; // 07/15/2020 @ 12:00am
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].nTimeout = 1598745600; // 08/30/2020 @ 12:00am
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000001000");
@ -303,7 +309,7 @@ public: @@ -303,7 +309,7 @@ public:
consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.RandomXHeight = 20; // RandomxX acticated on regtest.
consensus.RandomXHeight = 2000000; // RandomX acticated on regtest.
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 2.0 * 60; // Two minutes
consensus.nPowTargetSpacing = 2.0 * 60; // Two minutes
@ -312,15 +318,22 @@ public: @@ -312,15 +318,22 @@ public:
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
//consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
//consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
// Deployment of NsFix
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].bit = 3;
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].nStartTime = 1517356801; // January 31st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_NSFIX].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");

1
src/consensus/params.h

@ -18,6 +18,7 @@ enum DeploymentPos @@ -18,6 +18,7 @@ enum DeploymentPos
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147.
DEPLOYMENT_NSFIX, // Deployment of fix of Keva namespace creation.
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};

16
src/keva/main.cpp

@ -144,9 +144,9 @@ bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& name @@ -144,9 +144,9 @@ bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& name
if (tx.vin.size() == 0) {
return false;
}
valtype kevaNamespace = ToByteVector(Hash160(ToByteVector(tx.vin[0].prevout.hash)));
const std::vector<unsigned char>& ns_prefix = Params().Base58Prefix(CChainParams::KEVA_NAMESPACE);
kevaNamespace.insert(kevaNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
valtype kevaNamespace;
bool nsFixEnabled = IsNsFixEnabled(chainActive.Tip(), Params().GetConsensus());
CKevaScript::generateNamespace(tx.vin[0].prevout.hash, tx.vin[0].prevout.n, kevaNamespace, Params(), nsFixEnabled);
return kevaNamespace == nameSpace;
}
@ -336,8 +336,18 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight, @@ -336,8 +336,18 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
if (nameOpOut.getOpNamespaceDisplayName().size () > MAX_VALUE_LENGTH) {
return state.Invalid (error ("CheckKevaTransaction: display name value too long"));
}
LOCK(cs_main);
bool nsFixEnabled = IsNsFixEnabled(chainActive.Tip(), Params().GetConsensus());
if (!nsFixEnabled) {
// This is a historic bug.
return true;
}
// Make sure the namespace Id is correctly derived from vin[0].
valtype expectedNamespace;
CKevaScript::generateNamespace(tx.vin[0].prevout.hash, tx.vin[0].prevout.n, expectedNamespace, Params(), true);
return expectedNamespace == nameOpOut.getOpNamespace();
}
assert(nameOpOut.isAnyUpdate());

23
src/script/keva.cpp

@ -7,7 +7,9 @@ @@ -7,7 +7,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <script/keva.h>
#include <keva/common.h>
#include <hash.h>
#include <validation.h>
const std::string CKevaScript::KEVA_DISPLAY_NAME_KEY = "_KEVA_NS_";
@ -103,7 +105,20 @@ CScript CKevaScript::buildKevaNamespace(const CScript& addr, const valtype& name @@ -103,7 +105,20 @@ CScript CKevaScript::buildKevaNamespace(const CScript& addr, const valtype& name
return prefix + addr;
}
CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint256& txId, valtype& kaveNamespace, const CChainParams& params)
void CKevaScript::generateNamespace(const uint256& txId, int n, valtype& kevaNamespace, const CChainParams& params, bool nsFixEnabled)
{
auto vin = ToByteVector(txId);
if (nsFixEnabled) {
// The UXTO is vin and the number. This is the correct way to generate unique namespace.
auto nVal = ValtypeFromString(std::to_string(n));
vin.insert(vin.end(), nVal.begin(), nVal.end());
}
kevaNamespace = ToByteVector(Hash160(vin));
const std::vector<unsigned char>& ns_prefix = params.Base58Prefix(CChainParams::KEVA_NAMESPACE);
kevaNamespace.insert(kevaNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
}
CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint256& txId, int n, valtype& kaveNamespace, const CChainParams& params, bool nsFixEnabled)
{
CKevaScript kevaOp(oldScript);
if (!kevaOp.isNamespaceRegistration()) {
@ -112,10 +127,6 @@ CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint25 @@ -112,10 +127,6 @@ CScript CKevaScript::replaceKevaNamespace(const CScript& oldScript, const uint25
}
const valtype& displayName = kevaOp.getOpNamespaceDisplayName();
kaveNamespace = ToByteVector(Hash160(ToByteVector(txId)));
const std::vector<unsigned char>& ns_prefix = params.Base58Prefix(CChainParams::KEVA_NAMESPACE);
kaveNamespace.insert(kaveNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
CKevaScript::generateNamespace(txId, n, kaveNamespace, params, nsFixEnabled);
return CKevaScript::buildKevaNamespace(kevaOp.getAddress(), kaveNamespace, displayName);
}

3
src/script/keva.h

@ -273,8 +273,9 @@ public: @@ -273,8 +273,9 @@ public:
*/
static CScript buildKevaDelete(const CScript& addr, const valtype& nameSpace, const valtype& key);
static void generateNamespace(const uint256& txId, int n, valtype& kaveNamespace, const CChainParams& params, bool nsFixEnabled);
static CScript replaceKevaNamespace(const CScript& oldScript, const uint256& txId, valtype& kaveNamespace, const CChainParams& params);
static CScript replaceKevaNamespace(const CScript& oldScript, const uint256& txId, int n, valtype& kaveNamespace, const CChainParams& params, bool nsFixEnabled);
};

10
src/test/keva_tests.cpp

@ -66,13 +66,19 @@ BOOST_AUTO_TEST_CASE(keva_scripts) @@ -66,13 +66,19 @@ BOOST_AUTO_TEST_CASE(keva_scripts)
const uint256 txId = uint256S("0x78f49add562dc33e4cd61aa45c54012509ed4a53308908dd07f5634437939273");
valtype actualNamespace;
script = CKevaScript::replaceKevaNamespace(script, txId, actualNamespace, Params());
int n = 99999;
script = CKevaScript::replaceKevaNamespace(script, txId, n, actualNamespace, Params(), true);
const CKevaScript opReplace(script);
BOOST_CHECK(opReplace.isKevaOp());
BOOST_CHECK(opReplace.getAddress() == addr);
BOOST_CHECK(!opReplace.isAnyUpdate());
BOOST_CHECK(opReplace.getKevaOp() == OP_KEVA_NAMESPACE);
valtype expectedNamespace = ToByteVector(Hash160(ToByteVector(txId)));
auto vin = ToByteVector(txId);
auto nVal = ValtypeFromString(std::to_string(n));
vin.insert(vin.end(), nVal.begin(), nVal.end());
valtype expectedNamespace = ToByteVector(Hash160(ToByteVector(vin)));
const std::vector<unsigned char>& ns_prefix = Params().Base58Prefix(CChainParams::KEVA_NAMESPACE);
expectedNamespace.insert(expectedNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
BOOST_CHECK(opReplace.getOpNamespace() == expectedNamespace);

6
src/validation.cpp

@ -3120,6 +3120,12 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P @@ -3120,6 +3120,12 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
return true;
}
bool IsNsFixEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(cs_main);
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_NSFIX, versionbitscache) == THRESHOLD_ACTIVE);
}
bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(cs_main);

3
src/validation.h

@ -412,6 +412,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, @@ -412,6 +412,9 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
/** Check whether witness commitments are required for block. */
bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params);
/** Check whether Keva namespace creation fix is enabled. */
bool IsNsFixEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params);
/** When there are blocks in the active chain with missing data, rewind the chainstate and remove them from the block index */
bool RewindBlockIndex(const CChainParams& params);

4
src/versionbits.cpp

@ -17,6 +17,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B @@ -17,6 +17,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
{
/*.name =*/ "segwit",
/*.gbt_force =*/ true,
},
{
/*.name =*/ "nsfix",
/*.gbt_force =*/ true,
}
};

3
src/wallet/wallet.cpp

@ -2952,7 +2952,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, @@ -2952,7 +2952,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend,
CScript dummyScript = iter->scriptPubKey;
CKevaScript kevaOp(dummyScript);
if (kevaOp.isKevaOp() && kevaOp.isNamespaceRegistration()) {
iter->scriptPubKey = CKevaScript::replaceKevaNamespace(dummyScript, coin.outpoint.hash, kevaNamespace, Params());
bool nsFixEnabled = IsNsFixEnabled(chainActive.Tip(), Params().GetConsensus());
iter->scriptPubKey = CKevaScript::replaceKevaNamespace(dummyScript, coin.outpoint.hash, coin.outpoint.n, kevaNamespace, Params(), nsFixEnabled);
kevaDummyReplaced = true;
break;
}

99
test/functional/feature_keva_ns.py

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
#!/usr/bin/env python3
# Copyright (c) 2016-2017 The Bitcoin Core developers
# Copyright (c) 2018-2019 The Kevacoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the Key-Value Store."""
from test_framework.blocktools import witness_script, send_to_witness
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.authproxy import JSONRPCException
from io import BytesIO
from string import Template
import decimal
import re
import json
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
return float(o)
return super(DecimalEncoder, self).default(o)
class KevaTest(BitcoinTestFramework):
def sync_generate(self, node, num):
self.sync_all()
node.generate(num)
self.sync_all()
def set_test_params(self):
self.num_nodes = 3
self.setup_clean_chain = True
def setup_network(self):
self.setup_nodes()
connect_nodes(self.nodes[0], 1)
connect_nodes(self.nodes[1], 0)
connect_nodes(self.nodes[2], 0)
self.sync_all()
def dumpTx(self, tx):
print(json.dumps(self.nodes[0].decoderawtransaction(self.nodes[0].getrawtransaction(tx)), indent=4, cls=DecimalEncoder))
def run_test(self):
self.nodes[0].generate(2)
hash = self.nodes[0].getbestblockhash()
# THRESHOLD_DEFINED
assert(self.nodes[0].getblock(hash)['versionHex'] == '20000000')
self.nodes[0].generate(150)
hash = self.nodes[0].getbestblockhash()
# THRESHOLD_STARTED
assert(self.nodes[0].getblock(hash)['versionHex'] == '20000008')
self.nodes[0].generate(150)
hash = self.nodes[0].getbestblockhash()
# THRESHOLD_LOCKED_IN
assert(self.nodes[0].getblock(hash)['versionHex'] == '20000008')
self.nodes[0].generate(150)
hash = self.nodes[0].getbestblockhash()
# THRESHOLD_ACITVE
assert(self.nodes[0].getblock(hash)['versionHex'] == '20000000')
addr1 = self.nodes[1].getnewaddress()
addr2 = self.nodes[2].getnewaddress()
amount = Template('{"$addr1":1,"$addr2":1}').substitute(addr1=addr1, addr2=addr2)
amountJson = json.loads(amount)
self.nodes[0].sendmany("", amountJson)
self.sync_generate(self.nodes[0], 1)
ns1 = (self.nodes[1].keva_namespace('NS 1'))["namespaceId"]
ns2 = (self.nodes[2].keva_namespace('NS 2'))["namespaceId"]
self.sync_generate(self.nodes[0], 1)
# Since nsfix is enabled, the namespace will be the different.
assert(ns1 != ns2)
# The namespace should be created.
assert((self.nodes[0].keva_filter(ns1))[0]["value"] == 'NS 1')
assert((self.nodes[0].keva_filter(ns2))[0]["value"] == 'NS 2')
self.nodes[1].keva_put(ns1, 'key', 'value 1')
self.nodes[2].keva_put(ns2, 'key', 'value 2')
self.sync_generate(self.nodes[0], 1)
assert((self.nodes[0].keva_get(ns1, 'key'))["value"] == 'value 1')
assert((self.nodes[0].keva_get(ns2, 'key'))["value"] == 'value 2')
self.nodes[0].generate(20)
ns3 = (self.nodes[1].keva_namespace('NS 3'))["namespaceId"]
ns4 = (self.nodes[2].keva_namespace('NS 4'))["namespaceId"]
assert(ns3 != ns4)
# The namespace should be created.
self.sync_generate(self.nodes[0], 1)
assert((self.nodes[0].keva_filter(ns3))[0]["value"] == 'NS 3')
assert((self.nodes[0].keva_filter(ns4))[0]["value"] == 'NS 4')
if __name__ == '__main__':
KevaTest().main()

61
test/functional/feature_keva_ns_bug.py

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
#!/usr/bin/env python3
# Copyright (c) 2016-2017 The Bitcoin Core developers
# Copyright (c) 2018-2019 The Kevacoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the Key-Value Store."""
from test_framework.blocktools import witness_script, send_to_witness
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.authproxy import JSONRPCException
from io import BytesIO
from string import Template
import decimal
import re
import json
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
return float(o)
return super(DecimalEncoder, self).default(o)
class KevaTest(BitcoinTestFramework):
def sync_generate(self, node, num):
self.sync_all()
node.generate(num)
self.sync_all()
def set_test_params(self):
self.num_nodes = 3
self.setup_clean_chain = True
def setup_network(self):
self.setup_nodes()
connect_nodes(self.nodes[0], 1)
connect_nodes(self.nodes[1], 0)
connect_nodes(self.nodes[2], 0)
self.sync_all()
def dumpTx(self, tx):
print(json.dumps(self.nodes[0].decoderawtransaction(self.nodes[0].getrawtransaction(tx)), indent=4, cls=DecimalEncoder))
def run_test(self):
self.nodes[0].generate(101)
addr1 = self.nodes[1].getnewaddress()
addr2 = self.nodes[2].getnewaddress()
amount = Template('{"$addr1":1,"$addr2":1}').substitute(addr1=addr1, addr2=addr2)
amountJson = json.loads(amount)
self.nodes[0].sendmany("", amountJson)
self.sync_generate(self.nodes[0], 1)
ns1 = (self.nodes[1].keva_namespace('NS 1'))["namespaceId"]
ns2 = (self.nodes[2].keva_namespace('NS 2'))["namespaceId"]
self.sync_generate(self.nodes[0], 1)
# Before nsfix is enabled, the namespace will be the same.
# This is a historic bug.
assert(ns1 == ns2)
if __name__ == '__main__':
KevaTest().main()
Loading…
Cancel
Save