diff --git a/json/json_value.cpp b/json/json_value.cpp index 41d98787f6..b1b1a5221f 100644 --- a/json/json_value.cpp +++ b/json/json_value.cpp @@ -734,6 +734,7 @@ Value::asInt() const case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: + return boost::lexical_cast(value_.string_); case arrayValue: case objectValue: JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" ); @@ -761,6 +762,7 @@ Value::asUInt() const case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: + return boost::lexical_cast(value_.string_); case arrayValue: case objectValue: JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" ); diff --git a/src/Peer.cpp b/src/Peer.cpp index 506aad80aa..e446080493 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -875,7 +875,7 @@ void Peer::recvGetObjectByHash(ripple::TMGetObjectByHash& packet) reply.set_ledgerhash(packet.ledgerhash()); // This is a very minimal implementation - for (unsigned i = 0; i < packet.objects_size(); ++i) + for (int i = 0; i < packet.objects_size(); ++i) { uint256 hash; const ripple::TMIndexedObject& obj = packet.objects(i); diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 3b7f6c84f1..7ec8eb09e8 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -1394,7 +1394,7 @@ Json::Value RPCServer::doProfile(const Json::Value ¶ms) boost::posix_time::ptime ptStart(boost::posix_time::microsec_clock::local_time()); - for(int n=0; ngetTxnDB()->getDB(); + ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); + + SQL_FOREACH(db, sql) + { + Transaction::pointer trans=Transaction::transactionFromSQL(db, false); + if(trans) obj.append(trans->getJson(0)); + } + } + + return obj; + } + + return RPCError(rpcSRC_ACT_MALFORMED); +} + Json::Value RPCServer::doTx(const Json::Value& params) { // tx @@ -2736,6 +2764,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params { "server_info", &RPCServer::doServerInfo, 0, 0, true }, { "stop", &RPCServer::doStop, 0, 0, true }, { "tx", &RPCServer::doTx, 1, 1, true }, + { "tx_history", &RPCServer::doTxHistory, 1, 1, false, }, { "unl_add", &RPCServer::doUnlAdd, 1, 2, true }, { "unl_delete", &RPCServer::doUnlDelete, 1, 1, true }, diff --git a/src/RPCServer.h b/src/RPCServer.h index af8c6d754c..0513091def 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -159,6 +159,7 @@ private: Json::Value doStop(const Json::Value& params); Json::Value doTransitSet(const Json::Value& params); Json::Value doTx(const Json::Value& params); + Json::Value doTxHistory(const Json::Value& params); Json::Value doUnlAdd(const Json::Value& params); Json::Value doUnlDelete(const Json::Value& params); diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 6ef87abaf7..8eea1dd76d 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -593,6 +593,47 @@ bool Transaction::save() db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";"); } +Transaction::pointer Transaction::transactionFromSQL(Database* db, bool bValidate) +{ + Serializer rawTxn; + std::string status; + uint32 inLedger; + + int txSize = 2048; + rawTxn.resize(txSize); + + db->getStr("Status", status); + inLedger = db->getInt("LedgerSeq"); + txSize = db->getBinary("RawTxn", &*rawTxn.begin(), rawTxn.getLength()); + if (txSize > rawTxn.getLength()) + { + rawTxn.resize(txSize); + db->getBinary("RawTxn", &*rawTxn.begin(), rawTxn.getLength()); + } + + rawTxn.resize(txSize); + + SerializerIterator it(rawTxn); + SerializedTransaction::pointer txn = boost::make_shared(boost::ref(it)); + Transaction::pointer tr = boost::make_shared(txn, bValidate); + + TransStatus st(INVALID); + switch (status[0]) + { + case TXN_SQL_NEW: st = NEW; break; + case TXN_SQL_CONFLICT: st = CONFLICTED; break; + case TXN_SQL_HELD: st = HELD; break; + case TXN_SQL_VALIDATED: st = COMMITTED; break; + case TXN_SQL_INCLUDED: st = INCLUDED; break; + case TXN_SQL_UNKNOWN: break; + default: assert(false); + } + tr->setStatus(st); + tr->setLedger(inLedger); + return tr; +} + +// DAVID: would you rather duplicate this code or keep the lock longer? Transaction::pointer Transaction::transactionFromSQL(const std::string& sql) { Serializer rawTxn; diff --git a/src/Transaction.h b/src/Transaction.h index 7cd94aedd6..c78a617bbc 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -17,6 +17,8 @@ #include "SerializedTransaction.h" #include "TransactionErr.h" +class Database; + enum TransStatus { NEW = 0, // just received / generated @@ -130,6 +132,7 @@ public: Transaction(const SerializedTransaction::pointer& st, bool bValidate); static Transaction::pointer sharedTransaction(const std::vector&vucTransaction, bool bValidate); + static Transaction::pointer transactionFromSQL(Database* db, bool bValidate); Transaction( TransactionType ttKind,