mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-01 07:55:49 +00:00
Merge branch 'master' into ut
Conflicts: js/utils.js test/server.js
This commit is contained in:
205
js/remote.js
Normal file
205
js/remote.js
Normal file
@@ -0,0 +1,205 @@
|
||||
// Remote access to a server.
|
||||
// - We never send binary data.
|
||||
// - We use the W3C interface for node and browser compatibility:
|
||||
// http://www.w3.org/TR/websockets/#the-websocket-interface
|
||||
//
|
||||
// YYY Will later provide a network access which use multiple instances of this.
|
||||
// YYY A better model might be to allow requesting a target state: keep connected or not.
|
||||
//
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var WebSocket = require('ws');
|
||||
|
||||
// --> trusted: truthy, if remote is trusted
|
||||
var Remote = function(trusted, websocket_ip, websocket_port, trace) {
|
||||
this.trusted = trusted;
|
||||
this.websocket_ip = websocket_ip;
|
||||
this.websocket_port = websocket_port;
|
||||
this.id = 0;
|
||||
this.trace = trace;
|
||||
};
|
||||
|
||||
var remoteConfig = function(config, server, trace) {
|
||||
var serverConfig = config.servers[server];
|
||||
|
||||
return new Remote(serverConfig.trusted, serverConfig.websocket_ip, serverConfig.websocket_port, trace);
|
||||
};
|
||||
|
||||
Remote.method('connect_helper', function() {
|
||||
var self = this;
|
||||
|
||||
if (this.trace)
|
||||
console.log("remote: connect: %s", this.url);
|
||||
|
||||
this.ws = new WebSocket(this.url);
|
||||
|
||||
var ws = this.ws;
|
||||
|
||||
ws.response = {};
|
||||
|
||||
ws.onopen = function() {
|
||||
if (this.trace)
|
||||
console.log("remote: onopen: %s", ws.readyState);
|
||||
|
||||
ws.onclose = undefined;
|
||||
ws.onerror = undefined;
|
||||
|
||||
self.done(ws.readyState);
|
||||
};
|
||||
|
||||
ws.onerror = function() {
|
||||
if (this.trace)
|
||||
console.log("remote: onerror: %s", ws.readyState);
|
||||
|
||||
ws.onclose = undefined;
|
||||
|
||||
if (self.expire) {
|
||||
if (this.trace)
|
||||
console.log("remote: was expired");
|
||||
|
||||
self.done(ws.readyState);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delay and retry.
|
||||
setTimeout(function() {
|
||||
if (this.trace)
|
||||
console.log("remote: retry");
|
||||
|
||||
self.connect_helper();
|
||||
}, 50); // Retry rate 50ms.
|
||||
}
|
||||
};
|
||||
|
||||
// Covers failure to open.
|
||||
ws.onclose = function() {
|
||||
if (this.trace)
|
||||
console.log("remote: onclose: %s", ws.readyState);
|
||||
|
||||
ws.onerror = undefined;
|
||||
|
||||
self.done(ws.readyState);
|
||||
};
|
||||
|
||||
// Node's ws module doesn't pass arguments to onmessage.
|
||||
ws.on('message', function(json, flags) {
|
||||
var message = JSON.parse(json);
|
||||
// console.log("message: %s", json);
|
||||
|
||||
if (message.type !== 'response') {
|
||||
console.log("unexpected message: %s", json);
|
||||
|
||||
} else {
|
||||
var done = ws.response[message.id];
|
||||
|
||||
if (done) {
|
||||
done(message);
|
||||
|
||||
} else {
|
||||
console.log("unexpected message id: %s", json);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Target state is connectted.
|
||||
// done(readyState):
|
||||
// --> readyState: OPEN, CLOSED
|
||||
Remote.method('connect', function(done, timeout) {
|
||||
var self = this;
|
||||
|
||||
this.url = util.format("ws://%s:%s", this.websocket_ip, this.websocket_port);
|
||||
this.done = done;
|
||||
|
||||
if (timeout) {
|
||||
if (this.trace)
|
||||
console.log("remote: expire: false");
|
||||
|
||||
this.expire = false;
|
||||
|
||||
setTimeout(function () {
|
||||
if (this.trace)
|
||||
console.log("remote: expire: timeout");
|
||||
|
||||
self.expire = true;
|
||||
}, timeout);
|
||||
}
|
||||
else {
|
||||
if (this.trace)
|
||||
console.log("remote: expire: false");
|
||||
|
||||
this.expire = true;
|
||||
}
|
||||
|
||||
this.connect_helper();
|
||||
|
||||
});
|
||||
|
||||
// Target stated is disconnected.
|
||||
Remote.method('disconnect', function(done) {
|
||||
var ws = this.ws;
|
||||
|
||||
ws.onclose = function() {
|
||||
if (this.trace)
|
||||
console.log("remote: onclose: %s", ws.readyState);
|
||||
|
||||
done(ws.readyState);
|
||||
};
|
||||
|
||||
ws.close();
|
||||
});
|
||||
|
||||
// Send a command. The comman should lack the id.
|
||||
// <-> command: what to send, consumed.
|
||||
Remote.method('request', function(command, done) {
|
||||
this.id += 1; // Advance id.
|
||||
|
||||
var ws = this.ws;
|
||||
|
||||
command.id = this.id;
|
||||
|
||||
ws.response[command.id] = done;
|
||||
|
||||
if (this.trace)
|
||||
console.log("remote: send: %s", JSON.stringify(command));
|
||||
|
||||
ws.send(JSON.stringify(command));
|
||||
});
|
||||
|
||||
Remote.method('ledger_closed', function(done) {
|
||||
assert(this.trusted); // If not trusted, need to check proof.
|
||||
|
||||
this.request({ 'command' : 'ledger_closed' }, done);
|
||||
});
|
||||
|
||||
// Get the current proposed ledger entry. May be closed (and revised) at any time (even before returning).
|
||||
// Only for use by unit tests.
|
||||
Remote.method('ledger_current', function(done) {
|
||||
this.request({ 'command' : 'ledger_current' }, done);
|
||||
});
|
||||
|
||||
// <-> params:
|
||||
// --> ledger : optional
|
||||
// --> ledger_index : optional
|
||||
Remote.method('ledger_entry', function(params, done) {
|
||||
assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.
|
||||
|
||||
params.command = 'ledger_entry';
|
||||
|
||||
this.request(params, done);
|
||||
});
|
||||
|
||||
// Submit a json transaction.
|
||||
// done(value)
|
||||
// <-> value: { 'status', status, 'result' : result, ... }
|
||||
// done may be called up to 3 times.
|
||||
Remote.method('submit', function(json, done) {
|
||||
// this.request(..., function() {
|
||||
// });
|
||||
});
|
||||
|
||||
exports.Remote = Remote;
|
||||
exports.remoteConfig = remoteConfig;
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,10 +1,17 @@
|
||||
// YYY Should probably have two versions: node vs browser
|
||||
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
Function.prototype.method = function(name,func) {
|
||||
this.prototype[name] = func;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
var filterErr = function(code, done) {
|
||||
return function(e) {
|
||||
done(e && e.code === code ? undefined : e);
|
||||
done(e.code !== code ? e : undefined);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
1
|
||||
|
||||
[debug_logfile]
|
||||
debug.log
|
||||
log/debug.log
|
||||
|
||||
[sntp_servers]
|
||||
time.windows.com
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
uint64 STAmount::uRateOne = STAmount::getRate(STAmount(1), STAmount(1));
|
||||
|
||||
// --> sCurrency: "", "XNS", or three letter ISO code.
|
||||
bool STAmount::currencyFromString(uint160& uDstCurrency, const std::string& sCurrency)
|
||||
{
|
||||
bool bSuccess = true;
|
||||
@@ -359,19 +360,16 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
|
||||
if ((value < cMinValue) || (value > cMaxValue) || (offset < cMinOffset) || (offset > cMaxOffset))
|
||||
throw std::runtime_error("invalid currency value");
|
||||
|
||||
sapResult = new STAmount(name, uCurrencyID, value, offset, isNegative);
|
||||
sapResult = new STAmount(name, uCurrencyID, uIssuerID, value, offset, isNegative);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (offset != 512)
|
||||
throw std::runtime_error("invalid currency value");
|
||||
|
||||
sapResult = new STAmount(name, uCurrencyID);
|
||||
sapResult = new STAmount(name, uCurrencyID, uIssuerID);
|
||||
}
|
||||
|
||||
if (sapResult)
|
||||
sapResult->setIssuer(uIssuerID);
|
||||
|
||||
return sapResult;
|
||||
}
|
||||
|
||||
@@ -522,7 +520,7 @@ STAmount& STAmount::operator-=(const STAmount& a)
|
||||
STAmount STAmount::operator-(void) const
|
||||
{
|
||||
if (mValue == 0) return *this;
|
||||
return STAmount(name, mCurrency, mValue, mOffset, mIsNative, !mIsNegative);
|
||||
return STAmount(name, mCurrency, mIssuer, mValue, mOffset, mIsNative, !mIsNegative);
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator=(uint64 v)
|
||||
@@ -620,9 +618,9 @@ STAmount operator+(const STAmount& v1, const STAmount& v2)
|
||||
|
||||
int64 fv = vv1 + vv2;
|
||||
if (fv >= 0)
|
||||
return STAmount(v1.name, v1.mCurrency, fv, ov1, false);
|
||||
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, fv, ov1, false);
|
||||
else
|
||||
return STAmount(v1.name, v1.mCurrency, -fv, ov1, true);
|
||||
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, -fv, ov1, true);
|
||||
}
|
||||
|
||||
STAmount operator-(const STAmount& v1, const STAmount& v2)
|
||||
@@ -652,9 +650,9 @@ STAmount operator-(const STAmount& v1, const STAmount& v2)
|
||||
|
||||
int64 fv = vv1 - vv2;
|
||||
if (fv >= 0)
|
||||
return STAmount(v1.name, v1.mCurrency, fv, ov1, false);
|
||||
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, fv, ov1, false);
|
||||
else
|
||||
return STAmount(v1.name, v1.mCurrency, -fv, ov1, true);
|
||||
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, -fv, ov1, true);
|
||||
}
|
||||
|
||||
STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
|
||||
@@ -36,7 +36,7 @@ DatabaseCon::~DatabaseCon()
|
||||
}
|
||||
|
||||
Application::Application() :
|
||||
mUNL(mIOService),
|
||||
mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService),
|
||||
mNetOps(mIOService, &mMasterLedger), mTempNodeCache(16384, 90), mHashedObjectStore(16384, 300),
|
||||
mSNTPClient(mAuxService), mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL),
|
||||
mHashNodeDB(NULL), mNetNodeDB(NULL),
|
||||
@@ -51,10 +51,10 @@ extern int RpcDBCount, TxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount
|
||||
|
||||
void Application::stop()
|
||||
{
|
||||
mAuxService.stop();
|
||||
mIOService.stop();
|
||||
mHashedObjectStore.bulkWrite();
|
||||
mValidations.flush();
|
||||
mAuxService.stop();
|
||||
|
||||
Log(lsINFO) << "Stopped: " << mIOService.stopped();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
class Application
|
||||
{
|
||||
boost::asio::io_service mIOService, mAuxService;
|
||||
boost::asio::io_service::work mIOWork, mAuxWork;
|
||||
|
||||
Wallet mWallet;
|
||||
UniqueNodeList mUNL;
|
||||
|
||||
@@ -112,7 +112,8 @@ Json::Value callRPC(const std::string& strMethod, const Json::Value& params)
|
||||
"If the file does not exist, create it with owner-readable-only file permissions.");
|
||||
|
||||
// Connect to localhost
|
||||
std::cout << "Connecting to port:" << theConfig.RPC_PORT << std::endl;
|
||||
std::cout << "Connecting to: " << theConfig.RPC_IP << ":" << theConfig.RPC_PORT << std::endl;
|
||||
|
||||
boost::asio::ip::tcp::endpoint
|
||||
endpoint(boost::asio::ip::address::from_string(theConfig.RPC_IP), theConfig.RPC_PORT);
|
||||
boost::asio::ip::tcp::iostream stream;
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "Conversion.h"
|
||||
#include "base58.h"
|
||||
using namespace std;
|
||||
|
||||
#if 0
|
||||
|
||||
uint160 protobufTo160(const std::string& buf)
|
||||
{
|
||||
uint160 ret;
|
||||
// TODO:
|
||||
return(ret);
|
||||
}
|
||||
|
||||
uint256 protobufTo256(const std::string& hash)
|
||||
{
|
||||
uint256 ret;
|
||||
// TODO:
|
||||
return(ret);
|
||||
}
|
||||
|
||||
uint160 humanTo160(const std::string& buf)
|
||||
{
|
||||
vector<unsigned char> retVec;
|
||||
DecodeBase58(buf,retVec);
|
||||
uint160 ret;
|
||||
memcpy(ret.begin(), &retVec[0], ret.GetSerializeSize());
|
||||
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
bool humanToPK(const std::string& buf,std::vector<unsigned char>& retVec)
|
||||
{
|
||||
return(DecodeBase58(buf,retVec));
|
||||
}
|
||||
|
||||
bool u160ToHuman(uint160& buf, std::string& retStr)
|
||||
{
|
||||
retStr=EncodeBase58(buf.begin(),buf.end());
|
||||
return(true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
base_uint256 uint160::to256() const
|
||||
{
|
||||
uint256 m;
|
||||
memcpy(m.begin(), begin(), size());
|
||||
return m;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "uint256.h"
|
||||
#include <string>
|
||||
|
||||
extern uint160 protobufTo160(const std::string& buf);
|
||||
extern uint256 protobufTo256(const std::string& hash);
|
||||
extern uint160 humanTo160(const std::string& buf);
|
||||
extern bool humanToPK(const std::string& buf,std::vector<unsigned char>& retVec);
|
||||
|
||||
|
||||
extern bool u160ToHuman(uint160& buf, std::string& retStr);
|
||||
|
||||
13
src/FieldNames.cpp
Normal file
13
src/FieldNames.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
#include "FieldNames.h"
|
||||
|
||||
#define FIELD(name, type, index) { sf##name, #name, STI_##type, index },
|
||||
#define TYPE(name, type, index)
|
||||
|
||||
FieldName FieldNames[]=
|
||||
{
|
||||
#include "SerializeProto.h"
|
||||
};
|
||||
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
16
src/FieldNames.h
Normal file
16
src/FieldNames.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __FIELDNAMES__
|
||||
#define __FIELDNAMES__
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
#include "SerializedObject.h"
|
||||
|
||||
struct FieldName
|
||||
{
|
||||
SOE_Field field;
|
||||
const char *fieldName;
|
||||
SerializedTypeID fieldType;
|
||||
int fieldValue;
|
||||
int fieldID;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "../obj/src/newcoin.pb.h"
|
||||
#include "PackedMessage.h"
|
||||
#include "Config.h"
|
||||
#include "Conversion.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "Wallet.h"
|
||||
#include "LedgerTiming.h"
|
||||
@@ -21,7 +20,7 @@
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount), mLedgerSeq(0),
|
||||
Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount), mLedgerSeq(1),
|
||||
mCloseTime(0), mParentCloseTime(0), mCloseResolution(LEDGER_TIME_ACCURACY), mCloseFlags(0),
|
||||
mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false),
|
||||
mTransactionMap(new SHAMap()), mAccountStateMap(new SHAMap())
|
||||
@@ -505,7 +504,6 @@ void Ledger::addJson(Json::Value& ret, int options)
|
||||
{
|
||||
SerializerIterator sit(item->peekSerializer());
|
||||
Serializer sTxn(sit.getVL());
|
||||
Serializer sMeta(sit.getVL());
|
||||
|
||||
SerializerIterator tsit(sTxn);
|
||||
SerializedTransaction txn(tsit);
|
||||
|
||||
@@ -358,6 +358,18 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger)
|
||||
SHAMap::pointer initialSet = initialLedger.peekTransactionMap()->snapShot(false);
|
||||
uint256 txSet = initialSet->getHash();
|
||||
Log(lsINFO) << "initial position " << txSet;
|
||||
mapComplete(txSet, initialSet, false);
|
||||
|
||||
if (mValidating)
|
||||
mOurPosition = boost::make_shared<LedgerProposal>
|
||||
(mValSeed, initialLedger.getParentHash(), txSet, mCloseTime);
|
||||
else
|
||||
mOurPosition = boost::make_shared<LedgerProposal>(initialLedger.getParentHash(), txSet, mCloseTime);
|
||||
|
||||
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
|
||||
{
|
||||
it.second->setOurVote(initialLedger.hasTransaction(it.first));
|
||||
}
|
||||
|
||||
// if any peers have taken a contrary position, process disputes
|
||||
boost::unordered_set<uint256> found;
|
||||
@@ -365,19 +377,13 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger)
|
||||
{
|
||||
uint256 set = it.second->getCurrentHash();
|
||||
if (found.insert(set).second)
|
||||
{ // OPTIMIZEME: Don't process the same set more than once
|
||||
{
|
||||
boost::unordered_map<uint256, SHAMap::pointer>::iterator iit = mAcquired.find(set);
|
||||
if (iit != mAcquired.end())
|
||||
createDisputes(initialSet, iit->second);
|
||||
}
|
||||
}
|
||||
|
||||
if (mValidating)
|
||||
mOurPosition = boost::make_shared<LedgerProposal>
|
||||
(mValSeed, initialLedger.getParentHash(), txSet, mCloseTime);
|
||||
else
|
||||
mOurPosition = boost::make_shared<LedgerProposal>(initialLedger.getParentHash(), txSet, mCloseTime);
|
||||
mapComplete(txSet, initialSet, false);
|
||||
if (mProposing)
|
||||
propose();
|
||||
}
|
||||
@@ -389,16 +395,17 @@ void LedgerConsensus::createDisputes(SHAMap::ref m1, SHAMap::ref m2)
|
||||
for (SHAMap::SHAMapDiff::iterator pos = differences.begin(), end = differences.end(); pos != end; ++pos)
|
||||
{ // create disputed transactions (from the ledger that has them)
|
||||
if (pos->second.first)
|
||||
{
|
||||
{ // transaction is in first map
|
||||
assert(!pos->second.second);
|
||||
addDisputedTransaction(pos->first, pos->second.first->peekData());
|
||||
}
|
||||
else if (pos->second.second)
|
||||
{
|
||||
{ // transaction is in second map
|
||||
assert(!pos->second.first);
|
||||
addDisputedTransaction(pos->first, pos->second.second->peekData());
|
||||
}
|
||||
else assert(false);
|
||||
else // No other disagreement over a transaction should be possible
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +424,10 @@ void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::ref map, bool acq
|
||||
assert(hash == map->getHash());
|
||||
|
||||
if (mAcquired.find(hash) != mAcquired.end())
|
||||
{
|
||||
mAcquiring.erase(hash);
|
||||
return; // we already have this map
|
||||
}
|
||||
|
||||
if (mOurPosition && (!mOurPosition->isBowOut()) && (hash != mOurPosition->getCurrentHash()))
|
||||
{ // this could create disputed transactions
|
||||
@@ -799,19 +809,20 @@ void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vec
|
||||
{
|
||||
Log(lsTRACE) << "Transaction " << txID << " is disputed";
|
||||
boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.find(txID);
|
||||
if (it != mDisputes.end()) return;
|
||||
if (it != mDisputes.end())
|
||||
return;
|
||||
|
||||
bool ourPosition = false;
|
||||
bool ourVote = false;
|
||||
if (mOurPosition)
|
||||
{
|
||||
boost::unordered_map<uint256, SHAMap::pointer>::iterator mit = mAcquired.find(mOurPosition->getCurrentHash());
|
||||
if (mit != mAcquired.end())
|
||||
ourPosition = mit->second->hasItem(txID);
|
||||
ourVote = mit->second->hasItem(txID);
|
||||
else
|
||||
assert(false); // We don't have our own position?
|
||||
}
|
||||
|
||||
LCTransaction::pointer txn = boost::make_shared<LCTransaction>(txID, tx, ourPosition);
|
||||
LCTransaction::pointer txn = boost::make_shared<LCTransaction>(txID, tx, ourVote);
|
||||
mDisputes[txID] = txn;
|
||||
|
||||
BOOST_FOREACH(u160_prop_pair& pit, mPeerPositions)
|
||||
@@ -821,6 +832,16 @@ void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vec
|
||||
if (cit != mAcquired.end() && cit->second)
|
||||
txn->setVote(pit.first, cit->second->hasItem(txID));
|
||||
}
|
||||
|
||||
if (!ourVote && theApp->isNew(txID))
|
||||
{
|
||||
newcoin::TMTransaction msg;
|
||||
msg.set_rawtransaction(&(tx.front()), tx.size());
|
||||
msg.set_status(newcoin::tsNEW);
|
||||
msg.set_receivetimestamp(theApp->getOPs().getNetworkTimeNC());
|
||||
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(msg, newcoin::mtTRANSACTION);
|
||||
theApp->getConnectionPool().relayMessage(NULL, packet);
|
||||
}
|
||||
}
|
||||
|
||||
bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
const uint256& getTransactionID() const { return mTransactionID; }
|
||||
bool getOurVote() const { return mOurVote; }
|
||||
Serializer& peekTransaction() { return transaction; }
|
||||
void setOurVote(bool o) { mOurVote = o; }
|
||||
|
||||
void setVote(const uint160& peer, bool votesYes);
|
||||
void unVote(const uint160& peer);
|
||||
|
||||
@@ -291,7 +291,7 @@ SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::ref ledger,
|
||||
|
||||
}
|
||||
|
||||
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::ref ledger,
|
||||
bool LedgerEntrySet::threadTx(const NewcoinAddress& threadTo, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{
|
||||
Log(lsTRACE) << "Thread to " << threadTo.getAccountID();
|
||||
@@ -301,32 +301,36 @@ bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, const NewcoinAddres
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
return threadTx(metaNode, sle, ledger, newMods);
|
||||
return threadTx(sle, ledger, newMods);
|
||||
}
|
||||
|
||||
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, SLE::ref threadTo, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
bool LedgerEntrySet::threadTx(SLE::ref threadTo, Ledger::ref ledger, boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{ // node = the node that was modified/deleted/created
|
||||
// threadTo = the node that needs to know
|
||||
uint256 prevTxID;
|
||||
uint32 prevLgrID;
|
||||
if (!threadTo->thread(mSet.getTxID(), mSet.getLgrSeq(), prevTxID, prevLgrID))
|
||||
return false;
|
||||
if (metaNode.thread(prevTxID, prevLgrID))
|
||||
if (mSet.getAffectedNode(threadTo->getIndex(), TMNModifiedNode, false).thread(prevTxID, prevLgrID))
|
||||
return true;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LedgerEntrySet::threadOwners(TransactionMetaNode& metaNode, SLE::ref node, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
bool LedgerEntrySet::threadOwners(SLE::ref node, Ledger::ref ledger, boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{ // thread new or modified node to owner or owners
|
||||
if (node->hasOneOwner()) // thread to owner's account
|
||||
return threadTx(metaNode, node->getOwner(), ledger, newMods);
|
||||
else if (node->hasTwoOwners()) // thread to owner's accounts
|
||||
{
|
||||
Log(lsTRACE) << "Thread to single owner";
|
||||
return threadTx(node->getOwner(), ledger, newMods);
|
||||
}
|
||||
else if (node->hasTwoOwners()) // thread to owner's accounts]
|
||||
{
|
||||
Log(lsTRACE) << "Thread to two owners";
|
||||
return
|
||||
threadTx(metaNode, node->getFirstOwner(), ledger, newMods) ||
|
||||
threadTx(metaNode, node->getSecondOwner(), ledger, newMods);
|
||||
threadTx(node->getFirstOwner(), ledger, newMods) &&
|
||||
threadTx(node->getSecondOwner(), ledger, newMods);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -345,14 +349,17 @@ void LedgerEntrySet::calcRawMeta(Serializer& s)
|
||||
switch (it->second.mAction)
|
||||
{
|
||||
case taaMODIFY:
|
||||
Log(lsTRACE) << "Modified Node " << it->first;
|
||||
nType = TMNModifiedNode;
|
||||
break;
|
||||
|
||||
case taaDELETE:
|
||||
Log(lsTRACE) << "Deleted Node " << it->first;
|
||||
nType = TMNDeletedNode;
|
||||
break;
|
||||
|
||||
case taaCREATE:
|
||||
Log(lsTRACE) << "Created Node " << it->first;
|
||||
nType = TMNCreatedNode;
|
||||
break;
|
||||
|
||||
@@ -369,12 +376,12 @@ void LedgerEntrySet::calcRawMeta(Serializer& s)
|
||||
continue;
|
||||
|
||||
SLE::pointer curNode = it->second.mEntry;
|
||||
TransactionMetaNode &metaNode = mSet.getAffectedNode(it->first, nType);
|
||||
TransactionMetaNode &metaNode = mSet.getAffectedNode(it->first, nType, true);
|
||||
|
||||
if (nType == TMNDeletedNode)
|
||||
{
|
||||
assert(origNode);
|
||||
threadOwners(metaNode, origNode, mLedger, newMod);
|
||||
threadOwners(origNode, mLedger, newMod);
|
||||
|
||||
if (origNode->getIFieldPresent(sfAmount))
|
||||
{ // node has an amount, covers ripple state nodes
|
||||
@@ -408,13 +415,16 @@ void LedgerEntrySet::calcRawMeta(Serializer& s)
|
||||
if (nType == TMNCreatedNode) // if created, thread to owner(s)
|
||||
{
|
||||
assert(!origNode);
|
||||
threadOwners(metaNode, curNode, mLedger, newMod);
|
||||
threadOwners(curNode, mLedger, newMod);
|
||||
}
|
||||
|
||||
if ((nType == TMNCreatedNode) || (nType == TMNModifiedNode))
|
||||
{
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
threadTx(metaNode, curNode, mLedger, newMod);
|
||||
{
|
||||
Log(lsTRACE) << "Thread to self";
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
}
|
||||
}
|
||||
|
||||
if (nType == TMNModifiedNode)
|
||||
@@ -934,21 +944,16 @@ STAmount LedgerEntrySet::accountHolds(const uint160& uAccountID, const uint160&
|
||||
SLE::pointer sleAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uAccountID));
|
||||
|
||||
saAmount = sleAccount->getIValueFieldAmount(sfBalance);
|
||||
|
||||
Log(lsINFO) << "accountHolds: stamps: " << saAmount.getText();
|
||||
}
|
||||
else
|
||||
{
|
||||
saAmount = rippleHolds(uAccountID, uCurrencyID, uIssuerID);
|
||||
|
||||
Log(lsINFO) << "accountHolds: "
|
||||
<< saAmount.getFullText()
|
||||
<< " : "
|
||||
<< STAmount::createHumanCurrency(uCurrencyID)
|
||||
<< "/"
|
||||
<< NewcoinAddress::createHumanAccountID(uIssuerID);
|
||||
}
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("accountHolds: uAccountID=%s saAmount=%s")
|
||||
% NewcoinAddress::createHumanAccountID(uAccountID)
|
||||
% saAmount.getFullText());
|
||||
|
||||
return saAmount;
|
||||
}
|
||||
|
||||
@@ -961,30 +966,22 @@ STAmount LedgerEntrySet::accountFunds(const uint160& uAccountID, const STAmount&
|
||||
{
|
||||
STAmount saFunds;
|
||||
|
||||
Log(lsINFO) << "accountFunds: uAccountID="
|
||||
<< NewcoinAddress::createHumanAccountID(uAccountID);
|
||||
Log(lsINFO) << "accountFunds: saDefault.isNative()=" << saDefault.isNative();
|
||||
Log(lsINFO) << "accountFunds: saDefault.getIssuer()="
|
||||
<< NewcoinAddress::createHumanAccountID(saDefault.getIssuer());
|
||||
|
||||
if (!saDefault.isNative() && saDefault.getIssuer() == uAccountID)
|
||||
{
|
||||
saFunds = saDefault;
|
||||
|
||||
Log(lsINFO) << "accountFunds: offer funds: ripple self-funded: " << saFunds.getText();
|
||||
Log(lsINFO) << boost::str(boost::format("accountFunds: uAccountID=%s saDefault=%s SELF-FUNDED")
|
||||
% NewcoinAddress::createHumanAccountID(uAccountID)
|
||||
% saDefault.getFullText());
|
||||
}
|
||||
else
|
||||
{
|
||||
saFunds = accountHolds(uAccountID, saDefault.getCurrency(), saDefault.getIssuer());
|
||||
|
||||
Log(lsINFO) << "accountFunds: offer funds: uAccountID ="
|
||||
<< NewcoinAddress::createHumanAccountID(uAccountID)
|
||||
<< " : "
|
||||
<< saFunds.getText()
|
||||
<< "/"
|
||||
<< saDefault.getHumanCurrency()
|
||||
<< "/"
|
||||
<< NewcoinAddress::createHumanAccountID(saDefault.getIssuer());
|
||||
Log(lsINFO) << boost::str(boost::format("accountFunds: uAccountID=%s saDefault=%s saFunds=%s")
|
||||
% NewcoinAddress::createHumanAccountID(uAccountID)
|
||||
% saDefault.getFullText()
|
||||
% saFunds.getFullText());
|
||||
}
|
||||
|
||||
return saFunds;
|
||||
|
||||
@@ -42,14 +42,12 @@ protected:
|
||||
SLE::pointer getForMod(const uint256& node, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
bool threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::ref ledger,
|
||||
bool threadTx(const NewcoinAddress& threadTo, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
bool threadTx(TransactionMetaNode& metaNode, SLE::ref threadTo, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
bool threadTx(SLE::ref threadTo, Ledger::ref ledger, boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
bool threadOwners(TransactionMetaNode& metaNode, SLE::ref node, Ledger::ref ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
bool threadOwners(SLE::ref node, Ledger::ref ledger, boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Domain), STI_VL, SOE_IFFLAG, 32 },
|
||||
{ S_FIELD(PublishHash), STI_HASH256, SOE_IFFLAG, 64 },
|
||||
{ S_FIELD(PublishSize), STI_UINT32, SOE_IFFLAG, 128 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Contract", ltCONTRACT, {
|
||||
@@ -37,7 +36,6 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(FundCode), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(RemoveCode), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(ExpireCode), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "DirectoryNode", ltDIR_NODE, {
|
||||
@@ -45,20 +43,17 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Indexes), STI_VECTOR256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(IndexNext), STI_UINT64, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(IndexPrevious), STI_UINT64, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "GeneratorMap", ltGENERATOR_MAP, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Nickname", ltNICKNAME, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Offer", ltOFFER, {
|
||||
@@ -73,7 +68,6 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "RippleState", ltRIPPLE_STATE, {
|
||||
@@ -89,7 +83,6 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(LowQualityOut), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(HighQualityIn), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(HighQualityOut), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ NULL, ltINVALID }
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "Application.h"
|
||||
#include "NewcoinAddress.h"
|
||||
#include "Conversion.h"
|
||||
#include "Log.h"
|
||||
|
||||
uint32 LedgerMaster::getCurrentLedgerIndex()
|
||||
|
||||
@@ -66,10 +66,15 @@ public:
|
||||
|
||||
Ledger::pointer getLedgerByHash(const uint256& hash)
|
||||
{
|
||||
if (!hash)
|
||||
return mCurrentLedger;
|
||||
|
||||
if (mCurrentLedger && (mCurrentLedger->getHash() == hash))
|
||||
return mCurrentLedger;
|
||||
|
||||
if (mFinalizedLedger && (mFinalizedLedger->getHash() == hash))
|
||||
return mFinalizedLedger;
|
||||
|
||||
return mLedgerHistory.getLedgerByHash(hash);
|
||||
}
|
||||
|
||||
|
||||
46
src/Log.cpp
46
src/Log.cpp
@@ -10,6 +10,8 @@ boost::recursive_mutex Log::sLock;
|
||||
LogSeverity Log::sMinSeverity = lsINFO;
|
||||
|
||||
std::ofstream* Log::outStream = NULL;
|
||||
boost::filesystem::path *Log::pathToLog = NULL;
|
||||
uint32 Log::logRotateCounter = 0;
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
@@ -31,6 +33,48 @@ Log::~Log()
|
||||
(*outStream) << logMsg << std::endl;
|
||||
}
|
||||
|
||||
|
||||
std::string Log::rotateLog(void)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(sLock);
|
||||
boost::filesystem::path abs_path;
|
||||
std::string abs_path_str;
|
||||
|
||||
uint32 failsafe = 0;
|
||||
|
||||
std::string abs_new_path_str;
|
||||
do {
|
||||
std::string s;
|
||||
std::stringstream out;
|
||||
|
||||
failsafe++;
|
||||
if (failsafe == std::numeric_limits<uint32>::max()) {
|
||||
return "unable to create new log file; too many log files!";
|
||||
}
|
||||
abs_path = boost::filesystem::absolute("");
|
||||
abs_path /= *pathToLog;
|
||||
abs_path_str = abs_path.parent_path().string();
|
||||
out << logRotateCounter;
|
||||
s = out.str();
|
||||
|
||||
|
||||
abs_new_path_str = abs_path_str + "/" + s + + "_" + pathToLog->filename().string();
|
||||
|
||||
logRotateCounter++;
|
||||
|
||||
} while (boost::filesystem::exists(boost::filesystem::path(abs_new_path_str)));
|
||||
|
||||
outStream->close();
|
||||
boost::filesystem::rename(abs_path, boost::filesystem::path(abs_new_path_str));
|
||||
|
||||
|
||||
|
||||
setLogFile(*pathToLog);
|
||||
|
||||
return abs_new_path_str;
|
||||
|
||||
}
|
||||
|
||||
void Log::setMinSeverity(LogSeverity s)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(sLock);
|
||||
@@ -52,4 +96,6 @@ void Log::setLogFile(boost::filesystem::path path)
|
||||
outStream = newStream;
|
||||
if (outStream)
|
||||
Log(lsINFO) << "Starting up";
|
||||
|
||||
pathToLog = new boost::filesystem::path(path);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
// Ensure that we don't get value.h without writer.h
|
||||
#include "../json/json.h"
|
||||
|
||||
#include "types.h"
|
||||
#include <limits>
|
||||
|
||||
enum LogSeverity
|
||||
{
|
||||
lsTRACE = 0,
|
||||
@@ -33,6 +36,9 @@ protected:
|
||||
mutable std::ostringstream oss;
|
||||
LogSeverity mSeverity;
|
||||
|
||||
static boost::filesystem::path *pathToLog;
|
||||
static uint32 logRotateCounter;
|
||||
|
||||
public:
|
||||
Log(LogSeverity s) : mSeverity(s)
|
||||
{ ; }
|
||||
@@ -51,6 +57,7 @@ public:
|
||||
|
||||
static void setMinSeverity(LogSeverity);
|
||||
static void setLogFile(boost::filesystem::path);
|
||||
static std::string rotateLog(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -67,6 +67,13 @@ void NetworkOPs::closeTimeOffset(int offset)
|
||||
Log(lsINFO) << "Close time offset now " << mCloseTimeOffset;
|
||||
}
|
||||
|
||||
uint32 NetworkOPs::getLedgerID(const uint256& hash)
|
||||
{
|
||||
Ledger::ref lrLedger = mLedgerMaster->getLedgerByHash(hash);
|
||||
|
||||
return lrLedger ? lrLedger->getLedgerSeq() : 0;
|
||||
}
|
||||
|
||||
uint32 NetworkOPs::getCurrentLedgerID()
|
||||
{
|
||||
return mLedgerMaster->getCurrentLedger()->getLedgerSeq();
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
uint32 getValidationTimeNC();
|
||||
void closeTimeOffset(int);
|
||||
boost::posix_time::ptime getNetworkTimePT();
|
||||
uint32 getLedgerID(const uint256& hash);
|
||||
uint32 getCurrentLedgerID();
|
||||
OperatingMode getOperatingMode() { return mMode; }
|
||||
inline bool available() {
|
||||
@@ -103,13 +104,14 @@ public:
|
||||
return mMode >= omTRACKING;
|
||||
}
|
||||
|
||||
Ledger::pointer getCurrentLedger() { return mLedgerMaster->getCurrentLedger(); }
|
||||
Ledger::pointer getLedgerByHash(const uint256& hash) { return mLedgerMaster->getLedgerByHash(hash); }
|
||||
Ledger::pointer getLedgerBySeq(const uint32 seq) { return mLedgerMaster->getLedgerBySeq(seq); }
|
||||
|
||||
uint256 getClosedLedger()
|
||||
{ return mLedgerMaster->getClosedLedger()->getHash(); }
|
||||
|
||||
// FIXME: This function is basically useless since the hash is constantly changing and the ledger
|
||||
// is ephemeral and mutable.
|
||||
uint256 getCurrentLedger()
|
||||
{ return mLedgerMaster->getCurrentLedger()->getHash(); }
|
||||
SLE::pointer getSLE(Ledger::pointer lpLedger, const uint256& uHash) { return lpLedger->getSLE(uHash); }
|
||||
|
||||
//
|
||||
// Transaction operations
|
||||
@@ -150,7 +152,6 @@ public:
|
||||
Json::Value getOwnerInfo(const uint256& uLedger, const NewcoinAddress& naAccount);
|
||||
Json::Value getOwnerInfo(Ledger::pointer lpLedger, const NewcoinAddress& naAccount);
|
||||
|
||||
|
||||
// raw object operations
|
||||
bool findRawLedger(const uint256& ledgerHash, std::vector<unsigned char>& rawLedger);
|
||||
bool findRawTransaction(const uint256& transactionHash, std::vector<unsigned char>& rawTransaction);
|
||||
|
||||
@@ -73,6 +73,9 @@ public:
|
||||
bool setAccountID(const std::string& strAccountID);
|
||||
void setAccountID(const uint160& hash160In);
|
||||
|
||||
static NewcoinAddress createAccountID(const std::string& strAccountID)
|
||||
{ NewcoinAddress na; na.setAccountID(strAccountID); return na; }
|
||||
|
||||
static NewcoinAddress createAccountID(const uint160& uiAccountID);
|
||||
|
||||
static std::string createHumanAccountID(const uint160& uiAccountID)
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "Peer.h"
|
||||
#include "Config.h"
|
||||
#include "Application.h"
|
||||
#include "Conversion.h"
|
||||
#include "SerializedTransaction.h"
|
||||
#include "utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "Application.h"
|
||||
#include "RPC.h"
|
||||
#include "Wallet.h"
|
||||
#include "Conversion.h"
|
||||
#include "NewcoinAddress.h"
|
||||
#include "AccountState.h"
|
||||
#include "NicknameState.h"
|
||||
@@ -14,6 +13,8 @@
|
||||
#include "Log.h"
|
||||
#include "RippleLines.h"
|
||||
|
||||
#include "Pathfinder.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
@@ -422,7 +423,6 @@ Json::Value RPCServer::doAccountDomainSet(const Json::Value ¶ms)
|
||||
{
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -438,7 +438,7 @@ Json::Value RPCServer::doAccountDomainSet(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naVerifyGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -476,7 +476,6 @@ Json::Value RPCServer::doAccountEmailSet(const Json::Value ¶ms)
|
||||
{
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -492,7 +491,7 @@ Json::Value RPCServer::doAccountEmailSet(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naVerifyGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -569,12 +568,11 @@ Json::Value RPCServer::doAccountInfo(const Json::Value ¶ms)
|
||||
|
||||
ret["accepted"] = jAccepted;
|
||||
|
||||
uint256 uCurrent = mNetOps->getCurrentLedger();
|
||||
Json::Value jCurrent = accountFromString(uCurrent, naAccount, bIndex, strIdent, iIndex);
|
||||
Json::Value jCurrent = accountFromString(uint256(0), naAccount, bIndex, strIdent, iIndex);
|
||||
|
||||
if (jCurrent.empty())
|
||||
{
|
||||
AccountState::pointer asCurrent = mNetOps->getAccountState(uCurrent, naAccount);
|
||||
AccountState::pointer asCurrent = mNetOps->getAccountState(uint256(0), naAccount);
|
||||
|
||||
if (asCurrent)
|
||||
asCurrent->addJson(jCurrent);
|
||||
@@ -598,7 +596,6 @@ Json::Value RPCServer::doAccountInfo(const Json::Value ¶ms)
|
||||
Json::Value RPCServer::doAccountMessageSet(const Json::Value& params) {
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
NewcoinAddress naMessagePubKey;
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
@@ -619,7 +616,7 @@ Json::Value RPCServer::doAccountMessageSet(const Json::Value& params) {
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naVerifyGenerator);
|
||||
std::vector<unsigned char> vucDomain;
|
||||
|
||||
@@ -659,7 +656,6 @@ Json::Value RPCServer::doAccountPublishSet(const Json::Value ¶ms)
|
||||
{
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -675,7 +671,7 @@ Json::Value RPCServer::doAccountPublishSet(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naVerifyGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -717,7 +713,6 @@ Json::Value RPCServer::doAccountRateSet(const Json::Value ¶ms)
|
||||
{
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -733,7 +728,7 @@ Json::Value RPCServer::doAccountRateSet(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naVerifyGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -773,7 +768,6 @@ Json::Value RPCServer::doAccountRateSet(const Json::Value ¶ms)
|
||||
Json::Value RPCServer::doAccountWalletSet(const Json::Value& params) {
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -789,7 +783,7 @@ Json::Value RPCServer::doAccountWalletSet(const Json::Value& params) {
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
std::vector<unsigned char> vucDomain;
|
||||
|
||||
@@ -921,8 +915,6 @@ Json::Value RPCServer::doDataStore(const Json::Value& params)
|
||||
// Note: Nicknames are not automatically looked up by commands as they are advisory and can be changed.
|
||||
Json::Value RPCServer::doNicknameInfo(const Json::Value& params)
|
||||
{
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
std::string strNickname = params[0u].asString();
|
||||
boost::trim(strNickname);
|
||||
|
||||
@@ -931,7 +923,7 @@ Json::Value RPCServer::doNicknameInfo(const Json::Value& params)
|
||||
return RPCError(rpcNICKNAME_MALFORMED);
|
||||
}
|
||||
|
||||
NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname);
|
||||
NicknameState::pointer nsSrc = mNetOps->getNicknameState(uint256(0), strNickname);
|
||||
if (!nsSrc)
|
||||
{
|
||||
return RPCError(rpcNICKNAME_MISSING);
|
||||
@@ -951,7 +943,6 @@ Json::Value RPCServer::doNicknameSet(const Json::Value& params)
|
||||
{
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -979,7 +970,7 @@ Json::Value RPCServer::doNicknameSet(const Json::Value& params)
|
||||
}
|
||||
|
||||
STAmount saFee;
|
||||
NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname);
|
||||
NicknameState::pointer nsSrc = mNetOps->getNicknameState(uint256(0), strNickname);
|
||||
|
||||
if (!nsSrc)
|
||||
{
|
||||
@@ -1002,7 +993,7 @@ Json::Value RPCServer::doNicknameSet(const Json::Value& params)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, saFee, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -1068,7 +1059,7 @@ Json::Value RPCServer::doOfferCreate(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(mNetOps->getCurrentLedger(), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -1114,7 +1105,7 @@ Json::Value RPCServer::doOfferCancel(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(mNetOps->getCurrentLedger(), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -1154,10 +1145,9 @@ Json::Value RPCServer::doOwnerInfo(const Json::Value& params)
|
||||
|
||||
ret["accepted"] = jAccepted.empty() ? mNetOps->getOwnerInfo(uAccepted, naAccount) : jAccepted;
|
||||
|
||||
uint256 uCurrent = mNetOps->getCurrentLedger();
|
||||
Json::Value jCurrent = accountFromString(uCurrent, naAccount, bIndex, strIdent, iIndex);
|
||||
Json::Value jCurrent = accountFromString(uint256(0), naAccount, bIndex, strIdent, iIndex);
|
||||
|
||||
ret["current"] = jCurrent.empty() ? mNetOps->getOwnerInfo(uCurrent, naAccount) : jCurrent;
|
||||
ret["current"] = jCurrent.empty() ? mNetOps->getOwnerInfo(uint256(0), naAccount) : jCurrent;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1168,7 +1158,6 @@ Json::Value RPCServer::doPasswordFund(const Json::Value ¶ms)
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naDstAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -1188,7 +1177,7 @@ Json::Value RPCServer::doPasswordFund(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -1462,7 +1451,7 @@ Json::Value RPCServer::doRipple(const Json::Value ¶ms)
|
||||
bLimit = params.size() != iArg ? params[iArg].asString() == "limit" : false;
|
||||
bAverage = params.size() != iArg ? params[iArg].asString() == "average" : false;
|
||||
|
||||
if (!bPartial && !bFull)
|
||||
if (!bLimit && !bAverage)
|
||||
{
|
||||
return RPCError(rpcINVALID_PARAMS);
|
||||
}
|
||||
@@ -1494,8 +1483,7 @@ Json::Value RPCServer::doRipple(const Json::Value ¶ms)
|
||||
return RPCError(rpcDST_AMT_MALFORMED);
|
||||
}
|
||||
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
AccountState::pointer asDst = mNetOps->getAccountState(uLedger, naDstAccountID);
|
||||
AccountState::pointer asDst = mNetOps->getAccountState(uint256(0), naDstAccountID);
|
||||
STAmount saFee = theConfig.FEE_DEFAULT;
|
||||
|
||||
NewcoinAddress naVerifyGenerator;
|
||||
@@ -1503,7 +1491,7 @@ Json::Value RPCServer::doRipple(const Json::Value ¶ms)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, saFee, asSrc, naVerifyGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -1556,7 +1544,6 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naDstAccountID;
|
||||
STAmount saLimitAmount;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
bool bLimitAmount = true;
|
||||
bool bQualityIn = params.size() >= 6;
|
||||
bool bQualityOut = params.size() >= 7;
|
||||
@@ -1594,7 +1581,7 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -1627,7 +1614,6 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
|
||||
Json::Value RPCServer::doRippleLinesGet(const Json::Value ¶ms)
|
||||
{
|
||||
// uint256 uAccepted = mNetOps->getClosedLedger();
|
||||
uint256 uCurrent = mNetOps->getCurrentLedger();
|
||||
|
||||
std::string strIdent = params[0u].asString();
|
||||
bool bIndex;
|
||||
@@ -1637,7 +1623,7 @@ Json::Value RPCServer::doRippleLinesGet(const Json::Value ¶ms)
|
||||
|
||||
Json::Value ret;
|
||||
|
||||
ret = accountFromString(uCurrent, naAccount, bIndex, strIdent, iIndex);
|
||||
ret = accountFromString(uint256(0), naAccount, bIndex, strIdent, iIndex);
|
||||
|
||||
if (!ret.empty())
|
||||
return ret;
|
||||
@@ -1649,7 +1635,7 @@ Json::Value RPCServer::doRippleLinesGet(const Json::Value ¶ms)
|
||||
if (bIndex)
|
||||
ret["index"] = iIndex;
|
||||
|
||||
AccountState::pointer as = mNetOps->getAccountState(uCurrent, naAccount);
|
||||
AccountState::pointer as = mNetOps->getAccountState(uint256(0), naAccount);
|
||||
if (as)
|
||||
{
|
||||
Json::Value jsonLines(Json::arrayValue);
|
||||
@@ -1739,8 +1725,7 @@ Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
AccountState::pointer asDst = mNetOps->getAccountState(uLedger, naDstAccountID);
|
||||
AccountState::pointer asDst = mNetOps->getAccountState(uint256(0), naDstAccountID);
|
||||
bool bCreate = !asDst;
|
||||
STAmount saFee = bCreate ? theConfig.FEE_ACCOUNT_CREATE : theConfig.FEE_DEFAULT;
|
||||
|
||||
@@ -1749,7 +1734,7 @@ Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, saFee, asSrc, naVerifyGenerator);
|
||||
|
||||
// Log(lsINFO) << boost::str(boost::format("doSend: sSrcIssuer=%s sDstIssuer=%s saSrcAmountMax=%s saDstAmount=%s")
|
||||
@@ -1794,7 +1779,17 @@ Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
// Destination exists, ordinary send.
|
||||
|
||||
STPathSet spsPaths;
|
||||
/*
|
||||
uint160 srcCurrencyID;
|
||||
bool ret_b;
|
||||
ret_b = false;
|
||||
STAmount::currencyFromString(srcCurrencyID, sSrcCurrency);
|
||||
|
||||
Pathfinder pf(naSrcAccountID, naDstAccountID, srcCurrencyID, saDstAmount);
|
||||
|
||||
ret_b = pf.findPaths(5, 1, spsPaths);
|
||||
// TODO: Nope; the above can't be right
|
||||
*/
|
||||
trans = Transaction::sharedPayment(
|
||||
naAccountPublic, naAccountPrivate,
|
||||
naSrcAccountID,
|
||||
@@ -2081,7 +2076,6 @@ Json::Value RPCServer::accounts(const uint256& uLedger, const NewcoinAddress& na
|
||||
Json::Value RPCServer::doWalletAccounts(const Json::Value& params)
|
||||
{
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -2091,17 +2085,17 @@ Json::Value RPCServer::doWalletAccounts(const Json::Value& params)
|
||||
// Try the seed as a master seed.
|
||||
NewcoinAddress naMasterGenerator = NewcoinAddress::createGeneratorPublic(naSeed);
|
||||
|
||||
Json::Value jsonAccounts = accounts(uLedger, naMasterGenerator);
|
||||
Json::Value jsonAccounts = accounts(uint256(0), naMasterGenerator);
|
||||
|
||||
if (jsonAccounts.empty())
|
||||
{
|
||||
// No account via seed as master, try seed a regular.
|
||||
Json::Value ret = getMasterGenerator(uLedger, naSeed, naMasterGenerator);
|
||||
Json::Value ret = getMasterGenerator(uint256(0), naSeed, naMasterGenerator);
|
||||
|
||||
if (!ret.empty())
|
||||
return ret;
|
||||
|
||||
ret["accounts"] = accounts(uLedger, naMasterGenerator);
|
||||
ret["accounts"] = accounts(uint256(0), naMasterGenerator);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2124,7 +2118,6 @@ Json::Value RPCServer::doWalletAdd(const Json::Value& params)
|
||||
NewcoinAddress naSrcAccountID;
|
||||
STAmount saAmount;
|
||||
std::string sDstCurrency;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naRegularSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -2151,7 +2144,7 @@ Json::Value RPCServer::doWalletAdd(const Json::Value& params)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naRegularSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naRegularSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_ACCOUNT_CREATE, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -2177,7 +2170,7 @@ Json::Value RPCServer::doWalletAdd(const Json::Value& params)
|
||||
++iIndex;
|
||||
naNewAccountPublic.setAccountPublic(naMasterGenerator, iIndex);
|
||||
|
||||
asNew = mNetOps->getAccountState(uLedger, naNewAccountPublic);
|
||||
asNew = mNetOps->getAccountState(uint256(0), naNewAccountPublic);
|
||||
if (!asNew)
|
||||
bAgain = false;
|
||||
} while (bAgain);
|
||||
@@ -2312,7 +2305,6 @@ Json::Value RPCServer::doWalletCreate(const Json::Value& params)
|
||||
NewcoinAddress naSrcAccountID;
|
||||
NewcoinAddress naDstAccountID;
|
||||
NewcoinAddress naSeed;
|
||||
uint256 uLedger = mNetOps->getCurrentLedger();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
@@ -2326,7 +2318,7 @@ Json::Value RPCServer::doWalletCreate(const Json::Value& params)
|
||||
{
|
||||
return RPCError(rpcDST_ACT_MALFORMED);
|
||||
}
|
||||
else if (mNetOps->getAccountState(uLedger, naDstAccountID))
|
||||
else if (mNetOps->getAccountState(uint256(0), naDstAccountID))
|
||||
{
|
||||
return RPCError(rpcACT_EXISTS);
|
||||
}
|
||||
@@ -2339,7 +2331,7 @@ Json::Value RPCServer::doWalletCreate(const Json::Value& params)
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
Json::Value obj = authorize(uint256(0), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_ACCOUNT_CREATE, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
@@ -2518,6 +2510,11 @@ Json::Value RPCServer::doLogin(const Json::Value& params)
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doLogRotate(const Json::Value& params)
|
||||
{
|
||||
return Log::rotateLog();
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params)
|
||||
{
|
||||
Log(lsTRACE) << "RPC:" << command;
|
||||
@@ -2543,6 +2540,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{ "data_fetch", &RPCServer::doDataFetch, 1, 1, true },
|
||||
{ "data_store", &RPCServer::doDataStore, 2, 2, true },
|
||||
{ "ledger", &RPCServer::doLedger, 0, 2, false, optNetwork },
|
||||
{ "logrotate", &RPCServer::doLogRotate, 0, 0, false, optCurrent },
|
||||
{ "nickname_info", &RPCServer::doNicknameInfo, 1, 1, false, optCurrent },
|
||||
{ "nickname_set", &RPCServer::doNicknameSet, 2, 3, false, optCurrent },
|
||||
{ "offer_create", &RPCServer::doOfferCreate, 9, 10, false, optCurrent },
|
||||
@@ -2602,7 +2600,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{
|
||||
return RPCError(rpcNO_NETWORK);
|
||||
}
|
||||
else if ((commandsA[i].iOptions & optCurrent) && mNetOps->getCurrentLedger().isZero())
|
||||
// XXX Should verify we have a current ledger.
|
||||
else if ((commandsA[i].iOptions & optCurrent) && false)
|
||||
{
|
||||
return RPCError(rpcNO_CURRENT);
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ private:
|
||||
Json::Value doDataFetch(const Json::Value& params);
|
||||
Json::Value doDataStore(const Json::Value& params);
|
||||
Json::Value doLedger(const Json::Value& params);
|
||||
Json::Value doLogRotate(const Json::Value& params);
|
||||
Json::Value doNicknameInfo(const Json::Value& params);
|
||||
Json::Value doNicknameSet(const Json::Value& params);
|
||||
Json::Value doOfferCreate(const Json::Value& params);
|
||||
@@ -184,6 +185,7 @@ private:
|
||||
|
||||
Json::Value doLogin(const Json::Value& params);
|
||||
|
||||
|
||||
public:
|
||||
static pointer create(boost::asio::io_service& io_service, NetworkOPs* mNetOps)
|
||||
{
|
||||
|
||||
@@ -46,8 +46,6 @@ static uint8_t SNTPQueryData[48] =
|
||||
|
||||
SNTPClient::SNTPClient(boost::asio::io_service& service) : mSocket(service), mTimer(service), mResolver(service),
|
||||
mOffset(0), mLastOffsetUpdate((time_t) -1), mReceiveBuffer(256)
|
||||
{
|
||||
if (!theConfig.RUN_STANDALONE)
|
||||
{
|
||||
mSocket.open(boost::asio::ip::udp::v4());
|
||||
mSocket.async_receive_from(boost::asio::buffer(mReceiveBuffer, 256), mReceiveEndpoint,
|
||||
@@ -57,7 +55,6 @@ SNTPClient::SNTPClient(boost::asio::io_service& service) : mSocket(service), mTi
|
||||
mTimer.expires_from_now(boost::posix_time::seconds(NTP_QUERY_FREQUENCY));
|
||||
mTimer.async_wait(boost::bind(&SNTPClient::timerEntry, this, boost::asio::placeholders::error));
|
||||
}
|
||||
}
|
||||
|
||||
void SNTPClient::resolveComplete(const boost::system::error_code& error, boost::asio::ip::udp::resolver::iterator it)
|
||||
{
|
||||
|
||||
127
src/SerializeProto.h
Normal file
127
src/SerializeProto.h
Normal file
@@ -0,0 +1,127 @@
|
||||
// This is not really a header file, but it can be used as one with
|
||||
// appropriate #define statements.
|
||||
|
||||
// types (common)
|
||||
TYPE("Int32", UINT32, 1)
|
||||
TYPE("Int64", UINT64, 2)
|
||||
TYPE("Hash128", HASH128, 3)
|
||||
TYPE("Hash256", HASH256, 4)
|
||||
// 5 is reserved
|
||||
TYPE("Amount", AMOUNT, 6)
|
||||
TYPE("VariableLength", VL, 7)
|
||||
TYPE("Account", ACCOUNT, 8)
|
||||
// 9-13 are reserved
|
||||
TYPE("Object", OBJECT, 14)
|
||||
TYPE("Array", ARRAY, 15)
|
||||
|
||||
// types (uncommon)
|
||||
TYPE("Int8", UINT8, 16)
|
||||
TYPE("Int16", UINT16, 17)
|
||||
TYPE("Hash160", HASH160, 18)
|
||||
TYPE("PathSet", PATHSET, 19)
|
||||
TYPE("Vector256", VECTOR256, 20)
|
||||
|
||||
|
||||
|
||||
// 8-bit integers
|
||||
FIELD(CloseResolution, UINT8, 1)
|
||||
|
||||
// 32-bit integers (common)
|
||||
FIELD(Flags, UINT32, 1)
|
||||
FIELD(SourceTag, UINT32, 2)
|
||||
FIELD(Sequence, UINT32, 3)
|
||||
FIELD(LastTxnSeq, UINT32, 4)
|
||||
FIELD(LedgerSequence, UINT32, 5)
|
||||
FIELD(CloseTime, UINT32, 6)
|
||||
FIELD(ParentCloseTime, UINT32, 7)
|
||||
FIELD(SigningTime, UINT32, 8)
|
||||
FIELD(Expiration, UINT32, 9)
|
||||
FIELD(TransferRate, UINT32, 10)
|
||||
FIELD(PublishSize, UINT32, 11)
|
||||
|
||||
// 32-bit integers (uncommon)
|
||||
FIELD(HighQualityIn, UINT32, 16)
|
||||
FIELD(HighQualityOut, UINT32, 17)
|
||||
FIELD(LowQualityIn, UINT32, 18)
|
||||
FIELD(LowQualityOut, UINT32, 19)
|
||||
FIELD(QualityIn, UINT32, 20)
|
||||
FIELD(QualityOut, UINT32, 21)
|
||||
FIELD(StampEscrow, UINT32, 22)
|
||||
FIELD(BondAmount, UINT32, 23)
|
||||
FIELD(LoadFee, UINT32, 24)
|
||||
FIELD(OfferSequence, UINT32, 25)
|
||||
|
||||
// 64-bit integers
|
||||
FIELD(IndexNext, UINT64, 1)
|
||||
FIELD(IndexPrevious, UINT64, 2)
|
||||
FIELD(BookNode, UINT64, 3)
|
||||
FIELD(OwnerNode, UINT64, 4)
|
||||
FIELD(BaseFee, UINT64, 5)
|
||||
|
||||
// 128-bit
|
||||
FIELD(EmailHash, HASH128, 2)
|
||||
|
||||
// 256-bit (common)
|
||||
FIELD(LedgerHash, HASH256, 1)
|
||||
FIELD(ParentHash, HASH256, 2)
|
||||
FIELD(TransactionHash, HASH256, 3)
|
||||
FIELD(AccountHash, HASH256, 4)
|
||||
FIELD(LastTxnID, HASH256, 5)
|
||||
FIELD(WalletLocator, HASH256, 6)
|
||||
FIELD(PublishHash, HASH256, 7)
|
||||
|
||||
// 256-bit (uncommon)
|
||||
FIELD(BookDirectory, HASH256, 16)
|
||||
FIELD(InvoiceID, HASH256, 17)
|
||||
FIELD(Nickname, HASH256, 18)
|
||||
|
||||
// currency amount (common)
|
||||
FIELD(Amount, AMOUNT, 1)
|
||||
FIELD(Balance, AMOUNT, 2)
|
||||
FIELD(LimitAmount, AMOUNT, 3)
|
||||
FIELD(TakerPays, AMOUNT, 4)
|
||||
FIELD(TakerGets, AMOUNT, 5)
|
||||
FIELD(LowLimit, AMOUNT, 6)
|
||||
FIELD(HighLimit, AMOUNT, 7)
|
||||
FIELD(SendMax, AMOUNT, 9)
|
||||
|
||||
// current amount (uncommon)
|
||||
FIELD(MinimumOffer, AMOUNT, 16)
|
||||
FIELD(RippleEscrow, AMOUNT, 17)
|
||||
|
||||
// variable length
|
||||
FIELD(PublicKey, VL, 1)
|
||||
FIELD(MessageKey, VL, 2)
|
||||
FIELD(SigningKey, VL, 3)
|
||||
FIELD(Signature, VL, 4)
|
||||
FIELD(Generator, VL, 5)
|
||||
FIELD(Domain, VL, 6)
|
||||
FIELD(FundCode, VL, 7)
|
||||
FIELD(RemoveCode, VL, 8)
|
||||
FIELD(ExpireCode, VL, 9)
|
||||
FIELD(CreateCode, VL, 10)
|
||||
|
||||
// account
|
||||
FIELD(Account, ACCOUNT, 1)
|
||||
FIELD(Owner, ACCOUNT, 2)
|
||||
FIELD(Destination, ACCOUNT, 3)
|
||||
FIELD(Issuer, ACCOUNT, 4)
|
||||
FIELD(HighID, ACCOUNT, 5)
|
||||
FIELD(LowID, ACCOUNT, 6)
|
||||
FIELD(Target, ACCOUNT, 7)
|
||||
FIELD(AuthorizedKey, ACCOUNT, 8)
|
||||
|
||||
// path set
|
||||
FIELD(Paths, PATHSET, 1)
|
||||
|
||||
// vector of 256-bit
|
||||
FIELD(Indexes, VECTOR256, 1)
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
FIELD(MiddleTransaction, OBJECT, 2)
|
||||
FIELD(InnerTransaction, OBJECT, 3)
|
||||
|
||||
// array of objects
|
||||
// ARRAY/1 is reserved for end of array
|
||||
FIELD(SigningAccounts, ARRAY, 2)
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "Ledger.h"
|
||||
#include "Log.h"
|
||||
|
||||
SerializedLedgerEntry::SerializedLedgerEntry(SerializerIterator& sit, const uint256& index)
|
||||
: SerializedType("LedgerEntry"), mIndex(index)
|
||||
@@ -99,6 +100,7 @@ uint32 SerializedLedgerEntry::getThreadedLedger()
|
||||
bool SerializedLedgerEntry::thread(const uint256& txID, uint32 ledgerSeq, uint256& prevTxID, uint32& prevLedgerID)
|
||||
{
|
||||
uint256 oldPrevTxID = getIFieldH256(sfLastTxnID);
|
||||
Log(lsTRACE) << "Thread Tx:" << txID << " prev:" << oldPrevTxID;
|
||||
if (oldPrevTxID == txID)
|
||||
return false;
|
||||
prevTxID = oldPrevTxID;
|
||||
|
||||
@@ -42,9 +42,6 @@ std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, c
|
||||
case STI_VL:
|
||||
return std::auto_ptr<SerializedType>(new STVariableLength(name));
|
||||
|
||||
case STI_TL:
|
||||
return std::auto_ptr<SerializedType>(new STTaggedList(name));
|
||||
|
||||
case STI_ACCOUNT:
|
||||
return std::auto_ptr<SerializedType>(new STAccount(name));
|
||||
|
||||
@@ -91,9 +88,6 @@ std::auto_ptr<SerializedType> STObject::makeDeserializedObject(SerializedTypeID
|
||||
case STI_VL:
|
||||
return STVariableLength::deserialize(sit, name);
|
||||
|
||||
case STI_TL:
|
||||
return STTaggedList::deserialize(sit, name);
|
||||
|
||||
case STI_ACCOUNT:
|
||||
return STAccount::deserialize(sit, name);
|
||||
|
||||
@@ -476,17 +470,6 @@ std::vector<unsigned char> STObject::getValueFieldVL(SOE_Field field) const
|
||||
return cf->getValue();
|
||||
}
|
||||
|
||||
std::vector<TaggedListItem> STObject::getValueFieldTL(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf = peekAtPField(field);
|
||||
if (!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id = rf->getSType();
|
||||
if (id == STI_NOTPRESENT) return std::vector<TaggedListItem>(); // optional field not present
|
||||
const STTaggedList *cf = dynamic_cast<const STTaggedList *>(rf);
|
||||
if (!cf) throw std::runtime_error("Wrong field type");
|
||||
return cf->getValue();
|
||||
}
|
||||
|
||||
STAmount STObject::getValueFieldAmount(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf = peekAtPField(field);
|
||||
@@ -620,16 +603,6 @@ void STObject::setValueFieldVL(SOE_Field field, const std::vector<unsigned char>
|
||||
cf->setValue(v);
|
||||
}
|
||||
|
||||
void STObject::setValueFieldTL(SOE_Field field, const std::vector<TaggedListItem>& v)
|
||||
{
|
||||
SerializedType* rf = getPField(field);
|
||||
if (!rf) throw std::runtime_error("Field not found");
|
||||
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
|
||||
STTaggedList* cf = dynamic_cast<STTaggedList*>(rf);
|
||||
if (!cf) throw std::runtime_error("Wrong field type");
|
||||
cf->setValue(v);
|
||||
}
|
||||
|
||||
void STObject::setValueFieldAmount(SOE_Field field, const STAmount &v)
|
||||
{
|
||||
SerializedType* rf = getPField(field);
|
||||
|
||||
@@ -18,97 +18,16 @@ enum SOE_Type
|
||||
SOE_IFNFLAG = 3 // present if flag not set
|
||||
};
|
||||
|
||||
// JED: seems like there would be a better way to do this
|
||||
// maybe something that inherits from SerializedTransaction
|
||||
enum SOE_Field
|
||||
{
|
||||
sfInvalid = -1,
|
||||
sfGeneric = 0,
|
||||
|
||||
// common fields
|
||||
sfAcceptExpire,
|
||||
sfAcceptRate,
|
||||
sfAcceptStart,
|
||||
sfAccount,
|
||||
sfAmount,
|
||||
sfAuthorizedKey,
|
||||
sfBalance,
|
||||
sfBondAmount,
|
||||
sfBookDirectory,
|
||||
sfBookNode,
|
||||
sfBorrowExpire,
|
||||
sfBorrowRate,
|
||||
sfBorrowStart,
|
||||
sfBorrower,
|
||||
sfCreateCode,
|
||||
sfCloseTime,
|
||||
sfCurrency,
|
||||
sfCurrencyIn,
|
||||
sfCurrencyOut,
|
||||
sfDestination,
|
||||
sfDomain,
|
||||
sfEmailHash,
|
||||
sfExpiration,
|
||||
sfExpireCode,
|
||||
sfExtensions,
|
||||
sfFirstNode,
|
||||
sfFlags,
|
||||
sfFundCode,
|
||||
sfGenerator,
|
||||
sfGeneratorID,
|
||||
sfHash,
|
||||
sfHighID,
|
||||
sfHighLimit,
|
||||
sfHighQualityIn,
|
||||
sfHighQualityOut,
|
||||
sfIdentifier,
|
||||
sfIndexes,
|
||||
sfIndexNext,
|
||||
sfIndexPrevious,
|
||||
sfInvoiceID,
|
||||
sfIssuer,
|
||||
sfLastNode,
|
||||
sfLastTxnID,
|
||||
sfLastTxnSeq,
|
||||
sfLedgerHash,
|
||||
sfLimitAmount,
|
||||
sfLowID,
|
||||
sfLowLimit,
|
||||
sfLowQualityIn,
|
||||
sfLowQualityOut,
|
||||
sfMessageKey,
|
||||
sfMinimumOffer,
|
||||
sfNextAcceptExpire,
|
||||
sfNextAcceptRate,
|
||||
sfNextAcceptStart,
|
||||
sfNextTransitExpire,
|
||||
sfNextTransitRate,
|
||||
sfNextTransitStart,
|
||||
sfNickname,
|
||||
sfOfferSequence,
|
||||
sfOwner,
|
||||
sfOwnerNode,
|
||||
sfPaths,
|
||||
sfPubKey,
|
||||
sfPublishHash,
|
||||
sfPublishSize,
|
||||
sfQualityIn,
|
||||
sfQualityOut,
|
||||
sfRemoveCode,
|
||||
sfRippleEscrow,
|
||||
sfSendMax,
|
||||
sfSequence,
|
||||
sfSignature,
|
||||
sfSigningKey,
|
||||
sfSigningTime,
|
||||
sfSourceTag,
|
||||
sfStampEscrow,
|
||||
sfTakerGets,
|
||||
sfTakerPays,
|
||||
sfTarget,
|
||||
sfTransferRate,
|
||||
sfVersion,
|
||||
sfWalletLocator,
|
||||
#define FIELD(name, type, index) sf##name,
|
||||
#define TYPE(name, type, index)
|
||||
#include "SerializeProto.h"
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
|
||||
// test fields
|
||||
sfTest1, sfTest2, sfTest3, sfTest4
|
||||
|
||||
@@ -255,51 +255,6 @@ void STAccount::setValueNCA(const NewcoinAddress& nca)
|
||||
setValueH160(nca.getAccountID());
|
||||
}
|
||||
|
||||
std::string STTaggedList::getText() const
|
||||
{
|
||||
std::string ret;
|
||||
for (std::vector<TaggedListItem>::const_iterator it=value.begin(); it!=value.end(); ++it)
|
||||
{
|
||||
ret += boost::lexical_cast<std::string>(it->first);
|
||||
ret += ",";
|
||||
ret += strHex(it->second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value STTaggedList::getJson(int) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
for (std::vector<TaggedListItem>::const_iterator it=value.begin(); it!=value.end(); ++it)
|
||||
{
|
||||
Json::Value elem(Json::arrayValue);
|
||||
elem.append(it->first);
|
||||
elem.append(strHex(it->second));
|
||||
ret.append(elem);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
STTaggedList* STTaggedList::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STTaggedList(name, u.getTaggedList());
|
||||
}
|
||||
|
||||
int STTaggedList::getLength() const
|
||||
{
|
||||
int ret = Serializer::getTaggedListLength(value);
|
||||
if (ret<0) throw std::overflow_error("bad TL length");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool STTaggedList::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STTaggedList* v = dynamic_cast<const STTaggedList*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STPathSet* STPathSet::construct(SerializerIterator& s, const char *name)
|
||||
{
|
||||
std::vector<STPath> paths;
|
||||
|
||||
@@ -15,25 +15,15 @@ enum SerializedTypeID
|
||||
STI_DONE = -1,
|
||||
STI_NOTPRESENT = 0,
|
||||
|
||||
// standard types
|
||||
STI_OBJECT = 1,
|
||||
STI_UINT8 = 2,
|
||||
STI_UINT16 = 3,
|
||||
STI_UINT32 = 4,
|
||||
STI_UINT64 = 5,
|
||||
STI_HASH128 = 6,
|
||||
STI_HASH160 = 7,
|
||||
STI_HASH256 = 8,
|
||||
STI_VL = 9,
|
||||
STI_TL = 10,
|
||||
STI_AMOUNT = 11,
|
||||
STI_PATHSET = 12,
|
||||
STI_VECTOR256 = 13,
|
||||
#define TYPE(name, field, value) STI_##field = value,
|
||||
#define FIELD(name, field, value)
|
||||
#include "SerializeProto.h"
|
||||
#undef TYPE
|
||||
#undef FIELD
|
||||
|
||||
// high level types
|
||||
STI_ACCOUNT = 100,
|
||||
STI_TRANSACTION = 101,
|
||||
STI_LEDGERENTRY = 102
|
||||
STI_TRANSACTION = 100001,
|
||||
STI_LEDGERENTRY = 100002
|
||||
};
|
||||
|
||||
enum PathFlags
|
||||
@@ -247,9 +237,9 @@ protected:
|
||||
STAmount(const char *name, uint64 value, bool isNegative)
|
||||
: SerializedType(name), mValue(value), mOffset(0), mIsNative(true), mIsNegative(isNegative)
|
||||
{ ; }
|
||||
STAmount(const char *n, const uint160& cur, uint64 val, int off, bool isNative, bool isNegative)
|
||||
: SerializedType(n), mCurrency(cur), mValue(val), mOffset(off), mIsNative(isNative), mIsNegative(isNegative)
|
||||
{ ; }
|
||||
STAmount(const char *n, const uint160& cur, const uint160& iss, uint64 val, int off, bool isNat, bool isNeg)
|
||||
: SerializedType(n), mCurrency(cur), mIssuer(iss), mValue(val), mOffset(off),
|
||||
mIsNative(isNat), mIsNegative(isNeg) { ; }
|
||||
|
||||
uint64 toUInt64() const;
|
||||
static uint64 muldiv(uint64, uint64, uint64);
|
||||
@@ -269,8 +259,9 @@ public:
|
||||
{ canonicalize(); }
|
||||
|
||||
// YYY This should probably require issuer too.
|
||||
STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0, bool isNeg = false) :
|
||||
SerializedType(n), mCurrency(currency), mValue(v), mOffset(off), mIsNegative(isNeg)
|
||||
STAmount(const char* n, const uint160& currency, const uint160& issuer,
|
||||
uint64 v = 0, int off = 0, bool isNeg = false) :
|
||||
SerializedType(n), mCurrency(currency), mIssuer(issuer), mValue(v), mOffset(off), mIsNegative(isNeg)
|
||||
{ canonicalize(); }
|
||||
|
||||
STAmount(const char* n, int64 v);
|
||||
@@ -726,45 +717,6 @@ namespace boost
|
||||
};
|
||||
}
|
||||
|
||||
class STTaggedList : public SerializedType
|
||||
{
|
||||
protected:
|
||||
std::vector<TaggedListItem> value;
|
||||
|
||||
STTaggedList* duplicate() const { return new STTaggedList(name, value); }
|
||||
static STTaggedList* construct(SerializerIterator&, const char* name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STTaggedList() { ; }
|
||||
STTaggedList(const char* n) : SerializedType(n) { ; }
|
||||
STTaggedList(const std::vector<TaggedListItem>& v) : value(v) { ; }
|
||||
STTaggedList(const char* n, const std::vector<TaggedListItem>& v) : SerializedType(n), value(v) { ; }
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const;
|
||||
SerializedTypeID getSType() const { return STI_TL; }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { if (s.addTaggedList(value) < 0) throw(0); }
|
||||
|
||||
const std::vector<TaggedListItem>& peekValue() const { return value; }
|
||||
std::vector<TaggedListItem>& peekValue() { return value; }
|
||||
std::vector<TaggedListItem> getValue() const { return value; }
|
||||
virtual Json::Value getJson(int) const;
|
||||
|
||||
void setValue(const std::vector<TaggedListItem>& v) { value=v; }
|
||||
|
||||
int getItemCount() const { return value.size(); }
|
||||
bool isEmpty() const { return value.empty(); }
|
||||
|
||||
void clear() { value.erase(value.begin(), value.end()); }
|
||||
void addItem(const TaggedListItem& v) { value.push_back(v); }
|
||||
|
||||
operator std::vector<TaggedListItem>() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STVector256 : public SerializedType
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -154,6 +154,57 @@ uint256 Serializer::get256(int offset) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addFieldID(int type, int name)
|
||||
{
|
||||
int ret = mData.size();
|
||||
assert((type > 0) && (type < 256) && (name > 0) && (name < 256));
|
||||
if (type < 16)
|
||||
{
|
||||
if (name < 16) // common type, common name
|
||||
mData.push_back(static_cast<unsigned char>((type << 4) | name));
|
||||
else
|
||||
{ // common type, uncommon name
|
||||
mData.push_back(static_cast<unsigned char>(type << 4));
|
||||
mData.push_back(static_cast<unsigned char>(name));
|
||||
}
|
||||
}
|
||||
else if (name < 16)
|
||||
{ // uncommon type, common name
|
||||
mData.push_back(static_cast<unsigned char>(name));
|
||||
mData.push_back(static_cast<unsigned char>(type));
|
||||
}
|
||||
else
|
||||
{ // uncommon type, uncommon name
|
||||
mData.push_back(static_cast<unsigned char>(0));
|
||||
mData.push_back(static_cast<unsigned char>(type));
|
||||
mData.push_back(static_cast<unsigned char>(name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Serializer::getFieldID(int& type, int & name, int offset) const
|
||||
{
|
||||
if (!get8(type, offset))
|
||||
return false;
|
||||
name = type & 15;
|
||||
type >>= 4;
|
||||
if (type == 0)
|
||||
{ // uncommon type
|
||||
if (!get8(type, ++offset))
|
||||
return false;
|
||||
if ((type == 0) || (type < 16))
|
||||
return false;
|
||||
}
|
||||
if (name == 0)
|
||||
{ // uncommon name
|
||||
if (!get8(name, ++offset))
|
||||
return false;
|
||||
if ((name == 0) || (name < 16))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int Serializer::add8(unsigned char byte)
|
||||
{
|
||||
int ret = mData.size();
|
||||
@@ -535,6 +586,17 @@ int SerializerIterator::getBytesLeft()
|
||||
return mSerializer.size() - mPos;
|
||||
}
|
||||
|
||||
void SerializerIterator::getFieldID(int& type, int& field)
|
||||
{
|
||||
if (!mSerializer.getFieldID(type, field, mPos))
|
||||
throw std::runtime_error("invalid serializer getFieldID");
|
||||
++mPos;
|
||||
if (type >= 16)
|
||||
++mPos;
|
||||
if (field >= 16)
|
||||
++mPos;
|
||||
}
|
||||
|
||||
unsigned char SerializerIterator::get8()
|
||||
{
|
||||
int val;
|
||||
|
||||
@@ -67,6 +67,9 @@ public:
|
||||
bool getTaggedList(std::list<TaggedListItem>&, int offset, int& length) const;
|
||||
bool getTaggedList(std::vector<TaggedListItem>&, int offset, int& length) const;
|
||||
|
||||
bool getFieldID(int& type, int& name, int offset) const;
|
||||
int addFieldID(int type, int name);
|
||||
|
||||
// normal hash functions
|
||||
uint160 getRIPEMD160(int size=-1) const;
|
||||
uint256 getSHA256(int size=-1) const;
|
||||
@@ -156,6 +159,8 @@ public:
|
||||
uint160 get160();
|
||||
uint256 get256();
|
||||
|
||||
void getFieldID(int& type, int& field);
|
||||
|
||||
std::vector<unsigned char> getRaw(int iLength);
|
||||
|
||||
std::vector<unsigned char> getVL();
|
||||
|
||||
@@ -194,7 +194,7 @@ Transaction::pointer Transaction::setClaim(
|
||||
const std::vector<unsigned char>& vucSignature)
|
||||
{
|
||||
mTransaction->setITFieldVL(sfGenerator, vucGenerator);
|
||||
mTransaction->setITFieldVL(sfPubKey, vucPubKey);
|
||||
mTransaction->setITFieldVL(sfPublicKey, vucPubKey);
|
||||
mTransaction->setITFieldVL(sfSignature, vucSignature);
|
||||
|
||||
sign(naPrivateKey);
|
||||
@@ -455,7 +455,7 @@ Transaction::pointer Transaction::setPasswordSet(
|
||||
{
|
||||
mTransaction->setITFieldAccount(sfAuthorizedKey, naAuthKeyID);
|
||||
mTransaction->setITFieldVL(sfGenerator, vucGenerator);
|
||||
mTransaction->setITFieldVL(sfPubKey, vucPubKey);
|
||||
mTransaction->setITFieldVL(sfPublicKey, vucPubKey);
|
||||
mTransaction->setITFieldVL(sfSignature, vucSignature);
|
||||
|
||||
sign(naPrivateKey);
|
||||
@@ -542,7 +542,7 @@ Transaction::pointer Transaction::setWalletAdd(
|
||||
{
|
||||
mTransaction->setITFieldAmount(sfAmount, saAmount);
|
||||
mTransaction->setITFieldAccount(sfAuthorizedKey, naAuthKeyID);
|
||||
mTransaction->setITFieldVL(sfPubKey, naNewPubKey.getAccountPublic());
|
||||
mTransaction->setITFieldVL(sfPublicKey, naNewPubKey.getAccountPublic());
|
||||
mTransaction->setITFieldVL(sfSignature, vucSignature);
|
||||
|
||||
sign(naPrivateKey);
|
||||
|
||||
@@ -30,7 +30,7 @@ TER TransactionEngine::setAuthorized(const SerializedTransaction& txn, bool bMus
|
||||
//
|
||||
|
||||
std::vector<unsigned char> vucCipher = txn.getITFieldVL(sfGenerator);
|
||||
std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPubKey);
|
||||
std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPublicKey);
|
||||
std::vector<unsigned char> vucSignature = txn.getITFieldVL(sfSignature);
|
||||
NewcoinAddress naAccountPublic = NewcoinAddress::createAccountPublic(vucPubKey);
|
||||
|
||||
@@ -166,18 +166,24 @@ TER TransactionEngine::doAccountSet(const SerializedTransaction& txn)
|
||||
{
|
||||
uint32 uRate = txn.getITFieldU32(sfTransferRate);
|
||||
|
||||
if (!uRate)
|
||||
if (!uRate || uRate == QUALITY_ONE)
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: unset transfer rate";
|
||||
|
||||
mTxnAccount->makeIFieldAbsent(sfTransferRate);
|
||||
}
|
||||
else
|
||||
else if (uRate > QUALITY_ONE)
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: set transfer rate";
|
||||
|
||||
mTxnAccount->setIFieldU32(sfTransferRate, uRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: bad transfer rate";
|
||||
|
||||
return temBAD_TRANSFER_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -620,7 +626,7 @@ TER TransactionEngine::doWalletAdd(const SerializedTransaction& txn)
|
||||
{
|
||||
std::cerr << "WalletAdd>" << std::endl;
|
||||
|
||||
const std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPubKey);
|
||||
const std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPublicKey);
|
||||
const std::vector<unsigned char> vucSignature = txn.getITFieldVL(sfSignature);
|
||||
const uint160 uAuthKeyID = txn.getITFieldAccount(sfAuthorizedKey);
|
||||
const NewcoinAddress naMasterPubKey = NewcoinAddress::createAccountPublic(vucPubKey);
|
||||
@@ -710,8 +716,8 @@ TER TransactionEngine::takeOffers(
|
||||
boost::unordered_set<uint256> usOfferUnfundedBecame; // Offers that became unfunded.
|
||||
boost::unordered_set<uint160> usAccountTouched; // Accounts touched.
|
||||
|
||||
saTakerPaid = 0;
|
||||
saTakerGot = 0;
|
||||
saTakerPaid = STAmount(saTakerPays.getCurrency(), saTakerPays.getIssuer());
|
||||
saTakerGot = STAmount(saTakerGets.getCurrency(), saTakerGets.getIssuer());
|
||||
|
||||
while (temUNCERTAIN == terResult)
|
||||
{
|
||||
@@ -915,8 +921,11 @@ Log(lsWARNING) << "doOfferCreate> " << txn.getJson(0);
|
||||
const bool bPassive = isSetBit(txFlags, tfPassive);
|
||||
STAmount saTakerPays = txn.getITFieldAmount(sfTakerPays);
|
||||
STAmount saTakerGets = txn.getITFieldAmount(sfTakerGets);
|
||||
Log(lsWARNING) << "doOfferCreate: saTakerPays=" << saTakerPays.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays.getFullText()
|
||||
% saTakerGets.getFullText());
|
||||
|
||||
const uint160 uPaysIssuerID = saTakerPays.getIssuer();
|
||||
const uint160 uGetsIssuerID = saTakerGets.getIssuer();
|
||||
const uint32 uExpiration = txn.getITFieldU32(sfExpiration);
|
||||
@@ -999,14 +1008,14 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
STAmount saOfferGot;
|
||||
const uint256 uTakeBookBase = Ledger::getBookBase(uGetsCurrency, uGetsIssuerID, uPaysCurrency, uPaysIssuerID);
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: take against book: %s : %s/%s -> %s/%s")
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: take against book: %s for %s -> %s")
|
||||
% uTakeBookBase.ToString()
|
||||
% saTakerGets.getHumanCurrency()
|
||||
% NewcoinAddress::createHumanAccountID(saTakerGets.getIssuer())
|
||||
% saTakerPays.getHumanCurrency()
|
||||
% NewcoinAddress::createHumanAccountID(saTakerPays.getIssuer()));
|
||||
% saTakerGets.getFullText()
|
||||
% saTakerPays.getFullText());
|
||||
|
||||
// Take using the parameters of the offer.
|
||||
#if 1
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: BEFORE saTakerGets=" << saTakerGets.getFullText();
|
||||
terResult = takeOffers(
|
||||
bPassive,
|
||||
uTakeBookBase,
|
||||
@@ -1017,12 +1026,14 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
saOfferPaid, // How much was spent.
|
||||
saOfferGot // How much was got.
|
||||
);
|
||||
|
||||
#else
|
||||
terResult = tesSUCCESS;
|
||||
#endif
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers=" << terResult;
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saOfferPaid=" << saOfferPaid.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saOfferGot=" << saOfferGot.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerGets=" << saTakerGets.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: AFTER saTakerGets=" << saTakerGets.getFullText();
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
@@ -1033,9 +1044,8 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerGets=" << saTakerGets.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerGets=" << NewcoinAddress::createHumanAccountID(saTakerGets.getIssuer());
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: mTxnAccountID=" << NewcoinAddress::createHumanAccountID(mTxnAccountID);
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: funds=" << mNodes.accountFunds(mTxnAccountID, saTakerGets).getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: FUNDS=" << mNodes.accountFunds(mTxnAccountID, saTakerGets).getFullText();
|
||||
|
||||
// Log(lsWARNING) << "doOfferCreate: takeOffers: uPaysIssuerID=" << NewcoinAddress::createHumanAccountID(uPaysIssuerID);
|
||||
// Log(lsWARNING) << "doOfferCreate: takeOffers: uGetsIssuerID=" << NewcoinAddress::createHumanAccountID(uGetsIssuerID);
|
||||
@@ -1046,6 +1056,9 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
&& mNodes.accountFunds(mTxnAccountID, saTakerGets).isPositive()) // Still funded.
|
||||
{
|
||||
// We need to place the remainder of the offer into its order book.
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: offer not fully consumed: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays.getFullText()
|
||||
% saTakerGets.getFullText());
|
||||
|
||||
// Add offer to owner's directory.
|
||||
terResult = mNodes.dirAdd(uOwnerNode, Ledger::getOwnerDirIndex(mTxnAccountID), uLedgerIndex);
|
||||
@@ -1069,12 +1082,13 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
// Log(lsWARNING) << "doOfferCreate: uPaysIssuerID=" << NewcoinAddress::createHumanAccountID(uPaysIssuerID);
|
||||
// Log(lsWARNING) << "doOfferCreate: uGetsIssuerID=" << NewcoinAddress::createHumanAccountID(uGetsIssuerID);
|
||||
// Log(lsWARNING) << "doOfferCreate: saTakerPays.isNative()=" << saTakerPays.isNative();
|
||||
// Log(lsWARNING) << "doOfferCreate: saTakerGets.isNative()=" << saTakerGets.isNative();
|
||||
// Log(lsWARNING) << "doOfferCreate: uPaysCurrency=" << saTakerPays.getHumanCurrency();
|
||||
// Log(lsWARNING) << "doOfferCreate: uGetsCurrency=" << saTakerGets.getHumanCurrency();
|
||||
Log(lsWARNING) << "doOfferCreate: sfAccount=" << NewcoinAddress::createHumanAccountID(mTxnAccountID);
|
||||
Log(lsWARNING) << "doOfferCreate: uPaysIssuerID=" << NewcoinAddress::createHumanAccountID(uPaysIssuerID);
|
||||
Log(lsWARNING) << "doOfferCreate: uGetsIssuerID=" << NewcoinAddress::createHumanAccountID(uGetsIssuerID);
|
||||
Log(lsWARNING) << "doOfferCreate: saTakerPays.isNative()=" << saTakerPays.isNative();
|
||||
Log(lsWARNING) << "doOfferCreate: saTakerGets.isNative()=" << saTakerGets.isNative();
|
||||
Log(lsWARNING) << "doOfferCreate: uPaysCurrency=" << saTakerPays.getHumanCurrency();
|
||||
Log(lsWARNING) << "doOfferCreate: uGetsCurrency=" << saTakerGets.getHumanCurrency();
|
||||
|
||||
sleOffer->setIFieldAccount(sfAccount, mTxnAccountID);
|
||||
sleOffer->setIFieldU32(sfSequence, uSequence);
|
||||
@@ -1092,6 +1106,8 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsINFO) << "doOfferCreate: final sleOffer=" << sleOffer->getJson(0);
|
||||
|
||||
return terResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman)
|
||||
{ temBAD_PATH, "temBAD_PATH", "Malformed." },
|
||||
{ temBAD_PATH_LOOP, "temBAD_PATH_LOOP", "Malformed." },
|
||||
{ temBAD_PUBLISH, "temBAD_PUBLISH", "Malformed: bad publish." },
|
||||
{ temBAD_TRANSFER_RATE, "temBAD_TRANSFER_RATE", "Malformed: transfer rate must be >= 1.0" },
|
||||
{ temBAD_SET_ID, "temBAD_SET_ID", "Malformed." },
|
||||
{ temCREATEXNS, "temCREATEXNS", "Can not specify non XNS for Create." },
|
||||
{ temDST_IS_SRC, "temDST_IS_SRC", "Destination may not be source." },
|
||||
@@ -89,3 +90,4 @@ std::string transHuman(TER terCode)
|
||||
|
||||
return transResultInfo(terCode, strToken, strHuman) ? strHuman : "-";
|
||||
}
|
||||
// vim:ts=4
|
||||
|
||||
@@ -33,6 +33,7 @@ enum TER // aka TransactionEngineResult
|
||||
temBAD_PATH,
|
||||
temBAD_PATH_LOOP,
|
||||
temBAD_PUBLISH,
|
||||
temBAD_TRANSFER_RATE,
|
||||
temBAD_SET_ID,
|
||||
temCREATEXNS,
|
||||
temDST_IS_SRC,
|
||||
|
||||
@@ -15,16 +15,14 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(TransferRate), STI_UINT32, SOE_IFFLAG, 32 },
|
||||
{ S_FIELD(PublishHash), STI_HASH256, SOE_IFFLAG, 64 },
|
||||
{ S_FIELD(PublishSize), STI_UINT32, SOE_IFFLAG, 128 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Claim", ttCLAIM, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(PubKey), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(PublicKey), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "CreditSet", ttCREDIT_SET, {
|
||||
@@ -34,7 +32,6 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(LimitAmount), STI_AMOUNT, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(QualityIn), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(QualityOut), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
/*
|
||||
@@ -45,7 +42,6 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Identifier), STI_VL, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
*/
|
||||
@@ -55,7 +51,6 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Signature), STI_VL, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "OfferCreate", ttOFFER_CREATE, {
|
||||
@@ -64,31 +59,27 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(TakerGets), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "OfferCancel", ttOFFER_CANCEL, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(OfferSequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "PasswordFund", ttPASSWORD_FUND, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "PasswordSet", ttPASSWORD_SET, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(PubKey), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(PublicKey), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Payment", ttPAYMENT, {
|
||||
@@ -99,17 +90,15 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(Paths), STI_PATHSET, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(InvoiceID), STI_HASH256, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "WalletAdd", ttWALLET_ADD, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(PubKey), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(PublicKey), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Contract", ttCONTRACT, {
|
||||
@@ -122,13 +111,11 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ S_FIELD(FundCode), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(RemoveCode), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(ExpireCode), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Contract", ttCONTRACT_REMOVE, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ NULL, ttINVALID }
|
||||
|
||||
@@ -294,11 +294,15 @@ bool TransactionMetaSet::isNodeAffected(const uint256& node) const
|
||||
return mNodes.find(node) != mNodes.end();
|
||||
}
|
||||
|
||||
TransactionMetaNode& TransactionMetaSet::getAffectedNode(const uint256& node, int type)
|
||||
TransactionMetaNode& TransactionMetaSet::getAffectedNode(const uint256& node, int type, bool overrideType)
|
||||
{
|
||||
std::map<uint256, TransactionMetaNode>::iterator it = mNodes.find(node);
|
||||
if (it != mNodes.end())
|
||||
{
|
||||
if (overrideType)
|
||||
it->second.setType(type);
|
||||
return it->second;
|
||||
}
|
||||
return mNodes.insert(std::make_pair(node, TransactionMetaNode(node, type))).first->second;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ public:
|
||||
|
||||
TransactionMetaNode(int type, const uint256& node, SerializerIterator&);
|
||||
void addRaw(Serializer&);
|
||||
void setType(int t) { mType = t; }
|
||||
Json::Value getJson(int) const;
|
||||
|
||||
bool addAmount(int nodeType, const STAmount& amount);
|
||||
@@ -189,7 +190,7 @@ public:
|
||||
uint32 getLgrSeq() { return mLedger; }
|
||||
|
||||
bool isNodeAffected(const uint256&) const;
|
||||
TransactionMetaNode& getAffectedNode(const uint256&, int type);
|
||||
TransactionMetaNode& getAffectedNode(const uint256&, int type, bool overrideType);
|
||||
const TransactionMetaNode& peekAffectedNode(const uint256&) const;
|
||||
|
||||
Json::Value getJson(int) const;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// XXX Want a limit of 2000 validators.
|
||||
|
||||
#include "Application.h"
|
||||
#include "Conversion.h"
|
||||
#include "HttpsClient.h"
|
||||
#include "Log.h"
|
||||
#include "ParseSection.h"
|
||||
|
||||
246
src/WSDoor.cpp
246
src/WSDoor.cpp
@@ -75,7 +75,12 @@ public:
|
||||
Json::Value invokeCommand(const Json::Value& jvRequest);
|
||||
boost::unordered_set<NewcoinAddress> parseAccountIds(const Json::Value& jvArray);
|
||||
|
||||
// Commands
|
||||
// Request-Response Commands
|
||||
void doLedgerClosed(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
void doLedgerCurrent(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
void doLedgerEntry(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
|
||||
// Streaming Commands
|
||||
void doAccountInfoSubscribe(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
void doAccountInfoUnsubscribe(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
void doAccountTransactionSubscribe(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
@@ -293,6 +298,12 @@ Json::Value WSConnection::invokeCommand(const Json::Value& jvRequest)
|
||||
const char* pCommand;
|
||||
doFuncPtr dfpFunc;
|
||||
} commandsA[] = {
|
||||
// Request-Response Commands:
|
||||
{ "ledger_closed", &WSConnection::doLedgerClosed },
|
||||
{ "ledger_current", &WSConnection::doLedgerCurrent },
|
||||
{ "ledger_entry", &WSConnection::doLedgerEntry },
|
||||
|
||||
// Streaming commands:
|
||||
{ "account_info_subscribe", &WSConnection::doAccountInfoSubscribe },
|
||||
{ "account_info_unsubscribe", &WSConnection::doAccountInfoUnsubscribe },
|
||||
{ "account_transaction_subscribe", &WSConnection::doAccountTransactionSubscribe },
|
||||
@@ -541,6 +552,239 @@ void WSConnection::doLedgerAccountsUnsubscribe(Json::Value& jvResult, const Json
|
||||
}
|
||||
}
|
||||
|
||||
void WSConnection::doLedgerClosed(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
uint256 uLedger = theApp->getOPs().getClosedLedger();
|
||||
|
||||
jvResult["ledger_index"] = theApp->getOPs().getLedgerID(uLedger);
|
||||
jvResult["ledger"] = uLedger.ToString();
|
||||
}
|
||||
|
||||
void WSConnection::doLedgerCurrent(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
jvResult["ledger_index"] = theApp->getOPs().getCurrentLedgerID();
|
||||
}
|
||||
|
||||
void WSConnection::doLedgerEntry(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
NetworkOPs& noNetwork = theApp->getOPs();
|
||||
uint256 uLedger = jvRequest.isMember("ledger") ? uint256(jvRequest["ledger"].asString()) : 0;
|
||||
uint32 uLedgerIndex = jvRequest.isMember("ledger_index") && jvRequest["ledger_index"].isNumeric() ? jvRequest["ledger_index"].asUInt() : 0;
|
||||
|
||||
Ledger::pointer lpLedger;
|
||||
|
||||
if (!!uLedger)
|
||||
{
|
||||
// Ledger directly specified.
|
||||
lpLedger = noNetwork.getLedgerByHash(uLedger);
|
||||
|
||||
if (!lpLedger)
|
||||
{
|
||||
jvResult["error"] = "ledgerNotFound";
|
||||
return;
|
||||
}
|
||||
|
||||
uLedgerIndex = lpLedger->getLedgerSeq(); // Set the current index, override if needed.
|
||||
}
|
||||
else if (!!uLedgerIndex)
|
||||
{
|
||||
lpLedger = noNetwork.getLedgerBySeq(uLedgerIndex);
|
||||
|
||||
if (!lpLedger)
|
||||
{
|
||||
jvResult["error"] = "ledgerNotFound"; // ledger_index from future?
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to current ledger.
|
||||
lpLedger = noNetwork.getCurrentLedger();
|
||||
uLedgerIndex = lpLedger->getLedgerSeq(); // Set the current index.
|
||||
}
|
||||
|
||||
if (!!uLedger)
|
||||
jvResult["ledger"] = uLedger.ToString();
|
||||
|
||||
jvResult["ledger_index"] = uLedgerIndex;
|
||||
|
||||
uint256 uNodeIndex;
|
||||
bool bNodeBinary = false;
|
||||
|
||||
if (jvRequest.isMember("index"))
|
||||
{
|
||||
// XXX Needs to provide proof.
|
||||
uNodeIndex.SetHex(jvRequest["index"].asString());
|
||||
bNodeBinary = true;
|
||||
}
|
||||
else if (jvRequest.isMember("account_root"))
|
||||
{
|
||||
NewcoinAddress naAccount;
|
||||
|
||||
if (!naAccount.setAccountID(jvRequest["account_root"].asString()))
|
||||
{
|
||||
jvResult["error"] = "malformedAddress";
|
||||
}
|
||||
else
|
||||
{
|
||||
uNodeIndex = Ledger::getAccountRootIndex(naAccount.getAccountID());
|
||||
}
|
||||
}
|
||||
else if (jvRequest.isMember("directory"))
|
||||
{
|
||||
|
||||
if (!jvRequest.isObject())
|
||||
{
|
||||
uNodeIndex.SetHex(jvRequest["directory"].asString());
|
||||
}
|
||||
else if (jvRequest["directory"].isMember("sub_index")
|
||||
&& !jvRequest["directory"]["sub_index"].isIntegral())
|
||||
{
|
||||
jvResult["error"] = "malformedRequest";
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 uSubIndex = jvRequest["directory"].isMember("sub_index")
|
||||
? jvRequest["directory"]["sub_index"].asUInt()
|
||||
: 0;
|
||||
|
||||
if (jvRequest["directory"].isMember("dir_root"))
|
||||
{
|
||||
uint256 uDirRoot;
|
||||
|
||||
uDirRoot.SetHex(jvRequest["dir_root"].asString());
|
||||
|
||||
uNodeIndex = Ledger::getDirNodeIndex(uDirRoot, uSubIndex);
|
||||
}
|
||||
else if (jvRequest["directory"].isMember("owner"))
|
||||
{
|
||||
NewcoinAddress naOwnerID;
|
||||
|
||||
if (!naOwnerID.setAccountID(jvRequest["directory"]["owner"].asString()))
|
||||
{
|
||||
jvResult["error"] = "malformedAddress";
|
||||
}
|
||||
else
|
||||
{
|
||||
uint256 uDirRoot = Ledger::getOwnerDirIndex(naOwnerID.getAccountID());
|
||||
|
||||
uNodeIndex = Ledger::getDirNodeIndex(uDirRoot, uSubIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jvResult["error"] = "malformedRequest";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (jvRequest.isMember("generator"))
|
||||
{
|
||||
NewcoinAddress naGeneratorID;
|
||||
|
||||
if (!jvRequest.isObject())
|
||||
{
|
||||
uNodeIndex.SetHex(jvRequest["generator"].asString());
|
||||
}
|
||||
else if (!jvRequest["generator"].isMember("regular_seed"))
|
||||
{
|
||||
jvResult["error"] = "malformedRequest";
|
||||
}
|
||||
else if (!naGeneratorID.setSeedGeneric(jvRequest["generator"]["regular_seed"].asString()))
|
||||
{
|
||||
jvResult["error"] = "malformedAddress";
|
||||
}
|
||||
else
|
||||
{
|
||||
NewcoinAddress na0Public; // To find the generator's index.
|
||||
NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naGeneratorID);
|
||||
|
||||
na0Public.setAccountPublic(naGenerator, 0);
|
||||
|
||||
uNodeIndex = Ledger::getGeneratorIndex(na0Public.getAccountID());
|
||||
}
|
||||
}
|
||||
else if (jvRequest.isMember("offer"))
|
||||
{
|
||||
NewcoinAddress naAccountID;
|
||||
|
||||
if (!jvRequest.isObject())
|
||||
{
|
||||
uNodeIndex.SetHex(jvRequest["offer"].asString());
|
||||
}
|
||||
else if (!jvRequest["offer"].isMember("account")
|
||||
|| !jvRequest["offer"].isMember("seq")
|
||||
|| !jvRequest["offer"]["seq"].isIntegral())
|
||||
{
|
||||
jvResult["error"] = "malformedRequest";
|
||||
}
|
||||
else if (!naAccountID.setAccountID(jvRequest["offer"]["account"].asString()))
|
||||
{
|
||||
jvResult["error"] = "malformedAddress";
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 uSequence = jvRequest["offer"]["seq"].asUInt();
|
||||
|
||||
uNodeIndex = Ledger::getOfferIndex(naAccountID.getAccountID(), uSequence);
|
||||
}
|
||||
}
|
||||
else if (jvRequest.isMember("ripple_state"))
|
||||
{
|
||||
NewcoinAddress naA;
|
||||
NewcoinAddress naB;
|
||||
uint160 uCurrency;
|
||||
|
||||
if (!jvRequest.isMember("accounts")
|
||||
|| !jvRequest.isMember("currency")
|
||||
|| !jvRequest["accounts"].isArray()
|
||||
|| 2 != jvRequest["accounts"].size()) {
|
||||
jvResult["error"] = "malformedRequest";
|
||||
}
|
||||
else if (!naA.setAccountID(jvRequest["accounts"][0u].asString())
|
||||
|| !naB.setAccountID(jvRequest["accounts"][1u].asString())) {
|
||||
jvResult["error"] = "malformedAddress";
|
||||
}
|
||||
else if (!STAmount::currencyFromString(uCurrency, jvRequest["currency"].asString())) {
|
||||
jvResult["error"] = "malformedCurrency";
|
||||
}
|
||||
else
|
||||
{
|
||||
uNodeIndex = Ledger::getRippleStateIndex(naA, naB, uCurrency);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jvResult["error"] = "unknownOption";
|
||||
}
|
||||
|
||||
if (!!uNodeIndex)
|
||||
{
|
||||
SLE::pointer sleNode = noNetwork.getSLE(lpLedger, uNodeIndex);
|
||||
|
||||
if (!sleNode)
|
||||
{
|
||||
// Not found.
|
||||
// XXX Should also provide proof.
|
||||
jvResult["error"] = "entryNotFound";
|
||||
}
|
||||
else if (bNodeBinary)
|
||||
{
|
||||
// XXX Should also provide proof.
|
||||
Serializer s;
|
||||
|
||||
sleNode->add(s);
|
||||
|
||||
jvResult["node_binary"] = strHex(s.peekData());
|
||||
jvResult["index"] = uNodeIndex.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
jvResult["node"] = sleNode->getJson(0);
|
||||
jvResult["index"] = uNodeIndex.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WSConnection::doTransactionSubcribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().subTransaction(this))
|
||||
|
||||
@@ -51,6 +51,7 @@ void printHelp(const po::options_description& desc)
|
||||
cout << " data_fetch <key>" << endl;
|
||||
cout << " data_store <key> <value>" << endl;
|
||||
cout << " ledger [<id>|current|lastclosed] [full]" << endl;
|
||||
cout << " logrotate " << endl;
|
||||
cout << " nickname_info <nickname>" << endl;
|
||||
cout << " nickname_set <seed> <paying_account> <nickname> [<offer_minimum>] [<authorization>]" << endl;
|
||||
cout << " offer_create <seed> <paying_account> <taker_pays_amount> <taker_pays_currency> <taker_pays_issuer> <takers_gets_amount> <takers_gets_currency> <takers_gets_issuer> <expires> [passive]" << endl;
|
||||
|
||||
187
src/uint256.h
187
src/uint256.h
@@ -386,96 +386,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint160
|
||||
//
|
||||
|
||||
class uint160 : public base_uint160
|
||||
{
|
||||
public:
|
||||
typedef base_uint160 basetype;
|
||||
|
||||
uint160()
|
||||
{
|
||||
zero();
|
||||
}
|
||||
|
||||
uint160(const basetype& b)
|
||||
{
|
||||
*this = b;
|
||||
}
|
||||
|
||||
uint160& operator=(const basetype& b)
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
pn[i] = b.pn[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint160(uint64 b)
|
||||
{
|
||||
*this = b;
|
||||
}
|
||||
|
||||
uint160& operator=(uint64 uHost)
|
||||
{
|
||||
zero();
|
||||
|
||||
// Put in least significant bits.
|
||||
((uint64_t *) end())[-1] = htobe64(uHost);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit uint160(const std::string& str)
|
||||
{
|
||||
SetHex(str);
|
||||
}
|
||||
|
||||
explicit uint160(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
if (vch.size() == sizeof(pn))
|
||||
memcpy(pn, &vch[0], sizeof(pn));
|
||||
else
|
||||
zero();
|
||||
}
|
||||
|
||||
base_uint256 to256() const;
|
||||
};
|
||||
|
||||
inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; }
|
||||
inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; }
|
||||
|
||||
inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
|
||||
inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
|
||||
inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
|
||||
|
||||
inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
|
||||
inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
|
||||
inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
|
||||
inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
|
||||
inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
|
||||
|
||||
inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; }
|
||||
inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; }
|
||||
inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
|
||||
inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; }
|
||||
inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; }
|
||||
inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
|
||||
inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
|
||||
inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
|
||||
inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
|
||||
inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
|
||||
|
||||
extern std::size_t hash_value(const uint160&);
|
||||
|
||||
inline const std::string strHex(const uint160& ui)
|
||||
{
|
||||
return strHex(ui.begin(), ui.size());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint256
|
||||
@@ -694,5 +604,102 @@ inline int Testuint256AdHoc(std::vector<std::string> vArg)
|
||||
return (0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint160
|
||||
//
|
||||
|
||||
class uint160 : public base_uint160
|
||||
{
|
||||
public:
|
||||
typedef base_uint160 basetype;
|
||||
|
||||
uint160()
|
||||
{
|
||||
zero();
|
||||
}
|
||||
|
||||
uint160(const basetype& b)
|
||||
{
|
||||
*this = b;
|
||||
}
|
||||
|
||||
uint160& operator=(const basetype& b)
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
pn[i] = b.pn[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint160(uint64 b)
|
||||
{
|
||||
*this = b;
|
||||
}
|
||||
|
||||
uint160& operator=(uint64 uHost)
|
||||
{
|
||||
zero();
|
||||
|
||||
// Put in least significant bits.
|
||||
((uint64_t *) end())[-1] = htobe64(uHost);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit uint160(const std::string& str)
|
||||
{
|
||||
SetHex(str);
|
||||
}
|
||||
|
||||
explicit uint160(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
if (vch.size() == sizeof(pn))
|
||||
memcpy(pn, &vch[0], sizeof(pn));
|
||||
else
|
||||
zero();
|
||||
}
|
||||
|
||||
base_uint256 to256() const
|
||||
{
|
||||
uint256 m;
|
||||
memcpy(m.begin(), begin(), size());
|
||||
return m;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; }
|
||||
inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; }
|
||||
|
||||
inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
|
||||
inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
|
||||
inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
|
||||
|
||||
inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
|
||||
inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
|
||||
inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
|
||||
inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
|
||||
inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
|
||||
|
||||
inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; }
|
||||
inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; }
|
||||
inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
|
||||
inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; }
|
||||
inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; }
|
||||
inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
|
||||
inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
|
||||
inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
|
||||
inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
|
||||
inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
|
||||
|
||||
extern std::size_t hash_value(const uint160&);
|
||||
|
||||
inline const std::string strHex(const uint160& ui)
|
||||
{
|
||||
return strHex(ui.begin(), ui.size());
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
|
||||
@@ -9,15 +9,17 @@ exports.newcoind = path.join(process.cwd(), "newcoind");
|
||||
|
||||
// Configuration for servers.
|
||||
exports.servers = {
|
||||
// A local test server.
|
||||
alpha : {
|
||||
'trusted' : true,
|
||||
// "peer_ip" : "0.0.0.0",
|
||||
// "peer_port" : 51235,
|
||||
"rpc_ip" : "0.0.0.0",
|
||||
"rpc_port" : 5005,
|
||||
"websocket_ip" : "127.0.0.1",
|
||||
"websocket_port" : 6005,
|
||||
"validation_seed" : "shhDFVsmS2GSu5vUyZSPXYfj1r79h",
|
||||
"validators" : "n9L8LZZCwsdXzKUN9zoVxs4YznYXZ9hEhsQZY7aVpxtFaSceiyDZ beta"
|
||||
'rpc_ip' : "0.0.0.0",
|
||||
'rpc_port' : 5005,
|
||||
'websocket_ip' : "127.0.0.1",
|
||||
'websocket_port' : 6005,
|
||||
'validation_seed' : "shhDFVsmS2GSu5vUyZSPXYfj1r79h",
|
||||
'validators' : "n9L8LZZCwsdXzKUN9zoVxs4YznYXZ9hEhsQZY7aVpxtFaSceiyDZ beta"
|
||||
}
|
||||
};
|
||||
// vim:ts=4
|
||||
|
||||
129
test/server.js
129
test/server.js
@@ -1,4 +1,7 @@
|
||||
// Manage test servers
|
||||
//
|
||||
// YYY Would be nice to be able to hide server output.
|
||||
//
|
||||
|
||||
// Provide servers
|
||||
//
|
||||
@@ -6,7 +9,7 @@
|
||||
//
|
||||
|
||||
var config = require("./config.js");
|
||||
var utils = require("./utils.js");
|
||||
var utils = require("../js/utils.js");
|
||||
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
@@ -16,57 +19,63 @@ var WebSocket = require("ws");
|
||||
|
||||
var servers = {};
|
||||
|
||||
var serverPath = function(name) {
|
||||
return "tmp/server/" + name;
|
||||
// Create a server object
|
||||
var Server = function(name) {
|
||||
this.name = name;
|
||||
};
|
||||
|
||||
// Return a server's newcoind.cfg as string.
|
||||
var configContent = function(name) {
|
||||
var cfg = config.servers[name];
|
||||
Server.method('configContent', function() {
|
||||
var cfg = config.servers[this.name];
|
||||
|
||||
return Object.keys(cfg).map(function(o) {
|
||||
return util.format("[%s]\n%s\n", o, cfg[o]);
|
||||
}).join("");
|
||||
};
|
||||
});
|
||||
|
||||
var configPath = function(name) {
|
||||
return path.join(serverPath(name), "newcoind.cfg");
|
||||
};
|
||||
Server.method('serverPath', function() {
|
||||
return "tmp/server/" + this.name;
|
||||
});
|
||||
|
||||
Server.method('configPath', function() {
|
||||
return path.join(this.serverPath(), "newcoind.cfg");
|
||||
});
|
||||
|
||||
// Write a server's newcoind.cfg.
|
||||
var writeConfig = function(name, done) {
|
||||
fs.writeFile(configPath(name), configContent(name), 'utf8', done);
|
||||
};
|
||||
Server.method('writeConfig', function(done) {
|
||||
fs.writeFile(this.configPath(), this.configContent(), 'utf8', done);
|
||||
});
|
||||
|
||||
var serverSpawnSync = function(name) {
|
||||
// Spawn the server.
|
||||
Server.method('serverSpawnSync', function() {
|
||||
// Spawn in standalone mode for now.
|
||||
var server = child.spawn(
|
||||
this.child = child.spawn(
|
||||
config.newcoind,
|
||||
[
|
||||
"-a",
|
||||
"--conf=newcoind.cfg"
|
||||
],
|
||||
{
|
||||
cwd: serverPath(name),
|
||||
cwd: this.serverPath(),
|
||||
env: process.env,
|
||||
stdio: 'inherit'
|
||||
});
|
||||
|
||||
servers[name] = server;
|
||||
console.log("server: %s: %s -a --conf=%s", server.pid, config.newcoind, configPath(name));
|
||||
console.log("sever: start: servers = %s", Object.keys(servers).toString());
|
||||
console.log("server: start %s: %s -a --conf=%s", this.child.pid, config.newcoind, this.configPath());
|
||||
|
||||
server.on('exit', function (code, signal) {
|
||||
// By default, just log exits.
|
||||
this.child.on('exit', function(code, signal) {
|
||||
// If could not exec: code=127, signal=null
|
||||
// If regular exit: code=0, signal=null
|
||||
console.log("sever: spawn: server exited code=%s: signal=%s", code, signal);
|
||||
delete servers[name];
|
||||
console.log("server: spawn: server exited code=%s: signal=%s", code, signal);
|
||||
});
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
var makeBase = function(name, done) {
|
||||
var path = serverPath(name);
|
||||
// Prepare server's working directory.
|
||||
Server.method('makeBase', function(done) {
|
||||
var path = this.serverPath();
|
||||
var self = this;
|
||||
|
||||
// Reset the server directory, build it if needed.
|
||||
utils.resetPath(path, '0777', function(e) {
|
||||
@@ -74,49 +83,73 @@ var makeBase = function(name, done) {
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
writeConfig(name, done);
|
||||
self.writeConfig(done);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var wsOpen = function(done) {
|
||||
var socket = new WebSocket(util.format("ws:://%s:%s", server.websocket_ip, server.websocket_port));
|
||||
|
||||
socket.on('open') {
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
// Create a standalone server.
|
||||
// Prepare the working directory and spawn the server.
|
||||
exports.start = function(name, done) {
|
||||
makeBase(name, function (e) {
|
||||
Server.method('start', function(done) {
|
||||
var self = this;
|
||||
|
||||
this.makeBase(function(e) {
|
||||
if (e) {
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
serverSpawnSync(name);
|
||||
wsOpen(done);
|
||||
self.serverSpawnSync();
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
exports.stop = function(name, done) {
|
||||
console.log("sever: stop: servers = %s", Object.keys(servers).toString());
|
||||
var server = servers[name];
|
||||
|
||||
if (server) {
|
||||
server.on('exit', function (code, signal) {
|
||||
console.log("sever: stop: server exited");
|
||||
delete servers[name];
|
||||
// Stop a standalone server.
|
||||
Server.method('stop', function(done) {
|
||||
if (this.child) {
|
||||
// Update the on exit to invoke done.
|
||||
this.child.on('exit', function(code, signal) {
|
||||
console.log("server: stop: server exited");
|
||||
done();
|
||||
});
|
||||
server.kill();
|
||||
this.child.kill();
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("sever: stop: no such server");
|
||||
console.log("server: stop: no such server");
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
// Start the named server.
|
||||
exports.start = function(name, done) {
|
||||
if (servers[name])
|
||||
{
|
||||
console.log("server: start: server already started.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var server = new Server(name);
|
||||
|
||||
servers[name] = server;
|
||||
|
||||
console.log("server: start: %s", JSON.stringify(server));
|
||||
|
||||
server.start(done);
|
||||
}
|
||||
};
|
||||
|
||||
// Delete the named server.
|
||||
exports.stop = function(name, done) {
|
||||
console.log("server: stop: %s of %s", name, Object.keys(servers).toString());
|
||||
|
||||
var server = servers[name];
|
||||
if (server) {
|
||||
server.stop(done);
|
||||
delete servers[name];
|
||||
}
|
||||
};
|
||||
|
||||
exports.Server = Server;
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
// console.log("standalone-test.js>");
|
||||
|
||||
var fs = require("fs");
|
||||
var buster = require("buster");
|
||||
|
||||
var server = require("./server.js");
|
||||
var remote = require("../js/remote.js");
|
||||
var config = require("./config.js");
|
||||
|
||||
buster.testCase("Check standalone server startup", {
|
||||
// How long to wait for server to start.
|
||||
var serverDelay = 1500;
|
||||
|
||||
buster.testRunner.timeout = 5000;
|
||||
|
||||
buster.testCase("Standalone server startup", {
|
||||
"server start and stop": function(done) {
|
||||
server.start("alpha",
|
||||
function(e) {
|
||||
@@ -18,5 +23,166 @@ buster.testCase("Check standalone server startup", {
|
||||
}
|
||||
});
|
||||
|
||||
// console.log("standalone-test.js<");
|
||||
buster.testCase("WebSocket connection", {
|
||||
'setUp' :
|
||||
function(done) {
|
||||
server.start("alpha",
|
||||
function(e) {
|
||||
buster.refute(e);
|
||||
done();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
'tearDown' :
|
||||
function(done) {
|
||||
server.stop("alpha", function(e) {
|
||||
buster.refute(e);
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
"websocket connect and disconnect" :
|
||||
function(done) {
|
||||
var alpha = remote.remoteConfig(config, "alpha");
|
||||
|
||||
alpha.connect(function(stat) {
|
||||
buster.assert(1 == stat); // OPEN
|
||||
|
||||
alpha.disconnect(function(stat) {
|
||||
buster.assert(3 == stat); // CLOSED
|
||||
done();
|
||||
});
|
||||
}, serverDelay);
|
||||
},
|
||||
});
|
||||
|
||||
buster.testCase("Websocket commands", {
|
||||
'setUp' :
|
||||
function(done) {
|
||||
server.start("alpha",
|
||||
function(e) {
|
||||
buster.refute(e);
|
||||
|
||||
alpha = remote.remoteConfig(config, "alpha");
|
||||
|
||||
alpha.connect(function(stat) {
|
||||
buster.assert(1 == stat); // OPEN
|
||||
|
||||
done();
|
||||
}, serverDelay);
|
||||
});
|
||||
},
|
||||
|
||||
'tearDown' :
|
||||
function(done) {
|
||||
alpha.disconnect(function(stat) {
|
||||
buster.assert(3 == stat); // CLOSED
|
||||
|
||||
server.stop("alpha", function(e) {
|
||||
buster.refute(e);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'ledger_current' :
|
||||
function(done) {
|
||||
alpha.ledger_current(function (r) {
|
||||
console.log(r);
|
||||
|
||||
buster.assert.equals(r.ledger_index, 3);
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
'// ledger_closed' :
|
||||
function(done) {
|
||||
alpha.ledger_closed(function (r) {
|
||||
console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert.equals(r.ledger_index, 2);
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
'account_root success' :
|
||||
function(done) {
|
||||
alpha.ledger_closed(function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
buster.refute('error' in r);
|
||||
|
||||
alpha.ledger_entry({
|
||||
'ledger_index' : r.ledger_index,
|
||||
'account_root' : 'iHb9CJAWyB4ij91VRWn96DkukG4bwdtyTh'
|
||||
} , function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert('node' in r);
|
||||
done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'account_root malformedAddress' :
|
||||
function(done) {
|
||||
alpha.ledger_closed(function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
buster.refute('error' in r);
|
||||
|
||||
alpha.ledger_entry({
|
||||
'ledger_index' : r.ledger_index,
|
||||
'account_root' : 'foobar'
|
||||
} , function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert.equals(r.error, 'malformedAddress');
|
||||
done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'account_root entryNotFound' :
|
||||
function(done) {
|
||||
alpha.ledger_closed(function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
buster.refute('error' in r);
|
||||
|
||||
alpha.ledger_entry({
|
||||
'ledger_index' : r.ledger_index,
|
||||
'account_root' : 'iG1QQv2nh2gi7RCZ1P8YYcBUKCCN633jCn'
|
||||
} , function (r) {
|
||||
// console.log("account_root: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert.equals(r.error, 'entryNotFound');
|
||||
done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'ledger_entry index' :
|
||||
function(done) {
|
||||
alpha.ledger_closed(function (r) {
|
||||
// console.log("result: %s", JSON.stringify(r));
|
||||
|
||||
buster.refute('error' in r);
|
||||
|
||||
alpha.ledger_entry({
|
||||
'ledger_index' : r.ledger_index,
|
||||
'index' : "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8",
|
||||
} , function (r) {
|
||||
console.log("node: %s", JSON.stringify(r));
|
||||
|
||||
buster.assert('node_binary' in r);
|
||||
done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
Submodule websocketpp updated: f78b9df4ad...dd9899c34b
Reference in New Issue
Block a user