Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
jed
2012-09-30 17:22:33 -07:00
41 changed files with 987 additions and 424 deletions

205
js/remote.js Normal file
View 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

44
js/serializer.js Normal file
View File

@@ -0,0 +1,44 @@
//
var serializer = {};
serializer.addUInt16 = function(value) {
switch (typeof value) {
case 'string':
addUInt16(value.charCodeAt(0));
break;
case 'integer':
for (i = 16/8; i; i -=1) {
raw.push(value & 255);
value >>= 8;
}
break;
default:
throw 'UNEXPECTED_TYPE';
}
};
serializer.addUInt160 = function(value) {
switch (typeof value) {
case 'array':
raw.concat(value);
break;
case 'integer':
for (i = 160/8; i; i -=1) {
raw.push(value & 255);
value >>= 8;
}
break;
default:
throw 'UNEXPECTED_TYPE';
}
};
serializer.getSHA512Half = function() {
};
// vim:ts=4

View File

@@ -119,7 +119,7 @@
1
[debug_logfile]
debug.log
log/debug.log
[sntp_servers]
time.windows.com

View File

@@ -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;

View File

@@ -73,7 +73,8 @@ void Application::run()
boost::thread auxThread(boost::bind(&boost::asio::io_service::run, &mAuxService));
auxThread.detach();
mSNTPClient.init(theConfig.SNTP_SERVERS);
if (!theConfig.RUN_STANDALONE)
mSNTPClient.init(theConfig.SNTP_SERVERS);
//
// Construct databases.

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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())

View File

@@ -394,10 +394,9 @@ void LedgerEntrySet::calcRawMeta(Serializer& s)
if (origNode->getType() == ltRIPPLE_STATE)
{
metaNode.addAccount(TMSLowID, origNode->getIValueFieldAccount(sfLowID));
metaNode.addAccount(TMSHighID, origNode->getIValueFieldAccount(sfHighID));
metaNode.addAccount(TMSLowID, NewcoinAddress::createAccountID(origNode->getIValueFieldAmount(sfLowLimit).getIssuer()));
metaNode.addAccount(TMSHighID, NewcoinAddress::createAccountID(origNode->getIValueFieldAmount(sfHighLimit).getIssuer()));
}
}
if (origNode->getType() == ltOFFER)
@@ -1011,6 +1010,7 @@ STAmount LedgerEntrySet::rippleTransferFee(const uint160& uSenderID, const uint1
void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uReceiverID, const STAmount& saAmount, bool bCheckIssuer)
{
uint160 uIssuerID = saAmount.getIssuer();
uint160 uCurrencyID = saAmount.getCurrency();
assert(!bCheckIssuer || uSenderID == uIssuerID || uReceiverID == uIssuerID);
@@ -1024,14 +1024,16 @@ void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uRece
STAmount saBalance = saAmount;
saBalance.setIssuer(ACCOUNT_ONE);
sleRippleState = entryCreate(ltRIPPLE_STATE, uIndex);
if (!bFlipped)
saBalance.negate();
sleRippleState->setIFieldAmount(sfBalance, saBalance);
sleRippleState->setIFieldAccount(bFlipped ? sfHighID : sfLowID, uSenderID);
sleRippleState->setIFieldAccount(bFlipped ? sfLowID : sfHighID, uReceiverID);
sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit : sfLowLimit, STAmount(uCurrencyID, uSenderID));
sleRippleState->setIFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, uReceiverID));
}
else
{

View File

@@ -73,9 +73,7 @@ LedgerEntryFormat LedgerFormats[]=
{ "RippleState", ltRIPPLE_STATE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LowID), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LowLimit), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(HighID), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(HighLimit), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },

View File

@@ -5,7 +5,6 @@
#include "Application.h"
#include "NewcoinAddress.h"
#include "Conversion.h"
#include "Log.h"
uint32 LedgerMaster::getCurrentLedgerIndex()

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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
@@ -134,8 +136,8 @@ public:
// Directory functions
//
STVector256 getDirNodeInfo(const uint256& uLedger, const uint256& uRootIndex,
uint64& uNodePrevious, uint64& uNodeNext);
STVector256 getDirNodeInfo(const uint256& uLedger, const uint256& uRootIndex,
uint64& uNodePrevious, uint64& uNodeNext);
//
// Nickname functions
@@ -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);

View File

@@ -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)

View File

@@ -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"

View File

@@ -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 &params)
{
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 &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);
if (!obj.empty())
@@ -476,7 +476,6 @@ Json::Value RPCServer::doAccountEmailSet(const Json::Value &params)
{
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 &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);
if (!obj.empty())
@@ -569,12 +568,11 @@ Json::Value RPCServer::doAccountInfo(const Json::Value &params)
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 &params)
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 &params)
{
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 &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);
if (!obj.empty())
@@ -717,7 +713,6 @@ Json::Value RPCServer::doAccountRateSet(const Json::Value &params)
{
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 &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);
if (!obj.empty())
@@ -773,7 +768,6 @@ Json::Value RPCServer::doAccountRateSet(const Json::Value &params)
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 &params)
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 &params)
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 &params)
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 &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())
@@ -1462,7 +1451,7 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
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 &params)
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 &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);
if (!obj.empty())
@@ -1556,8 +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;
uint32 uQualityIn = 0;
@@ -1575,7 +1561,7 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
{
return RPCError(rpcDST_ACT_MALFORMED);
}
else if (!saLimitAmount.setFullValue(params[3u].asString(), params.size() >= 5 ? params[4u].asString() : ""))
else if (!saLimitAmount.setFullValue(params[3u].asString(), params.size() >= 5 ? params[4u].asString() : "", params[2u].asString()))
{
return RPCError(rpcSRC_AMT_MALFORMED);
}
@@ -1594,7 +1580,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())
@@ -1606,8 +1592,7 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
asSrc->getSeq(),
theConfig.FEE_DEFAULT,
0, // YYY No source tag
naDstAccountID,
bLimitAmount, saLimitAmount,
saLimitAmount,
bQualityIn, uQualityIn,
bQualityOut, uQualityOut);
@@ -1627,7 +1612,6 @@ Json::Value RPCServer::doRippleLineSet(const Json::Value& params)
Json::Value RPCServer::doRippleLinesGet(const Json::Value &params)
{
// uint256 uAccepted = mNetOps->getClosedLedger();
uint256 uCurrent = mNetOps->getCurrentLedger();
std::string strIdent = params[0u].asString();
bool bIndex;
@@ -1637,7 +1621,7 @@ Json::Value RPCServer::doRippleLinesGet(const Json::Value &params)
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 +1633,7 @@ Json::Value RPCServer::doRippleLinesGet(const Json::Value &params)
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 +1723,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 +1732,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 +1777,17 @@ Json::Value RPCServer::doSend(const Json::Value& params)
// Destination exists, ordinary send.
STPathSet spsPaths;
uint160 srcCurrencyID;
bool ret_b;
ret_b = false;
if (!saSrcAmountMax.isNative() || !saDstAmount.isNative())
{
STAmount::currencyFromString(srcCurrencyID, sSrcCurrency);
Pathfinder pf(naSrcAccountID, naDstAccountID, srcCurrencyID, saDstAmount);
ret_b = pf.findPaths(5, 1, spsPaths);
}
trans = Transaction::sharedPayment(
naAccountPublic, naAccountPrivate,
naSrcAccountID,
@@ -2081,7 +2074,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 +2083,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 +2116,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 +2142,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 +2168,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 +2303,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 +2316,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 +2329,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 +2508,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 +2538,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, true, 0 },
{ "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 +2598,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);
}

View File

@@ -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)
{

View File

@@ -744,7 +744,7 @@ void RippleCalc::calcNodeRipple(
{
const uint160 uCurrencyID = saCur.getCurrency();
const uint160 uCurIssuerID = saCur.getIssuer();
const uint160 uPrvIssuerID = saPrv.getIssuer();
// const uint160 uPrvIssuerID = saPrv.getIssuer();
STAmount saCurIn = STAmount::divide(STAmount::multiply(saCur, uQualityOut, uCurrencyID, uCurIssuerID), uQualityIn, uCurrencyID, uCurIssuerID);

View File

@@ -7,12 +7,12 @@ RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) :
{
if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return;
mLowID = mLedgerEntry->getIValueFieldAccount(sfLowID);
mHighID = mLedgerEntry->getIValueFieldAccount(sfHighID);
mLowLimit = mLedgerEntry->getIValueFieldAmount(sfLowLimit);
mHighLimit = mLedgerEntry->getIValueFieldAmount(sfHighLimit);
mLowID = NewcoinAddress::createAccountID(mLowLimit.getIssuer());
mHighID = NewcoinAddress::createAccountID(mHighLimit.getIssuer());
mLowQualityIn = mLedgerEntry->getIFieldU32(sfLowQualityIn);
mLowQualityOut = mLedgerEntry->getIFieldU32(sfLowQualityOut);

View File

@@ -128,12 +128,12 @@ NewcoinAddress SerializedLedgerEntry::getOwner()
NewcoinAddress SerializedLedgerEntry::getFirstOwner()
{
return getIValueFieldAccount(sfLowID);
return NewcoinAddress::createAccountID(getIValueFieldAmount(sfLowLimit).getIssuer());
}
NewcoinAddress SerializedLedgerEntry::getSecondOwner()
{
return getIValueFieldAccount(sfHighID);
return NewcoinAddress::createAccountID(getIValueFieldAmount(sfHighLimit).getIssuer());
}
std::vector<uint256> SerializedLedgerEntry::getOwners()
@@ -146,16 +146,25 @@ std::vector<uint256> SerializedLedgerEntry::getOwners()
switch (getIFieldSType(i))
{
case sfAccount:
case sfLowID:
case sfHighID:
{
const STAccount* entry = dynamic_cast<const STAccount *>(mObject.peekAtPIndex(i));
if ((entry != NULL) && entry->getValueH160(account))
owners.push_back(Ledger::getAccountRootIndex(account));
}
{
const STAccount* entry = dynamic_cast<const STAccount *>(mObject.peekAtPIndex(i));
if ((entry != NULL) && entry->getValueH160(account))
owners.push_back(Ledger::getAccountRootIndex(account));
}
break;
case sfLowLimit:
case sfHighLimit:
{
const STAmount* entry = dynamic_cast<const STAmount *>(mObject.peekAtPIndex(i));
if ((entry != NULL))
owners.push_back(Ledger::getAccountRootIndex(entry->getIssuer()));
}
break;
default:
nothing();
break;
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -15,24 +15,11 @@ enum SerializedTypeID
STI_DONE = -1,
STI_NOTPRESENT = 0,
// common types
STI_UINT32 = 1,
STI_UINT64 = 2,
STI_HASH128 = 3,
STI_HASH256 = 4,
STI_TL = 5,
STI_AMOUNT = 6,
STI_VL = 7,
STI_ACCOUNT = 8,
STI_OBJECT = 14,
STI_ARRAY = 15,
// uncommon types
STI_UINT8 = 16,
STI_UINT16 = 17,
STI_HASH160 = 18,
STI_PATHSET = 19,
STI_VECTOR256 = 20,
#define TYPE(name, field, value) STI_##field = value,
#define FIELD(name, field, value)
#include "SerializeProto.h"
#undef TYPE
#undef FIELD
// high level types
STI_TRANSACTION = 100001,
@@ -730,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:

View File

@@ -256,18 +256,13 @@ Transaction::pointer Transaction::sharedCreate(
Transaction::pointer Transaction::setCreditSet(
const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naDstAccountID,
bool bLimitAmount,
const STAmount& saLimitAmount,
bool bQualityIn,
uint32 uQualityIn,
bool bQualityOut,
uint32 uQualityOut)
{
mTransaction->setITFieldAccount(sfDestination, naDstAccountID);
if (bLimitAmount)
mTransaction->setITFieldAmount(sfLimitAmount, saLimitAmount);
mTransaction->setITFieldAmount(sfLimitAmount, saLimitAmount);
if (bQualityIn)
mTransaction->setITFieldU32(sfQualityIn, uQualityIn);
@@ -286,8 +281,6 @@ Transaction::pointer Transaction::sharedCreditSet(
uint32 uSeq,
const STAmount& saFee,
uint32 uSourceTag,
const NewcoinAddress& naDstAccountID,
bool bLimitAmount,
const STAmount& saLimitAmount,
bool bQualityIn,
uint32 uQualityIn,
@@ -296,8 +289,8 @@ Transaction::pointer Transaction::sharedCreditSet(
{
pointer tResult = boost::make_shared<Transaction>(ttCREDIT_SET, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag);
return tResult->setCreditSet(naPrivateKey, naDstAccountID,
bLimitAmount, saLimitAmount,
return tResult->setCreditSet(naPrivateKey,
saLimitAmount,
bQualityIn, uQualityIn,
bQualityOut, uQualityOut);
}

View File

@@ -74,8 +74,6 @@ private:
Transaction::pointer setCreditSet(
const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naDstAccountID,
bool bLimitAmount,
const STAmount& saLimitAmount,
bool bQualityIn,
uint32 uQualityIn,
@@ -185,8 +183,6 @@ public:
uint32 uSeq,
const STAmount& saFee,
uint32 uSourceTag,
const NewcoinAddress& naDstAccountID,
bool bLimitAmount,
const STAmount& saLimitAmount,
bool bQualityIn,
uint32 uQualityIn,

View File

@@ -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;
}
}
//
@@ -235,18 +241,27 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn)
TER terResult = tesSUCCESS;
Log(lsINFO) << "doCreditSet>";
const STAmount saLimitAmount = txn.getITFieldAmount(sfLimitAmount);
const bool bQualityIn = txn.getITFieldPresent(sfQualityIn);
const uint32 uQualityIn = bQualityIn ? txn.getITFieldU32(sfQualityIn) : 0;
const bool bQualityOut = txn.getITFieldPresent(sfQualityOut);
const uint32 uQualityOut = bQualityIn ? txn.getITFieldU32(sfQualityOut) : 0;
const uint160 uCurrencyID = saLimitAmount.getCurrency();
uint160 uDstAccountID = saLimitAmount.getIssuer();
const bool bFlipped = mTxnAccountID > uDstAccountID; // true, iff current is not lowest.
bool bDelIndex = false;
// Check if destination makes sense.
uint160 uDstAccountID = txn.getITFieldAccount(sfDestination);
if (!uDstAccountID)
{
Log(lsINFO) << "doCreditSet: Invalid transaction: Destination account not specifed.";
Log(lsINFO) << "doCreditSet: Malformed transaction: Destination account not specifed.";
return temDST_NEEDED;
}
else if (mTxnAccountID == uDstAccountID)
{
Log(lsINFO) << "doCreditSet: Invalid transaction: Can not extend credit to self.";
Log(lsINFO) << "doCreditSet: Malformed transaction: Can not extend credit to self.";
return temDST_IS_SRC;
}
@@ -259,15 +274,8 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn)
return terNO_DST;
}
const bool bFlipped = mTxnAccountID > uDstAccountID; // true, iff current is not lowest.
const bool bLimitAmount = txn.getITFieldPresent(sfLimitAmount);
const STAmount saLimitAmount = bLimitAmount ? txn.getITFieldAmount(sfLimitAmount) : STAmount();
const bool bQualityIn = txn.getITFieldPresent(sfQualityIn);
const uint32 uQualityIn = bQualityIn ? txn.getITFieldU32(sfQualityIn) : 0;
const bool bQualityOut = txn.getITFieldPresent(sfQualityOut);
const uint32 uQualityOut = bQualityIn ? txn.getITFieldU32(sfQualityOut) : 0;
const uint160 uCurrencyID = saLimitAmount.getCurrency();
bool bDelIndex = false;
STAmount saLimitAllow = saLimitAmount;
saLimitAllow.setIssuer(mTxnAccountID);
SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(mTxnAccountID, uDstAccountID, uCurrencyID));
if (sleRippleState)
@@ -277,8 +285,8 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn)
if (!saLimitAmount)
{
// Zeroing line.
uint160 uLowID = sleRippleState->getIValueFieldAccount(sfLowID).getAccountID();
uint160 uHighID = sleRippleState->getIValueFieldAccount(sfHighID).getAccountID();
uint160 uLowID = sleRippleState->getIValueFieldAmount(sfLowLimit).getIssuer();
uint160 uHighID = sleRippleState->getIValueFieldAmount(sfHighLimit).getIssuer();
bool bLow = uLowID == uSrcAccountID;
bool bHigh = uLowID == uDstAccountID;
bool bBalanceZero = !sleRippleState->getIValueFieldAmount(sfBalance);
@@ -299,8 +307,7 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn)
if (!bDelIndex)
{
if (bLimitAmount)
sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit: sfLowLimit , saLimitAmount);
sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit: sfLowLimit, saLimitAllow);
if (!bQualityIn)
{
@@ -348,10 +355,9 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn)
Log(lsINFO) << "doCreditSet: Creating ripple line: " << sleRippleState->getIndex().ToString();
sleRippleState->setIFieldAmount(sfBalance, STAmount(uCurrencyID, ACCOUNT_ONE)); // Zero balance in currency.
sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit : sfLowLimit, saLimitAmount);
sleRippleState->setIFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, ACCOUNT_ONE));
sleRippleState->setIFieldAccount(bFlipped ? sfHighID : sfLowID, mTxnAccountID);
sleRippleState->setIFieldAccount(bFlipped ? sfLowID : sfHighID, uDstAccountID);
sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit : sfLowLimit, saLimitAllow);
sleRippleState->setIFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, uDstAccountID));
if (uQualityIn)
sleRippleState->setIFieldU32(bFlipped ? sfHighQualityIn : sfLowQualityIn, uQualityIn);
if (uQualityOut)

View File

@@ -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

View File

@@ -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,

View File

@@ -27,11 +27,10 @@ TransactionFormat InnerTxnFormats[]=
},
{ "CreditSet", ttCREDIT_SET, {
{ 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(LimitAmount), STI_AMOUNT, SOE_IFFLAG, 2 },
{ S_FIELD(QualityIn), STI_UINT32, SOE_IFFLAG, 4 },
{ S_FIELD(QualityOut), STI_UINT32, SOE_IFFLAG, 8 },
{ S_FIELD(LimitAmount), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(QualityIn), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(QualityOut), STI_UINT32, SOE_IFFLAG, 2 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
/*

View File

@@ -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"

View File

@@ -16,11 +16,11 @@
// Version we prefer to speak:
#define PROTO_VERSION_MAJOR 0
#define PROTO_VERSION_MINOR 7
#define PROTO_VERSION_MINOR 8
// Version we will speak to:
#define MIN_PROTO_MAJOR 0
#define MIN_PROTO_MINOR 7
#define MIN_PROTO_MINOR 8
#define MAKE_VERSION_INT(maj,min) ((maj << 16) | min)
#define GET_VERSION_MAJOR(ver) (ver >> 16)

View File

@@ -22,6 +22,9 @@
// This is a light weight, untrusted interface for web clients.
// For now we don't provide proof. Later we will.
//
// Might need to support this header for browsers: Access-Control-Allow-Origin: *
// - https://developer.mozilla.org/en-US/docs/HTTP_access_control
//
//
// Strategy:
@@ -75,7 +78,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 +301,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 +555,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))

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -1,4 +1,7 @@
// Manage test servers
//
// YYY Would be nice to be able to hide server output.
//
// Provide servers
//

View File

@@ -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,4 +23,166 @@ buster.testCase("Check standalone server startup", {
}
});
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