mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-22 23:00:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -158,7 +158,13 @@ STAmount::STAmount(SField::ref n, const Json::Value& v)
|
||||
|
||||
mIsNative = !currency.isString() || currency.asString().empty() || (currency.asString() == SYSTEM_CURRENCY_CODE);
|
||||
|
||||
if (!mIsNative) {
|
||||
if (mIsNative)
|
||||
{
|
||||
if (v.isObject())
|
||||
throw std::runtime_error("XRP may not be specified as an object");
|
||||
}
|
||||
else
|
||||
{ // non-XRP
|
||||
if (!currencyFromString(mCurrency, currency.asString()))
|
||||
throw std::runtime_error("invalid currency");
|
||||
|
||||
|
||||
@@ -582,7 +582,7 @@ bool SHAMap::addGiveItem(SHAMapItem::ref item, bool isTransaction, bool hasMeta)
|
||||
stack.pop();
|
||||
|
||||
if (node->isLeaf() && (node->peekItem()->getTag() == tag))
|
||||
throw std::runtime_error("addGiveItem ends on leaf with same tag");
|
||||
return false;
|
||||
|
||||
uint256 prevHash;
|
||||
returnNode(node, true);
|
||||
|
||||
@@ -7,5 +7,10 @@
|
||||
|
||||
bool TransactionEngine::checkInvariants(TER result, const SerializedTransaction& txn, TransactionEngineParams params)
|
||||
{
|
||||
|
||||
// 1) Make sure transaction changed account sequence number to correct value
|
||||
|
||||
// 2) Make sure transaction didn't create XRP
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,12 +176,20 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
|
||||
if (isSetBit(params, tapOPEN_LEDGER))
|
||||
{
|
||||
if (!mLedger->addTransaction(txID, s))
|
||||
{
|
||||
cLog(lsFATAL) << "Tried to add transaction to open ledger that already had it";
|
||||
assert(false);
|
||||
throw std::runtime_error("Duplicate transaction applied");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mLedger->addTransaction(txID, s, m))
|
||||
assert(false);
|
||||
{
|
||||
cLog(lsFATAL) << "Tried to add transaction to ledger that already had it";
|
||||
assert(false);
|
||||
throw std::runtime_error("Duplicate transaction applied to closed ledger");
|
||||
}
|
||||
|
||||
// Charge whatever fee they specified.
|
||||
STAmount saPaid = txn.getTransactionFee();
|
||||
|
||||
@@ -142,7 +142,8 @@ TER Transactor::checkSeq()
|
||||
cLog(lsWARNING) << "applyTransaction: past sequence number";
|
||||
|
||||
return tefPAST_SEQ;
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
mTxnAccount->setFieldU32(sfSequence, t_seq + 1);
|
||||
}
|
||||
|
||||
@@ -821,20 +821,37 @@ Remote.prototype.request_account_offers = function (accountID, account_index, cu
|
||||
.ledger_choose(current);
|
||||
};
|
||||
|
||||
Remote.prototype.request_account_tx = function (accountID, ledger_min, ledger_max) {
|
||||
|
||||
/*
|
||||
account: account,
|
||||
ledger_index_min: ledger_index, // optional, defaults to -1 if ledger_index_max is specified.
|
||||
ledger_index_max: ledger_index, // optional, defaults to -1 if ledger_index_min is specified.
|
||||
binary: boolean, // optional, defaults to false
|
||||
count: boolean, // optional, defaults to false
|
||||
descending: boolean, // optional, defaults to false
|
||||
offset: integer, // optional, defaults to 0
|
||||
limit: integer // optional
|
||||
*/
|
||||
|
||||
Remote.prototype.request_account_tx = function (obj) {
|
||||
// XXX Does this require the server to be trusted?
|
||||
//utils.assert(this.trusted);
|
||||
|
||||
var request = new Request(this, 'account_tx');
|
||||
|
||||
request.message.account = accountID;
|
||||
request.message.account = obj.account;
|
||||
|
||||
if (ledger_min === ledger_max) {
|
||||
request.message.ledger = ledger_min;
|
||||
if (false && ledger_min === ledger_max) {
|
||||
//request.message.ledger = ledger_min;
|
||||
}
|
||||
else {
|
||||
request.message.ledger_min = ledger_min;
|
||||
request.message.ledger_max = ledger_max;
|
||||
if (obj.ledger_index_min) {request.message.ledger_index_min = obj.ledger_index_min;}
|
||||
if (obj.ledger_index_max) {request.message.ledger_index_max = obj.ledger_index_max;}
|
||||
if (obj.binary) {request.message.binary = obj.binary;}
|
||||
if (obj.count) {request.message.count = obj.count;}
|
||||
if (obj.descending) {request.message.descending = obj.descending;}
|
||||
if (obj.offset) {request.message.offset = obj.offset;}
|
||||
if (obj.limit) {request.message.limit = obj.limit;}
|
||||
}
|
||||
|
||||
return request;
|
||||
|
||||
190
test/account_tx-test.js
Normal file
190
test/account_tx-test.js
Normal file
@@ -0,0 +1,190 @@
|
||||
var async = require("async");
|
||||
var buster = require("buster");
|
||||
|
||||
var Amount = require("../src/js/amount").Amount;
|
||||
var Remote = require("../src/js/remote").Remote;
|
||||
var Transaction = require("../src/js/transaction").Transaction;
|
||||
var Server = require("./server").Server;
|
||||
|
||||
var testutils = require("./testutils");
|
||||
|
||||
require('../src/js/config').load(require('./config'));
|
||||
|
||||
buster.testRunner.timeout = 250000; //This is a very long test!
|
||||
|
||||
|
||||
// Hard-coded limits we'll be testing:
|
||||
var BINARY_LIMIT = 500;
|
||||
var NONBINARY_LIMIT = 200;
|
||||
|
||||
var ACCOUNT = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
|
||||
var FIRST_BATCH = 199; // Within both limits
|
||||
var OFFSET = 180;
|
||||
var LIMIT = 170;
|
||||
var SECOND_BATCH = 10; // Between NONBINARY_LIMIT and BINARY_LIMIT
|
||||
var THIRD_BATCH = 295; // Exceeds both limits
|
||||
|
||||
buster.testCase("Account_tx tests", {
|
||||
'setUp' : testutils.build_setup(),
|
||||
'tearDown' : testutils.build_teardown(),
|
||||
|
||||
"make a lot of transactions and query using account_tx" :
|
||||
function (done) {
|
||||
var self = this;
|
||||
var final_create;
|
||||
|
||||
var transactionCounter = 0;
|
||||
|
||||
var createOfferFunction = function (callback) {
|
||||
self.remote.transaction()
|
||||
.offer_create("root", "500", "100/USD/root")
|
||||
.on('proposed', function (m) {
|
||||
transactionCounter++;
|
||||
console.log('Submitted transaction', transactionCounter);
|
||||
callback(m.result !== 'tesSUCCESS');
|
||||
})
|
||||
.on('final', function (m) {
|
||||
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
|
||||
buster.assert(final_create);
|
||||
})
|
||||
.submit();
|
||||
};
|
||||
|
||||
function lotsOfTransactions(number, whenDone) {
|
||||
var bunchOfOffers = [];
|
||||
for (var i=0; i<number; i++) {
|
||||
bunchOfOffers.push(createOfferFunction);
|
||||
}
|
||||
async.parallel(bunchOfOffers, function (error) {
|
||||
buster.refute(error);
|
||||
self.remote
|
||||
.once('ledger_closed', function (message) {
|
||||
final_create = message;
|
||||
})
|
||||
.ledger_accept();
|
||||
whenDone();
|
||||
});
|
||||
}
|
||||
|
||||
function firstBatch() {
|
||||
lotsOfTransactions(FIRST_BATCH,
|
||||
function(){runTests(self, FIRST_BATCH, 0, 0,
|
||||
function(){runTests(self, FIRST_BATCH, OFFSET, 0,
|
||||
function(){runTests(self, FIRST_BATCH, 0, LIMIT, secondBatch)})}
|
||||
)});
|
||||
}
|
||||
|
||||
function secondBatch() {
|
||||
lotsOfTransactions(SECOND_BATCH,
|
||||
function(){runTests(self, FIRST_BATCH+SECOND_BATCH, 0, 0,
|
||||
function(){runTests(self, FIRST_BATCH+SECOND_BATCH, OFFSET, 0, thirdBatch)}
|
||||
)});
|
||||
}
|
||||
|
||||
function thirdBatch() {
|
||||
lotsOfTransactions(THIRD_BATCH,
|
||||
function(){runTests(self, FIRST_BATCH+SECOND_BATCH+THIRD_BATCH, 0, 0,
|
||||
function(){runTests(self, FIRST_BATCH+SECOND_BATCH+THIRD_BATCH, OFFSET, 0, done)}
|
||||
)});
|
||||
}
|
||||
|
||||
firstBatch();
|
||||
|
||||
|
||||
function standardErrorHandler(callback) {
|
||||
return function(r) {
|
||||
console.log("ERROR!");
|
||||
console.log(r);
|
||||
callback(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function runTests(self, actualNumberOfTransactions, offset, limit, finalCallback) {
|
||||
console.log("Testing batch with offset and limit:", offset, limit);
|
||||
async.series([
|
||||
function(callback) {
|
||||
console.log('nonbinary');
|
||||
self.remote.request_account_tx({
|
||||
account:ACCOUNT,
|
||||
ledger_index_min:0,
|
||||
ledger_index_max:5,
|
||||
offset:offset,
|
||||
limit:limit
|
||||
}).on('success', function (r) {
|
||||
buster.assert(r.transactions, "No transactions returned.");
|
||||
var targetLength = Math.min(NONBINARY_LIMIT, limit ? Math.min(limit,actualNumberOfTransactions-offset) : actualNumberOfTransactions-offset);
|
||||
buster.assert(r.transactions.length == targetLength, "Got "+r.transactions.length+" transactions; expected "+targetLength );
|
||||
|
||||
//Check for proper ordering.
|
||||
for (var i=0; i<r.transactions.length-1; i++) {
|
||||
var t1 = r.transactions[i].tx;
|
||||
var t2 = r.transactions[i+1].tx;
|
||||
buster.assert(t1.inLedger<t2.inLedger || (t1.inLedger==t2.inLedger && t1.hash < t2.hash ),
|
||||
"Transactions were not ordered correctly: "+t1.inLedger+"#"+t1.hash+" should not have come before "+t2.inLedger+"#"+t2.hash);
|
||||
}
|
||||
callback(false);
|
||||
})
|
||||
.on('error', standardErrorHandler(callback))
|
||||
.request();
|
||||
},
|
||||
|
||||
function(callback) {
|
||||
console.log('binary');
|
||||
self.remote.request_account_tx({
|
||||
account:ACCOUNT,
|
||||
ledger_index_min:0,
|
||||
ledger_index_max:5,
|
||||
binary:true,
|
||||
offset:offset,
|
||||
limit:limit
|
||||
}).on('success', function (r) {
|
||||
buster.assert(r.transactions, "No transactions returned.");
|
||||
var targetLength = Math.min(BINARY_LIMIT, limit ? Math.min(limit,actualNumberOfTransactions-offset) : actualNumberOfTransactions-offset);
|
||||
buster.assert(r.transactions.length == targetLength, "Got "+r.transactions.length+" transactions; expected "+targetLength );
|
||||
callback(false);
|
||||
})
|
||||
.on('error', standardErrorHandler(callback))
|
||||
.request();
|
||||
},
|
||||
|
||||
function(callback) {
|
||||
console.log('nonbinary+offset');
|
||||
self.remote.request_account_tx({
|
||||
account:ACCOUNT,
|
||||
ledger_index_min:0,
|
||||
ledger_index_max:5,
|
||||
descending:true,
|
||||
offset:offset,
|
||||
limit:limit
|
||||
}).on('success', function (r) {
|
||||
buster.assert(r.transactions, "No transactions returned.");
|
||||
var targetLength = Math.min(NONBINARY_LIMIT, limit ? Math.min(limit,actualNumberOfTransactions-offset) : actualNumberOfTransactions-offset );
|
||||
buster.assert(r.transactions.length == targetLength, "Got "+r.transactions.length+" transactions; expected "+targetLength );
|
||||
//Check for proper ordering.
|
||||
for (var i=0; i<r.transactions.length-1; i++) {
|
||||
var t1 = r.transactions[i].tx;
|
||||
var t2 = r.transactions[i+1].tx;
|
||||
buster.assert(t1.inLedger>t2.inLedger || (t1.inLedger==t2.inLedger && t1.hash > t2.hash ),
|
||||
"Transactions were not ordered correctly: "+t1.inLedger+"#"+t1.hash+" should not have come before "+t2.inLedger+"#"+t2.hash);
|
||||
}
|
||||
callback(false);
|
||||
})
|
||||
.on('error', standardErrorHandler(callback))
|
||||
.request();
|
||||
},
|
||||
|
||||
|
||||
], function (error) {
|
||||
buster.refute(error);
|
||||
finalCallback();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// TODO:
|
||||
// Test the "count" feature.
|
||||
Reference in New Issue
Block a user