Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
jed
2012-10-09 09:55:29 -07:00
22 changed files with 525 additions and 178 deletions

View File

@@ -73,6 +73,7 @@ void Application::run()
boost::thread auxThread(boost::bind(&boost::asio::io_service::run, &mAuxService));
auxThread.detach();
if (!theConfig.RUN_STANDALONE)
mSNTPClient.init(theConfig.SNTP_SERVERS);
@@ -87,9 +88,24 @@ void Application::run()
boost::thread t6(boost::bind(&InitDB, &mNetNodeDB, "netnode.db", NetNodeDBInit, NetNodeDBCount));
t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join();
if(theConfig.START_UP==Config::FRESH)
{
Log(lsINFO) << "Starting new Ledger";
startNewLedger();
}else if(theConfig.START_UP==Config::LOAD)
{
Log(lsINFO) << "Loading Old Ledger";
loadOldLedger();
}else
{ // TODO: This should really not validate a ledger until it gets the current one from our peers
// but I'll let david make this change since a lot of code assumes we have a ledger
// for now just do what we always were doing
startNewLedger();
}
//
// Begin validation and ip maintenance.
// - Wallet maintains local information: including identity and network connection persistency information.
// - Wallet maintains local information: including identity and network connection persistence information.
//
mWallet.start();
@@ -132,6 +148,33 @@ void Application::run()
if (!theConfig.RUN_STANDALONE)
mConnectionPool.start();
if (theConfig.RUN_STANDALONE)
{
Log(lsWARNING) << "Running in standalone mode";
mNetOps.setStandAlone();
}
else
mNetOps.setStateTimer();
mIOService.run(); // This blocks
mWSDoor->stop();
std::cout << "Done." << std::endl;
}
Application::~Application()
{
delete mTxnDB;
delete mLedgerDB;
delete mWalletDB;
delete mHashNodeDB;
delete mNetNodeDB;
}
void Application::startNewLedger()
{
// New stuff.
NewcoinAddress rootSeedMaster = NewcoinAddress::createSeedGeneric("masterpassphrase");
NewcoinAddress rootGeneratorMaster = NewcoinAddress::createGeneratorPublic(rootSeedMaster);
@@ -156,30 +199,18 @@ void Application::run()
assert(!!secondLedger->getAccountState(rootAddress));
mNetOps.setLastCloseTime(secondLedger->getCloseTimeNC());
}
if (theConfig.RUN_STANDALONE)
{
Log(lsWARNING) << "Running in standalone mode";
mNetOps.setStandAlone();
mMasterLedger.runStandAlone();
}
else
mNetOps.setStateTimer();
mIOService.run(); // This blocks
mWSDoor->stop();
std::cout << "Done." << std::endl;
}
Application::~Application()
void Application::loadOldLedger()
{
delete mTxnDB;
delete mLedgerDB;
delete mWalletDB;
delete mHashNodeDB;
delete mNetNodeDB;
Ledger::pointer lastLedger = Ledger::getSQL("SELECT * from Ledgers order by LedgerSeq desc limit 1;",true);
if(!lastLedger)
{
std::cout << "No Ledger found?" << std::endl;
exit(-1);
}
mMasterLedger.pushLedger(lastLedger);
mNetOps.setLastCloseTime(lastLedger->getCloseTimeNC());
}
// vim:ts=4

View File

@@ -67,6 +67,9 @@ class Application
std::map<std::string, Peer::pointer> mPeerMap;
boost::recursive_mutex mPeerMapLock;
void startNewLedger();
void loadOldLedger();
public:
Application();
~Application();

View File

@@ -155,6 +155,7 @@ void Config::setup(const std::string& strConf)
VALIDATORS_SITE = DEFAULT_VALIDATORS_SITE;
RUN_STANDALONE = false;
START_UP = NORMAL;
load();
}

View File

@@ -56,6 +56,9 @@ public:
std::vector<std::string> IPS; // Peer IPs from newcoind.cfg.
std::vector<std::string> SNTP_SERVERS; // SNTP servers from newcoind.cfg.
enum StartUpType {FRESH,NORMAL,LOAD};
StartUpType START_UP;
// Network parameters
int NETWORK_START_TIME; // The Unix time we start ledger 0.
int TRANSACTION_FEE_BASE;

View File

@@ -38,11 +38,11 @@ Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(s
}
Ledger::Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash,
uint64 totCoins, uint32 closeTime, uint32 parentCloseTime, int closeFlags, int closeResolution, uint32 ledgerSeq)
uint64 totCoins, uint32 closeTime, uint32 parentCloseTime, int closeFlags, int closeResolution, uint32 ledgerSeq,bool isMutable)
: mParentHash(parentHash), mTransHash(transHash), mAccountHash(accountHash), mTotCoins(totCoins),
mLedgerSeq(ledgerSeq), mCloseTime(closeTime), mParentCloseTime(parentCloseTime),
mCloseResolution(closeResolution), mCloseFlags(closeFlags),
mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false)
mClosed(false), mValidHash(false), mAccepted(false), mImmutable(isMutable)
{
updateHash();
}
@@ -391,7 +391,7 @@ void Ledger::saveAcceptedLedger(Ledger::ref ledger)
theApp->getOPs().pubLedger(ledger);
}
Ledger::pointer Ledger::getSQL(const std::string& sql)
Ledger::pointer Ledger::getSQL(const std::string& sql,bool isMutable)
{
uint256 ledgerHash, prevHash, accountHash, transHash;
uint64 totCoins;
@@ -424,9 +424,8 @@ Ledger::pointer Ledger::getSQL(const std::string& sql)
db->endIterRows();
}
Ledger::pointer ret =
boost::make_shared<Ledger>(prevHash, transHash, accountHash, totCoins, closingTime, prevClosingTime,
closeFlags, closeResolution, ledgerSeq);
Ledger::pointer ret =Ledger::pointer(new Ledger(prevHash, transHash, accountHash, totCoins, closingTime, prevClosingTime,
closeFlags, closeResolution, ledgerSeq,isMutable));
if (ret->getHash() != ledgerHash)
{
if (sLog(lsERROR))

View File

@@ -84,7 +84,7 @@ private:
protected:
static Ledger::pointer getSQL(const std::string& sqlStatement);
SLE::pointer getASNode(LedgerStateParms& parms, const uint256& nodeID, LedgerEntryType let);
@@ -93,7 +93,7 @@ public:
Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash,
uint64 totCoins, uint32 closeTime, uint32 parentCloseTime, int closeFlags, int closeResolution,
uint32 ledgerSeq); // used for database ledgers
uint32 ledgerSeq,bool immutable); // used for database ledgers
Ledger(const std::vector<unsigned char>& rawLedger);
@@ -103,6 +103,8 @@ public:
Ledger(Ledger& target, bool isMutable); // snapshot
static Ledger::pointer getSQL(const std::string& sqlStatement,bool immutable=false);
void updateHash();
void setClosed() { mClosed = true; }
void setAccepted(uint32 closeTime, int closeResolution, bool correctCloseTime);

View File

@@ -527,15 +527,20 @@ void LedgerConsensus::statePreClose()
}
if (ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed,
mPreviousMSeconds, sinceClose, idleInterval))
{ // it is time to close the ledger
mPreviousMSeconds, sinceClose, idleInterval))
{
closeLedger();
}
}
void LedgerConsensus::closeLedger()
{
mState = lcsESTABLISH;
mConsensusStartTime = boost::posix_time::microsec_clock::universal_time();
mCloseTime = theApp->getOPs().getCloseTimeNC();
theApp->getOPs().setLastCloseTime(mCloseTime);
statusChange(newcoin::neCLOSING_LEDGER, *mPreviousLedger);
takeInitialPosition(*theApp->getMasterLedger().closeLedger());
}
}
void LedgerConsensus::stateEstablish()
@@ -551,7 +556,7 @@ void LedgerConsensus::stateEstablish()
{
cLog(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)";
mState = lcsFINISHED;
beginAccept();
beginAccept(false);
}
}
@@ -929,7 +934,7 @@ bool LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
return set->takeNodes(nodeIDs, nodeData, peer);
}
void LedgerConsensus::beginAccept()
void LedgerConsensus::beginAccept(bool synchronous)
{
SHAMap::pointer consensusSet = mAcquired[mOurPosition->getCurrentHash()];
if (!consensusSet)
@@ -940,7 +945,10 @@ void LedgerConsensus::beginAccept()
}
theApp->getOPs().newLCL(mPeerPositions.size(), mCurrentMSeconds, mNewLedgerHash);
theApp->getIOService().post(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet));
if (synchronous)
accept(consensusSet);
else
theApp->getIOService().post(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet));
}
void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::pointer txSet)
@@ -1173,7 +1181,6 @@ void LedgerConsensus::accept(SHAMap::ref set)
theApp->getOPs().closeTimeOffset(offset);
}
#ifdef DEBUG
if (sLog(lsTRACE))
{
Log(lsTRACE) << "newLCL";
@@ -1181,7 +1188,6 @@ void LedgerConsensus::accept(SHAMap::ref set)
newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
Log(lsTRACE) << p;
}
#endif
}
void LedgerConsensus::endConsensus()
@@ -1189,6 +1195,16 @@ void LedgerConsensus::endConsensus()
theApp->getOPs().endConsensus(mHaveCorrectLCL);
}
void LedgerConsensus::simulate()
{
cLog(lsINFO) << "Simulating consensus";
closeLedger();
mCurrentMSeconds = 100;
beginAccept(true);
endConsensus();
cLog(lsINFO) << "Simulation complete";
}
Json::Value LedgerConsensus::getJson()
{
Json::Value ret(Json::objectValue);

View File

@@ -148,8 +148,9 @@ protected:
void updateOurPositions();
void playbackProposals();
int getThreshold();
void closeLedger();
void beginAccept();
void beginAccept(bool synchronous);
void endConsensus();
public:
@@ -189,6 +190,8 @@ public:
void swapDefer(boost::unordered_map< uint160, std::list<LedgerProposal::pointer> > &n)
{ mDeferredProposals.swap(n); }
// test/debug
void simulate();
};

View File

@@ -21,7 +21,7 @@ bool LedgerMaster::addHeldTransaction(const Transaction::pointer& transaction)
void LedgerMaster::pushLedger(Ledger::ref newLedger)
{
// Caller should already have properly assembled this ledger into "ready-to-close" form --
// all candidate transactions must already be appled
// all candidate transactions must already be applied
Log(lsINFO) << "PushLedger: " << newLedger->getHash();
ScopedLock sl(mLock);
if (!!mFinalizedLedger)
@@ -70,6 +70,8 @@ void LedgerMaster::storeLedger(Ledger::ref ledger)
mLedgerHistory.addLedger(ledger);
}
Ledger::pointer LedgerMaster::closeLedger()
{
boost::recursive_mutex::scoped_lock sl(mLock);

View File

@@ -43,8 +43,6 @@ public:
// The finalized ledger is the last closed/accepted ledger
Ledger::pointer getClosedLedger() { return mFinalizedLedger; }
void runStandAlone() { mFinalizedLedger = mCurrentLedger; }
TER doTransaction(const SerializedTransaction& txn, TransactionEngineParams params);
void pushLedger(Ledger::ref newLedger);

View File

@@ -28,12 +28,12 @@
enum LogSeverity
{
lsTRACE = 0,
lsDEBUG = 1,
lsINFO = 2,
lsWARNING = 3,
lsERROR = 4,
lsFATAL = 5
lsTRACE = 0, // Very low-level progress information, details inside an operation
lsDEBUG = 1, // Function-level progress information, operations
lsINFO = 2, // Server-level progress information, major operations
lsWARNING = 3, // Conditions that warrant human attention, may indicate a problem
lsERROR = 4, // A condition that indicates a problem
lsFATAL = 5 // A severe condition that indicates a server problem
};
class LogPartition

View File

@@ -424,7 +424,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
// If full or tracking, check only at wobble time!
uint256 networkClosed;
bool ledgerChange = checkLastClosedLedger(peerList, networkClosed);
assert(networkClosed.isNonZero());
if(networkClosed.isZero())return;
// WRITEME: Unless we are in omFULL and in the process of doing a consensus,
// we must count how many nodes share our LCL, how many nodes disagree with our LCL,
@@ -438,12 +438,12 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
setMode(omTRACKING);
}
if ((mMode == omTRACKING) && !ledgerChange)
if ((mMode == omTRACKING) && !ledgerChange )
{
// check if the ledger is good enough to go to omFULL
// Note: Do not go to omFULL if we don't have the previous ledger
// check if the ledger is bad enough to go to omCONNECTED -- TODO
if (theApp->getOPs().getNetworkTimeNC() < theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC())
if (theApp->getOPs().getNetworkTimeNC() < mLedgerMaster->getCurrentLedger()->getCloseTimeNC())
setMode(omFULL);
}
@@ -454,7 +454,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
}
if ((!mConsensus) && (mMode != omDISCONNECTED))
beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger());
beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger());
if (mConsensus)
mConsensus->timerEntry();
}
@@ -470,6 +470,8 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
cLog(lsTRACE) << "NetworkOPs::checkLastClosedLedger";
Ledger::pointer ourClosed = mLedgerMaster->getClosedLedger();
if(!ourClosed) return(false);
uint256 closedLedger = ourClosed->getHash();
uint256 prevClosedLedger = ourClosed->getParentHash();
@@ -650,7 +652,7 @@ int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer clo
assert(!mConsensus);
prevLedger->setImmutable();
mConsensus = boost::make_shared<LedgerConsensus>(
networkClosed, prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC());
networkClosed, prevLedger, mLedgerMaster->getCurrentLedger()->getCloseTimeNC());
mConsensus->swapDefer(mDeferredProposals);
cLog(lsDEBUG) << "Initiating consensus engine";
@@ -670,7 +672,7 @@ bool NetworkOPs::haveConsensusObject()
if (!ledgerChange)
{
cLog(lsWARNING) << "Beginning consensus due to peer action";
beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger());
beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger());
}
return mConsensus;
}
@@ -770,7 +772,7 @@ void NetworkOPs::mapComplete(const uint256& hash, SHAMap::ref map)
void NetworkOPs::endConsensus(bool correctLCL)
{
uint256 deadLedger = theApp->getMasterLedger().getClosedLedger()->getParentHash();
uint256 deadLedger = mLedgerMaster->getClosedLedger()->getParentHash();
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
BOOST_FOREACH(Peer::ref it, peerList)
if (it && (it->getClosedLedgerHash() == deadLedger))
@@ -1222,6 +1224,12 @@ void NetworkOPs::newLCL(int proposers, int convergeTime, const uint256& ledgerHa
mLastCloseHash = ledgerHash;
}
uint32 NetworkOPs::acceptLedger()
{ // accept the current transaction tree, return the new ledger's sequence
beginConsensus(mLedgerMaster->getClosedLedger()->getHash(), mLedgerMaster->getCurrentLedger());
mConsensus->simulate();
return mLedgerMaster->getCurrentLedger()->getLedgerSeq();
}
#if 0
void NetworkOPs::subAccountChanges(InfoSub* ispListener, const uint256 uLedgerHash)

View File

@@ -190,6 +190,7 @@ public:
uint32 getLastCloseTime() { return mLastCloseTime; }
void setLastCloseTime(uint32 t) { mLastCloseTime = t; }
Json::Value getServerInfo();
uint32 acceptLedger();
// client information retrieval functions
std::vector< std::pair<uint32, uint256> >

View File

@@ -70,6 +70,7 @@ Json::Value RPCServer::RPCError(int iError)
{ rpcNO_GEN_DECRPYT, "noGenDectypt", "Password failed to decrypt master public generator." },
{ rpcNO_NETWORK, "noNetwork", "Network not available." },
{ rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." },
{ rpcNOT_STANDALONE, "notStandAlone", "Operation valid in debug mode only." },
{ rpcPASSWD_CHANGED, "passwdChanged", "Wrong key, password changed." },
{ rpcPAYS_ACT_MALFORMED, "paysActMalformed", "Pays account malformed." },
{ rpcPAYS_AMT_MALFORMED, "paysAmtMalformed", "Pays amount malformed." },
@@ -419,6 +420,16 @@ Json::Value RPCServer::accountFromString(const uint256& uLedger, NewcoinAddress&
return Json::Value(Json::objectValue);
}
Json::Value RPCServer::doAcceptLedger(const Json::Value &params)
{
if (!theConfig.RUN_STANDALONE)
return RPCError(rpcNOT_STANDALONE);
Json::Value obj(Json::objectValue);
obj["newLedger"] = theApp->getOPs().acceptLedger();
return obj;
}
// account_domain_set <seed> <paying_account> [<domain>]
Json::Value RPCServer::doAccountDomainSet(const Json::Value &params)
{
@@ -2641,6 +2652,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
bool mAdminRequired;
unsigned int iOptions;
} commandsA[] = {
{ "accept_ledger", &RPCServer::doAcceptLedger, 0, 0, true },
{ "account_domain_set", &RPCServer::doAccountDomainSet, 2, 3, false, optCurrent },
{ "account_email_set", &RPCServer::doAccountEmailSet, 2, 3, false, optCurrent },
{ "account_info", &RPCServer::doAccountInfo, 1, 2, false, optCurrent },

View File

@@ -23,6 +23,7 @@ public:
// Misc failure
rpcLOAD_FAILED,
rpcNO_PERMISSION,
rpcNOT_STANDALONE,
// Networking
rpcNO_CLOSED,
@@ -128,6 +129,7 @@ private:
Json::Value accountFromString(const uint256& uLedger, NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex);
Json::Value doAcceptLedger(const Json::Value &params);
Json::Value doAccountDomainSet(const Json::Value &params);
Json::Value doAccountEmailSet(const Json::Value &params);
Json::Value doAccountInfo(const Json::Value& params);

View File

@@ -30,7 +30,6 @@
FIELD(TransactionType, UINT16, 2)
// 32-bit integers (common)
FIELD(ObjectType, UINT32, 1)
FIELD(Flags, UINT32, 2)
FIELD(SourceTag, UINT32, 3)
FIELD(Sequence, UINT32, 4)
@@ -91,7 +90,7 @@
FIELD(Fee, AMOUNT, 8)
FIELD(SendMax, AMOUNT, 9)
// current amount (uncommon)
// currency amount (uncommon)
FIELD(MinimumOffer, AMOUNT, 16)
FIELD(RippleEscrow, AMOUNT, 17)
@@ -113,8 +112,6 @@
FIELD(Owner, ACCOUNT, 2)
FIELD(Destination, ACCOUNT, 3)
FIELD(Issuer, ACCOUNT, 4)
FIELD(HighID, ACCOUNT, 5)
FIELD(LowID, ACCOUNT, 6)
FIELD(Target, ACCOUNT, 7)
FIELD(AuthorizedKey, ACCOUNT, 8)

View File

@@ -98,6 +98,8 @@ int main(int argc, char* argv[])
("test,t", "Perform unit tests.")
("parameters", po::value< vector<string> >(), "Specify comma separated parameters.")
("verbose,v", "Increase log level.")
("load","Load the current ledger from the local DB.")
("start","Start from a fresh Ledger.")
;
// Interpret positional arguments as --parameters.
@@ -154,6 +156,9 @@ int main(int argc, char* argv[])
}
}
if(vm.count("start")) theConfig.START_UP=Config::FRESH;
else if(vm.count("load")) theConfig.START_UP=Config::LOAD;
if (iResult)
{
nothing();