Browse Source

Finally everything built!

cn
Jianping Wu 6 years ago
parent
commit
17a422025e
  1. 10
      src/Makefile.am
  2. 2
      src/Makefile.bench.include
  3. 7
      src/coins.cpp
  4. 5
      src/coins.h
  5. 16
      src/keva/common.cpp
  6. 11
      src/keva/common.h
  7. 2
      src/txmempool.cpp
  8. 36
      src/txmempool.h
  9. 77
      src/wallet/rpckeva.cpp
  10. 2
      src/wallet/test/wallet_tests.cpp

10
src/Makefile.am

@ -252,15 +252,13 @@ libbitcoin_wallet_a_SOURCES = \
wallet/fees.cpp \ wallet/fees.cpp \
wallet/init.cpp \ wallet/init.cpp \
wallet/rpcdump.cpp \ wallet/rpcdump.cpp \
wallet/rpckeva.cpp \
wallet/rpcwallet.cpp \ wallet/rpcwallet.cpp \
wallet/wallet.cpp \ wallet/wallet.cpp \
wallet/walletdb.cpp \ wallet/walletdb.cpp \
wallet/walletutil.cpp \ wallet/walletutil.cpp \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)
libbitcoin_wallet_a_SOURCES += \
wallet/rpckeva.cpp
# crypto primitives library # crypto primitives library
crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(SSL_CFLAGS) crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(SSL_CFLAGS)
crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
@ -328,6 +326,8 @@ libbitcoin_consensus_a_SOURCES = \
script/bitcoinconsensus.cpp \ script/bitcoinconsensus.cpp \
script/interpreter.cpp \ script/interpreter.cpp \
script/interpreter.h \ script/interpreter.h \
script/keva.h \
script/keva.cpp \
script/script.cpp \ script/script.cpp \
script/script.h \ script/script.h \
script/script_error.cpp \ script/script_error.cpp \
@ -338,9 +338,7 @@ libbitcoin_consensus_a_SOURCES = \
uint256.h \ uint256.h \
utilstrencodings.cpp \ utilstrencodings.cpp \
utilstrencodings.h \ utilstrencodings.h \
version.h \ version.h
script/keva.h \
script/keva.cpp
# common: shared between bitcoind, and bitcoin-qt and non-server tools # common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)

2
src/Makefile.bench.include

@ -51,7 +51,7 @@ endif
if ENABLE_WALLET if ENABLE_WALLET
bench_bench_litecoin_SOURCES += bench/coin_selection.cpp bench_bench_litecoin_SOURCES += bench/coin_selection.cpp
bench_bench_litecoin_LDADD += $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CRYPTO) bench_bench_litecoin_LDADD += $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO)
endif endif
bench_bench_litecoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) bench_bench_litecoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)

7
src/coins.cpp

@ -10,6 +10,7 @@
bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; } bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(); } uint256 CCoinsView::GetBestBlock() const { return uint256(); }
std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); } std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
bool CCoinsView::HasNamespace(const valtype &nameSpace) const { return false; }
bool CCoinsView::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { return false; } bool CCoinsView::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { return false; }
bool CCoinsView::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; } bool CCoinsView::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
@ -27,6 +28,7 @@ bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { re
bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); } bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); } std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
bool CCoinsViewBacked::HasNamespace(const valtype &nameSpace) const { return false; }
bool CCoinsViewBacked::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { return false; } bool CCoinsViewBacked::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { return false; }
bool CCoinsViewBacked::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; } bool CCoinsViewBacked::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
@ -148,6 +150,10 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
hashBlock = hashBlockIn; hashBlock = hashBlockIn;
} }
bool CCoinsViewCache::HasNamespace(const valtype &nameSpace) const {
return cacheNames.hasNamespace(nameSpace);
}
bool CCoinsViewCache::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { bool CCoinsViewCache::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const {
if (cacheNames.isDeleted(nameSpace, key)) if (cacheNames.isDeleted(nameSpace, key))
return false; return false;
@ -160,7 +166,6 @@ bool CCoinsViewCache::GetName(const valtype &nameSpace, const valtype &key, CKev
return base->GetName(nameSpace, key, data); return base->GetName(nameSpace, key, data);
} }
bool CCoinsViewCache::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { bool CCoinsViewCache::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const {
/* Query the base view first, and then apply the cached changes (if /* Query the base view first, and then apply the cached changes (if
there are any). */ there are any). */

5
src/coins.h

@ -164,6 +164,9 @@ public:
//! the old block hash, in that order. //! the old block hash, in that order.
virtual std::vector<uint256> GetHeadBlocks() const; virtual std::vector<uint256> GetHeadBlocks() const;
// Check if a namespace exists.
virtual bool HasNamespace(const valtype& nameSpace) const;
// Get a name (if it exists) // Get a name (if it exists)
virtual bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const; virtual bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const;
@ -200,6 +203,7 @@ public:
bool HaveCoin(const COutPoint &outpoint) const override; bool HaveCoin(const COutPoint &outpoint) const override;
uint256 GetBestBlock() const override; uint256 GetBestBlock() const override;
std::vector<uint256> GetHeadBlocks() const override; std::vector<uint256> GetHeadBlocks() const override;
bool HasNamespace(const valtype& nameSpace) const override;
bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const override; bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const override;
bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override; bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override;
void SetBackend(CCoinsView &viewIn); void SetBackend(CCoinsView &viewIn);
@ -240,6 +244,7 @@ public:
bool HaveCoin(const COutPoint &outpoint) const override; bool HaveCoin(const COutPoint &outpoint) const override;
uint256 GetBestBlock() const override; uint256 GetBestBlock() const override;
void SetBestBlock(const uint256 &hashBlock); void SetBestBlock(const uint256 &hashBlock);
bool HasNamespace(const valtype &nameSpace) const override;
bool GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const override; bool GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const override;
bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override; bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override;
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;

16
src/keva/common.cpp

@ -174,7 +174,7 @@ CCacheNameIterator::next (valtype& name, CKevaData& data)
/* CKevaCache. */ /* CKevaCache. */
bool bool
CKevaCache::get (const valtype& nameSpace, const valtype& key, CKevaData& data) const CKevaCache::get(const valtype& nameSpace, const valtype& key, CKevaData& data) const
{ {
valtype name = nameSpace; valtype name = nameSpace;
name.insert( name.end(), key.begin(), key.end() ); name.insert( name.end(), key.begin(), key.end() );
@ -186,8 +186,14 @@ CKevaCache::get (const valtype& nameSpace, const valtype& key, CKevaData& data)
return true; return true;
} }
bool CKevaCache::hasNamespace(const valtype& nameSpace) const
{
auto ni = namespaces.find(nameSpace);
return (ni != namespaces.end());
}
void void
CKevaCache::set (const valtype& nameSpace, const valtype& key, const CKevaData& data) CKevaCache::set(const valtype& nameSpace, const valtype& key, const CKevaData& data)
{ {
valtype name = nameSpace; valtype name = nameSpace;
name.insert( name.end(), key.begin(), key.end() ); name.insert( name.end(), key.begin(), key.end() );
@ -200,10 +206,12 @@ CKevaCache::set (const valtype& nameSpace, const valtype& key, const CKevaData&
ei->second = data; ei->second = data;
else else
entries.insert (std::make_pair (name, data)); entries.insert (std::make_pair (name, data));
namespaces.insert(nameSpace);
} }
void void
CKevaCache::remove (const valtype& nameSpace, const valtype& key) CKevaCache::remove(const valtype& nameSpace, const valtype& key)
{ {
valtype name = nameSpace; valtype name = nameSpace;
name.insert( name.end(), key.begin(), key.end() ); name.insert( name.end(), key.begin(), key.end() );
@ -215,7 +223,7 @@ CKevaCache::remove (const valtype& nameSpace, const valtype& key)
} }
CNameIterator* CNameIterator*
CKevaCache::iterateNames (CNameIterator* base) const CKevaCache::iterateNames(CNameIterator* base) const
{ {
return new CCacheNameIterator (*this, base); return new CCacheNameIterator (*this, base);
} }

11
src/keva/common.h

@ -377,6 +377,7 @@ public:
* by the unit tests. * by the unit tests.
*/ */
typedef std::map<valtype, CKevaData, NameComparator> EntryMap; typedef std::map<valtype, CKevaData, NameComparator> EntryMap;
typedef std::set<valtype> NamespaceSet;
private: private:
@ -384,6 +385,8 @@ private:
EntryMap entries; EntryMap entries;
/** Deleted names. */ /** Deleted names. */
std::set<valtype> deleted; std::set<valtype> deleted;
/** Namespaces */
NamespaceSet namespaces;
#if 0 #if 0
/** /**
@ -448,14 +451,16 @@ public:
/* Try to get a name's associated data. This looks only /* Try to get a name's associated data. This looks only
in entries, and doesn't care about deleted data. */ in entries, and doesn't care about deleted data. */
bool get (const valtype& nameSpace, const valtype& key, CKevaData& data) const; bool get(const valtype& nameSpace, const valtype& key, CKevaData& data) const;
bool hasNamespace(const valtype& nameSpace) const;
/* Insert (or update) a name. If it is marked as "deleted", this also /* Insert (or update) a name. If it is marked as "deleted", this also
removes the "deleted" mark. */ removes the "deleted" mark. */
void set (const valtype& nameSpace, const valtype& key, const CKevaData& data); void set(const valtype& nameSpace, const valtype& key, const CKevaData& data);
/* Delete a name. If it is in the "entries" set also, remove it there. */ /* Delete a name. If it is in the "entries" set also, remove it there. */
void remove (const valtype& nameSpace, const valtype& key); void remove(const valtype& nameSpace, const valtype& key);
/* Return a name iterator that combines a "base" iterator with the changes /* Return a name iterator that combines a "base" iterator with the changes
made to it according to the cache. The base iterator is taken made to it according to the cache. The base iterator is taken

2
src/txmempool.cpp

@ -329,7 +329,7 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee,
} }
CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator) : CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator) :
nTransactionsUpdated(0), minerPolicyEstimator(estimator) nTransactionsUpdated(0), minerPolicyEstimator(estimator), kevaMemPool(*this)
{ {
_clear(); //lock free clear _clear(); //lock free clear

36
src/txmempool.h

@ -16,6 +16,7 @@
#include <amount.h> #include <amount.h>
#include <coins.h> #include <coins.h>
#include <indirectmap.h> #include <indirectmap.h>
#include <keva/main.h>
#include <policy/feerate.h> #include <policy/feerate.h>
#include <primitives/transaction.h> #include <primitives/transaction.h>
#include <sync.h> #include <sync.h>
@ -472,6 +473,9 @@ private:
mutable bool blockSinceLastRollingFeeBump; mutable bool blockSinceLastRollingFeeBump;
mutable double rollingMinimumFeeRate; //!< minimum fee to get into the pool, decreases exponentially mutable double rollingMinimumFeeRate; //!< minimum fee to get into the pool, decreases exponentially
/** Keva-related mempool data. */
CKevaMemPool kevaMemPool;
void trackPackageRemoved(const CFeeRate& rate); void trackPackageRemoved(const CFeeRate& rate);
public: public:
@ -661,6 +665,38 @@ public:
return (mapTx.count(hash) != 0); return (mapTx.count(hash) != 0);
} }
inline bool registersNamespace(const valtype& nameSpace) const
{
AssertLockHeld(cs);
return kevaMemPool.registersNamespace(nameSpace);
}
inline bool updatesKey(const valtype& nameSpace, const valtype& key) const
{
AssertLockHeld(cs);
return kevaMemPool.updatesKey(nameSpace, key);
}
inline uint256 getTxForNamespace(const valtype& name) const
{
AssertLockHeld(cs);
return kevaMemPool.getTxForNamespace(name);
}
/**
* Check if a tx can be added to it according to name criteria.
* (The non-name criteria are checked in main.cpp and not here, we
* leave it there for as little changes as possible.)
* @param tx The tx that should be added.
* @return True if it doesn't conflict.
*/
inline bool
checkNameOps (const CTransaction& tx) const
{
AssertLockHeld(cs);
return kevaMemPool.checkTx(tx);
}
CTransactionRef get(const uint256& hash) const; CTransactionRef get(const uint256& hash) const;
TxMempoolInfo info(const uint256& hash) const; TxMempoolInfo info(const uint256& hash) const;
std::vector<TxMempoolInfo> infoAll() const; std::vector<TxMempoolInfo> infoAll() const;

77
src/wallet/rpckeva.cpp

@ -24,8 +24,7 @@
/* ************************************************************************** */ /* ************************************************************************** */
UniValue UniValue keva_namespace(const JSONRPCRequest& request)
keva_namespace (const JSONRPCRequest& request)
{ {
CWallet* const pwallet = GetWalletForJSONRPCRequest(request); CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
if (!EnsureWalletIsAvailable (pwallet, request.fHelp)) if (!EnsureWalletIsAvailable (pwallet, request.fHelp))
@ -50,9 +49,9 @@ keva_namespace (const JSONRPCRequest& request)
ObserveSafeMode (); ObserveSafeMode ();
const std::string displayNameStr = request.params[0].get_str (); const std::string displayNameStr = request.params[0].get_str();
const valtype displayName = ValtypeFromString (displayNameStr); const valtype displayName = ValtypeFromString (displayNameStr);
if (displayName.size () > MAX_NAME_LENGTH) if (displayName.size () > MAX_NAMESPACE_LENGTH)
throw JSONRPCError (RPC_INVALID_PARAMETER, "the name is too long"); throw JSONRPCError (RPC_INVALID_PARAMETER, "the name is too long");
/* No explicit locking should be necessary. CReserveKey takes care /* No explicit locking should be necessary. CReserveKey takes care
@ -66,7 +65,7 @@ keva_namespace (const JSONRPCRequest& request)
const bool ok = keyName.GetReservedKey(pubKey, true); const bool ok = keyName.GetReservedKey(pubKey, true);
assert (ok); assert (ok);
CKeyID keyId = pubKey.GetID() CKeyID keyId = pubKey.GetID();
// The namespace is: Hash160(Hash160(keyId) || displayName) // The namespace is: Hash160(Hash160(keyId) || displayName)
valtype toHash = ToByteVector(Hash160(ToByteVector(keyId))); valtype toHash = ToByteVector(Hash160(ToByteVector(keyId)));
@ -79,24 +78,23 @@ keva_namespace (const JSONRPCRequest& request)
CCoinControl coinControl; CCoinControl coinControl;
CWalletTx wtx; CWalletTx wtx;
SendMoneyToScript(pwallet, newScript, nullptr, SendMoneyToScript(pwallet, newScript, nullptr,
NAME_LOCKED_AMOUNT, false, wtx, coinControl); KEVA_LOCKED_AMOUNT, false, wtx, coinControl);
keyName.KeepKey(); keyName.KeepKey();
const std::string randStr = HexStr(rand);
const std::string txid = wtx.GetHash().GetHex(); const std::string txid = wtx.GetHash().GetHex();
LogPrintf ("name_new: name=%s, rand=%s, tx=%s\n", LogPrintf("keva_namespace: namespace=%s, displayName=%s, tx=%s\n",
nameStr.c_str(), randStr.c_str(), txid.c_str()); namespaceHash.ToString().c_str(), displayNameStr.c_str(), txid.c_str());
UniValue res(UniValue::VARR); UniValue res(UniValue::VARR);
res.push_back(txid); res.push_back(txid);
res.push_back(randStr); res.push_back(namespaceHash.ToString());
return res; return res;
} }
/* ************************************************************************** */ /* ************************************************************************** */
#if 0
UniValue keva_namespace(const JSONRPCRequest& request) UniValue keva_namespace(const JSONRPCRequest& request)
{ {
CWallet* const pwallet = GetWalletForJSONRPCRequest(request); CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
@ -123,20 +121,22 @@ UniValue keva_namespace(const JSONRPCRequest& request)
ObserveSafeMode (); ObserveSafeMode ();
const std::string displayName = request.params[0].get_str(); const valtype displayName = ValtypeFromString(request.params[0].get_str());
const valtype displayNameVal = ValtypeFromString(displayName); if (displayName.size() > MAX_NAMESPACE_LENGTH) {
if (displayNameVal.size() > MAX_NAMESPACE_LENGTH)
throw JSONRPCError (RPC_INVALID_PARAMETER, "the display name of the namespace is too long"); throw JSONRPCError (RPC_INVALID_PARAMETER, "the display name of the namespace is too long");
}
#if 0
/* Reject updates to a name for which the mempool already has /* Reject updates to a name for which the mempool already has
a pending update. This is not a hard rule enforced by network a pending update. This is not a hard rule enforced by network
rules, but it is necessary with the current mempool implementation. */ rules, but it is necessary with the current mempool implementation. */
{ {
LOCK (mempool.cs); LOCK (mempool.cs);
if (mempool.updatesName(name)) if (mempool.registersNamespace(name))
throw JSONRPCError (RPC_TRANSACTION_ERROR, throw JSONRPCError (RPC_TRANSACTION_ERROR,
"there is already a pending update for this name"); "there is already a pending update for this name");
} }
#endif
/* No more locking required, similarly to name_new. */ /* No more locking required, similarly to name_new. */
EnsureWalletIsUnlocked (pwallet); EnsureWalletIsUnlocked (pwallet);
@ -148,36 +148,31 @@ UniValue keva_namespace(const JSONRPCRequest& request)
bool usedKey = false; bool usedKey = false;
CScript addrName; CScript addrName;
if (request.params.size () == 3) if (request.params.size () == 3) {
{ keyName.ReturnKey();
keyName.ReturnKey (); const CTxDestination dest = DecodeDestination (request.params[2].get_str ());
const CTxDestination dest if (!IsValidDestination (dest)) {
= DecodeDestination (request.params[2].get_str ());
if (!IsValidDestination (dest))
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, "invalid address"); throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, "invalid address");
addrName = GetScriptForDestination (dest);
} }
else addrName = GetScriptForDestination(dest);
{ } else {
usedKey = true; usedKey = true;
addrName = GetScriptForDestination (pubKeyReserve.GetID ()); addrName = GetScriptForDestination(pubKeyReserve.GetID ());
} }
const CScript nameScript const CScript kevaScript = CKevaScript::buildKevaNamespace(addrName, name, displayName);
= CNameScript::buildNameUpdate (addrName, name, value);
CCoinControl coinControl; CCoinControl coinControl;
CWalletTx wtx; CWalletTx wtx;
SendMoneyToScript (pwallet, nameScript, &txIn, SendMoneyToScript(pwallet, kevaScript, nullptr, KEVA_LOCKED_AMOUNT, false, wtx, coinControl);
NAME_LOCKED_AMOUNT, false, wtx, coinControl);
if (usedKey) if (usedKey) {
keyName.KeepKey (); keyName.KeepKey ();
}
return wtx.GetHash ().GetHex (); return wtx.GetHash ().GetHex ();
} }
#endif
UniValue keva_put(const JSONRPCRequest& request) UniValue keva_put(const JSONRPCRequest& request)
{ {
@ -207,8 +202,8 @@ UniValue keva_put(const JSONRPCRequest& request)
ObserveSafeMode (); ObserveSafeMode ();
const std::string namespaceStr = request.params[0].get_str (); const std::string namespaceStr = request.params[0].get_str ();
const valtype namespaceVal = ValtypeFromString (namespaceStr); const valtype nameSpace = ValtypeFromString (namespaceStr);
if (namespaceVal.size () > MAX_NAMESPACE_LENGTH) if (nameSpace.size () > MAX_NAMESPACE_LENGTH)
throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long"); throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long");
const std::string keyStr = request.params[1].get_str (); const std::string keyStr = request.params[1].get_str ();
@ -231,18 +226,20 @@ UniValue keva_put(const JSONRPCRequest& request)
rules, but it is necessary with the current mempool implementation. */ rules, but it is necessary with the current mempool implementation. */
{ {
LOCK (mempool.cs); LOCK (mempool.cs);
if (mempool.updatesName (name)) if (mempool.updatesKey(nameSpace, key)) {
throw JSONRPCError (RPC_TRANSACTION_ERROR, throw JSONRPCError (RPC_TRANSACTION_ERROR,
"there is already a pending update for this name"); "there is already a pending update for this name");
} }
}
CNameData oldData; CKevaData oldData;
{ {
LOCK (cs_main); LOCK (cs_main);
if (!pcoinsTip->GetName (name, oldData) || oldData.isExpired ()) if (!pcoinsTip->HasNamespace(nameSpace)) {
throw JSONRPCError (RPC_TRANSACTION_ERROR, throw JSONRPCError (RPC_TRANSACTION_ERROR,
"this name can not be updated"); "this name can not be updated");
} }
}
const COutPoint outp = oldData.getUpdateOutpoint (); const COutPoint outp = oldData.getUpdateOutpoint ();
const CTxIn txIn(outp); const CTxIn txIn(outp);
@ -275,12 +272,12 @@ UniValue keva_put(const JSONRPCRequest& request)
} }
const CScript nameScript const CScript nameScript
= CNameScript::buildNameUpdate (addrName, name, value); = CKevaScript::buildKevaPut(addrName, nameSpace, key, value);
CCoinControl coinControl; CCoinControl coinControl;
CWalletTx wtx; CWalletTx wtx;
SendMoneyToScript (pwallet, nameScript, &txIn, SendMoneyToScript(pwallet, nameScript, &txIn,
NAME_LOCKED_AMOUNT, false, wtx, coinControl); KEVA_LOCKED_AMOUNT, false, wtx, coinControl);
if (usedKey) if (usedKey)
keyName.KeepKey (); keyName.KeepKey ();

2
src/wallet/test/wallet_tests.cpp

@ -636,7 +636,7 @@ public:
int changePos = -1; int changePos = -1;
std::string error; std::string error;
CCoinControl dummy; CCoinControl dummy;
BOOST_CHECK(wallet->CreateTransaction({recipient}, wtx, reservekey, fee, changePos, error, dummy)); BOOST_CHECK(wallet->CreateTransaction({recipient}, nullptr, wtx, reservekey, fee, changePos, error, dummy));
CValidationState state; CValidationState state;
BOOST_CHECK(wallet->CommitTransaction(wtx, reservekey, nullptr, state)); BOOST_CHECK(wallet->CommitTransaction(wtx, reservekey, nullptr, state));
CMutableTransaction blocktx; CMutableTransaction blocktx;

Loading…
Cancel
Save