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. 4
      src/txmempool.cpp
  8. 36
      src/txmempool.h
  9. 85
      src/wallet/rpckeva.cpp
  10. 2
      src/wallet/test/wallet_tests.cpp

10
src/Makefile.am

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

2
src/Makefile.bench.include

@ -51,7 +51,7 @@ endif @@ -51,7 +51,7 @@ endif
if ENABLE_WALLET
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
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 @@ @@ -10,6 +10,7 @@
bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return 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::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { 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 @@ -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); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
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::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
@ -148,6 +150,10 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { @@ -148,6 +150,10 @@ void CCoinsViewCache::SetBestBlock(const uint256 &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 {
if (cacheNames.isDeleted(nameSpace, key))
return false;
@ -160,7 +166,6 @@ bool CCoinsViewCache::GetName(const valtype &nameSpace, const valtype &key, CKev @@ -160,7 +166,6 @@ bool CCoinsViewCache::GetName(const valtype &nameSpace, const valtype &key, CKev
return base->GetName(nameSpace, key, data);
}
bool CCoinsViewCache::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const {
/* Query the base view first, and then apply the cached changes (if
there are any). */

5
src/coins.h

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

16
src/keva/common.cpp

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

11
src/keva/common.h

@ -377,6 +377,7 @@ public: @@ -377,6 +377,7 @@ public:
* by the unit tests.
*/
typedef std::map<valtype, CKevaData, NameComparator> EntryMap;
typedef std::set<valtype> NamespaceSet;
private:
@ -384,6 +385,8 @@ private: @@ -384,6 +385,8 @@ private:
EntryMap entries;
/** Deleted names. */
std::set<valtype> deleted;
/** Namespaces */
NamespaceSet namespaces;
#if 0
/**
@ -448,14 +451,16 @@ public: @@ -448,14 +451,16 @@ public:
/* Try to get a name's associated data. This looks only
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
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. */
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
made to it according to the cache. The base iterator is taken

4
src/txmempool.cpp

@ -284,7 +284,7 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, b @@ -284,7 +284,7 @@ void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, b
// should be a bit faster.
// However, if we happen to be in the middle of processing a reorg, then
// the mempool can be in an inconsistent state. In this case, the set
// of ancestors reachable via mapLinks will be the same as the set of
// of ancestors reachable via mapLinks will be the same as the set of
// ancestors whose packages include this transaction, because when we
// add a new transaction to the mempool in addUnchecked(), we assume it
// has no children, and in the case of a reorg where that assumption is
@ -329,7 +329,7 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, @@ -329,7 +329,7 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee,
}
CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator) :
nTransactionsUpdated(0), minerPolicyEstimator(estimator)
nTransactionsUpdated(0), minerPolicyEstimator(estimator), kevaMemPool(*this)
{
_clear(); //lock free clear

36
src/txmempool.h

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
#include <amount.h>
#include <coins.h>
#include <indirectmap.h>
#include <keva/main.h>
#include <policy/feerate.h>
#include <primitives/transaction.h>
#include <sync.h>
@ -472,6 +473,9 @@ private: @@ -472,6 +473,9 @@ private:
mutable bool blockSinceLastRollingFeeBump;
mutable double rollingMinimumFeeRate; //!< minimum fee to get into the pool, decreases exponentially
/** Keva-related mempool data. */
CKevaMemPool kevaMemPool;
void trackPackageRemoved(const CFeeRate& rate);
public:
@ -661,6 +665,38 @@ public: @@ -661,6 +665,38 @@ public:
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;
TxMempoolInfo info(const uint256& hash) const;
std::vector<TxMempoolInfo> infoAll() const;

85
src/wallet/rpckeva.cpp

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

2
src/wallet/test/wallet_tests.cpp

@ -636,7 +636,7 @@ public: @@ -636,7 +636,7 @@ public:
int changePos = -1;
std::string error;
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;
BOOST_CHECK(wallet->CommitTransaction(wtx, reservekey, nullptr, state));
CMutableTransaction blocktx;

Loading…
Cancel
Save