mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 02:55:50 +00:00
More work on ledger sequencing:
Track whether ledger is accepted. Assert on modifications to an accepted ledger. Save accepted ledgers to DB. Load ledger by hash/index. Ledger history functions, ledger canonicalization. 'Push' ledger to history.
This commit is contained in:
79
Ledger.cpp
79
Ledger.cpp
@@ -1,3 +1,10 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Ledger.h"
|
||||
#include "newcoin.pb.h"
|
||||
#include "PackedMessage.h"
|
||||
@@ -5,15 +12,10 @@
|
||||
#include "Conversion.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "Wallet.h"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
Ledger::Ledger(const uint160& masterID, uint64 startAmount) :
|
||||
mFeeHeld(0), mTimeStamp(0), mLedgerSeq(0), mClosed(false)
|
||||
mFeeHeld(0), mTimeStamp(0), mLedgerSeq(0),
|
||||
mClosed(false), mValidHash(false), mAccepted(false)
|
||||
{
|
||||
mTransactionMap=SHAMap::pointer(new SHAMap());
|
||||
mAccountStateMap=SHAMap::pointer(new SHAMap());
|
||||
@@ -27,16 +29,17 @@ Ledger::Ledger(const uint160& masterID, uint64 startAmount) :
|
||||
Ledger::Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash,
|
||||
uint64 feeHeld, uint64 timeStamp, uint32 ledgerSeq)
|
||||
: mParentHash(parentHash), mTransHash(transHash), mAccountHash(accountHash),
|
||||
mFeeHeld(feeHeld), mTimeStamp(timeStamp), mLedgerSeq(ledgerSeq), mClosed(false)
|
||||
mFeeHeld(feeHeld), mTimeStamp(timeStamp), mLedgerSeq(ledgerSeq),
|
||||
mClosed(false), mValidHash(false), mAccepted(false)
|
||||
{
|
||||
updateHash();
|
||||
}
|
||||
|
||||
Ledger::Ledger(Ledger &prevLedger, uint64 ts) : mTimeStamp(ts), mClosed(false),
|
||||
mTransactionMap(new SHAMap()), mAccountStateMap(prevLedger.mAccountStateMap)
|
||||
Ledger::Ledger(Ledger &prevLedger, uint64 ts) : mTimeStamp(ts),
|
||||
mTransactionMap(new SHAMap()), mAccountStateMap(prevLedger.mAccountStateMap),
|
||||
mClosed(false), mValidHash(false), mAccepted(false)
|
||||
{
|
||||
prevLedger.updateHash();
|
||||
mParentHash=prevLedger.mHash;
|
||||
mParentHash=prevLedger.getHash();
|
||||
mLedgerSeq=prevLedger.mLedgerSeq+1;
|
||||
}
|
||||
|
||||
@@ -45,6 +48,7 @@ void Ledger::updateHash()
|
||||
Serializer s(116);
|
||||
addRaw(s);
|
||||
mHash=s.getSHA512Half();
|
||||
mValidHash=true;
|
||||
}
|
||||
|
||||
void Ledger::addRaw(Serializer &s)
|
||||
@@ -84,18 +88,21 @@ uint64 Ledger::getBalance(const uint160& accountID)
|
||||
|
||||
bool Ledger::updateAccountState(AccountState::pointer state)
|
||||
{
|
||||
assert(!mAccepted);
|
||||
SHAMapItem::pointer item(new SHAMapItem(state->getAccountID(), state->getRaw()));
|
||||
return mAccountStateMap->updateGiveItem(item);
|
||||
}
|
||||
|
||||
bool Ledger::addAccountState(AccountState::pointer state)
|
||||
{
|
||||
assert(!mAccepted);
|
||||
SHAMapItem::pointer item(new SHAMapItem(state->getAccountID(), state->getRaw()));
|
||||
return mAccountStateMap->addGiveItem(item);
|
||||
}
|
||||
|
||||
bool Ledger::addTransaction(Transaction::pointer trans)
|
||||
{ // low-level - just add to table
|
||||
assert(!mAccepted);
|
||||
assert(!!trans->getID());
|
||||
SHAMapItem::pointer item(new SHAMapItem(trans->getID(), trans->getSigned()->getData()));
|
||||
return mTransactionMap->addGiveItem(item);
|
||||
@@ -103,6 +110,7 @@ bool Ledger::addTransaction(Transaction::pointer trans)
|
||||
|
||||
bool Ledger::delTransaction(const uint256& transID)
|
||||
{
|
||||
assert(!mAccepted);
|
||||
return mTransactionMap->delItem(transID);
|
||||
}
|
||||
|
||||
@@ -118,6 +126,7 @@ Transaction::pointer Ledger::getTransaction(const uint256& transID)
|
||||
|
||||
Ledger::TransResult Ledger::applyTransaction(Transaction::pointer trans)
|
||||
{
|
||||
assert(!mAccepted);
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
if(trans->getSourceLedger()>mLedgerSeq) return TR_BADLSEQ;
|
||||
|
||||
@@ -187,6 +196,7 @@ Ledger::TransResult Ledger::applyTransaction(Transaction::pointer trans)
|
||||
|
||||
Ledger::TransResult Ledger::removeTransaction(Transaction::pointer trans)
|
||||
{ // high-level - reverse application of transaction
|
||||
assert(!mAccepted);
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
if(!mTransactionMap || !mAccountStateMap) return TR_ERROR;
|
||||
try
|
||||
@@ -247,7 +257,7 @@ Ledger::pointer Ledger::closeLedger(uint64 timeStamp)
|
||||
return Ledger::pointer(new Ledger(*this, timeStamp));
|
||||
}
|
||||
|
||||
bool Ledger::unitTest(void)
|
||||
bool Ledger::unitTest()
|
||||
{
|
||||
LocalAccount l1(true), l2(true);
|
||||
assert(l1.peekPubKey());
|
||||
@@ -283,6 +293,43 @@ bool Ledger::unitTest(void)
|
||||
}
|
||||
|
||||
|
||||
uint256 Ledger::getHash()
|
||||
{
|
||||
if(!mValidHash) updateHash();
|
||||
return(mHash);
|
||||
}
|
||||
|
||||
void Ledger::saveAcceptedLedger(Ledger::pointer ledger)
|
||||
{
|
||||
std::string sql="INSERT INTO Ledgers "
|
||||
"(LedgerHash,LedgerSeq,PrevHash,FeeHeld,ClosingTime,AccountSetHash,TransSetHash) VALUES ('";
|
||||
sql.append(ledger->getHash().GetHex());
|
||||
sql.append("','");
|
||||
sql.append(boost::lexical_cast<std::string>(ledger->mLedgerSeq));
|
||||
sql.append("','");
|
||||
sql.append(ledger->mParentHash.GetHex());
|
||||
sql.append("','");
|
||||
sql.append(boost::lexical_cast<std::string>(ledger->mFeeHeld));
|
||||
sql.append("','");
|
||||
sql.append(boost::lexical_cast<std::string>(ledger->mTimeStamp));
|
||||
sql.append("','");
|
||||
sql.append(ledger->mAccountHash.GetHex());
|
||||
sql.append("','");
|
||||
sql.append(ledger->mTransHash.GetHex());
|
||||
sql.append("');");
|
||||
|
||||
ScopedLock sl(theApp->getDBLock());
|
||||
theApp->getDB()->executeSQL(sql.c_str());
|
||||
}
|
||||
|
||||
Ledger::pointer Ledger::loadByIndex(uint32 ledgerIndex)
|
||||
{
|
||||
}
|
||||
|
||||
Ledger::pointer Ledger::loadByHash(const uint256& ledgerHash)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
Ledger::pointer Ledger::getParent()
|
||||
@@ -421,12 +468,6 @@ Ledger::Account* Ledger::getAccount(const uint160& address)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
uint256& Ledger::getHash()
|
||||
{
|
||||
if(!mValidHash) hash();
|
||||
return(mHash);
|
||||
}
|
||||
|
||||
uint256& Ledger::getSignature()
|
||||
{
|
||||
if(!mValidSig) sign();
|
||||
|
||||
17
Ledger.h
17
Ledger.h
@@ -41,7 +41,7 @@ private:
|
||||
uint256 mHash, mParentHash, mTransHash, mAccountHash;
|
||||
uint64 mFeeHeld, mTimeStamp;
|
||||
uint32 mLedgerSeq;
|
||||
bool mClosed;
|
||||
bool mClosed, mValidHash, mAccepted;
|
||||
|
||||
SHAMap::pointer mTransactionMap, mAccountStateMap;
|
||||
|
||||
@@ -64,13 +64,15 @@ public:
|
||||
Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash,
|
||||
uint64 feeHeld, uint64 timeStamp, uint32 ledgerSeq); // used for received ledgers
|
||||
|
||||
void setClosed(void) { mClosed=true; }
|
||||
bool isClosed(void) { return mClosed; }
|
||||
void setClosed() { mClosed=true; }
|
||||
void setAccepted() { mAccepted=true; }
|
||||
bool isClosed() { return mClosed; }
|
||||
bool isAccepted() { mAccepted=true; }
|
||||
|
||||
// ledger signature operations
|
||||
void addRaw(Serializer &s);
|
||||
|
||||
uint256 getHash() const;
|
||||
uint256 getHash();
|
||||
const uint256& getParentHash() const { return mParentHash; }
|
||||
const uint256& getTransHash() const { return mTransHash; }
|
||||
const uint256& getAccountHash() const { return mAccountHash; }
|
||||
@@ -92,11 +94,16 @@ public:
|
||||
TransResult removeTransaction(Transaction::pointer trans);
|
||||
TransResult hasTransaction(Transaction::pointer trans);
|
||||
|
||||
// database functions
|
||||
static void saveAcceptedLedger(Ledger::pointer);
|
||||
static Ledger::pointer loadByIndex(uint32 ledgerIndex);
|
||||
static Ledger::pointer loadByHash(const uint256& ledgerHash);
|
||||
|
||||
Ledger::pointer closeLedger(uint64 timestamp);
|
||||
bool isCompatible(boost::shared_ptr<Ledger> other);
|
||||
bool signLedger(std::vector<unsigned char> &signature, const LocalHanko &hanko);
|
||||
|
||||
static bool unitTest(void);
|
||||
static bool unitTest();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,78 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "boost/bind.hpp"
|
||||
|
||||
#include "LedgerHistory.h"
|
||||
#include "Config.h"
|
||||
#include "Application.h"
|
||||
#include <string>
|
||||
|
||||
void LedgerHistory::addLedger(Ledger::pointer ledger)
|
||||
{
|
||||
uint256 h(ledger->getHash());
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
if(!mLedgersByHash[h]) mLedgersByHash[h]=ledger;
|
||||
}
|
||||
|
||||
void LedgerHistory::addAcceptedLedger(Ledger::pointer ledger)
|
||||
{
|
||||
assert(ledger && ledger->isAccepted());
|
||||
uint256 h(ledger->getHash());
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
if(!!mLedgersByHash[h]) return;
|
||||
mLedgersByHash[h]=ledger;
|
||||
mLedgersByIndex[ledger->getLedgerSeq()]=ledger;
|
||||
|
||||
theApp->getIOService().post(boost::bind(&Ledger::saveAcceptedLedger, ledger));
|
||||
}
|
||||
|
||||
Ledger::pointer LedgerHistory::getLedgerBySeq(uint32 index)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
Ledger::pointer ret(mLedgersByIndex[index]);
|
||||
if(ret) return ret;
|
||||
sl.unlock();
|
||||
ret=Ledger::loadByIndex(index);
|
||||
if(!ret) return ret;
|
||||
|
||||
assert(ret->getLedgerSeq()==index);
|
||||
uint256 h=ret->getHash();
|
||||
sl.lock();
|
||||
mLedgersByIndex[index]=ret;
|
||||
mLedgersByHash[h]=ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ledger::pointer LedgerHistory::getLedgerByHash(const uint256& hash)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
Ledger::pointer ret(mLedgersByHash[hash]);
|
||||
if(ret) return ret;
|
||||
|
||||
sl.unlock();
|
||||
ret=Ledger::loadByHash(hash);
|
||||
if(!ret) return ret;
|
||||
|
||||
assert(ret->getHash()==hash);
|
||||
sl.lock();
|
||||
mLedgersByHash[hash]=ret;
|
||||
if(ret->isAccepted()) mLedgersByIndex[ret->getLedgerSeq()]=ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ledger::pointer LedgerHistory::canonicalizeLedger(Ledger::pointer ledger, bool save)
|
||||
{
|
||||
uint256 h(ledger->getHash());
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
Ledger::pointer ret(mLedgersByHash[h]);
|
||||
if(ret) return ret;
|
||||
if(!save) return ledger;
|
||||
assert(ret->getHash()==h);
|
||||
mLedgersByHash[h]=ledger;
|
||||
if(ret->isAccepted()) mLedgersByIndex[ret->getLedgerSeq()]=ledger;
|
||||
return ledger;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool LedgerHistory::loadLedger(const uint256& hash)
|
||||
|
||||
@@ -5,12 +5,11 @@
|
||||
|
||||
class LedgerHistory
|
||||
{
|
||||
boost::recursive_mutex mLock;
|
||||
|
||||
std::map<uint32, Ledger::pointer> mLedgersByIndex;
|
||||
std::map<uint256, Ledger::pointer> mLedgersByHash;
|
||||
|
||||
bool loadClosedLedger(uint32 index);
|
||||
bool loadLedger(const uint256& hash);
|
||||
|
||||
public:
|
||||
LedgerHistory() { ; }
|
||||
|
||||
@@ -19,6 +18,7 @@ public:
|
||||
|
||||
Ledger::pointer getLedgerBySeq(uint32 index);
|
||||
Ledger::pointer getLedgerByHash(const uint256& hash);
|
||||
Ledger::pointer canonicalizeLedger(Ledger::pointer, bool cache);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -24,6 +24,23 @@ uint64 LedgerMaster::getBalance(std::string& addr)
|
||||
return mCurrentLedger->getBalance(humanTo160(addr));
|
||||
}
|
||||
|
||||
bool LedgerMaster::addTransaction(Transaction::pointer transaction)
|
||||
{
|
||||
return mCurrentLedger->applyTransaction(transaction)==Ledger::TR_SUCCESS;
|
||||
}
|
||||
|
||||
void LedgerMaster::pushLedger(Ledger::pointer newLedger)
|
||||
{
|
||||
ScopedLock sl(mLock);
|
||||
if(!!mFinalizingLedger)
|
||||
{
|
||||
mFinalizingLedger->setClosed();
|
||||
mFinalizingLedger->setAccepted();
|
||||
mLedgerHistory.addAcceptedLedger(mFinalizingLedger);
|
||||
}
|
||||
mFinalizingLedger=mCurrentLedger;
|
||||
mCurrentLedger=newLedger;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
class LedgerMaster
|
||||
{
|
||||
boost::recursive_mutex mLock;
|
||||
bool mIsSynced;
|
||||
|
||||
Ledger::pointer mCurrentLedger;
|
||||
@@ -32,12 +33,14 @@ public:
|
||||
LedgerMaster();
|
||||
|
||||
uint32 getCurrentLedgerIndex();
|
||||
bool IsSynced(void) { return mIsSynced; }
|
||||
void SetSynced(void) { mIsSynced=true; }
|
||||
bool IsSynced() { return mIsSynced; }
|
||||
void SetSynced() { mIsSynced=true; }
|
||||
|
||||
Ledger::pointer getCurrentLedger() { return mCurrentLedger; }
|
||||
Ledger::pointer getClosingLedger() { return mFinalizingLedger; }
|
||||
|
||||
void pushLedger(Ledger::pointer newLedger);
|
||||
|
||||
Ledger::pointer getLedgerBySeq(uint32 index)
|
||||
{
|
||||
if(mCurrentLedger && (mCurrentLedger->getLedgerSeq()==index)) return mCurrentLedger;
|
||||
|
||||
Reference in New Issue
Block a user