mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -92,6 +92,7 @@ public:
|
||||
|
||||
bool isGeneric() const { return fieldCode == 0; }
|
||||
bool isInvalid() const { return fieldCode == -1; }
|
||||
bool isUseful() const { return fieldCode > 0; }
|
||||
bool isKnown() const { return fieldType != STI_UNKNOWN; }
|
||||
bool isBinary() const { return fieldValue < 256; }
|
||||
bool isDiscardable() const { return fieldValue > 256; }
|
||||
|
||||
@@ -23,22 +23,23 @@ enum JobType
|
||||
jtINVALID = -1,
|
||||
jtVALIDATION_ut = 0, // A validation from an untrusted source
|
||||
jtCLIENTOP_ut = 1, // A client operation from a non-local/untrusted source
|
||||
jtTRANSACTION = 2, // A transaction received from the network
|
||||
jtPROPOSAL_ut = 3, // A proposal from an untrusted source
|
||||
jtCLIENTOP_t = 4, // A client operation from a trusted source
|
||||
jtVALIDATION_t = 5, // A validation from a trusted source
|
||||
jtTRANSACTION_l = 6, // A local transaction
|
||||
jtPROPOSAL_t = 7, // A proposal from a trusted source
|
||||
jtADMIN = 8, // An administrative operation
|
||||
jtDEATH = 9, // job of death, used internally
|
||||
jtPROOFWORK = 2, // A proof of work demand from another server
|
||||
jtTRANSACTION = 3, // A transaction received from the network
|
||||
jtPROPOSAL_ut = 4, // A proposal from an untrusted source
|
||||
jtCLIENTOP_t = 5, // A client operation from a trusted source
|
||||
jtVALIDATION_t = 6, // A validation from a trusted source
|
||||
jtTRANSACTION_l = 7, // A local transaction
|
||||
jtPROPOSAL_t = 8, // A proposal from a trusted source
|
||||
jtADMIN = 9, // An administrative operation
|
||||
jtDEATH = 10, // job of death, used internally
|
||||
|
||||
// special types not dispatched by the job pool
|
||||
jtCLIENT = 10,
|
||||
jtPEER = 11,
|
||||
jtDISK = 12,
|
||||
jtRPC = 13,
|
||||
jtACCEPTLEDGER = 14,
|
||||
jtPUBLEDGER = 15,
|
||||
jtCLIENT = 16,
|
||||
jtPEER = 17,
|
||||
jtDISK = 18,
|
||||
jtRPC = 19,
|
||||
jtACCEPTLEDGER = 20,
|
||||
jtPUBLEDGER = 21,
|
||||
};
|
||||
#define NUM_JOB_TYPES 24
|
||||
|
||||
|
||||
@@ -328,8 +328,8 @@ bool LedgerEntrySet::threadTx(SLE::ref threadTo, Ledger::ref ledger,
|
||||
if (!threadTo->thread(mSet.getTxID(), mSet.getLgrSeq(), prevTxID, prevLgrID))
|
||||
return false;
|
||||
|
||||
if (prevTxID.isZero() || TransactionMetaSet::thread(mSet.getAffectedNode(threadTo->getIndex(), sfModifiedNode),
|
||||
prevTxID, prevLgrID))
|
||||
if (prevTxID.isZero() ||
|
||||
TransactionMetaSet::thread(mSet.getAffectedNode(threadTo, sfModifiedNode), prevTxID, prevLgrID))
|
||||
return true;
|
||||
|
||||
assert(false);
|
||||
@@ -359,7 +359,7 @@ bool LedgerEntrySet::threadOwners(SLE::ref node, Ledger::ref ledger,
|
||||
return false;
|
||||
}
|
||||
|
||||
void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
void LedgerEntrySet::calcRawMeta(Serializer& s, TER result, uint32 index)
|
||||
{ // calculate the raw meta data and return it. This must be called before the set is committed
|
||||
|
||||
// Entries modified only as a result of building the transaction metadata
|
||||
@@ -402,14 +402,17 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
|
||||
SLE::pointer origNode = mLedger->getSLE(it.first);
|
||||
SLE::pointer curNode = it.second.mEntry;
|
||||
|
||||
if ((type == &sfModifiedNode) && (*curNode == *origNode))
|
||||
continue;
|
||||
|
||||
uint16 nodeType = curNode ? curNode->getFieldU16(sfLedgerEntryType) : origNode->getFieldU16(sfLedgerEntryType);
|
||||
|
||||
mSet.setAffectedNode(it.first, *type, nodeType);
|
||||
|
||||
if (type == &sfDeletedNode)
|
||||
{
|
||||
assert(origNode);
|
||||
assert(curNode);
|
||||
assert(origNode && curNode);
|
||||
threadOwners(origNode, mLedger, newMod); // thread transaction to owners
|
||||
|
||||
STObject prevs(sfPreviousFields);
|
||||
@@ -432,6 +435,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
}
|
||||
else if (type == &sfModifiedNode)
|
||||
{
|
||||
assert(curNode && origNode);
|
||||
if (curNode->isThreadedType()) // thread transaction to node it modified
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
|
||||
@@ -455,7 +459,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
}
|
||||
else if (type == &sfCreatedNode) // if created, thread to owner(s)
|
||||
{
|
||||
assert(!origNode);
|
||||
assert(curNode && !origNode);
|
||||
threadOwners(curNode, mLedger, newMod);
|
||||
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
@@ -470,6 +474,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
if (!news.empty())
|
||||
mSet.getAffectedNode(it.first).addObject(news);
|
||||
}
|
||||
else assert(false);
|
||||
}
|
||||
|
||||
// add any new modified nodes to the modification set
|
||||
@@ -477,7 +482,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
BOOST_FOREACH(u256_sle_pair& it, newMod)
|
||||
entryModify(it.second);
|
||||
|
||||
mSet.addRaw(s, result);
|
||||
mSet.addRaw(s, result, index);
|
||||
cLog(lsTRACE) << "Metadata:" << mSet.getJson(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
STAmount accountFunds(const uint160& uAccountID, const STAmount& saDefault);
|
||||
|
||||
Json::Value getJson(int) const;
|
||||
void calcRawMeta(Serializer&, TER result);
|
||||
void calcRawMeta(Serializer&, TER result, uint32 index);
|
||||
|
||||
// iterator functions
|
||||
typedef std::map<uint256, LedgerEntrySetEntry>::iterator iterator;
|
||||
|
||||
@@ -581,6 +581,17 @@ void Peer::processReadBuffer()
|
||||
}
|
||||
break;
|
||||
|
||||
case ripple::mtPROOFOFWORK:
|
||||
{
|
||||
ripple::TMProofWork msg;
|
||||
if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
|
||||
recvProofWork(msg);
|
||||
else
|
||||
cLog(lsWARNING) << "parse error: " << type;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
cLog(lsWARNING) << "Unknown Msg: " << type;
|
||||
cLog(lsWARNING) << strHex(&mReadbuf[0], mReadbuf.size());
|
||||
@@ -1124,6 +1135,23 @@ void Peer::recvAccount(ripple::TMAccount& packet)
|
||||
{
|
||||
}
|
||||
|
||||
void Peer::recvProofWork(ripple::TMProofWork& packet)
|
||||
{
|
||||
if (packet.has_result())
|
||||
{ // this is a reply to a proof of work we sent
|
||||
// WRITEME
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.has_target() && packet.has_challenge() && packet.has_iterations())
|
||||
{ // this is a challenge
|
||||
// WRITEME
|
||||
return;
|
||||
}
|
||||
|
||||
cLog(lsINFO) << "Received in valid proof of work object from peer";
|
||||
}
|
||||
|
||||
void Peer::recvStatus(ripple::TMStatusChange& packet)
|
||||
{
|
||||
cLog(lsTRACE) << "Received status change from peer " << getIP();
|
||||
|
||||
@@ -126,6 +126,7 @@ protected:
|
||||
void recvStatus(ripple::TMStatusChange& packet);
|
||||
void recvPropose(const boost::shared_ptr<ripple::TMProposeSet>& packet);
|
||||
void recvHaveTxSet(ripple::TMHaveTransactionSet& packet);
|
||||
void recvProofWork(ripple::TMProofWork& packet);
|
||||
|
||||
void getSessionCookie(std::string& strDst);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -101,20 +101,32 @@ public:
|
||||
STAmount saOutPass; // <-- Amount actually sent.
|
||||
bool bConsumed; // If true, use consumes full liquidity. False, may or may not.
|
||||
|
||||
PathState* setIndex(const int iIndex) {
|
||||
mIndex = iIndex;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
PathState(
|
||||
const int iIndex,
|
||||
const STAmount& saSend,
|
||||
const STAmount& saSendMax,
|
||||
const Ledger::ref lrLedger = Ledger::pointer()
|
||||
) : mLedger(lrLedger), saInReq(saSendMax), saOutReq(saSend) { ; }
|
||||
|
||||
void setExpanded(
|
||||
const LedgerEntrySet& lesSource,
|
||||
const STPath& spSourcePath,
|
||||
const uint160& uReceiverID,
|
||||
const uint160& uSenderID,
|
||||
const STAmount& saSend,
|
||||
const STAmount& saSendMax
|
||||
const uint160& uSenderID
|
||||
);
|
||||
|
||||
void setCanonical(
|
||||
PathState::ref pspExpanded
|
||||
);
|
||||
|
||||
Json::Value getJson() const;
|
||||
|
||||
static PathState::pointer createPathState(
|
||||
const int iIndex,
|
||||
static PathState::pointer createExpanded(
|
||||
const LedgerEntrySet& lesSource,
|
||||
const STPath& spSourcePath,
|
||||
const uint160& uReceiverID,
|
||||
@@ -123,7 +135,22 @@ public:
|
||||
const STAmount& saSendMax
|
||||
)
|
||||
{
|
||||
return boost::make_shared<PathState>(iIndex, lesSource, spSourcePath, uReceiverID, uSenderID, saSend, saSendMax);
|
||||
PathState::pointer pspNew = boost::make_shared<PathState>(saSend, saSendMax, lesSource.getLedgerRef());
|
||||
|
||||
pspNew->setExpanded(lesSource, spSourcePath, uReceiverID, uSenderID);
|
||||
|
||||
return pspNew;
|
||||
}
|
||||
|
||||
static PathState::pointer createCanonical(
|
||||
PathState::ref pspExpanded
|
||||
)
|
||||
{
|
||||
PathState::pointer pspNew = boost::make_shared<PathState>(pspExpanded->saOutAct, pspExpanded->saInAct);
|
||||
|
||||
pspNew->setCanonical(pspExpanded);
|
||||
|
||||
return pspNew;
|
||||
}
|
||||
|
||||
static bool lessPriority(PathState::ref lhs, PathState::ref rhs);
|
||||
@@ -141,7 +168,6 @@ public:
|
||||
// If the transaction fails to meet some constraint, still need to delete unfunded offers.
|
||||
boost::unordered_set<uint256> musUnfundedFound; // Offers that were found unfunded.
|
||||
|
||||
PathState::pointer pathCreate(const STPath& spPath);
|
||||
void pathNext(PathState::ref pspCur, const int iPaths, const LedgerEntrySet& lesCheckpoint, LedgerEntrySet& lesCurrent);
|
||||
TER calcNode(const unsigned int uNode, PathState::ref pspCur, const bool bMultiQuality);
|
||||
TER calcNodeRev(const unsigned int uNode, PathState::ref pspCur, const bool bMultiQuality);
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
FIELD(OfferSequence, UINT32, 25)
|
||||
FIELD(FirstLedgerSequence, UINT32, 26)
|
||||
FIELD(LastLedgerSequence, UINT32, 27)
|
||||
FIELD(TransactionIndex, UINT32, 28)
|
||||
|
||||
// 64-bit integers
|
||||
FIELD(IndexNext, UINT64, 1)
|
||||
|
||||
@@ -934,7 +934,7 @@ STArray* STArray::construct(SerializerIterator& sit, SField::ref field)
|
||||
throw std::runtime_error("Unknown field");
|
||||
}
|
||||
|
||||
value.push_back(STObject(fn));
|
||||
value.push_back(new STObject(fn));
|
||||
value.rbegin()->set(sit, 1);
|
||||
}
|
||||
|
||||
@@ -1234,6 +1234,9 @@ BOOST_AUTO_TEST_SUITE(SerializedObject)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( FieldManipulation_test )
|
||||
{
|
||||
if (sfGeneric.isUseful())
|
||||
BOOST_FAIL("sfGeneric must not be useful");
|
||||
|
||||
SField sfTestVL(STI_VL, 255, "TestVL");
|
||||
SField sfTestH256(STI_HASH256, 255, "TestH256");
|
||||
SField sfTestU32(STI_UINT32, 255, "TestU32");
|
||||
|
||||
@@ -46,6 +46,8 @@ public:
|
||||
STObject(const std::vector<SOElement::ptr>& type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
|
||||
{ set(sit); setType(type); }
|
||||
|
||||
std::auto_ptr<STObject> oClone() const { return std::auto_ptr<STObject>(new STObject(*this)); }
|
||||
|
||||
static std::auto_ptr<STObject> parseJson(const Json::Value& value, SField::ref name = sfGeneric, int depth = 0);
|
||||
|
||||
virtual ~STObject() { ; }
|
||||
@@ -81,7 +83,7 @@ public:
|
||||
SerializedType& back() { return mData.back(); }
|
||||
const SerializedType& back() const { return mData.back(); }
|
||||
|
||||
int getCount() const { return mData.size(); }
|
||||
int getCount() const { return mData.size(); }
|
||||
|
||||
bool setFlag(uint32);
|
||||
bool clearFlag(uint32);
|
||||
@@ -167,6 +169,10 @@ public:
|
||||
bool operator!=(const STObject& o) const { return ! (*this == o); }
|
||||
};
|
||||
|
||||
// allow ptr_* collections of STObject's
|
||||
inline STObject* new_clone(const STObject& s) { return s.oClone().release(); }
|
||||
inline void delete_clone(const STObject* s) { boost::checked_delete(s); }
|
||||
|
||||
inline STObject::iterator range_begin(STObject& x) { return x.begin(); }
|
||||
inline STObject::iterator range_end(STObject &x) { return x.end(); }
|
||||
namespace boost
|
||||
@@ -180,12 +186,12 @@ namespace boost
|
||||
class STArray : public SerializedType, private IS_INSTANCE(SerializedArray)
|
||||
{
|
||||
public:
|
||||
typedef std::vector<STObject> vector;
|
||||
typedef std::vector<STObject>::iterator iterator;
|
||||
typedef std::vector<STObject>::const_iterator const_iterator;
|
||||
typedef std::vector<STObject>::reverse_iterator reverse_iterator;
|
||||
typedef std::vector<STObject>::const_reverse_iterator const_reverse_iterator;
|
||||
typedef std::vector<STObject>::size_type size_type;
|
||||
typedef boost::ptr_vector<STObject> vector;
|
||||
typedef boost::ptr_vector<STObject>::iterator iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_iterator const_iterator;
|
||||
typedef boost::ptr_vector<STObject>::reverse_iterator reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_reverse_iterator const_reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::size_type size_type;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -210,7 +216,7 @@ public:
|
||||
vector& getValue() { return value; }
|
||||
|
||||
// vector-like functions
|
||||
void push_back(const STObject& object) { value.push_back(object); }
|
||||
void push_back(const STObject& object) { value.push_back(object.oClone()); }
|
||||
STObject& operator[](int j) { return value[j]; }
|
||||
const STObject& operator[](int j) const { return value[j]; }
|
||||
iterator begin() { return value.begin(); }
|
||||
|
||||
@@ -19,6 +19,15 @@ DECLARE_INSTANCE(SerializedValue);
|
||||
STAmount saZero(CURRENCY_ONE, ACCOUNT_ONE, 0);
|
||||
STAmount saOne(CURRENCY_ONE, ACCOUNT_ONE, 1);
|
||||
|
||||
SerializedType& SerializedType::operator=(const SerializedType& t)
|
||||
{
|
||||
if ((t.fName != fName) && fName->isUseful() && t.fName->isUseful())
|
||||
Log(lsWARNING) << "Caution: " << t.fName->getName() << " not replacing " << fName->getName();
|
||||
if (!fName->isUseful()) fName = t.fName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void STPathSet::printDebug() {
|
||||
for (int i = 0; i < value.size(); i++) {
|
||||
std::cout << i << ": ";
|
||||
|
||||
@@ -10,6 +10,15 @@
|
||||
#include "Serializer.h"
|
||||
#include "FieldNames.h"
|
||||
#include "InstanceCounter.h"
|
||||
#include "Log.h"
|
||||
|
||||
// CAUTION: Do not create a vector (or similar container) of any object derived from
|
||||
// SerializedType. Use Boost ptr_* containers. The copy assignment operator of
|
||||
// SerializedType has semantics that will cause contained types to change their names
|
||||
// when an object is deleted because copy assignment is used to "slide down" the
|
||||
// remaining types and this will not copy the field name. Changing the copy assignment
|
||||
// operator to copy the field name breaks the use of copy assignment just to copy values,
|
||||
// which is used in the transaction engine code.
|
||||
|
||||
enum PathFlags
|
||||
{
|
||||
@@ -68,8 +77,8 @@ public:
|
||||
|
||||
void addFieldID(Serializer& s) const { s.addFieldID(fName->fieldType, fName->fieldValue); }
|
||||
|
||||
SerializedType& operator=(const SerializedType& t)
|
||||
{ if (!fName->fieldCode) fName = t.fName; return *this; }
|
||||
SerializedType& operator=(const SerializedType& t);
|
||||
|
||||
bool operator==(const SerializedType& t) const
|
||||
{ return (getSType() == t.getSType()) && isEquivalent(t); }
|
||||
bool operator!=(const SerializedType& t) const
|
||||
|
||||
@@ -119,7 +119,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
|
||||
{
|
||||
// Transaction succeeded fully or (retries are not allowed and the transaction succeeded partially).
|
||||
Serializer m;
|
||||
mNodes.calcRawMeta(m, terResult);
|
||||
mNodes.calcRawMeta(m, terResult, mTxnSeq++);
|
||||
|
||||
txnWrite();
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ private:
|
||||
|
||||
protected:
|
||||
Ledger::pointer mLedger;
|
||||
int mTxnSeq;
|
||||
|
||||
uint160 mTxnAccountID;
|
||||
SLE::pointer mTxnAccount;
|
||||
@@ -65,8 +66,8 @@ protected:
|
||||
public:
|
||||
typedef boost::shared_ptr<TransactionEngine> pointer;
|
||||
|
||||
TransactionEngine() { ; }
|
||||
TransactionEngine(Ledger::ref ledger) : mLedger(ledger) { assert(mLedger); }
|
||||
TransactionEngine() : mTxnSeq(0) { ; }
|
||||
TransactionEngine(Ledger::ref ledger) : mLedger(ledger), mTxnSeq(0) { assert(mLedger); }
|
||||
|
||||
LedgerEntrySet& getNodes() { return mNodes; }
|
||||
Ledger::pointer getLedger() { return mLedger; }
|
||||
|
||||
@@ -20,6 +20,7 @@ TransactionMetaSet::TransactionMetaSet(const uint256& txid, uint32 ledger, const
|
||||
throw std::runtime_error("bad metadata");
|
||||
|
||||
mResult = obj->getFieldU8(sfTransactionResult);
|
||||
mIndex = obj->getFieldU32(sfTransactionIndex);
|
||||
mNodes = * dynamic_cast<STArray*>(&obj->getField(sfAffectedNodes));
|
||||
}
|
||||
|
||||
@@ -79,20 +80,21 @@ std::vector<RippleAddress> TransactionMetaSet::getAffectedAccounts()
|
||||
}
|
||||
*/
|
||||
|
||||
STObject& TransactionMetaSet::getAffectedNode(const uint256& node, SField::ref type)
|
||||
STObject& TransactionMetaSet::getAffectedNode(SLE::ref node, SField::ref type)
|
||||
{
|
||||
assert(&type);
|
||||
uint256 index = node->getIndex();
|
||||
BOOST_FOREACH(STObject& it, mNodes)
|
||||
{
|
||||
if (it.getFieldH256(sfLedgerIndex) == node)
|
||||
if (it.getFieldH256(sfLedgerIndex) == index)
|
||||
return it;
|
||||
}
|
||||
|
||||
mNodes.push_back(STObject(sfModifiedNode));
|
||||
mNodes.push_back(STObject(type));
|
||||
STObject& obj = mNodes.back();
|
||||
|
||||
assert(obj.getFName() == type);
|
||||
obj.setFieldH256(sfLedgerIndex, node);
|
||||
obj.setFieldH256(sfLedgerIndex, index);
|
||||
obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
|
||||
|
||||
return obj;
|
||||
}
|
||||
@@ -153,13 +155,15 @@ STObject TransactionMetaSet::getAsObject() const
|
||||
STObject metaData(sfTransactionMetaData);
|
||||
assert(mResult != 255);
|
||||
metaData.setFieldU8(sfTransactionResult, mResult);
|
||||
metaData.setFieldU32(sfTransactionIndex, mIndex);
|
||||
metaData.addObject(mNodes);
|
||||
return metaData;
|
||||
}
|
||||
|
||||
void TransactionMetaSet::addRaw(Serializer& s, TER result)
|
||||
void TransactionMetaSet::addRaw(Serializer& s, TER result, uint32 index)
|
||||
{
|
||||
mResult = static_cast<int>(result);
|
||||
mIndex = index;
|
||||
assert((mResult == 0) || ((mResult > 100) && (mResult <= 255)));
|
||||
|
||||
mNodes.sort(compare);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Serializer.h"
|
||||
#include "SerializedTypes.h"
|
||||
#include "SerializedObject.h"
|
||||
#include "SerializedLedger.h"
|
||||
#include "TransactionErr.h"
|
||||
|
||||
class TransactionMetaSet
|
||||
@@ -22,13 +23,15 @@ public:
|
||||
protected:
|
||||
uint256 mTransactionID;
|
||||
uint32 mLedger;
|
||||
uint32 mIndex;
|
||||
int mResult;
|
||||
|
||||
STArray mNodes;
|
||||
|
||||
public:
|
||||
TransactionMetaSet() : mLedger(0), mResult(255) { ; }
|
||||
TransactionMetaSet(const uint256& txID, uint32 ledger) : mTransactionID(txID), mLedger(ledger), mResult(255) { ; }
|
||||
TransactionMetaSet() : mLedger(0), mIndex(static_cast<uint32>(-1)), mResult(255) { ; }
|
||||
TransactionMetaSet(const uint256& txID, uint32 ledger, uint32 index) :
|
||||
mTransactionID(txID), mLedger(ledger), mIndex(static_cast<uint32>(-1)), mResult(255) { ; }
|
||||
TransactionMetaSet(const uint256& txID, uint32 ledger, const std::vector<unsigned char>&);
|
||||
|
||||
void init(const uint256& transactionID, uint32 ledger);
|
||||
@@ -39,17 +42,18 @@ public:
|
||||
uint32 getLgrSeq() { return mLedger; }
|
||||
int getResult() const { return mResult; }
|
||||
TER getResultTER() const { return static_cast<TER>(mResult); }
|
||||
uint32 getIndex() const { return mIndex; }
|
||||
|
||||
bool isNodeAffected(const uint256&) const;
|
||||
void setAffectedNode(const uint256&, SField::ref type, uint16 nodeType);
|
||||
STObject& getAffectedNode(const uint256&, SField::ref type);
|
||||
STObject& getAffectedNode(SLE::ref node, SField::ref type); // create if needed
|
||||
STObject& getAffectedNode(const uint256&);
|
||||
const STObject& peekAffectedNode(const uint256&) const;
|
||||
//std::vector<RippleAddress> getAffectedAccounts();
|
||||
|
||||
|
||||
Json::Value getJson(int p) const { return getAsObject().getJson(p); }
|
||||
void addRaw(Serializer&, TER);
|
||||
void addRaw(Serializer&, TER, uint32 index);
|
||||
|
||||
STObject getAsObject() const;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ enum MessageType {
|
||||
mtHELLO = 1;
|
||||
mtERROR_MSG = 2;
|
||||
mtPING = 3;
|
||||
mtPOW = 4;
|
||||
mtPROOFOFWORK = 4;
|
||||
|
||||
// network presence detection
|
||||
mtGET_CONTACTS = 10;
|
||||
@@ -33,13 +33,13 @@ enum MessageType {
|
||||
}
|
||||
|
||||
|
||||
// empty message (or just result) = request proof of work
|
||||
// token, iterations, target, challenge = give proof of work challenge
|
||||
// token, response = show proof of work
|
||||
// token, result = result of pow attempt
|
||||
// token, iterations, target, challenge = issue demand for proof of work
|
||||
// token, response = give solution to proof of work
|
||||
// token, result = report result of pow
|
||||
|
||||
message TMProofWork
|
||||
{
|
||||
optional string token = 1;
|
||||
required string token = 1;
|
||||
optional uint32 iterations = 2;
|
||||
optional bytes target = 3;
|
||||
optional bytes challenge = 4;
|
||||
|
||||
@@ -22,4 +22,4 @@ var Account = function (network, account) {
|
||||
|
||||
exports.Account = Account;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
106
src/js/amount.js
106
src/js/amount.js
@@ -344,6 +344,10 @@ Amount.from_json = function(j) {
|
||||
return (new Amount()).parse_json(j);
|
||||
};
|
||||
|
||||
Amount.from_human = function(j) {
|
||||
return (new Amount()).parse_human(j);
|
||||
};
|
||||
|
||||
Amount.is_valid = function (j) {
|
||||
return Amount.from_json(j).is_valid();
|
||||
};
|
||||
@@ -388,6 +392,18 @@ Amount.prototype.currency = function() {
|
||||
return this._currency;
|
||||
};
|
||||
|
||||
Amount.prototype.set_currency = function(c) {
|
||||
if ('string' === typeof c) {
|
||||
this._currency.parse_json(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.copyTo(this._currency);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Only checks the value. Not the currency and issuer.
|
||||
Amount.prototype.is_valid = function() {
|
||||
return !isNaN(this._value);
|
||||
@@ -462,8 +478,15 @@ Amount.prototype.to_human = function (opts)
|
||||
{
|
||||
opts = opts || {};
|
||||
|
||||
var int_part = this._value.divide(consts.bi_xns_unit).toString(10);
|
||||
var fraction_part = this._value.mod(consts.bi_xns_unit).toString(10);
|
||||
// Default options
|
||||
if ("undefined" === typeof opts.group_sep) opts.group_sep = true;
|
||||
opts.group_width = opts.group_width || 3;
|
||||
|
||||
var denominator = this._is_native ?
|
||||
consts.bi_xns_unit :
|
||||
consts.bi_10.clone().pow(-this._offset);
|
||||
var int_part = this._value.divide(denominator).toString(10);
|
||||
var fraction_part = this._value.mod(denominator).toString(10);
|
||||
|
||||
int_part = int_part.replace(/^0*/, '');
|
||||
fraction_part = fraction_part.replace(/0*$/, '');
|
||||
@@ -472,6 +495,13 @@ Amount.prototype.to_human = function (opts)
|
||||
fraction_part = fraction_part.slice(0, opts.precision);
|
||||
}
|
||||
|
||||
if (opts.group_sep) {
|
||||
if ("string" !== typeof opts.group_sep) {
|
||||
opts.group_sep = ',';
|
||||
}
|
||||
int_part = utils.chunkString(int_part, opts.group_width, true).join(opts.group_sep);
|
||||
}
|
||||
|
||||
var formatted = '';
|
||||
formatted += int_part.length ? int_part : '0';
|
||||
formatted += fraction_part.length ? '.'+fraction_part : '';
|
||||
@@ -534,6 +564,67 @@ Amount.prototype.to_text_full = function() {
|
||||
: this.to_text() + "/" + this._currency.to_json() + "/" + this._issuer.to_json();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tries to correctly interpret an amount as entered by a user.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* XRP 250 => 250000000/XRP
|
||||
* 25.2 XRP => 25200000/XRP
|
||||
* USD 100.40 => 100.4/USD/?
|
||||
* 100 => 100000000/XRP
|
||||
*/
|
||||
Amount.prototype.parse_human = function(j) {
|
||||
// Cast to string
|
||||
j = ""+j;
|
||||
|
||||
// Parse
|
||||
var m = j.match(/^\s*([a-z]{3})?\s*(-)?(\d+)(?:\.(\d*))?\s*([a-z]{3})?\s*$/i);
|
||||
|
||||
if (m) {
|
||||
var currency = m[1] || m[5] || "XRP",
|
||||
integer = m[3] || "0",
|
||||
fraction = m[4] || "",
|
||||
precision = null;
|
||||
|
||||
currency = currency.toUpperCase();
|
||||
|
||||
this._value = new BigInteger(integer);
|
||||
this.set_currency(currency);
|
||||
|
||||
// XRP have exactly six digits of precision
|
||||
if (currency === 'XRP') {
|
||||
fraction = fraction.slice(0, 6);
|
||||
while (fraction.length < 6) {
|
||||
fraction += "0";
|
||||
}
|
||||
this._is_native = true;
|
||||
this._value = this._value.multiply(consts.bi_xns_unit).add(new BigInteger(fraction));
|
||||
}
|
||||
// Other currencies have arbitrary precision
|
||||
else {
|
||||
while (fraction[fraction.length - 1] === "0") {
|
||||
fraction = fraction.slice(0, fraction.length - 1);
|
||||
}
|
||||
|
||||
precision = fraction.length;
|
||||
|
||||
this._is_native = false;
|
||||
var multiplier = consts.bi_10.clone().pow(precision);
|
||||
this._value = this._value.multiply(multiplier).add(new BigInteger(fraction));
|
||||
this._offset = -precision;
|
||||
|
||||
this.canonicalize();
|
||||
}
|
||||
|
||||
this._is_negative = !!m[2];
|
||||
} else {
|
||||
this._value = NaN;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Parse a XRP value from untrusted input.
|
||||
// - integer = raw units
|
||||
// - float = with precision 6
|
||||
@@ -551,7 +642,7 @@ Amount.prototype.parse_native = function(j) {
|
||||
this._value = new BigInteger(m[2]);
|
||||
}
|
||||
else {
|
||||
// Float notation
|
||||
// Float notation : values multiplied by 1,000,000.
|
||||
|
||||
var int_part = (new BigInteger(m[2])).multiply(consts.bi_xns_unit);
|
||||
var fraction_part = (new BigInteger(m[3])).multiply(new BigInteger(String(Math.pow(10, 1+consts.xns_precision-m[3].length))));
|
||||
@@ -578,7 +669,8 @@ Amount.prototype.parse_native = function(j) {
|
||||
return this;
|
||||
};
|
||||
|
||||
// Parse a non-native value.
|
||||
// Parse a non-native value for the json wire format.
|
||||
// Requires _currency to be set!
|
||||
Amount.prototype.parse_value = function(j) {
|
||||
this._is_native = false;
|
||||
|
||||
@@ -647,9 +739,9 @@ Amount.prototype.parse_json = function(j) {
|
||||
var m = j.match(/^(.+)\/(...)\/(.+)$/);
|
||||
|
||||
if (m) {
|
||||
this.parse_value(m[1]);
|
||||
this._currency = Currency.from_json(m[2]);
|
||||
this._issuer = UInt160.from_json(m[3]);
|
||||
this.parse_value(m[1]);
|
||||
}
|
||||
else {
|
||||
this.parse_native(j);
|
||||
@@ -663,9 +755,9 @@ Amount.prototype.parse_json = function(j) {
|
||||
else if ('object' === typeof j && 'value' in j) {
|
||||
// Parse the passed value to sanitize and copy it.
|
||||
|
||||
this.parse_value(j.value);
|
||||
this._currency.parse_json(j.currency); // Never XRP.
|
||||
this._issuer.parse_json(j.issuer);
|
||||
this.parse_value(j.value);
|
||||
}
|
||||
else {
|
||||
this._value = NaN;
|
||||
@@ -727,4 +819,4 @@ exports.UInt160 = UInt160;
|
||||
|
||||
exports.config = {};
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -1216,4 +1216,4 @@ BigInteger.ONE = nbv(1);
|
||||
exports.nbi = nbi;
|
||||
exports.BigInteger = BigInteger;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -55,4 +55,4 @@ Network.protocol.stop = function () {
|
||||
|
||||
exports.Network = Network;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -88,4 +88,4 @@ exports.mkPath = mkPath;
|
||||
exports.resetPath = resetPath;
|
||||
exports.rmPath = rmPath;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -22,6 +22,8 @@ var Amount = require('./amount.js').Amount;
|
||||
var Currency = require('./amount.js').Currency;
|
||||
var UInt160 = require('./amount.js').UInt160;
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
// Request events emitted:
|
||||
// 'success' : Request successful.
|
||||
// 'error' : Request failed.
|
||||
@@ -37,23 +39,16 @@ var Request = function (remote, command) {
|
||||
};
|
||||
this.remote = remote;
|
||||
this.requested = false;
|
||||
|
||||
this.on('request', function () {
|
||||
self.request_default();
|
||||
});
|
||||
};
|
||||
|
||||
Request.prototype = new EventEmitter;
|
||||
|
||||
// Send the request to a remote.
|
||||
Request.prototype.request = function (remote) {
|
||||
this.emit('request', remote);
|
||||
};
|
||||
|
||||
Request.prototype.request_default = function () {
|
||||
if (!this.requested) {
|
||||
this.requested = true;
|
||||
this.remote.request(this);
|
||||
this.emit('request', remote);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -189,7 +184,8 @@ var Remote = function (opts, trace) {
|
||||
this.trusted = opts.trusted;
|
||||
this.websocket_ip = opts.websocket_ip;
|
||||
this.websocket_port = opts.websocket_port;
|
||||
this.local_sequence = opts.local_sequence;
|
||||
this.local_sequence = opts.local_sequence; // Locally track sequence numbers
|
||||
this.local_fee = opts.local_fee; // Locally set fees
|
||||
this.id = 0;
|
||||
this.trace = opts.trace || trace;
|
||||
this._ledger_current_index = undefined;
|
||||
@@ -460,12 +456,12 @@ Remote.prototype._connect_message = function (ws, json) {
|
||||
unexpected = true;
|
||||
}
|
||||
else if ('success' === message.status) {
|
||||
if (this.trace) console.log("remote: response: %s", JSON.stringify(message, undefined, 2));
|
||||
if (this.trace) utils.logObject("remote: response: %s", message);
|
||||
|
||||
request.emit('success', message.result);
|
||||
}
|
||||
else if (message.error) {
|
||||
if (this.trace) console.log("remote: error: %s", JSON.stringify(message, undefined, 2));
|
||||
if (this.trace) utils.logObject("remote: error: %s", message);
|
||||
|
||||
request.emit('error', {
|
||||
'error' : 'remoteError',
|
||||
@@ -491,7 +487,7 @@ Remote.prototype._connect_message = function (ws, json) {
|
||||
|
||||
// Account subscription event
|
||||
case 'account':
|
||||
if (this.trace) console.log("remote: account: %s", JSON.stringify(message, undefined, 2));
|
||||
if (this.trace) utils.logObject("remote: account: %s", message);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -535,12 +531,12 @@ Remote.prototype.request = function (request) {
|
||||
|
||||
this.id += 1; // Advance id.
|
||||
|
||||
if (this.trace) console.log("remote: request: %s", JSON.stringify(request.message));
|
||||
if (this.trace) utils.logObject("remote: request: %s", request.message);
|
||||
|
||||
this.ws.send(JSON.stringify(request.message));
|
||||
}
|
||||
else {
|
||||
if (this.trace) console.log("remote: request: DROPPING: %s", JSON.stringify(request.message));
|
||||
if (this.trace) utils.logObject("remote: request: DROPPING: %s", request.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -592,7 +588,8 @@ Remote.prototype.request_ledger_entry = function (type) {
|
||||
this.type = type;
|
||||
|
||||
// Transparent caching:
|
||||
request.on('request', function (remote) { // Intercept default request.
|
||||
this.request_default = this.request;
|
||||
this.request = function () { // Intercept default request.
|
||||
if (self._ledger_hash) {
|
||||
// XXX Add caching.
|
||||
}
|
||||
@@ -610,7 +607,7 @@ Remote.prototype.request_ledger_entry = function (type) {
|
||||
|
||||
if (node) {
|
||||
// Emulate fetch of ledger entry.
|
||||
this.request.emit('success', {
|
||||
self.emit('success', {
|
||||
// YYY Missing lots of fields.
|
||||
'node' : node,
|
||||
});
|
||||
@@ -634,7 +631,7 @@ Remote.prototype.request_ledger_entry = function (type) {
|
||||
this.request_default();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return request;
|
||||
};
|
||||
@@ -1174,7 +1171,7 @@ Transaction.prototype.submit = function (callback) {
|
||||
|
||||
// YYY Might check paths for invalid accounts.
|
||||
|
||||
if (undefined === tx_json.Fee) {
|
||||
if (this.remote.local_fee && undefined === tx_json.Fee) {
|
||||
if ('Payment' === tx_json.TransactionType
|
||||
&& tx_json.Flags & Remote.flags.Payment.CreateAccount) {
|
||||
|
||||
@@ -1346,7 +1343,7 @@ Transaction.prototype.set_flags = function (flags) {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.tx_json.Flags & Remote.flags.Payment.CreateAccount)
|
||||
if (this.remote.local_fee && (this.tx_json.Flags & Remote.flags.Payment.CreateAccount))
|
||||
this.tx_json.Fee = Remote.fees.account_create.to_json();
|
||||
}
|
||||
|
||||
@@ -1399,10 +1396,13 @@ Transaction.prototype.offer_create = function (src, taker_pays, taker_gets, expi
|
||||
this.secret = this._account_secret(src);
|
||||
this.tx_json.TransactionType = 'OfferCreate';
|
||||
this.tx_json.Account = UInt160.json_rewrite(src);
|
||||
this.tx_json.Fee = Remote.fees.offer.to_json();
|
||||
this.tx_json.TakerPays = Amount.json_rewrite(taker_pays);
|
||||
this.tx_json.TakerGets = Amount.json_rewrite(taker_gets);
|
||||
|
||||
if (this.remote.local_fee) {
|
||||
this.tx_json.Fee = Remote.fees.offer.to_json();
|
||||
}
|
||||
|
||||
if (expiration)
|
||||
this.tx_json.Expiration = Date === expiration.constructor
|
||||
? expiration.getTime()
|
||||
@@ -1489,4 +1489,4 @@ Transaction.prototype.wallet_add = function (src, amount, authorized_key, public
|
||||
exports.config = {};
|
||||
exports.Remote = Remote;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -41,4 +41,4 @@ serializer.addUInt160 = function(value) {
|
||||
serializer.getSHA512Half = function() {
|
||||
};
|
||||
|
||||
// vim:ts=4
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -70,10 +70,30 @@ var stringToArray = function (s) {
|
||||
return a;
|
||||
};
|
||||
|
||||
exports.trace = trace;
|
||||
exports.arraySet = arraySet;
|
||||
exports.hexToString = hexToString;
|
||||
exports.stringToArray = stringToArray;
|
||||
exports.stringToHex = stringToHex;
|
||||
var chunkString = function (str, n, leftAlign) {
|
||||
var ret = [];
|
||||
var i=0, len=str.length;
|
||||
if (leftAlign) {
|
||||
i = str.length % n;
|
||||
if (i) ret.push(str.slice(0, i));
|
||||
}
|
||||
for(; i < len; i += n) {
|
||||
ret.push(str.slice(i, n+i));
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
var logObject = function (msg, obj) {
|
||||
console.log(msg, JSON.stringify(obj, undefined, 2));
|
||||
};
|
||||
|
||||
|
||||
exports.trace = trace;
|
||||
exports.arraySet = arraySet;
|
||||
exports.hexToString = hexToString;
|
||||
exports.stringToArray = stringToArray;
|
||||
exports.stringToHex = stringToHex;
|
||||
exports.logObject = logObject;
|
||||
exports.chunkString = chunkString;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
7
src/js/utils.web.js
Normal file
7
src/js/utils.web.js
Normal file
@@ -0,0 +1,7 @@
|
||||
exports = module.exports = require('./utils.js');
|
||||
|
||||
// We override this function for browsers, because they print objects nicer
|
||||
// natively than JSON.stringify can.
|
||||
exports.logObject = function (msg, obj) {
|
||||
console.log(msg, "", obj);
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
var buster = require("buster");
|
||||
var buster = require("buster");
|
||||
|
||||
var jsbn = require('../src/js/jsbn.js');
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
var nbi = jsbn.nbi;
|
||||
var jsbn = require('../src/js/jsbn.js');
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
var nbi = jsbn.nbi;
|
||||
|
||||
var amount = require("../src/js/amount.js");
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var UInt160 = require("../src/js/amount.js").UInt160;
|
||||
var amount = require("../src/js/amount.js");
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var UInt160 = require("../src/js/amount.js").UInt160;
|
||||
|
||||
require("../src/js/amount.js").config = require("./config.js");
|
||||
|
||||
@@ -107,4 +107,4 @@ buster.testCase("Amount", {
|
||||
}
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -4,6 +4,8 @@ config["Newcoin tests"] = {
|
||||
rootPath: "../",
|
||||
environment: "node",
|
||||
tests: [
|
||||
"test/*-test.js"
|
||||
"test/*-test.js"
|
||||
]
|
||||
}
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
//
|
||||
// Configuration for unit tests
|
||||
// Configuration for unit tests: to be locally customized as needed.
|
||||
//
|
||||
|
||||
var path = require("path");
|
||||
var path = require("path");
|
||||
var testconfig = require("./testconfig.js");
|
||||
|
||||
exports.accounts = testconfig.accounts;
|
||||
|
||||
// Where to find the binary.
|
||||
exports.rippled = path.resolve("build/rippled");
|
||||
|
||||
exports.server_default = "alpha";
|
||||
exports.server_default = "alpha";
|
||||
|
||||
// Configuration for servers.
|
||||
exports.servers = {
|
||||
// A local test server.
|
||||
"alpha" : {
|
||||
'trusted' : true,
|
||||
'no_server' : true,
|
||||
// "peer_ip" : "0.0.0.0",
|
||||
// "peer_port" : 51235,
|
||||
'rpc_ip' : "0.0.0.0",
|
||||
@@ -22,48 +24,10 @@ exports.servers = {
|
||||
'websocket_ip' : "127.0.0.1",
|
||||
'websocket_port' : 5006,
|
||||
'local_sequence' : true,
|
||||
'local_fee' : true,
|
||||
// 'validation_seed' : "shhDFVsmS2GSu5vUyZSPXYfj1r79h",
|
||||
// 'validators' : "n9L8LZZCwsdXzKUN9zoVxs4YznYXZ9hEhsQZY7aVpxtFaSceiyDZ beta"
|
||||
}
|
||||
};
|
||||
|
||||
// Configuration for test accounts.
|
||||
exports.accounts = {
|
||||
// Users
|
||||
"alice" : {
|
||||
'account' : "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
|
||||
'secret' : "alice",
|
||||
},
|
||||
"bob" : {
|
||||
'account' : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
|
||||
'secret' : "bob",
|
||||
},
|
||||
"carol" : {
|
||||
'account' : "rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW",
|
||||
'secret' : "carol",
|
||||
},
|
||||
|
||||
// Nexuses
|
||||
"bitstamp" : {
|
||||
'account' : "r4jKmc2nQb5yEU6eycefiNKGHTU5NQJASx",
|
||||
'secret' : "bitstamp",
|
||||
},
|
||||
"mtgox" : {
|
||||
'account' : "rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v",
|
||||
'secret' : "mtgox",
|
||||
},
|
||||
|
||||
// Merchants
|
||||
"amazon" : {
|
||||
'account' : "rhheXqX7bDnXePJeMHhubDDvw2uUTtenPd",
|
||||
'secret' : "amazon",
|
||||
},
|
||||
|
||||
// Master account
|
||||
"root" : {
|
||||
'account' : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
'secret' : "masterpassphrase",
|
||||
},
|
||||
};
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
var async = require("async");
|
||||
var buster = require("buster");
|
||||
var async = require("async");
|
||||
var buster = require("buster");
|
||||
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
|
||||
var testutils = require("./testutils.js");
|
||||
var testutils = require("./testutils.js");
|
||||
|
||||
require("../src/js/amount.js").config = require("./config.js");
|
||||
require("../src/js/remote.js").config = require("./config.js");
|
||||
|
||||
buster.testRunner.timeout = 5000;
|
||||
|
||||
|
||||
buster.testCase("//Monitor account", {
|
||||
'setUp' : testutils.build_setup({ verbose: true }),
|
||||
'tearDown' : testutils.build_teardown(),
|
||||
@@ -21,34 +21,34 @@ buster.testCase("//Monitor account", {
|
||||
var self = this;
|
||||
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
self.what = "Create accounts.";
|
||||
function (callback) {
|
||||
self.what = "Create accounts.";
|
||||
|
||||
testutils.create_accounts(self.remote, "root", "10000", ["alice"], callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Close ledger.";
|
||||
testutils.create_accounts(self.remote, "root", "10000", ["alice"], callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Close ledger.";
|
||||
|
||||
self.remote.once('ledger_closed', function (ledger_closed, ledger_index) {
|
||||
callback();
|
||||
});
|
||||
self.remote.once('ledger_closed', function (ledger_closed, ledger_index) {
|
||||
callback();
|
||||
});
|
||||
|
||||
self.remote.ledger_accept();
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Dumping root.";
|
||||
self.remote.ledger_accept();
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Dumping root.";
|
||||
|
||||
testutils.account_dump(self.remote, "root", function (error) {
|
||||
buster.refute(error);
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
testutils.account_dump(self.remote, "root", function (error) {
|
||||
buster.refute(error);
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
], function (error) {
|
||||
buster.refute(error, self.what);
|
||||
done();
|
||||
buster.refute(error, self.what);
|
||||
done();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
1253
test/offer-test.js
1253
test/offer-test.js
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
||||
var async = require("async");
|
||||
var buster = require("buster");
|
||||
var async = require("async");
|
||||
var buster = require("buster");
|
||||
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
|
||||
var testutils = require("./testutils.js");
|
||||
var testutils = require("./testutils.js");
|
||||
|
||||
require("../src/js/amount.js").config = require("./config.js");
|
||||
require("../src/js/remote.js").config = require("./config.js");
|
||||
@@ -21,46 +21,47 @@ buster.testCase("Path finding", {
|
||||
var self = this;
|
||||
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
self.what = "Create accounts.";
|
||||
function (callback) {
|
||||
self.what = "Create accounts.";
|
||||
|
||||
testutils.create_accounts(self.remote, "root", "10000", ["alice", "bob", "mtgox"], callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Set credit limits.";
|
||||
testutils.create_accounts(self.remote, "root", "10000", ["alice", "bob", "mtgox"], callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Set credit limits.";
|
||||
|
||||
testutils.credit_limits(self.remote,
|
||||
{
|
||||
"alice" : "600/USD/mtgox",
|
||||
"bob" : "700/USD/mtgox",
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Distribute funds.";
|
||||
testutils.credit_limits(self.remote,
|
||||
{
|
||||
"alice" : "600/USD/mtgox",
|
||||
"bob" : "700/USD/mtgox",
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Distribute funds.";
|
||||
|
||||
testutils.payments(self.remote,
|
||||
{
|
||||
"mtgox" : [ "70/USD/alice", "50/USD/bob" ],
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Find path from alice to mtgox";
|
||||
testutils.payments(self.remote,
|
||||
{
|
||||
"mtgox" : [ "70/USD/alice", "50/USD/bob" ],
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Find path from alice to mtgox";
|
||||
|
||||
self.remote.request_ripple_path_find("alice", "bob", "5/USD/mtgox",
|
||||
[ { 'currency' : "USD" } ])
|
||||
.on('success', function (m) {
|
||||
console.log("proposed: m", JSON.stringify(m));
|
||||
self.remote.request_ripple_path_find("alice", "bob", "5/USD/mtgox",
|
||||
[ { 'currency' : "USD" } ])
|
||||
.on('success', function (m) {
|
||||
console.log("proposed: m", JSON.stringify(m));
|
||||
|
||||
callback();
|
||||
})
|
||||
.request();
|
||||
},
|
||||
], function (error) {
|
||||
buster.refute(error, self.what);
|
||||
done();
|
||||
});
|
||||
callback();
|
||||
})
|
||||
.request();
|
||||
},
|
||||
], function (error) {
|
||||
buster.refute(error, self.what);
|
||||
done();
|
||||
});
|
||||
},
|
||||
});
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
var buster = require("buster");
|
||||
var buster = require("buster");
|
||||
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var Server = require("./server.js").Server;
|
||||
|
||||
var testutils = require("./testutils.js");
|
||||
var testutils = require("./testutils.js");
|
||||
|
||||
require("../src/js/amount.js").config = require("./config.js");
|
||||
require("../src/js/remote.js").config = require("./config.js");
|
||||
|
||||
// How long to wait for server to start.
|
||||
var serverDelay = 1500; // XXX Not implemented.
|
||||
var serverDelay = 1500; // XXX Not implemented.
|
||||
|
||||
buster.testRunner.timeout = 5000;
|
||||
|
||||
|
||||
buster.testCase("Remote functions", {
|
||||
'setUp' : testutils.build_setup(),
|
||||
'tearDown' : testutils.build_teardown(),
|
||||
@@ -21,16 +21,16 @@ buster.testCase("Remote functions", {
|
||||
"request_ledger_current" :
|
||||
function (done) {
|
||||
this.remote.request_ledger_current().on('success', function (m) {
|
||||
// console.log(m);
|
||||
// console.log(m);
|
||||
|
||||
buster.assert.equals(m.ledger_current_index, 3);
|
||||
done();
|
||||
})
|
||||
buster.assert.equals(m.ledger_current_index, 3);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log(m);
|
||||
// console.log(m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
buster.assert(false);
|
||||
})
|
||||
|
||||
.request();
|
||||
},
|
||||
@@ -38,16 +38,16 @@ buster.testCase("Remote functions", {
|
||||
"request_ledger_hash" :
|
||||
function (done) {
|
||||
this.remote.request_ledger_hash().on('success', function (m) {
|
||||
// console.log("result: %s", JSON.stringify(m));
|
||||
// console.log("result: %s", JSON.stringify(m));
|
||||
|
||||
buster.assert.equals(m.ledger_index, 2);
|
||||
done();
|
||||
})
|
||||
buster.assert.equals(m.ledger_index, 2);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
buster.assert(false);
|
||||
})
|
||||
.request();
|
||||
},
|
||||
|
||||
@@ -56,30 +56,30 @@ buster.testCase("Remote functions", {
|
||||
var self = this;
|
||||
|
||||
this.remote.request_ledger_hash().on('success', function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
self.remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
self.remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert('node' in r);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
buster.assert('node' in r);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
.request();
|
||||
})
|
||||
buster.assert(false);
|
||||
})
|
||||
.request();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
buster.assert(false);
|
||||
})
|
||||
.request();
|
||||
},
|
||||
|
||||
@@ -89,31 +89,31 @@ buster.testCase("Remote functions", {
|
||||
var self = this;
|
||||
|
||||
this.remote.request_ledger_hash().on('success', function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
self.remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("zHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
self.remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("zHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
buster.assert(false);
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert.equals(m.error, 'remoteError');
|
||||
buster.assert.equals(m.remote.error, 'malformedAddress');
|
||||
done();
|
||||
})
|
||||
.request();
|
||||
})
|
||||
buster.assert.equals(m.error, 'remoteError');
|
||||
buster.assert.equals(m.remote.error, 'malformedAddress');
|
||||
done();
|
||||
})
|
||||
.request();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
buster.assert(false);
|
||||
})
|
||||
.request();
|
||||
},
|
||||
|
||||
@@ -122,31 +122,31 @@ buster.testCase("Remote functions", {
|
||||
var self = this;
|
||||
|
||||
this.remote.request_ledger_hash().on('success', function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
self.remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("alice")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
self.remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("alice")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
buster.assert(false);
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert.equals(m.error, 'remoteError');
|
||||
buster.assert.equals(m.remote.error, 'entryNotFound');
|
||||
done();
|
||||
})
|
||||
.request();
|
||||
})
|
||||
buster.assert.equals(m.error, 'remoteError');
|
||||
buster.assert.equals(m.remote.error, 'entryNotFound');
|
||||
done();
|
||||
})
|
||||
.request();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
}).request();
|
||||
buster.assert(false);
|
||||
}).request();
|
||||
},
|
||||
|
||||
"ledger_entry index" :
|
||||
@@ -154,51 +154,52 @@ buster.testCase("Remote functions", {
|
||||
var self = this;
|
||||
|
||||
this.remote.request_ledger_hash().on('success', function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
self.remote
|
||||
.request_ledger_entry('index')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("alice")
|
||||
.index("2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
self.remote
|
||||
.request_ledger_entry('index')
|
||||
.ledger_hash(r.ledger_hash)
|
||||
.account_root("alice")
|
||||
.index("2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8")
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert('node_binary' in r);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
buster.assert('node_binary' in r);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
}).
|
||||
request();
|
||||
})
|
||||
buster.assert(false);
|
||||
}).
|
||||
request();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log(m);
|
||||
// console.log(m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
buster.assert(false);
|
||||
})
|
||||
.request();
|
||||
},
|
||||
|
||||
"create account" :
|
||||
function (done) {
|
||||
this.remote.transaction()
|
||||
.payment('root', 'alice', Amount.from_json("10000"))
|
||||
.set_flags('CreateAccount')
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
.payment('root', 'alice', Amount.from_json("10000"))
|
||||
.set_flags('CreateAccount')
|
||||
.on('success', function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
// Need to verify account and balance.
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
// Need to verify account and balance.
|
||||
buster.assert(true);
|
||||
done();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
.submit();
|
||||
buster.assert(false);
|
||||
})
|
||||
.submit();
|
||||
},
|
||||
|
||||
"create account final" :
|
||||
@@ -209,39 +210,39 @@ buster.testCase("Remote functions", {
|
||||
var got_success;
|
||||
|
||||
this.remote.transaction()
|
||||
.payment('root', 'alice', Amount.from_json("10000"))
|
||||
.set_flags('CreateAccount')
|
||||
.on('success', function (r) {
|
||||
// console.log("create_account: %s", JSON.stringify(r));
|
||||
.payment('root', 'alice', Amount.from_json("10000"))
|
||||
.set_flags('CreateAccount')
|
||||
.on('success', function (r) {
|
||||
// console.log("create_account: %s", JSON.stringify(r));
|
||||
|
||||
got_success = true;
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", m);
|
||||
got_success = true;
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
})
|
||||
.on('final', function (m) {
|
||||
// console.log("final: %s", JSON.stringify(m));
|
||||
buster.assert(false);
|
||||
})
|
||||
.on('final', function (m) {
|
||||
// console.log("final: %s", JSON.stringify(m));
|
||||
|
||||
buster.assert(got_success && got_proposed);
|
||||
done();
|
||||
})
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
buster.assert(got_success && got_proposed);
|
||||
done();
|
||||
})
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
// buster.assert.equals(m.result, 'terNO_DST');
|
||||
buster.assert.equals(m.result, 'tesSUCCESS');
|
||||
// buster.assert.equals(m.result, 'terNO_DST');
|
||||
buster.assert.equals(m.result, 'tesSUCCESS');
|
||||
|
||||
got_proposed = true;
|
||||
got_proposed = true;
|
||||
|
||||
self.remote.ledger_accept();
|
||||
})
|
||||
.on('status', function (s) {
|
||||
// console.log("status: %s", JSON.stringify(s));
|
||||
})
|
||||
.submit();
|
||||
self.remote.ledger_accept();
|
||||
})
|
||||
.on('status', function (s) {
|
||||
// console.log("status: %s", JSON.stringify(s));
|
||||
})
|
||||
.submit();
|
||||
},
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
1129
test/send-test.js
1129
test/send-test.js
File diff suppressed because it is too large
Load Diff
@@ -12,17 +12,17 @@ buster.testCase("Standalone server startup", {
|
||||
alpha = Server.from_config("alpha");
|
||||
|
||||
alpha
|
||||
.on('started', function () {
|
||||
alpha
|
||||
.on('stopped', function () {
|
||||
buster.assert(true);
|
||||
.on('started', function () {
|
||||
alpha
|
||||
.on('stopped', function () {
|
||||
buster.assert(true);
|
||||
|
||||
done();
|
||||
})
|
||||
.stop();
|
||||
})
|
||||
.start();
|
||||
done();
|
||||
})
|
||||
.stop();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
//
|
||||
// Usage:
|
||||
// s = new Server(name, config)
|
||||
// s.verbose() : optional
|
||||
// s.verbose() : optional
|
||||
// .start()
|
||||
// 'started'
|
||||
// 'started'
|
||||
//
|
||||
// s.stop() : stops server is started.
|
||||
// s.stop() : stops server is started.
|
||||
// 'stopped'
|
||||
//
|
||||
|
||||
@@ -15,22 +15,22 @@
|
||||
// Servers are created in tmp/server/$server
|
||||
//
|
||||
|
||||
var buster = require("buster");
|
||||
var child = require("child_process");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var util = require("util");
|
||||
var buster = require("buster");
|
||||
var child = require("child_process");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var util = require("util");
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var config = require("./config.js");
|
||||
var nodeutils = require("../src/js/nodeutils.js");
|
||||
var config = require("./config.js");
|
||||
var nodeutils = require("../src/js/nodeutils.js");
|
||||
|
||||
// Create a server object
|
||||
var Server = function (name, config, verbose) {
|
||||
this.name = name;
|
||||
this.config = config;
|
||||
this.started = false;
|
||||
this.quiet = !verbose;
|
||||
this.name = name;
|
||||
this.config = config;
|
||||
this.started = false;
|
||||
this.quiet = !verbose;
|
||||
};
|
||||
|
||||
Server.prototype = new EventEmitter;
|
||||
@@ -66,7 +66,7 @@ Server.prototype._writeConfig = function(done) {
|
||||
fs.writeFile(
|
||||
this.configPath(),
|
||||
Object.keys(this.config).map(function(o) {
|
||||
return util.format("[%s]\n%s\n", o, self.config[o]);
|
||||
return util.format("[%s]\n%s\n", o, self.config[o]);
|
||||
}).join(""),
|
||||
'utf8', done);
|
||||
};
|
||||
@@ -111,10 +111,10 @@ Server.prototype._makeBase = function (done) {
|
||||
// Reset the server directory, build it if needed.
|
||||
nodeutils.resetPath(path, '0777', function (e) {
|
||||
if (e) {
|
||||
throw e;
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
self._writeConfig(done);
|
||||
self._writeConfig(done);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -128,17 +128,17 @@ Server.prototype.verbose = function () {
|
||||
// Create a standalone server.
|
||||
// Prepare the working directory and spawn the server.
|
||||
Server.prototype.start = function () {
|
||||
var self = this;
|
||||
var self = this;
|
||||
|
||||
if (!this.quiet) console.log("server: start: %s: %s", this.name, JSON.stringify(this.config));
|
||||
|
||||
this._makeBase(function (e) {
|
||||
if (e) {
|
||||
throw e;
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
self._serverSpawnSync();
|
||||
self.emit('started');
|
||||
self._serverSpawnSync();
|
||||
self.emit('started');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -153,10 +153,10 @@ Server.prototype.stop = function () {
|
||||
// Update the on exit to invoke done.
|
||||
this.child.on('exit', function (code, signal) {
|
||||
|
||||
if (!self.quiet) console.log("server: stop: server exited");
|
||||
if (!self.quiet) console.log("server: stop: server exited");
|
||||
|
||||
self.emit('stopped');
|
||||
delete this.child;
|
||||
self.emit('stopped');
|
||||
delete this.child;
|
||||
});
|
||||
|
||||
this.child.kill();
|
||||
@@ -171,4 +171,4 @@ Server.prototype.stop = function () {
|
||||
|
||||
exports.Server = Server;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
48
test/testconfig.js
Normal file
48
test/testconfig.js
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Configuration for unit tests: not to be locally customized.
|
||||
//
|
||||
|
||||
// Configuration for test accounts.
|
||||
exports.accounts = {
|
||||
// Users
|
||||
"alice" : {
|
||||
'account' : "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
|
||||
'secret' : "alice",
|
||||
},
|
||||
"bob" : {
|
||||
'account' : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
|
||||
'secret' : "bob",
|
||||
},
|
||||
"carol" : {
|
||||
'account' : "rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW",
|
||||
'secret' : "carol",
|
||||
},
|
||||
"dan" : {
|
||||
'account' : "rJ85Mok8YRNxSo7NnxKGrPuk29uAeZQqwZ",
|
||||
'secret' : "dan",
|
||||
},
|
||||
|
||||
// Nexuses
|
||||
"bitstamp" : {
|
||||
'account' : "r4jKmc2nQb5yEU6eycefiNKGHTU5NQJASx",
|
||||
'secret' : "bitstamp",
|
||||
},
|
||||
"mtgox" : {
|
||||
'account' : "rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v",
|
||||
'secret' : "mtgox",
|
||||
},
|
||||
|
||||
// Merchants
|
||||
"amazon" : {
|
||||
'account' : "rhheXqX7bDnXePJeMHhubDDvw2uUTtenPd",
|
||||
'secret' : "amazon",
|
||||
},
|
||||
|
||||
// Master account
|
||||
"root" : {
|
||||
'account' : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
'secret' : "masterpassphrase",
|
||||
},
|
||||
};
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
@@ -1,5 +1,4 @@
|
||||
var async = require("async");
|
||||
// var buster = require("buster");
|
||||
|
||||
var Amount = require("../src/js/amount.js").Amount;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
@@ -15,24 +14,24 @@ var account_dump = function (remote, account, callback) {
|
||||
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
self.what = "Get latest account_root";
|
||||
self.what = "Get latest account_root";
|
||||
|
||||
remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(remote.ledger_hash())
|
||||
.account_root("root")
|
||||
.on('success', function (r) {
|
||||
//console.log("account_root: %s", JSON.stringify(r, undefined, 2));
|
||||
remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(remote.ledger_hash())
|
||||
.account_root("root")
|
||||
.on('success', function (r) {
|
||||
//console.log("account_root: %s", JSON.stringify(r, undefined, 2));
|
||||
|
||||
callback();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
console.log("error: %s", m);
|
||||
callback();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
callback();
|
||||
})
|
||||
.request();
|
||||
buster.assert(false);
|
||||
callback();
|
||||
})
|
||||
.request();
|
||||
},
|
||||
], function (error) {
|
||||
callback(error);
|
||||
@@ -106,10 +105,10 @@ var build_setup = function (opts, host) {
|
||||
* @param host {String} Identifier for the host configuration to be used.
|
||||
*/
|
||||
var build_teardown = function (host) {
|
||||
|
||||
|
||||
return function (done) {
|
||||
|
||||
|
||||
|
||||
|
||||
host = host || config.server_default;
|
||||
|
||||
var data = this.store[host];
|
||||
@@ -117,22 +116,22 @@ var build_teardown = function (host) {
|
||||
|
||||
async.series([
|
||||
function disconnectWebsocketStep(callback) {
|
||||
|
||||
|
||||
data.remote
|
||||
.on('disconnected', callback)
|
||||
.connect(false);
|
||||
},
|
||||
function stopServerStep(callback) {
|
||||
|
||||
if (opts.no_server)
|
||||
|
||||
if (opts.no_server)
|
||||
{
|
||||
|
||||
return callback();
|
||||
}
|
||||
|
||||
return callback();
|
||||
}
|
||||
|
||||
data.server.on('stopped', callback).stop();
|
||||
}
|
||||
], done);
|
||||
], done);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -144,15 +143,15 @@ var create_accounts = function (remote, src, amount, accounts, callback) {
|
||||
.payment(src, account, amount)
|
||||
.set_flags('CreateAccount')
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
})
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
}, callback);
|
||||
};
|
||||
@@ -163,14 +162,14 @@ var credit_limit = function (remote, src, amount, callback) {
|
||||
remote.transaction()
|
||||
.ripple_line_set(src, amount)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
};
|
||||
@@ -181,8 +180,8 @@ var credit_limits = function (remote, balances, callback) {
|
||||
var limits = [];
|
||||
|
||||
for (var src in balances) {
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
|
||||
for (var index in values) {
|
||||
limits.push( { "source" : src, "amount" : values[index] } );
|
||||
@@ -192,7 +191,7 @@ var credit_limits = function (remote, balances, callback) {
|
||||
async.every(limits,
|
||||
function (limit, callback) {
|
||||
credit_limit(remote, limit.source, limit.amount,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
@@ -205,14 +204,14 @@ var payment = function (remote, src, dst, amount, callback) {
|
||||
remote.transaction()
|
||||
.payment(src, dst, amount)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
};
|
||||
@@ -223,8 +222,8 @@ var payments = function (remote, balances, callback) {
|
||||
var sends = [];
|
||||
|
||||
for (var src in balances) {
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
|
||||
for (var index in values) {
|
||||
var amount_json = values[index];
|
||||
@@ -237,7 +236,7 @@ var payments = function (remote, balances, callback) {
|
||||
async.every(sends,
|
||||
function (send, callback) {
|
||||
payment(remote, send.source, send.destination, send.amount,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
@@ -251,14 +250,14 @@ var transfer_rate = function (remote, src, billionths, callback) {
|
||||
.account_set(src)
|
||||
.transfer_rate(billionths)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
};
|
||||
@@ -270,32 +269,32 @@ var verify_balance = function (remote, src, amount_json, callback) {
|
||||
if (amount_req.is_native()) {
|
||||
remote.request_account_balance(src, 'CURRENT')
|
||||
.once('account_balance', function (amount_act) {
|
||||
if (!amount_act.equals(amount_req))
|
||||
console.log("verify_balance: failed: %s / %s",
|
||||
amount_act.to_text_full(),
|
||||
amount_req.to_text_full());
|
||||
if (!amount_act.equals(amount_req))
|
||||
console.log("verify_balance: failed: %s / %s",
|
||||
amount_act.to_text_full(),
|
||||
amount_req.to_text_full());
|
||||
|
||||
callback(!amount_act.equals(amount_req));
|
||||
})
|
||||
callback(!amount_act.equals(amount_req));
|
||||
})
|
||||
.request();
|
||||
}
|
||||
else {
|
||||
remote.request_ripple_balance(src, amount_req.issuer().to_json(), amount_req.currency().to_json(), 'CURRENT')
|
||||
.once('ripple_state', function (m) {
|
||||
// console.log("BALANCE: %s", JSON.stringify(m));
|
||||
// console.log("account_balance: %s", m.account_balance.to_text_full());
|
||||
// console.log("account_limit: %s", m.account_limit.to_text_full());
|
||||
// console.log("issuer_balance: %s", m.issuer_balance.to_text_full());
|
||||
// console.log("issuer_limit: %s", m.issuer_limit.to_text_full());
|
||||
// console.log("BALANCE: %s", JSON.stringify(m));
|
||||
// console.log("account_balance: %s", m.account_balance.to_text_full());
|
||||
// console.log("account_limit: %s", m.account_limit.to_text_full());
|
||||
// console.log("issuer_balance: %s", m.issuer_balance.to_text_full());
|
||||
// console.log("issuer_limit: %s", m.issuer_limit.to_text_full());
|
||||
|
||||
var account_balance = Amount.from_json(m.account_balance);
|
||||
var account_balance = Amount.from_json(m.account_balance);
|
||||
|
||||
if (!account_balance.equals(amount_req)) {
|
||||
console.log("verify_balance: failed: %s vs %s is %s: %s", src, account_balance.to_text_full(), amount_req.to_text_full(), account_balance.not_equals_why(amount_req));
|
||||
}
|
||||
if (!account_balance.equals(amount_req)) {
|
||||
console.log("verify_balance: failed: %s vs %s is %s: %s", src, account_balance.to_text_full(), amount_req.to_text_full(), account_balance.not_equals_why(amount_req));
|
||||
}
|
||||
|
||||
callback(!account_balance.equals(amount_req));
|
||||
})
|
||||
callback(!account_balance.equals(amount_req));
|
||||
})
|
||||
.request();
|
||||
}
|
||||
};
|
||||
@@ -304,8 +303,8 @@ var verify_balances = function (remote, balances, callback) {
|
||||
var tests = [];
|
||||
|
||||
for (var src in balances) {
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
|
||||
for (var index in values) {
|
||||
tests.push( { "source" : src, "amount" : values[index] } );
|
||||
@@ -315,7 +314,7 @@ var verify_balances = function (remote, balances, callback) {
|
||||
async.every(tests,
|
||||
function (check, callback) {
|
||||
verify_balance(remote, check.source, check.amount,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
@@ -332,13 +331,13 @@ var verify_offer = function (remote, owner, seq, taker_pays, taker_gets, callbac
|
||||
remote.request_ledger_entry('offer')
|
||||
.offer_id(owner, seq)
|
||||
.on('success', function (m) {
|
||||
var wrong = (!Amount.from_json(m.node.TakerGets).equals(Amount.from_json(taker_gets))
|
||||
|| !Amount.from_json(m.node.TakerPays).equals(Amount.from_json(taker_pays)));
|
||||
var wrong = (!Amount.from_json(m.node.TakerGets).equals(Amount.from_json(taker_gets))
|
||||
|| !Amount.from_json(m.node.TakerPays).equals(Amount.from_json(taker_pays)));
|
||||
|
||||
if (wrong)
|
||||
console.log("verify_offer: failed: %s", JSON.stringify(m));
|
||||
if (wrong)
|
||||
console.log("verify_offer: failed: %s", JSON.stringify(m));
|
||||
|
||||
callback(wrong);
|
||||
callback(wrong);
|
||||
})
|
||||
.request();
|
||||
};
|
||||
@@ -349,32 +348,32 @@ var verify_offer_not_found = function (remote, owner, seq, callback) {
|
||||
remote.request_ledger_entry('offer')
|
||||
.offer_id(owner, seq)
|
||||
.on('success', function (m) {
|
||||
console.log("verify_offer_not_found: found offer: %s", JSON.stringify(m));
|
||||
console.log("verify_offer_not_found: found offer: %s", JSON.stringify(m));
|
||||
|
||||
callback('entryFound');
|
||||
callback('entryFound');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("verify_offer_not_found: success: %s", JSON.stringify(m));
|
||||
// console.log("verify_offer_not_found: success: %s", JSON.stringify(m));
|
||||
|
||||
callback('remoteError' !== m.error
|
||||
|| 'entryNotFound' !== m.remote.error);
|
||||
callback('remoteError' !== m.error
|
||||
|| 'entryNotFound' !== m.remote.error);
|
||||
})
|
||||
.request();
|
||||
};
|
||||
|
||||
exports.account_dump = account_dump;
|
||||
exports.account_dump = account_dump;
|
||||
|
||||
exports.build_setup = build_setup;
|
||||
exports.create_accounts = create_accounts;
|
||||
exports.credit_limit = credit_limit;
|
||||
exports.credit_limits = credit_limits;
|
||||
exports.payment = payment;
|
||||
exports.payments = payments;
|
||||
exports.build_teardown = build_teardown;
|
||||
exports.transfer_rate = transfer_rate;
|
||||
exports.verify_balance = verify_balance;
|
||||
exports.verify_balances = verify_balances;
|
||||
exports.verify_offer = verify_offer;
|
||||
exports.verify_offer_not_found = verify_offer_not_found;
|
||||
exports.build_setup = build_setup;
|
||||
exports.create_accounts = create_accounts;
|
||||
exports.credit_limit = credit_limit;
|
||||
exports.credit_limits = credit_limits;
|
||||
exports.payment = payment;
|
||||
exports.payments = payments;
|
||||
exports.build_teardown = build_teardown;
|
||||
exports.transfer_rate = transfer_rate;
|
||||
exports.verify_balance = verify_balance;
|
||||
exports.verify_balances = verify_balances;
|
||||
exports.verify_offer = verify_offer;
|
||||
exports.verify_offer_not_found = verify_offer_not_found;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var fs = require("fs");
|
||||
var fs = require("fs");
|
||||
var buster = require("buster");
|
||||
|
||||
var utils = require("../src/js/utils.js");
|
||||
@@ -23,4 +23,4 @@ buster.testCase("Utils", {
|
||||
}
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -17,23 +17,23 @@ buster.testCase("WebSocket connection", {
|
||||
|
||||
"websocket connect and disconnect" :
|
||||
function (done) {
|
||||
var alpha = Remote.from_config("alpha");
|
||||
var alpha = Remote.from_config("alpha");
|
||||
|
||||
alpha
|
||||
.on('connected', function () {
|
||||
// OPEN
|
||||
buster.assert(true);
|
||||
.on('connected', function () {
|
||||
// OPEN
|
||||
buster.assert(true);
|
||||
|
||||
alpha
|
||||
.on('disconnected', function () {
|
||||
// CLOSED
|
||||
buster.assert(true);
|
||||
done();
|
||||
})
|
||||
.connect(false);
|
||||
})
|
||||
.connect();
|
||||
alpha
|
||||
.on('disconnected', function () {
|
||||
// CLOSED
|
||||
buster.assert(true);
|
||||
done();
|
||||
})
|
||||
.connect(false);
|
||||
})
|
||||
.connect();
|
||||
},
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
Reference in New Issue
Block a user