diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 30656cd218..495974f34f 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -162,7 +162,7 @@ bool Ledger::addTransaction(Transaction::pointer trans) assert(!mAccepted); assert(!!trans->getID()); Serializer s; - trans->getSTransaction()->getTransaction(s, false); + trans->getSTransaction()->add(s); SHAMapItem::pointer item = boost::make_shared(trans->getID(), s.peekData()); if (!mTransactionMap->addGiveItem(item, true)) return false; mTotCoins -= trans->getFee(); diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 44d2807ff8..0785db6ca4 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -9,6 +9,8 @@ #include "SerializedValidation.h" #include "Log.h" +#define TRUST_NETWORK + TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, 1), mHaveRoot(false) { mMap = boost::make_shared(); @@ -339,7 +341,6 @@ int LedgerConsensus::stateFinished(int secondsSinceClose) int LedgerConsensus::stateAccepted(int secondsSinceClose) { // we have accepted a new ledger - statusChange(newcoin::neACCEPTED_LEDGER, theApp->getMasterLedger().getClosedLedger()); endConsensus(); return 4; } @@ -432,7 +433,6 @@ void LedgerConsensus::closeLedger() { Log(lsINFO) << "Closing ledger"; Ledger::pointer initial = theApp->getMasterLedger().getCurrentLedger(); - statusChange(newcoin::neCLOSING_LEDGER, initial); statusChange(newcoin::neCLOSING_LEDGER, mPreviousLedger); } @@ -525,7 +525,8 @@ bool LedgerConsensus::peerPosition(LedgerProposal::pointer newPosition) return true; } } - Log(lsINFO) << "Peer changes position"; + Log(lsINFO) << "Peer position " << newPosition->getProposeSeq() << "/" + << newPosition->getCurrentHash().GetHex(); currentPosition = newPosition; SHAMap::pointer set = getTransactionTree(newPosition->getCurrentHash(), true); if (set) @@ -595,10 +596,12 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led while (item) { Log(lsINFO) << "Processing candidate transaction: " << item->getTag().GetHex(); +#ifndef TRUST_NETWORK try { +#endif SerializerIterator sit(item->peekSerializer()); - SerializedTransaction::pointer txn = boost::make_shared(boost::ref(sit), 0); + SerializedTransaction::pointer txn = boost::make_shared(boost::ref(sit)); TransactionEngineResult result = engine.applyTransaction(*txn, tepNO_CHECK_FEE); if (result > 0) { @@ -616,11 +619,13 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led Log(lsINFO) << " hard fail"; assert(!ledger->hasTransaction(item->getTag())); } +#ifndef TRUST_NETWORK } catch (...) { Log(lsWARNING) << " Throws"; } +#endif item = set->peekNextItem(item->getTag()); } @@ -655,7 +660,11 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led void LedgerConsensus::accept(SHAMap::pointer set) { + assert(set->getHash() == mOurPosition->getCurrentHash()); Log(lsINFO) << "Computing new LCL based on network consensus"; + Log(lsDEBUG) << "Consensus " << mOurPosition->getCurrentHash().GetHex(); + Log(lsDEBUG) << "Previous LCL " << mPreviousLedger->getParentHash().GetHex(); + Ledger::pointer newLCL = boost::make_shared(mPreviousLedger); std::deque failedTransactions; @@ -680,7 +689,8 @@ void LedgerConsensus::accept(SHAMap::pointer set) newcoin::TMValidation val; val.set_validation(&validation[0], validation.size()); theApp->getConnectionPool().relayMessage(NULL, boost::make_shared(val, newcoin::mtVALIDATION)); - Log(lsINFO) << "Validation sent"; + Log(lsINFO) << "Validation sent " << newLCL->getHash().GetHex(); + statusChange(newcoin::neACCEPTED_LEDGER, newOL); } void LedgerConsensus::endConsensus() diff --git a/src/LedgerMaster.cpp b/src/LedgerMaster.cpp index 0b13b55ecf..67ef56705d 100644 --- a/src/LedgerMaster.cpp +++ b/src/LedgerMaster.cpp @@ -20,7 +20,7 @@ void LedgerMaster::pushLedger(Ledger::pointer newLedger) // Caller should already have properly assembled this ledger into "ready-to-close" form -- // all candidate transactions must already be appled ScopedLock sl(mLock); - if(!!mFinalizedLedger) + if (!!mFinalizedLedger) { mFinalizedLedger->setClosed(); mFinalizedLedger->setAccepted(); @@ -37,7 +37,8 @@ void LedgerMaster::pushLedger(Ledger::pointer newLCL, Ledger::pointer newOL) assert(!newOL->isClosed() && !newOL->isAccepted()); ScopedLock sl(mLock); - mLedgerHistory.addAcceptedLedger(newLCL); + if (!!mFinalizedLedger) + mLedgerHistory.addAcceptedLedger(mFinalizedLedger); mFinalizedLedger = newLCL; mCurrentLedger = newOL; mEngine.setLedger(newOL); @@ -90,7 +91,7 @@ void LedgerMaster::applyFutureProposals(uint32 ledgerIndex) { for(list< pair >::iterator iter=mFutureProposals.begin(); iter !=mFutureProposals.end(); ) { - if( (*iter).second.ledgerindex() == ledgerIndex) + if ((*iter).second.ledgerindex() == ledgerIndex) { checkLedgerProposal((*iter).first,(*iter).second); mFutureProposals.erase(iter); diff --git a/src/Log.h b/src/Log.h index e226d3bf53..bb5bbc14fb 100644 --- a/src/Log.h +++ b/src/Log.h @@ -39,6 +39,11 @@ public: return oss << t; } + std::ostringstream& ref(void) const + { + return oss; + } + static void setMinSeverity(LogSeverity); }; diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 0a0da2fea1..50c208cc76 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -85,7 +85,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, newcoin::TMTransaction tx; Serializer s; - trans->getSTransaction()->getTransaction(s, false); + trans->getSTransaction()->add(s); tx.set_rawtransaction(&s.getData().front(), s.getLength()); tx.set_status(newcoin::tsCURRENT); tx.set_receivetimestamp(getNetworkTimeNC()); diff --git a/src/Peer.cpp b/src/Peer.cpp index 7610b6416b..a2132d1ee0 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -580,7 +580,7 @@ void Peer::recvTransaction(newcoin::TMTransaction& packet) std::string rawTx = packet.rawtransaction(); Serializer s(std::vector(rawTx.begin(), rawTx.end())); SerializerIterator sit(s); - SerializedTransaction::pointer stx = boost::make_shared(boost::ref(sit), -1); + SerializedTransaction::pointer stx = boost::make_shared(boost::ref(sit)); tx = boost::make_shared(stx, true); if (tx->getStatus() == INVALID) throw(0); @@ -708,6 +708,11 @@ void Peer::recvStatus(newcoin::TMStatusChange& packet) mClosedLedgerTime = ptFromSeconds(packet.networktime()); Log(lsTRACE) << "peer LCL is " << mClosedLedgerHash.GetHex(); } + else if(packet.has_previousledgerhash() && packet.previousledgerhash().size() == (256 / 8)) + { + memcpy(mClosedLedgerHash.begin(), packet.previousledgerhash().data(), 256 / 8); + mClosedLedgerTime = ptFromSeconds(packet.networktime()); + } } void Peer::recvGetLedger(newcoin::TMGetLedger& packet) diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index 05d2add063..e9c0564c5f 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -186,9 +186,12 @@ std::string STObject::getFullText() const for (boost::ptr_vector::const_iterator it = mData.begin(), end = mData.end(); it != end; ++it) { - if (!first) ret += ", "; - else first = false; - ret += it->getFullText(); + if (it->getSType() != STI_NOTPRESENT) + { + if (!first) ret += ", "; + else first = false; + ret += it->getFullText(); + } } ret += "}"; @@ -234,8 +237,8 @@ bool STObject::isEquivalent(const SerializedType& t) const boost::ptr_vector::const_iterator it2 = v->mData.begin(), end2 = v->mData.end(); while ((it1 != end1) && (it2 != end2)) { - if (it1->getSType() != it2->getSType()) return false; - if (!it1->isEquivalent(*it2)) return false; + if ((it1->getSType() != it2->getSType()) || !it1->isEquivalent(*it2)) + return false; ++it1; ++it2; } diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index e4a4fefa44..9f66a25ebe 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -8,29 +8,26 @@ SerializedTransaction::SerializedTransaction(TransactionType type) : mType(type) mFormat = getTxnFormat(type); if (mFormat == NULL) throw std::runtime_error("invalid transaction type"); - mMiddleTxn.giveObject(new STUInt32("Magic", TransactionMagic)); mMiddleTxn.giveObject(new STVariableLength("SigningPubKey")); mMiddleTxn.giveObject(new STAccount("SourceAccount")); mMiddleTxn.giveObject(new STUInt32("Sequence")); mMiddleTxn.giveObject(new STUInt16("Type", static_cast(type))); - mMiddleTxn.giveObject(new STAmount("Fee")); + mMiddleTxn.giveObject(new STUInt64("Fee")); - mInnerTxn=STObject(mFormat->elements, "InnerTransaction"); + mInnerTxn = STObject(mFormat->elements, "InnerTransaction"); } -SerializedTransaction::SerializedTransaction(SerializerIterator& sit, int length) +SerializedTransaction::SerializedTransaction(SerializerIterator& sit) { - if (length == -1) length = sit.getBytesLeft(); - else if (length == 0) length = sit.get32(); + int length = sit.getBytesLeft(); if ((length < TransactionMinLen) || (length > TransactionMaxLen)) + { + Log(lsERROR) << "Transaction has invalid length: " << length; throw std::runtime_error("Transaction length invalid"); + } mSignature.setValue(sit.getVL()); - if (sit.get32() != TransactionMagic) - throw std::runtime_error("Transaction has invalid magic"); - - mMiddleTxn.giveObject(new STUInt32("Magic", TransactionMagic)); mMiddleTxn.giveObject(new STVariableLength("SigningPubKey", sit.getVL())); STAccount sa("SourceAccount", sit.getVL()); @@ -47,7 +44,7 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit, int length Log(lsERROR) << "Transaction has invalid type"; throw std::runtime_error("Transaction has invalid type"); } - mMiddleTxn.giveObject(new STAmount("Fee", sit.get64())); + mMiddleTxn.giveObject(new STUInt64("Fee", sit.get64())); mInnerTxn = STObject(mFormat->elements, sit, "InnerTransaction"); } @@ -94,14 +91,11 @@ std::vector SerializedTransaction::getAffectedAccounts() const return accounts; } -int SerializedTransaction::getTransaction(Serializer& s, bool include_length) const +void SerializedTransaction::add(Serializer& s) const { - int l = getLength(); - if (include_length) s.add32(l); mSignature.add(s); mMiddleTxn.add(s); mInnerTxn.add(s); - return l; } bool SerializedTransaction::isEquivalent(const SerializedType& t) const @@ -117,6 +111,7 @@ bool SerializedTransaction::isEquivalent(const SerializedType& t) const uint256 SerializedTransaction::getSigningHash() const { Serializer s; + s.add32(TransactionMagic); mMiddleTxn.add(s); mInnerTxn.add(s); return s.getSHA512Half(); @@ -156,32 +151,18 @@ void SerializedTransaction::setSignature(const std::vector& sig) mSignature.setValue(sig); } -uint32 SerializedTransaction::getVersion() const +uint64 SerializedTransaction::getTransactionFee() const { - const STUInt32* v = dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionIVersion)); + const STUInt64* v = dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionIFee)); if (!v) throw std::runtime_error("corrupt transaction"); return v->getValue(); } -void SerializedTransaction::setVersion(uint32 ver) +void SerializedTransaction::setTransactionFee(uint64 fee) { - STUInt32* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionIVersion)); + STUInt64* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionIFee)); if (!v) throw std::runtime_error("corrupt transaction"); - v->setValue(ver); -} - -STAmount SerializedTransaction::getTransactionFee() const -{ - const STAmount* v = dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionIFee)); - if (!v) throw std::runtime_error("corrupt transaction"); - return v->getNValue(); -} - -void SerializedTransaction::setTransactionFee(STAmount saFee) -{ - STAmount* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionIFee)); - if (!v) throw std::runtime_error("corrupt transaction"); - v->setNValue(saFee); + v->setValue(fee); } uint32 SerializedTransaction::getSequence() const diff --git a/src/SerializedTransaction.h b/src/SerializedTransaction.h index ed6300815b..3e84ab3bf4 100644 --- a/src/SerializedTransaction.h +++ b/src/SerializedTransaction.h @@ -26,7 +26,7 @@ protected: SerializedTransaction* duplicate() const { return new SerializedTransaction(*this); } public: - SerializedTransaction(SerializerIterator& sit, int length); // -1=all remaining, 0=get from sit + SerializedTransaction(SerializerIterator& sit); SerializedTransaction(TransactionType type); // STObject functions @@ -34,7 +34,7 @@ public: SerializedTypeID getSType() const { return STI_TRANSACTION; } std::string getFullText() const; std::string getText() const; - void add(Serializer& s) const { getTransaction(s, true); } + void add(Serializer& s) const; virtual bool isEquivalent(const SerializedType& t) const; // outer transaction functions / signature functions @@ -43,13 +43,9 @@ public: void setSignature(const std::vector& s); uint256 getSigningHash() const; - // middle transaction functions - uint32 getVersion() const; - void setVersion(uint32); - TransactionType getTxnType() const { return mType; } - STAmount getTransactionFee() const; - void setTransactionFee(STAmount saFee); + uint64 getTransactionFee() const; + void setTransactionFee(uint64 fee); const NewcoinAddress& getSourceAccount() const { return mSourceAccount; } std::vector getSigningPubKey() const; @@ -111,8 +107,6 @@ public: std::vector getAffectedAccounts() const; - // whole transaction functions - int getTransaction(Serializer& s, bool include_length) const; uint256 getTransactionID() const; virtual Json::Value getJson(int options) const; diff --git a/src/SerializedTypes.cpp b/src/SerializedTypes.cpp index 276b13464d..6b7d9e52b2 100644 --- a/src/SerializedTypes.cpp +++ b/src/SerializedTypes.cpp @@ -147,7 +147,7 @@ std::string STVariableLength::getText() const STVariableLength* STVariableLength::construct(SerializerIterator& u, const char *name) { - return new STVariableLength(u.getVL()); + return new STVariableLength(name, u.getVL()); } int STVariableLength::getLength() const diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index 70e3660866..f9c68a2e15 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -68,7 +68,8 @@ public: virtual void add(Serializer& s) const { return; } - virtual bool isEquivalent(const SerializedType& t) const { return true; } + virtual bool isEquivalent(const SerializedType& t) const + { assert(getSType() == STI_NOTPRESENT); return t.getSType() == STI_NOTPRESENT; } bool operator==(const SerializedType& t) const { return (getSType() == t.getSType()) && isEquivalent(t); } diff --git a/src/Transaction.cpp b/src/Transaction.cpp index aa9427bbf6..f102710cfb 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -37,7 +37,7 @@ Transaction::pointer Transaction::sharedTransaction(const std::vector(boost::ref(sit), -1); + SerializedTransaction::pointer st = boost::make_shared(boost::ref(sit)); return boost::make_shared(st, bValidate); } @@ -396,7 +396,7 @@ Transaction::pointer Transaction::transactionFromSQL(const std::string& sql) Serializer s(rawTxn); SerializerIterator it(s); - SerializedTransaction::pointer txn = boost::make_shared(boost::ref(it), -1); + SerializedTransaction::pointer txn = boost::make_shared(boost::ref(it)); Transaction::pointer tr = boost::make_shared(txn, true); TransStatus st(INVALID); diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 05812b29f1..9997b47103 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -1,13 +1,19 @@ + #include "TransactionEngine.h" +#include + +#include "../json/writer.h" + #include "Config.h" #include "TransactionFormats.h" #include "utils.h" - -#include +#include "Log.h" typedef SerializedLedgerEntry SLE; + + #define DIR_NODE_MAX 32 // We return the uNodeDir so that on delete we can quickly know where the element is mentioned in the directory. @@ -230,6 +236,24 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran { std::cerr << "applyTransaction>" << std::endl; +#ifdef DEBUG + if (1) + { + Serializer ser; + txn.add(ser); + SerializerIterator sit(ser); + SerializedTransaction s2(sit); + if (!s2.isEquivalent(txn)) + { + std::cerr << "Transaction serdes mismatch" << std::endl; + Json::StyledStreamWriter ssw; + ssw.write(Log(lsINFO).ref(), txn.getJson(0)); + ssw.write(Log(lsFATAL).ref(), s2.getJson(0)); + assert(false); + } + } +#endif + TransactionEngineResult result = terSUCCESS; uint256 txID = txn.getTransactionID(); diff --git a/src/TransactionFormats.h b/src/TransactionFormats.h index 95a4c01dca..f6fc893134 100644 --- a/src/TransactionFormats.h +++ b/src/TransactionFormats.h @@ -23,12 +23,11 @@ struct TransactionFormat const int32 TransactionMagic = 0x54584E00; // 'TXN' -const int TransactionIVersion = 0; -const int TransactionISigningPubKey = 1; -const int TransactionISourceID = 2; -const int TransactionISequence = 3; -const int TransactionIType = 4; -const int TransactionIFee = 5; +const int TransactionISigningPubKey = 0; +const int TransactionISourceID = 1; +const int TransactionISequence = 2; +const int TransactionIType = 3; +const int TransactionIFee = 4; const int TransactionMinLen = 32; const int TransactionMaxLen = 1048576;