mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-03-13 06:01:45 +00:00
1. Fixed pending information containing other people's information.
2. Fixed keva undo.
This commit is contained in:
parent
8c5def9909
commit
37dfb034a6
@ -226,8 +226,9 @@ CKevaCache::remove(const valtype& nameSpace, const valtype& key)
|
||||
{
|
||||
auto name = std::make_tuple(nameSpace, key);
|
||||
const EntryMap::iterator ei = entries.find(name);
|
||||
if (ei != entries.end())
|
||||
if (ei != entries.end()) {
|
||||
entries.erase(ei);
|
||||
}
|
||||
|
||||
deleted.insert(name);
|
||||
}
|
||||
|
@ -36,33 +36,35 @@ CKevaTxUndo::fromOldState(const valtype& nameSpace, const valtype& key, const CC
|
||||
void
|
||||
CKevaTxUndo::apply(CCoinsViewCache& view) const
|
||||
{
|
||||
if (isNew)
|
||||
if (isNew) {
|
||||
view.DeleteName(nameSpace, key);
|
||||
else
|
||||
}
|
||||
else {
|
||||
view.SetName(nameSpace, key, oldData, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* CKevaMemPool. */
|
||||
|
||||
void
|
||||
CKevaMemPool::addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry)
|
||||
CKevaMemPool::addUnchecked(const uint256& hash, const CKevaScript& kevaOp)
|
||||
{
|
||||
AssertLockHeld (pool.cs);
|
||||
if (entry.isNamespaceRegistration()) {
|
||||
const valtype& nameSpace = entry.getNamespace();
|
||||
listUnconfirmedNamespaces.push_back(std::make_tuple(hash, nameSpace, entry.getDisplayName()));
|
||||
if (kevaOp.isNamespaceRegistration()) {
|
||||
const valtype& nameSpace = kevaOp.getOpNamespace();
|
||||
listUnconfirmedNamespaces.push_back(std::make_tuple(hash, nameSpace, kevaOp.getOpNamespaceDisplayName()));
|
||||
}
|
||||
|
||||
if (entry.isKeyUpdate()) {
|
||||
const valtype& nameSpace = entry.getNamespace();
|
||||
listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, entry.getKey(), entry.getValue()));
|
||||
if (kevaOp.getKevaOp() == OP_KEVA_PUT) {
|
||||
const valtype& nameSpace = kevaOp.getOpNamespace();
|
||||
listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, kevaOp.getOpKey(), kevaOp.getOpValue()));
|
||||
}
|
||||
|
||||
if (entry.isKeyDelete()) {
|
||||
const valtype& nameSpace = entry.getNamespace();
|
||||
if (kevaOp.getKevaOp() == OP_KEVA_DELETE) {
|
||||
const valtype& nameSpace = kevaOp.getOpNamespace();
|
||||
const valtype& empty = ValtypeFromString("");
|
||||
listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, entry.getKey(), empty));
|
||||
listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, kevaOp.getOpKey(), empty));
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,8 +377,8 @@ void ApplyKevaTransaction(const CTransaction& tx, unsigned nHeight,
|
||||
} else if (op.isAnyUpdate()) {
|
||||
const valtype& nameSpace = op.getOpNamespace();
|
||||
const valtype& key = op.getOpKey();
|
||||
LogPrint (BCLog::KEVA, "Updating name at height %d: %s\n",
|
||||
nHeight, ValtypeToString (nameSpace).c_str ());
|
||||
LogPrint (BCLog::KEVA, "Updating key at height %d: %s %s\n",
|
||||
nHeight, ValtypeToString(nameSpace).c_str(), ValtypeToString(key).c_str());
|
||||
|
||||
CKevaTxUndo opUndo;
|
||||
opUndo.fromOldState(nameSpace, key, view);
|
||||
|
@ -147,18 +147,17 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an entry without checking it. It should have been checked
|
||||
* already. If this conflicts with the mempool, it may throw.
|
||||
* Added unconfirmed keva values.
|
||||
* @param hash The tx hash.
|
||||
* @param entry The new mempool entry.
|
||||
* @param entry The new keva entry.
|
||||
*/
|
||||
void addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry);
|
||||
void addUnchecked(const uint256& hash, const CKevaScript& kevaOp);
|
||||
|
||||
/**
|
||||
* Remove the given mempool entry. It is assumed that it is present.
|
||||
* @param entry The entry to remove.
|
||||
*/
|
||||
void remove (const CTxMemPoolEntry& entry);
|
||||
void remove(const CTxMemPoolEntry& entry);
|
||||
|
||||
/**
|
||||
* Remove conflicts for the given tx, based on name operations. I. e.,
|
||||
@ -167,7 +166,7 @@ public:
|
||||
* @param tx The transaction for which we look for conflicts.
|
||||
* @param removed Put removed tx here.
|
||||
*/
|
||||
void removeConflicts (const CTransaction& tx);
|
||||
void removeConflicts(const CTransaction& tx);
|
||||
|
||||
/**
|
||||
* Check if a tx can be added (based on name criteria) without
|
||||
@ -175,7 +174,7 @@ public:
|
||||
* @param tx The transaction to check.
|
||||
* @return True if it doesn't conflict.
|
||||
*/
|
||||
bool checkTx (const CTransaction& tx) const;
|
||||
bool checkTx(const CTransaction& tx) const;
|
||||
|
||||
/** Keva get unconfirmed namespaces. */
|
||||
void getUnconfirmedNamespaceList(std::vector<std::tuple<valtype, valtype, uint256>>& nameSpaces) const;
|
||||
|
@ -423,7 +423,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
|
||||
nTransactionsUpdated++;
|
||||
totalTxSize += entry.GetTxSize();
|
||||
if (minerPolicyEstimator) {minerPolicyEstimator->processTransaction(entry, validFeeEstimate);}
|
||||
kevaMemPool.addUnchecked (hash, entry);
|
||||
|
||||
vTxHashes.emplace_back(tx.GetWitnessHash(), newit);
|
||||
newit->vTxHashesIdx = vTxHashes.size() - 1;
|
||||
|
@ -693,6 +693,12 @@ public:
|
||||
return kevaMemPool.checkTx(tx);
|
||||
}
|
||||
|
||||
inline void addKevaUnchecked(const uint256& hash, const CKevaScript& kevaOp)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
kevaMemPool.addUnchecked(hash, kevaOp);
|
||||
}
|
||||
|
||||
/** Keva get unconfirmed key values. */
|
||||
bool getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const;
|
||||
|
||||
|
@ -110,6 +110,7 @@ public:
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(vtxundo);
|
||||
READWRITE(vkevaundo);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -184,7 +184,8 @@ UniValue keva_list_namespaces(const JSONRPCRequest& request)
|
||||
UniValue res(UniValue::VARR);
|
||||
for (const auto& item : mapObjects) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV(item.first, item.second);
|
||||
obj.pushKV("namespaceId", item.first);
|
||||
obj.pushKV("displayName", item.second);
|
||||
res.push_back(obj);
|
||||
}
|
||||
|
||||
|
@ -3176,6 +3176,20 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
CKevaScript kevaOp;
|
||||
auto _tx = wtx.tx;
|
||||
if (_tx->IsKevacoin()) {
|
||||
for (const auto& txOut : _tx->vout) {
|
||||
const CKevaScript curKevaOp(txOut.scriptPubKey);
|
||||
if (!curKevaOp.isKevaOp()) {
|
||||
continue;
|
||||
}
|
||||
assert(!kevaOp.isKevaOp());
|
||||
kevaOp = curKevaOp;
|
||||
}
|
||||
assert(kevaOp.isKevaOp());
|
||||
mempool.addKevaUnchecked(wtx.GetHash(), kevaOp);
|
||||
}
|
||||
wtx.RelayWalletTransaction(connman);
|
||||
}
|
||||
}
|
||||
|
@ -16,15 +16,91 @@ import re
|
||||
class KevaTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 3
|
||||
self.num_nodes = 2
|
||||
|
||||
def setup_network(self):
|
||||
super().setup_network()
|
||||
connect_nodes(self.nodes[0], 2)
|
||||
connect_nodes_bi(self.nodes, 0, 1)
|
||||
self.sync_all()
|
||||
|
||||
def run_unconfirmed_namespaces(self):
|
||||
self.sync_all()
|
||||
response = self.nodes[1].keva_namespace('second_namespace')
|
||||
namespaceId = response['namespaceId']
|
||||
response = self.nodes[1].keva_list_namespaces()
|
||||
# Node 0's unconfirmed namespace should not be here
|
||||
assert(len(response) == 1)
|
||||
|
||||
# Node 0's unconfirmed operations should not be here
|
||||
self.nodes[1].keva_put(namespaceId, 'second_key', 'second_value')
|
||||
response = self.nodes[1].keva_pending()
|
||||
# Pending namespace and put operation.
|
||||
assert(len(response) == 2)
|
||||
self.sync_all()
|
||||
|
||||
def run_test_disconnect_block(self, namespaceId):
|
||||
key = 'This is the test key'
|
||||
value = 'This is the test value'
|
||||
self.nodes[0].keva_put(namespaceId, key, value)
|
||||
self.nodes[0].generate(1)
|
||||
response = self.nodes[0].keva_get(namespaceId, key)
|
||||
assert(response['value'] == value)
|
||||
# Disconnect the block
|
||||
self.sync_all()
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash())
|
||||
self.sync_all()
|
||||
response = self.nodes[0].keva_get(namespaceId, key)
|
||||
assert(response['value'] == '')
|
||||
|
||||
self.log.info("Test undeleting after disconnecting blocks")
|
||||
keyToDelete = 'This is the test key to delete'
|
||||
valueToDelete = 'This is the test value of the key'
|
||||
self.nodes[0].keva_put(namespaceId, keyToDelete, valueToDelete)
|
||||
self.nodes[0].generate(1)
|
||||
response = self.nodes[0].keva_get(namespaceId, keyToDelete)
|
||||
assert(response['value'] == valueToDelete)
|
||||
# Now delete the key
|
||||
self.nodes[0].keva_delete(namespaceId, keyToDelete)
|
||||
self.nodes[0].generate(1)
|
||||
response = self.nodes[0].keva_get(namespaceId, keyToDelete)
|
||||
assert(response['value'] == '')
|
||||
# Disconnect the block
|
||||
self.sync_all()
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash())
|
||||
self.sync_all()
|
||||
response = self.nodes[0].keva_get(namespaceId, keyToDelete)
|
||||
# The value should be undeleted.
|
||||
assert(response['value'] == valueToDelete)
|
||||
|
||||
self.log.info("Test namespace after disconnecting blocks")
|
||||
displayName = 'A new namspace'
|
||||
response = self.nodes[0].keva_namespace(displayName)
|
||||
newNamespaceId = response['namespaceId']
|
||||
self.nodes[0].generate(1)
|
||||
response = self.nodes[0].keva_list_namespaces()
|
||||
found = False
|
||||
print(response)
|
||||
for ns in response:
|
||||
if (ns['namespaceId'] == newNamespaceId):
|
||||
found = True
|
||||
assert(found)
|
||||
# Now disconnect the block and the namespace should be gone.
|
||||
self.sync_all()
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash())
|
||||
self.sync_all()
|
||||
found = False
|
||||
for ns in response:
|
||||
if (ns['namespaceId'] == newNamespaceId):
|
||||
found = True
|
||||
assert(not found)
|
||||
|
||||
|
||||
def run_test(self):
|
||||
self.nodes[0].generate(161) #block 161
|
||||
self.nodes[0].generate(105)
|
||||
self.nodes[1].generate(105)
|
||||
response = self.nodes[0].keva_namespace('first_namespace')
|
||||
namespaceId = response['namespaceId']
|
||||
|
||||
@ -38,6 +114,9 @@ class KevaTest(BitcoinTestFramework):
|
||||
response = self.nodes[0].keva_get(namespaceId, key)
|
||||
assert(response['value'] == value)
|
||||
|
||||
self.log.info("Test other wallet's unconfirmed namespaces do not show up in ours")
|
||||
self.run_unconfirmed_namespaces()
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
response = self.nodes[0].keva_pending()
|
||||
assert(len(response) == 0)
|
||||
@ -99,5 +178,9 @@ class KevaTest(BitcoinTestFramework):
|
||||
response = self.nodes[0].keva_get(namespaceId, keyToDelete)
|
||||
assert(response['value'] == newValue)
|
||||
|
||||
self.log.info("Test disconnecting blocks")
|
||||
self.run_test_disconnect_block(namespaceId)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
KevaTest().main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user