Browse Source

remove GetCoins/SetCoins

miguelfreitas
Miguel Freitas 12 years ago
parent
commit
26bbd5614f
  1. 1
      src/bitcoinrpc.cpp
  2. 92
      src/main.cpp
  3. 22
      src/main.h
  4. 41
      src/rpcblockchain.cpp
  5. 28
      src/rpcrawtransaction.cpp
  6. 2
      src/txdb.cpp
  7. 2
      src/txdb.h
  8. 7
      src/wallet.cpp

1
src/bitcoinrpc.cpp

@ -251,7 +251,6 @@ static const CRPCCommand vRPCCommands[] =
{ "decoderawtransaction", &decoderawtransaction, false, false }, { "decoderawtransaction", &decoderawtransaction, false, false },
{ "signrawtransaction", &signrawtransaction, false, false }, { "signrawtransaction", &signrawtransaction, false, false },
{ "sendrawtransaction", &sendrawtransaction, false, false }, { "sendrawtransaction", &sendrawtransaction, false, false },
{ "gettxout", &gettxout, true, false },
{ "lockunspent", &lockunspent, false, false }, { "lockunspent", &lockunspent, false, false },
{ "listlockunspent", &listlockunspent, false, false }, { "listlockunspent", &listlockunspent, false, false },
{ "verifychain", &verifychain, true, false }, { "verifychain", &verifychain, true, false },

92
src/main.cpp

@ -269,9 +269,6 @@ int CBlockLocator::GetHeight()
// CCoinsView implementations // CCoinsView implementations
// //
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; }
bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
CBlockIndex *CCoinsView::GetBestBlock() { return NULL; } CBlockIndex *CCoinsView::GetBestBlock() { return NULL; }
bool CCoinsView::SetBestBlock(CBlockIndex *pindex) { return false; } bool CCoinsView::SetBestBlock(CBlockIndex *pindex) { return false; }
bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return false; } bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return false; }
@ -279,9 +276,6 @@ bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { } CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { }
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); }
bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
CBlockIndex *CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); } CBlockIndex *CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(CBlockIndex *pindex) { return base->SetBestBlock(pindex); } bool CCoinsViewBacked::SetBestBlock(CBlockIndex *pindex) { return base->SetBestBlock(pindex); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
@ -290,45 +284,6 @@ bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stat
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), pindexTip(NULL) { } CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), pindexTip(NULL) { }
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
if (cacheCoins.count(txid)) {
coins = cacheCoins[txid];
return true;
}
if (base->GetCoins(txid, coins)) {
cacheCoins[txid] = coins;
return true;
}
return false;
}
std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
std::map<uint256,CCoins>::iterator it = cacheCoins.lower_bound(txid);
if (it != cacheCoins.end() && it->first == txid)
return it;
CCoins tmp;
if (!base->GetCoins(txid,tmp))
return cacheCoins.end();
std::map<uint256,CCoins>::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins()));
tmp.swap(ret->second);
return ret;
}
CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
std::map<uint256,CCoins>::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end());
return it->second;
}
bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) {
cacheCoins[txid] = coins;
return true;
}
bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
return FetchCoins(txid) != cacheCoins.end();
}
CBlockIndex *CCoinsViewCache::GetBestBlock() { CBlockIndex *CCoinsViewCache::GetBestBlock() {
if (pindexTip == NULL) if (pindexTip == NULL)
pindexTip = base->GetBestBlock(); pindexTip = base->GetBestBlock();
@ -362,26 +317,10 @@ unsigned int CCoinsViewCache::GetCacheSize() {
It does not check for spendings by memory pool transactions. */ It does not check for spendings by memory pool transactions. */
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
if (base->GetCoins(txid, coins))
return true;
if (mempool.exists(txid)) {
const CTransaction &tx = mempool.lookup(txid);
coins = CCoins(tx, MEMPOOL_HEIGHT);
return true;
}
return false;
}
bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {
return mempool.exists(txid) || base->HaveCoins(txid);
}
CCoinsViewCache *pcoinsTip = NULL; CCoinsViewCache *pcoinsTip = NULL;
CBlockTreeDB *pblocktree = NULL; CBlockTreeDB *pblocktree = NULL;
bool IsStandardTx(const CTransaction& tx, string& reason) bool IsStandardTx(const CTransaction& tx, string& reason)
{ {
if (tx.nVersion > CTransaction::CURRENT_VERSION) { if (tx.nVersion > CTransaction::CURRENT_VERSION) {
@ -408,19 +347,20 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
CBlock blockTmp; CBlock blockTmp;
if (pblock == NULL) { if (pblock == NULL) {
/* [MF] FIXME: Use GetTransaction to obtain block? */ CTransaction tx2;
/* uint256 hashBlock2;
CCoins coins;
if (pcoinsTip->GetCoins(GetUsernameHash(), coins)) { if( GetTransaction(GetUsernameHash(), tx2, hashBlock2) && hashBlock2 != uint256() ) {
CBlockIndex *pindex = FindBlockByHeight(coins.nHeight); std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock2);
if (pindex) { if (mi != mapBlockIndex.end()) {
if (!ReadBlockFromDisk(blockTmp, pindex)) CBlockIndex *pindex = (*mi).second;
return 0; if (pindex) {
pblock = &blockTmp; if (!ReadBlockFromDisk(blockTmp, pindex))
return 0;
pblock = &blockTmp;
}
} }
} }
*/
return 0;
} }
if (pblock) { if (pblock) {
@ -1142,11 +1082,6 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
for (unsigned int i = 1; i < block.vtx.size(); i++) { for (unsigned int i = 1; i < block.vtx.size(); i++) {
if( pblocktree->HaveTxIndex(block.vtx[i].GetUsernameHash()) ) if( pblocktree->HaveTxIndex(block.vtx[i].GetUsernameHash()) )
return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction")); return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"));
// [MF] FIXME: check here for indexTx (done above!)
//uint256 hash = block.GetTxHash(i);
//if (view.HaveCoins(block.vtx[i].GetUsernameHash()))
// return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"));
} }
CBlockUndo blockundo; CBlockUndo blockundo;
@ -1527,7 +1462,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
return true; return true;
} }
// [MF] consistency check, don't check if tx already exists in db // [MF] basic consistency check. doesn't check if tx already exists in db
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
{ {
// These are checks that are independent of context // These are checks that are independent of context
@ -1775,6 +1710,7 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
{ {
uint256 hash = block.vtx[i].GetHash(); uint256 hash = block.vtx[i].GetHash();
// [MF] unsure. force 0, use userhash for filter, hash for merkletree // [MF] unsure. force 0, use userhash for filter, hash for merkletree
// [MF] FIXME: this is most likely broken!
if (i == 0 || filter.IsRelevantAndUpdate(block.vtx[i], block.vtx[i].GetUsernameHash())) if (i == 0 || filter.IsRelevantAndUpdate(block.vtx[i], block.vtx[i].GetUsernameHash()))
{ {
vMatch.push_back(true); vMatch.push_back(true);

22
src/main.h

@ -1051,16 +1051,6 @@ struct CCoinsStats
class CCoinsView class CCoinsView
{ {
public: public:
// Retrieve the CCoins (unspent transaction outputs) for a given txid
virtual bool GetCoins(const uint256 &txid, CCoins &coins);
// Modify the CCoins for a given txid
virtual bool SetCoins(const uint256 &txid, const CCoins &coins);
// Just check whether we have data for a given txid.
// This may (but cannot always) return true for fully spent transactions
virtual bool HaveCoins(const uint256 &txid);
// Retrieve the block index whose state this CCoinsView currently represents // Retrieve the block index whose state this CCoinsView currently represents
virtual CBlockIndex *GetBestBlock(); virtual CBlockIndex *GetBestBlock();
@ -1085,9 +1075,6 @@ protected:
public: public:
CCoinsViewBacked(CCoinsView &viewIn); CCoinsViewBacked(CCoinsView &viewIn);
bool GetCoins(const uint256 &txid, CCoins &coins);
bool SetCoins(const uint256 &txid, const CCoins &coins);
bool HaveCoins(const uint256 &txid);
CBlockIndex *GetBestBlock(); CBlockIndex *GetBestBlock();
bool SetBestBlock(CBlockIndex *pindex); bool SetBestBlock(CBlockIndex *pindex);
void SetBackend(CCoinsView &viewIn); void SetBackend(CCoinsView &viewIn);
@ -1105,19 +1092,10 @@ protected:
public: public:
CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false); CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
// Standard CCoinsView methods
bool GetCoins(const uint256 &txid, CCoins &coins);
bool SetCoins(const uint256 &txid, const CCoins &coins);
bool HaveCoins(const uint256 &txid);
CBlockIndex *GetBestBlock(); CBlockIndex *GetBestBlock();
bool SetBestBlock(CBlockIndex *pindex); bool SetBestBlock(CBlockIndex *pindex);
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex); bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);
// Return a modifiable reference to a CCoins. Check HaveCoins first.
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
// copying.
CCoins &GetCoins(const uint256 &txid);
// Push the modifications applied to this cache to its base. // Push the modifications applied to this cache to its base.
// Failure to call this method before destruction will cause the changes to be forgotten. // Failure to call this method before destruction will cause the changes to be forgotten.
bool Flush(); bool Flush();

41
src/rpcblockchain.cpp

@ -182,47 +182,6 @@ Value getblock(const Array& params, bool fHelp)
return blockToJSON(block, pblockindex); return blockToJSON(block, pblockindex);
} }
Value gettxout(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 2 || params.size() > 3)
throw runtime_error(
"gettxout <txid> <n> [includemempool=true]\n"
"Returns details about an unspent transaction output.");
Object ret;
std::string strHash = params[0].get_str();
uint256 hash(strHash);
int n = params[1].get_int();
bool fMempool = true;
if (params.size() > 2)
fMempool = params[2].get_bool();
CCoins coins;
if (fMempool) {
LOCK(mempool.cs);
CCoinsViewMemPool view(*pcoinsTip, mempool);
if (!view.GetCoins(hash, coins))
return Value::null;
//mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
} else {
if (!pcoinsTip->GetCoins(hash, coins))
return Value::null;
}
ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex()));
if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
ret.push_back(Pair("confirmations", 0));
else
ret.push_back(Pair("confirmations", pcoinsTip->GetBestBlock()->nHeight - coins.nHeight + 1));
ret.push_back(Pair("userName", coins.userName.ToString()));
Object o;
ScriptPubKeyToJSON(coins.pubKey, o);
ret.push_back(Pair("pubKey", o));
ret.push_back(Pair("version", coins.nVersion));
return ret;
}
Value verifychain(const Array& params, bool fHelp) Value verifychain(const Array& params, bool fHelp)
{ {

28
src/rpcrawtransaction.cpp

@ -300,8 +300,8 @@ Value signrawtransaction(const Array& params, bool fHelp)
CScript scriptPubKey(pkData.begin(), pkData.end()); CScript scriptPubKey(pkData.begin(), pkData.end());
CCoins coins; CCoins coins;
/*
if (view.GetCoins(txid, coins)) { if (view.GetCoins(txid, coins)) {
/*
if (coins.IsAvailable(nOut) && coins.vout[nOut].scriptPubKey != scriptPubKey) { if (coins.IsAvailable(nOut) && coins.vout[nOut].scriptPubKey != scriptPubKey) {
string err("Previous output scriptPubKey mismatch:\n"); string err("Previous output scriptPubKey mismatch:\n");
err = err + coins.vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ err = err + coins.vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
@ -309,15 +309,13 @@ Value signrawtransaction(const Array& params, bool fHelp)
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
} }
// what todo if txid is known, but the actual output isn't? // what todo if txid is known, but the actual output isn't?
*/
} }
/*
if ((unsigned int)nOut >= coins.vout.size()) if ((unsigned int)nOut >= coins.vout.size())
coins.vout.resize(nOut+1); coins.vout.resize(nOut+1);
coins.vout[nOut].scriptPubKey = scriptPubKey; coins.vout[nOut].scriptPubKey = scriptPubKey;
coins.vout[nOut].nValue = 0; // we don't know the actual output value coins.vout[nOut].nValue = 0; // we don't know the actual output value
*/
view.SetCoins(txid, coins); view.SetCoins(txid, coins);
*/
// if redeemScript given and not using the local wallet (private keys // if redeemScript given and not using the local wallet (private keys
// given), add redeemScript to the tempKeystore so it can be signed: // given), add redeemScript to the tempKeystore so it can be signed:
@ -414,20 +412,20 @@ Value sendrawtransaction(const Array& params, bool fHelp)
uint256 hashTx = tx.GetUsernameHash(); uint256 hashTx = tx.GetUsernameHash();
bool fHave = false; bool fHave = false;
CCoinsViewCache &view = *pcoinsTip; uint256 hashBlock;
CCoins existingCoins; CTransaction tx2;
{ fHave = GetTransaction(hashTx, tx2, hashBlock);
fHave = view.GetCoins(tx.GetUsernameHash(), existingCoins); if (!fHave) {
if (!fHave) { // push to local node
// push to local node CValidationState state;
CValidationState state; if (!mempool.accept(state, tx, false, NULL))
if (!mempool.accept(state, tx, false, NULL)) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
}
} }
if (fHave) { if (fHave) {
if (existingCoins.nHeight < 1000000000) if (hashBlock != uint256())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "transaction already in block chain"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "transaction already in block chain");
if (tx.GetHash() != tx2.GetHash())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "conflict transaction detected (same user, different tx)");
// Not in block, but already in the memory pool; will drop // Not in block, but already in the memory pool; will drop
// through to re-relay it. // through to re-relay it.
} else { } else {

2
src/txdb.cpp

@ -24,6 +24,7 @@ void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) { CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
} }
/*
bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) { bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) {
return db.Read(make_pair('c', txid), coins); return db.Read(make_pair('c', txid), coins);
} }
@ -37,6 +38,7 @@ bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
bool CCoinsViewDB::HaveCoins(const uint256 &txid) { bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
return db.Exists(make_pair('c', txid)); return db.Exists(make_pair('c', txid));
} }
*/
CBlockIndex *CCoinsViewDB::GetBestBlock() { CBlockIndex *CCoinsViewDB::GetBestBlock() {
uint256 hashBestChain; uint256 hashBestChain;

2
src/txdb.h

@ -16,9 +16,11 @@ protected:
public: public:
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
/*
bool GetCoins(const uint256 &txid, CCoins &coins); bool GetCoins(const uint256 &txid, CCoins &coins);
bool SetCoins(const uint256 &txid, const CCoins &coins); bool SetCoins(const uint256 &txid, const CCoins &coins);
bool HaveCoins(const uint256 &txid); bool HaveCoins(const uint256 &txid);
*/
CBlockIndex *GetBestBlock(); CBlockIndex *GetBestBlock();
bool SetBestBlock(CBlockIndex *pindex); bool SetBestBlock(CBlockIndex *pindex);
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex); bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex);

7
src/wallet.cpp

@ -719,9 +719,12 @@ void CWallet::ReacceptWalletTransactions()
if (wtx.IsSpamMessage() && wtx.IsSpent(0)) if (wtx.IsSpamMessage() && wtx.IsSpent(0))
continue; continue;
CCoins coins; CTransaction tx;
uint256 hashBlock;
bool fUpdated = false; bool fUpdated = false;
bool fFound = pcoinsTip->GetCoins(wtx.GetUsernameHash(), coins); bool fFound = false;
// [MF] can't use GetTransaction from main.cpp here. so?
// GetTransaction(wtx.GetUsernameHash(), tx, hashBlock);
if (fFound || wtx.GetDepthInMainChain() > 0) if (fFound || wtx.GetDepthInMainChain() > 0)
{ {
/* /*

Loading…
Cancel
Save