mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,6 +15,7 @@
|
||||
# Ignore object files.
|
||||
*.o
|
||||
build
|
||||
tags
|
||||
|
||||
# Ignore locally installed node_modules
|
||||
node_modules
|
||||
|
||||
@@ -132,7 +132,7 @@ for file in RIPPLE_SRCS:
|
||||
|
||||
rippled = env.Program('build/rippled', RIPPLE_OBJS)
|
||||
|
||||
tags = env.CTags('build/obj/tags', RIPPLE_SRCS)
|
||||
tags = env.CTags('tags', RIPPLE_SRCS)
|
||||
|
||||
Default(rippled, tags)
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#
|
||||
# Sample rippled.cfg
|
||||
#
|
||||
# This file contains configuration information for rippled.
|
||||
#
|
||||
# This file should be named rippled.cfg. This file is UTF-8 with Dos, UNIX,
|
||||
# or Mac style end of lines. Blank lines and lines beginning with '#' are
|
||||
# ignored. Undefined sections are reserved. No escapes are currently defined.
|
||||
@@ -19,8 +21,7 @@
|
||||
#
|
||||
# Example: ripple.com
|
||||
#
|
||||
# [unl_default]:
|
||||
# XXX This should be called: [validators_file]
|
||||
# [validators_file]:
|
||||
# Specifies how to bootstrap the UNL list. The UNL list is based on a
|
||||
# validators.txt file and is maintained in the databases. When rippled
|
||||
# starts up, if the databases are missing or are obsolete due to an upgrade
|
||||
@@ -75,6 +76,11 @@
|
||||
# [peer_port]:
|
||||
# Port to bind to allow external connections from peers.
|
||||
#
|
||||
# [peer_private]:
|
||||
# 0 or 1.
|
||||
# 0: allow peers to broadcast your address. [default]
|
||||
# 1: request peers not broadcast your address.
|
||||
#
|
||||
# [rpc_ip]:
|
||||
# IP address or domain to bind to allow insecure RPC connections.
|
||||
# Defaults to not allow RPC connections.
|
||||
@@ -83,7 +89,8 @@
|
||||
# Port to bind to if allowing insecure RPC connections.
|
||||
#
|
||||
# [rpc_allow_remote]:
|
||||
# 0 or 1. 0 only allows RPC connections from 127.0.0.1. [default 0]
|
||||
# 0 or 1.
|
||||
# 0: only allows RPC connections from 127.0.0.1. [default]
|
||||
#
|
||||
# [websocket_ip]:
|
||||
# IP address or domain to bind to allow client connections.
|
||||
@@ -20,6 +20,7 @@
|
||||
#define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water"
|
||||
#define SECTION_PEER_IP "peer_ip"
|
||||
#define SECTION_PEER_PORT "peer_port"
|
||||
#define SECTION_PEER_PRIVATE "peer_private"
|
||||
#define SECTION_PEER_SCAN_INTERVAL_MIN "peer_scan_interval_min"
|
||||
#define SECTION_PEER_SSL_CIPHER_LIST "peer_ssl_cipher_list"
|
||||
#define SECTION_PEER_START_MAX "peer_start_max"
|
||||
@@ -27,7 +28,7 @@
|
||||
#define SECTION_RPC_IP "rpc_ip"
|
||||
#define SECTION_RPC_PORT "rpc_port"
|
||||
#define SECTION_SNTP "sntp_servers"
|
||||
#define SECTION_UNL_DEFAULT "unl_default"
|
||||
#define SECTION_VALIDATORS_FILE "validators_file"
|
||||
#define SECTION_VALIDATION_QUORUM "validation_quorum"
|
||||
#define SECTION_VALIDATION_SEED "validation_seed"
|
||||
#define SECTION_WEBSOCKET_PUBLIC_IP "websocket_public_ip"
|
||||
@@ -143,6 +144,8 @@ void Config::setup(const std::string& strConf)
|
||||
PEER_START_MAX = DEFAULT_PEER_START_MAX;
|
||||
PEER_CONNECT_LOW_WATER = DEFAULT_PEER_CONNECT_LOW_WATER;
|
||||
|
||||
PEER_PRIVATE = false;
|
||||
|
||||
TRANSACTION_FEE_BASE = 1000;
|
||||
|
||||
NETWORK_QUORUM = 0; // Don't need to see other nodes
|
||||
@@ -222,6 +225,9 @@ void Config::load()
|
||||
if (sectionSingleB(secConfig, SECTION_PEER_PORT, strTemp))
|
||||
PEER_PORT = boost::lexical_cast<int>(strTemp);
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_PEER_PRIVATE, strTemp))
|
||||
PEER_PRIVATE = boost::lexical_cast<bool>(strTemp);
|
||||
|
||||
(void) sectionSingleB(secConfig, SECTION_RPC_IP, RPC_IP);
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_RPC_PORT, strTemp))
|
||||
@@ -292,8 +298,8 @@ void Config::load()
|
||||
if (sectionSingleB(secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp))
|
||||
ACCOUNT_PROBE_MAX = boost::lexical_cast<int>(strTemp);
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_UNL_DEFAULT, strTemp))
|
||||
UNL_DEFAULT = strTemp;
|
||||
if (sectionSingleB(secConfig, SECTION_VALIDATORS_FILE, strTemp))
|
||||
VALIDATORS_FILE = strTemp;
|
||||
|
||||
if (sectionSingleB(secConfig, SECTION_DEBUG_LOGFILE, strTemp))
|
||||
DEBUG_LOGFILE = strTemp;
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
boost::filesystem::path CONFIG_DIR;
|
||||
boost::filesystem::path DATA_DIR;
|
||||
boost::filesystem::path DEBUG_LOGFILE;
|
||||
boost::filesystem::path UNL_DEFAULT;
|
||||
boost::filesystem::path VALIDATORS_FILE;
|
||||
|
||||
std::string VALIDATORS_SITE; // Where to find validators.txt on the Internet.
|
||||
std::vector<std::string> VALIDATORS; // Validators from rippled.cfg.
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
int LEDGER_SECONDS;
|
||||
int LEDGER_PROPOSAL_DELAY_SECONDS;
|
||||
int LEDGER_AVALANCHE_SECONDS;
|
||||
bool LEDGER_CREATOR; // should be false unless we are starting a new ledger
|
||||
bool LEDGER_CREATOR; // Should be false unless we are starting a new ledger.
|
||||
bool RUN_STANDALONE;
|
||||
|
||||
// Note: The following parameters do not relate to the UNL or trust at all
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
int PEER_SCAN_INTERVAL_MIN;
|
||||
int PEER_START_MAX;
|
||||
unsigned int PEER_CONNECT_LOW_WATER;
|
||||
bool PEER_PRIVATE; // True to ask peers not to relay current IP.
|
||||
|
||||
// Websocket networking parameters
|
||||
std::string WEBSOCKET_PUBLIC_IP; // XXX Going away. Merge with the inbound peer connction.
|
||||
|
||||
@@ -300,6 +300,7 @@ void ConnectionPool::connectTo(const std::string& strIp, int iPort)
|
||||
{
|
||||
if (theConfig.RUN_STANDALONE)
|
||||
return;
|
||||
|
||||
{
|
||||
Database* db = theApp->getWalletDB()->getDB();
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
|
||||
@@ -396,7 +396,7 @@ bool LedgerAcquire::takeBase(const std::string& data)
|
||||
}
|
||||
|
||||
bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
const std::list< std::vector<unsigned char> >& data)
|
||||
const std::list< std::vector<unsigned char> >& data, SMAddNode& san)
|
||||
{
|
||||
if (!mHaveBase) return false;
|
||||
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
|
||||
@@ -406,11 +406,15 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
{
|
||||
if (nodeIDit->isRoot())
|
||||
{
|
||||
if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait, snfWIRE, &tFilter))
|
||||
if (!san.combine(mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait,
|
||||
snfWIRE, &tFilter)))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!san.combine(mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter)))
|
||||
return false;
|
||||
}
|
||||
else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter))
|
||||
return false;
|
||||
++nodeIDit;
|
||||
++nodeDatait;
|
||||
}
|
||||
@@ -428,7 +432,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
}
|
||||
|
||||
bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
const std::list< std::vector<unsigned char> >& data)
|
||||
const std::list< std::vector<unsigned char> >& data, SMAddNode& san)
|
||||
{
|
||||
cLog(lsTRACE) << "got ASdata (" << nodeIDs.size() <<") acquiring ledger " << mHash;
|
||||
tLog(nodeIDs.size() == 1, lsTRACE) << "got AS node: " << nodeIDs.front();
|
||||
@@ -446,14 +450,14 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
{
|
||||
if (nodeIDit->isRoot())
|
||||
{
|
||||
if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(),
|
||||
*nodeDatait, snfWIRE, &tFilter))
|
||||
if (!san.combine(mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(),
|
||||
*nodeDatait, snfWIRE, &tFilter)))
|
||||
{
|
||||
cLog(lsWARNING) << "Bad ledger base";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter))
|
||||
else if (!san.combine(mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter)))
|
||||
{
|
||||
cLog(lsWARNING) << "Unable to add AS node";
|
||||
return false;
|
||||
@@ -474,24 +478,22 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LedgerAcquire::takeAsRootNode(const std::vector<unsigned char>& data)
|
||||
bool LedgerAcquire::takeAsRootNode(const std::vector<unsigned char>& data, SMAddNode& san)
|
||||
{
|
||||
if (!mHaveBase)
|
||||
return false;
|
||||
AccountStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
|
||||
if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), data, snfWIRE, &tFilter))
|
||||
return false;
|
||||
return true;
|
||||
return san.combine(
|
||||
mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), data, snfWIRE, &tFilter));
|
||||
}
|
||||
|
||||
bool LedgerAcquire::takeTxRootNode(const std::vector<unsigned char>& data)
|
||||
bool LedgerAcquire::takeTxRootNode(const std::vector<unsigned char>& data, SMAddNode& san)
|
||||
{
|
||||
if (!mHaveBase)
|
||||
return false;
|
||||
TransactionStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
|
||||
if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), data, snfWIRE, &tFilter))
|
||||
return false;
|
||||
return true;
|
||||
return san.combine(
|
||||
mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), data, snfWIRE, &tFilter));
|
||||
}
|
||||
|
||||
LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash)
|
||||
@@ -532,13 +534,13 @@ void LedgerAcquireMaster::dropLedger(const uint256& hash)
|
||||
mLedgers.erase(hash);
|
||||
}
|
||||
|
||||
bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref peer)
|
||||
SMAddNode LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref peer)
|
||||
{
|
||||
uint256 hash;
|
||||
if (packet.ledgerhash().size() != 32)
|
||||
{
|
||||
std::cerr << "Acquire error" << std::endl;
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
memcpy(hash.begin(), packet.ledgerhash().data(), 32);
|
||||
cLog(lsTRACE) << "Got data (" << packet.nodes().size() << ") for acquiring ledger: " << hash;
|
||||
@@ -547,7 +549,7 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
|
||||
if (!ledger)
|
||||
{
|
||||
cLog(lsINFO) << "Got data for ledger we're not acquiring";
|
||||
return false;
|
||||
return SMAddNode();
|
||||
}
|
||||
|
||||
if (packet.type() == ripple::liBASE)
|
||||
@@ -555,23 +557,24 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
|
||||
if (packet.nodes_size() < 1)
|
||||
{
|
||||
cLog(lsWARNING) << "Got empty base data";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
if (!ledger->takeBase(packet.nodes(0).nodedata()))
|
||||
{
|
||||
cLog(lsWARNING) << "Got invalid base data";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
if ((packet.nodes().size() > 1) && !ledger->takeAsRootNode(strCopy(packet.nodes(1).nodedata())))
|
||||
SMAddNode san = SMAddNode::useful();
|
||||
if ((packet.nodes().size() > 1) && !ledger->takeAsRootNode(strCopy(packet.nodes(1).nodedata()), san))
|
||||
{
|
||||
cLog(lsWARNING) << "Included ASbase invalid";
|
||||
}
|
||||
if ((packet.nodes().size() > 2) && !ledger->takeTxRootNode(strCopy(packet.nodes(2).nodedata())))
|
||||
if ((packet.nodes().size() > 2) && !ledger->takeTxRootNode(strCopy(packet.nodes(2).nodedata()), san))
|
||||
{
|
||||
cLog(lsWARNING) << "Included TXbase invalid";
|
||||
}
|
||||
ledger->trigger(peer, false);
|
||||
return true;
|
||||
return san;
|
||||
}
|
||||
|
||||
if ((packet.type() == ripple::liTX_NODE) || (packet.type() == ripple::liAS_NODE))
|
||||
@@ -581,8 +584,8 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
|
||||
|
||||
if (packet.nodes().size() <= 0)
|
||||
{
|
||||
cLog(lsINFO) << "Got request for no nodes";
|
||||
return false;
|
||||
cLog(lsINFO) << "Got response with no nodes";
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
for (int i = 0; i < packet.nodes().size(); ++i)
|
||||
{
|
||||
@@ -590,24 +593,24 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
|
||||
if (!node.has_nodeid() || !node.has_nodedata())
|
||||
{
|
||||
cLog(lsWARNING) << "Got bad node";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
|
||||
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
|
||||
nodeData.push_back(std::vector<unsigned char>(node.nodedata().begin(), node.nodedata().end()));
|
||||
}
|
||||
bool ret;
|
||||
SMAddNode ret;
|
||||
if (packet.type() == ripple::liTX_NODE)
|
||||
ret = ledger->takeTxNode(nodeIDs, nodeData);
|
||||
ledger->takeTxNode(nodeIDs, nodeData, ret);
|
||||
else
|
||||
ret = ledger->takeAsNode(nodeIDs, nodeData);
|
||||
if (ret)
|
||||
ledger->takeAsNode(nodeIDs, nodeData, ret);
|
||||
if (!ret.isInvalid())
|
||||
ledger->trigger(peer, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cLog(lsWARNING) << "Not sure what ledger data we got";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -97,10 +97,12 @@ public:
|
||||
void addOnComplete(boost::function<void (LedgerAcquire::pointer)>);
|
||||
|
||||
bool takeBase(const std::string& data);
|
||||
bool takeTxNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data);
|
||||
bool takeTxRootNode(const std::vector<unsigned char>& data);
|
||||
bool takeAsNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data);
|
||||
bool takeAsRootNode(const std::vector<unsigned char>& data);
|
||||
bool takeTxNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data,
|
||||
SMAddNode&);
|
||||
bool takeTxRootNode(const std::vector<unsigned char>& data, SMAddNode&);
|
||||
bool takeAsNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data,
|
||||
SMAddNode&);
|
||||
bool takeAsRootNode(const std::vector<unsigned char>& data, SMAddNode&);
|
||||
void trigger(Peer::ref, bool timer);
|
||||
bool tryLocal();
|
||||
void addPeers();
|
||||
@@ -119,7 +121,7 @@ public:
|
||||
LedgerAcquire::pointer find(const uint256& hash);
|
||||
bool hasLedger(const uint256& ledgerHash);
|
||||
void dropLedger(const uint256& ledgerHash);
|
||||
bool gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
|
||||
SMAddNode gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -126,21 +126,23 @@ void TransactionAcquire::trigger(Peer::ref peer, bool timer)
|
||||
resetTimer();
|
||||
}
|
||||
|
||||
bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
|
||||
SMAddNode TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
|
||||
const std::list< std::vector<unsigned char> >& data, Peer::ref peer)
|
||||
{
|
||||
if (mComplete)
|
||||
{
|
||||
cLog(lsTRACE) << "TX set complete";
|
||||
return true;
|
||||
return SMAddNode();
|
||||
}
|
||||
if (mFailed)
|
||||
{
|
||||
cLog(lsTRACE) << "TX set failed";
|
||||
return false;
|
||||
return SMAddNode();
|
||||
}
|
||||
try
|
||||
{
|
||||
if (nodeIDs.empty())
|
||||
return SMAddNode::invalid();
|
||||
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
|
||||
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
|
||||
ConsensusTransSetSF sf;
|
||||
@@ -151,12 +153,12 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (mHaveRoot)
|
||||
{
|
||||
cLog(lsWARNING) << "Got root TXS node, already have it";
|
||||
return false;
|
||||
return SMAddNode();
|
||||
}
|
||||
if (!mMap->addRootNode(getHash(), *nodeDatait, snfWIRE, NULL))
|
||||
{
|
||||
cLog(lsWARNING) << "TX acquire got bad root node";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
else
|
||||
mHaveRoot = true;
|
||||
@@ -164,19 +166,19 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
|
||||
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait, &sf))
|
||||
{
|
||||
cLog(lsWARNING) << "TX acquire got bad non-root node";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
++nodeIDit;
|
||||
++nodeDatait;
|
||||
}
|
||||
trigger(peer, false);
|
||||
progress();
|
||||
return true;
|
||||
return SMAddNode::useful();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cLog(lsERROR) << "Peer sends us junky transaction node data";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -996,14 +998,14 @@ bool LedgerConsensus::peerHasSet(Peer::ref peer, const uint256& hashSet, ripple:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
|
||||
SMAddNode LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
|
||||
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData)
|
||||
{
|
||||
boost::unordered_map<uint256, TransactionAcquire::pointer>::iterator acq = mAcquiring.find(setHash);
|
||||
if (acq == mAcquiring.end())
|
||||
{
|
||||
cLog(lsINFO) << "Got TX data for set not acquiring: " << setHash;
|
||||
return false;
|
||||
return SMAddNode();
|
||||
}
|
||||
TransactionAcquire::pointer set = acq->second; // We must keep the set around during the function
|
||||
return set->takeNodes(nodeIDs, nodeData, peer);
|
||||
|
||||
@@ -45,7 +45,8 @@ public:
|
||||
|
||||
SHAMap::pointer getMap() { return mMap; }
|
||||
|
||||
bool takeNodes(const std::list<SHAMapNode>& IDs, const std::list< std::vector<unsigned char> >& data, Peer::ref);
|
||||
SMAddNode takeNodes(const std::list<SHAMapNode>& IDs,
|
||||
const std::list< std::vector<unsigned char> >& data, Peer::ref);
|
||||
};
|
||||
|
||||
class LCTransaction
|
||||
@@ -184,7 +185,7 @@ public:
|
||||
|
||||
bool peerHasSet(Peer::ref peer, const uint256& set, ripple::TxSetStatus status);
|
||||
|
||||
bool peerGaveNodes(Peer::ref peer, const uint256& setHash,
|
||||
SMAddNode peerGaveNodes(Peer::ref peer, const uint256& setHash,
|
||||
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
|
||||
|
||||
bool isOurPubKey(const RippleAddress &k) { return k == mValPublic; }
|
||||
|
||||
@@ -813,13 +813,13 @@ SHAMap::pointer NetworkOPs::getTXMap(const uint256& hash)
|
||||
return mConsensus->getTransactionTree(hash, false);
|
||||
}
|
||||
|
||||
bool NetworkOPs::gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
|
||||
SMAddNode NetworkOPs::gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
|
||||
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData)
|
||||
{
|
||||
if (!haveConsensusObject())
|
||||
{
|
||||
cLog(lsWARNING) << "Got TX data with no consensus object";
|
||||
return false;
|
||||
return SMAddNode();
|
||||
}
|
||||
return mConsensus->peerGaveNodes(peer, hash, nodeIDs, nodeData);
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
// ledger proposal/close functions
|
||||
void processTrustedProposal(LedgerProposal::pointer proposal, boost::shared_ptr<ripple::TMProposeSet> set,
|
||||
RippleAddress nodePublic, uint256 checkLedger, bool sigGood);
|
||||
bool gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
|
||||
SMAddNode gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
|
||||
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
|
||||
bool recvValidation(const SerializedValidation::pointer& val);
|
||||
SHAMap::pointer getTXMap(const uint256& hash);
|
||||
|
||||
@@ -36,27 +36,24 @@ Test XRP to USD
|
||||
Test USD to EUR
|
||||
*/
|
||||
|
||||
|
||||
// we sort the options by:
|
||||
// cost of path
|
||||
// length of path
|
||||
// width of path
|
||||
// correct currency at the end
|
||||
|
||||
|
||||
|
||||
bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
|
||||
{
|
||||
if(first->mTotalCost<second->mTotalCost) return(true);
|
||||
if(first->mTotalCost>second->mTotalCost) return(false);
|
||||
if (first->mTotalCost<second->mTotalCost) return(true);
|
||||
if (first->mTotalCost>second->mTotalCost) return(false);
|
||||
|
||||
if(first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
|
||||
if(!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
|
||||
if (first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
|
||||
if (!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
|
||||
|
||||
if(first->mPath.getElementCount()<second->mPath.getElementCount()) return(true);
|
||||
if(first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
|
||||
if (first->mPath.getElementCount()<second->mPath.getElementCount()) return(true);
|
||||
if (first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
|
||||
|
||||
if(first->mMinWidth<second->mMinWidth) return true;
|
||||
if (first->mMinWidth<second->mMinWidth) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -76,98 +73,115 @@ PathOption::PathOption(PathOption::pointer other)
|
||||
}
|
||||
|
||||
|
||||
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
||||
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
||||
mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
||||
{
|
||||
mLedger=theApp->getMasterLedger().getCurrentLedger();
|
||||
}
|
||||
|
||||
// Returns a single path, if possible.
|
||||
// --> maxSearchSteps: unused
|
||||
// --> maxPay: unused
|
||||
bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet)
|
||||
{
|
||||
if(mLedger) {
|
||||
std::queue<STPath> pqueue;
|
||||
STPathElement ele(mSrcAccountID,
|
||||
mSrcCurrencyID,
|
||||
uint160());
|
||||
STPath path;
|
||||
path.addElement(ele);
|
||||
pqueue.push(path);
|
||||
while(pqueue.size()) {
|
||||
if (mLedger) {
|
||||
std::queue<STPath> pqueue;
|
||||
STPathElement ele(mSrcAccountID,
|
||||
mSrcCurrencyID,
|
||||
uint160());
|
||||
STPath path;
|
||||
|
||||
STPath path = pqueue.front();
|
||||
pqueue.pop();
|
||||
// get the first path from the queue
|
||||
path.addElement(ele); // Add the source.
|
||||
|
||||
ele = path.mPath.back();
|
||||
// get the last node from the path
|
||||
pqueue.push(path);
|
||||
|
||||
if (ele.mAccountID == mDstAccountID) {
|
||||
path.mPath.erase(path.mPath.begin());
|
||||
path.mPath.erase(path.mPath.begin() + path.mPath.size()-1);
|
||||
if (path.mPath.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
retPathSet.addPath(path);
|
||||
return true;
|
||||
}
|
||||
// found the destination
|
||||
while (pqueue.size()) {
|
||||
STPath path = pqueue.front();
|
||||
|
||||
if (!ele.mCurrencyID) {
|
||||
BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXRPInBooks())
|
||||
{
|
||||
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
pqueue.pop(); // Pop the first path from the queue.
|
||||
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrencyID = book->getCurrencyOut();
|
||||
new_path.mCurrentAccount = book->getCurrencyOut();
|
||||
ele = path.mPath.back(); // Get the last node from the path.
|
||||
|
||||
pqueue.push(new_path);
|
||||
// Determine if path is solved.
|
||||
if (ele.mAccountID == mDstAccountID) {
|
||||
// Found a path to the destination.
|
||||
|
||||
}
|
||||
}
|
||||
if (2 == path.mPath.size()) {
|
||||
// Empty path is default. Drop it.
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
RippleLines rippleLines(ele.mAccountID);
|
||||
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
|
||||
{
|
||||
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(line->getAccountIDPeer().getAccountID(),
|
||||
ele.mCurrencyID,
|
||||
uint160());
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
} // BOOST_FOREACHE
|
||||
// Remove implied first and last nodes.
|
||||
path.mPath.erase(path.mPath.begin());
|
||||
path.mPath.erase(path.mPath.begin() + path.mPath.size()-1);
|
||||
|
||||
// every offer that wants the source currency
|
||||
std::vector<OrderBook::pointer> books;
|
||||
mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books);
|
||||
// Return the path.
|
||||
retPathSet.addPath(path);
|
||||
|
||||
BOOST_FOREACH(OrderBook::pointer book,books)
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
return true;
|
||||
}
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrentAccount=book->getIssuerOut();
|
||||
new_path.mCurrencyID=book->getCurrencyOut();
|
||||
if (!ele.mCurrencyID) {
|
||||
// Last element is for XRP continue with qualifying books.
|
||||
|
||||
pqueue.push(new_path);
|
||||
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
|
||||
{
|
||||
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
|
||||
}
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrencyID = book->getCurrencyOut();
|
||||
new_path.mCurrentAccount = book->getCurrencyOut();
|
||||
|
||||
} // else
|
||||
// enumerate all adjacent nodes, construct a new path and push it into the queue
|
||||
} // While
|
||||
} // if there is a ledger
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Last element is for non-XRP continue by adding ripple lines and order books.
|
||||
|
||||
// Create new paths for each outbound account not already in the path.
|
||||
RippleLines rippleLines(ele.mAccountID);
|
||||
|
||||
BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines())
|
||||
{
|
||||
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(line->getAccountIDPeer().getAccountID(),
|
||||
ele.mCurrencyID,
|
||||
uint160());
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Every book that wants the source currency.
|
||||
std::vector<OrderBook::pointer> books;
|
||||
|
||||
mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books);
|
||||
|
||||
BOOST_FOREACH(OrderBook::pointer book,books)
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrentAccount=book->getIssuerOut();
|
||||
new_path.mCurrencyID=book->getCurrencyOut();
|
||||
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
// enumerate all adjacent nodes, construct a new path and push it into the queue
|
||||
} // While
|
||||
} // if there is a ledger
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
||||
@@ -196,9 +210,9 @@ bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
||||
|
||||
void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
{
|
||||
if(!tail->mCurrencyID)
|
||||
if (!tail->mCurrencyID)
|
||||
{ // source XRP
|
||||
BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXRPInBooks())
|
||||
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
|
||||
{
|
||||
PathOption::pointer pathOption(new PathOption(tail));
|
||||
|
||||
@@ -209,13 +223,14 @@ void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
pathOption->mCurrencyID=book->getCurrencyOut();
|
||||
addPathOption(pathOption);
|
||||
}
|
||||
}else
|
||||
}
|
||||
else
|
||||
{ // ripple
|
||||
RippleLines rippleLines(tail->mCurrentAccount);
|
||||
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
|
||||
{
|
||||
// TODO: make sure we can move in the correct direction
|
||||
STAmount balance=line->getBalance();
|
||||
STAmount balance=line->getBalance();
|
||||
if(balance.getCurrency()==tail->mCurrencyID)
|
||||
{ // we have a ripple line from the tail to somewhere else
|
||||
PathOption::pointer pathOption(new PathOption(tail));
|
||||
|
||||
@@ -430,24 +430,29 @@ void Peer::processReadBuffer()
|
||||
case ripple::mtCONTACT:
|
||||
{
|
||||
ripple::TMContact msg;
|
||||
|
||||
if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
|
||||
recvContact(msg);
|
||||
else
|
||||
cLog(lsWARNING) << "parse error: " << type;
|
||||
}
|
||||
break;
|
||||
|
||||
case ripple::mtGET_PEERS:
|
||||
{
|
||||
ripple::TMGetPeers msg;
|
||||
|
||||
if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
|
||||
recvGetPeers(msg);
|
||||
else
|
||||
cLog(lsWARNING) << "parse error: " << type;
|
||||
}
|
||||
break;
|
||||
|
||||
case ripple::mtPEERS:
|
||||
{
|
||||
ripple::TMPeers msg;
|
||||
|
||||
if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
|
||||
recvPeers(msg);
|
||||
else
|
||||
@@ -666,7 +671,17 @@ void Peer::recvHello(ripple::TMHello& packet)
|
||||
std::string strIP = getSocket().remote_endpoint().address().to_string();
|
||||
int iPort = packet.ipv4port();
|
||||
|
||||
theApp->getConnectionPool().savePeer(strIP, iPort, UniqueNodeList::vsInbound);
|
||||
if (mHello.nodeprivate())
|
||||
{
|
||||
cLog(lsINFO) << boost::str(boost::format("Recv(Hello): Private connection: %s %s") % strIP % iPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't save IP address if the node wants privacy.
|
||||
// Note: We don't go so far as to delete it. If a node which has previously announced itself now wants
|
||||
// privacy, it should at least change its port.
|
||||
theApp->getConnectionPool().savePeer(strIP, iPort, UniqueNodeList::vsInbound);
|
||||
}
|
||||
}
|
||||
|
||||
// Consider us connected. No longer accepting mtHELLO.
|
||||
@@ -994,7 +1009,7 @@ void Peer::recvGetContacts(ripple::TMGetContacts& packet)
|
||||
{
|
||||
}
|
||||
|
||||
// return a list of your favorite people
|
||||
// Return a list of your favorite people
|
||||
// TODO: filter out all the LAN peers
|
||||
// TODO: filter out the peer you are talking to
|
||||
void Peer::recvGetPeers(ripple::TMGetPeers& packet)
|
||||
@@ -1417,12 +1432,14 @@ void Peer::recvLedger(ripple::TMLedgerData& packet)
|
||||
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
|
||||
nodeData.push_back(std::vector<unsigned char>(node.nodedata().begin(), node.nodedata().end()));
|
||||
}
|
||||
if (!theApp->getOPs().gotTXData(shared_from_this(), hash, nodeIDs, nodeData))
|
||||
SMAddNode san = theApp->getOPs().gotTXData(shared_from_this(), hash, nodeIDs, nodeData);
|
||||
if (san.isInvalid())
|
||||
punishPeer(PP_UNWANTED_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this()))
|
||||
SMAddNode san = theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this());
|
||||
if (san.isInvalid())
|
||||
punishPeer(PP_UNWANTED_DATA);
|
||||
}
|
||||
|
||||
@@ -1510,6 +1527,7 @@ void Peer::sendHello()
|
||||
h.set_nodepublic(theApp->getWallet().getNodePublic().humanNodePublic());
|
||||
h.set_nodeproof(&vchSig[0], vchSig.size());
|
||||
h.set_ipv4port(theConfig.PEER_PORT);
|
||||
h.set_nodeprivate(theConfig.PEER_PRIVATE);
|
||||
|
||||
Ledger::pointer closedLedger = theApp->getMasterLedger().getClosedLedger();
|
||||
if (closedLedger && closedLedger->isClosed())
|
||||
@@ -1526,7 +1544,7 @@ void Peer::sendHello()
|
||||
|
||||
void Peer::sendGetPeers()
|
||||
{
|
||||
// get other peers this guy knows about
|
||||
// Ask peer for known other peers.
|
||||
ripple::TMGetPeers getPeers;
|
||||
|
||||
getPeers.set_doweneedthis(1);
|
||||
|
||||
@@ -22,6 +22,12 @@ enum PeerPunish
|
||||
PP_BAD_SIGNATURE = 4, // Object had bad signature
|
||||
};
|
||||
|
||||
enum PeerReward
|
||||
{
|
||||
PR_NEEDED_DATA = 1,
|
||||
PR_NEW_TRANSACTION = 2,
|
||||
};
|
||||
|
||||
typedef std::pair<std::string,int> ipPort;
|
||||
|
||||
DEFINE_INSTANCE(Peer);
|
||||
@@ -49,6 +55,7 @@ private:
|
||||
ipPort mIpPortConnect;
|
||||
uint256 mCookieHash;
|
||||
uint64 mPeerId;
|
||||
bool mPrivate; // Keep peer IP private.
|
||||
|
||||
uint256 mClosedLedgerHash, mPreviousLedgerHash;
|
||||
std::list<uint256> mRecentLedgers;
|
||||
|
||||
@@ -109,12 +109,9 @@ bool ProofOfWork::checkSolution(const uint256& solution) const
|
||||
return getSHA512Half(buf2) <= mTarget;
|
||||
}
|
||||
|
||||
ProofOfWorkGenerator::ProofOfWorkGenerator() :
|
||||
mIterations(128),
|
||||
mTarget("0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
|
||||
mLastDifficultyChange(time(NULL)),
|
||||
mValidTime(180)
|
||||
ProofOfWorkGenerator::ProofOfWorkGenerator() : mValidTime(180)
|
||||
{
|
||||
setDifficulty(1);
|
||||
RAND_bytes(mSecret.begin(), mSecret.size());
|
||||
}
|
||||
|
||||
@@ -162,6 +159,8 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
|
||||
time_t t = lexical_cast_s<time_t>(fields[3]);
|
||||
time_t now = time(NULL);
|
||||
|
||||
int iterations = lexical_cast_s<int>(fields[2]);
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
if ((t * 4) > (now + mValidTime))
|
||||
@@ -169,10 +168,15 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
|
||||
cLog(lsDEBUG) << "PoW " << token << " has expired";
|
||||
return powEXPIRED;
|
||||
}
|
||||
|
||||
if (((iterations != mIterations) || (target != mTarget)) && getPowEntry(target, iterations) < (mPowEntry - 2))
|
||||
{ // difficulty has increased more than two times since PoW requested
|
||||
cLog(lsINFO) << "Difficulty has increased since PoW requested";
|
||||
return powTOOEASY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ProofOfWork pow(token, lexical_cast_s<int>(fields[2]), challenge, target);
|
||||
ProofOfWork pow(token, iterations, challenge, target);
|
||||
if (!pow.checkSolution(solution))
|
||||
{
|
||||
cLog(lsDEBUG) << "PoW " << token << " has a bad nonce";
|
||||
@@ -181,7 +185,6 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
// if (...) return powTOOEASY;
|
||||
if (!mSolvedChallenges.insert(powMap_vt(now, challenge)).second)
|
||||
{
|
||||
cLog(lsDEBUG) << "PoW " << token << " has been reused";
|
||||
@@ -208,6 +211,32 @@ void ProofOfWorkGenerator::sweep()
|
||||
} while(1);
|
||||
}
|
||||
|
||||
void ProofOfWorkGenerator::loadHigh()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
if (mLastDifficultyChange == now)
|
||||
return;
|
||||
if (mPowEntry == 30)
|
||||
return;
|
||||
++mPowEntry;
|
||||
mLastDifficultyChange = now;
|
||||
}
|
||||
|
||||
void ProofOfWorkGenerator::loadLow()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
if (mLastDifficultyChange == now)
|
||||
return;
|
||||
if (mPowEntry == 0)
|
||||
return;
|
||||
--mPowEntry;
|
||||
mLastDifficultyChange = now;
|
||||
}
|
||||
|
||||
struct PowEntry
|
||||
{
|
||||
const char *target;
|
||||
@@ -256,6 +285,19 @@ PowEntry PowEntries[31] =
|
||||
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 262144}, // 77309411328, 8 MB
|
||||
};
|
||||
|
||||
int ProofOfWorkGenerator::getPowEntry(const uint256& target, int iterations)
|
||||
{
|
||||
for (int i = 0; i < 31; ++i)
|
||||
if (PowEntries[i].iterations == iterations)
|
||||
{
|
||||
uint256 t;
|
||||
t.SetHex(PowEntries[i].target);
|
||||
if (t == target)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ProofOfWorkGenerator::setDifficulty(int i)
|
||||
{
|
||||
assert((i >= 0) && (i <= 30));
|
||||
|
||||
@@ -78,6 +78,8 @@ public:
|
||||
void loadHigh();
|
||||
void loadLow();
|
||||
void sweep(void);
|
||||
|
||||
static int getPowEntry(const uint256& target, int iterations);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -526,11 +526,19 @@ Json::Value RPCHandler::doOwnerInfo(const Json::Value& params)
|
||||
}
|
||||
|
||||
|
||||
Json::Value RPCHandler::doPathFind(const Json::Value& params)
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doPeers(const Json::Value& params)
|
||||
{
|
||||
// peers
|
||||
Json::Value obj(Json::objectValue);
|
||||
|
||||
obj["peers"]=theApp->getConnectionPool().getPeersJson();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -759,20 +767,21 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
return rpcError(rpcDST_ACT_MALFORMED);
|
||||
}
|
||||
|
||||
if(!txJSON.isMember("Fee"))
|
||||
if (!txJSON.isMember("Fee"))
|
||||
{
|
||||
if(mNetOps->getAccountState(uint256(0), dstAccountID))
|
||||
if (mNetOps->getAccountState(uint256(0), dstAccountID))
|
||||
txJSON["Fee"]=(int)theConfig.FEE_DEFAULT;
|
||||
else txJSON["Fee"]=(int)theConfig.FEE_ACCOUNT_CREATE;
|
||||
}
|
||||
|
||||
if(!txJSON.isMember("Paths") && jvRequest.isMember("build_path") )
|
||||
if (!txJSON.isMember("Paths") && jvRequest.isMember("build_path"))
|
||||
{
|
||||
if(txJSON["Amount"].isObject() || txJSON.isMember("SendMax") )
|
||||
if (txJSON["Amount"].isObject() || txJSON.isMember("SendMax"))
|
||||
{ // we need a ripple path
|
||||
STPathSet spsPaths;
|
||||
uint160 srcCurrencyID;
|
||||
if(txJSON.isMember("SendMax") && txJSON["SendMax"].isMember("currency"))
|
||||
|
||||
if (txJSON.isMember("SendMax") && txJSON["SendMax"].isMember("currency"))
|
||||
{
|
||||
STAmount::currencyFromString(srcCurrencyID, txJSON["SendMax"]["currency"].asString());
|
||||
}
|
||||
@@ -782,7 +791,8 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
}
|
||||
|
||||
STAmount dstAmount;
|
||||
if(txJSON["Amount"].isObject())
|
||||
|
||||
if (txJSON["Amount"].isObject())
|
||||
{
|
||||
std::string issuerStr;
|
||||
if( txJSON["Amount"].isMember("issuer")) issuerStr=txJSON["Amount"]["issuer"].asString();
|
||||
@@ -791,14 +801,17 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
{
|
||||
return rpcError(rpcDST_AMT_MALFORMED);
|
||||
}
|
||||
}else if (!dstAmount.setFullValue(txJSON["Amount"].asString()))
|
||||
}
|
||||
else if (!dstAmount.setFullValue(txJSON["Amount"].asString()))
|
||||
{
|
||||
return rpcError(rpcDST_AMT_MALFORMED);
|
||||
}
|
||||
|
||||
Pathfinder pf(srcAddress, dstAccountID, srcCurrencyID, dstAmount);
|
||||
|
||||
pf.findPaths(5, 1, spsPaths);
|
||||
if(!spsPaths.isEmpty())
|
||||
|
||||
if (!spsPaths.isEmpty())
|
||||
{
|
||||
txJSON["Paths"]=spsPaths.getJson(0);
|
||||
if(txJSON.isMember("Flags")) txJSON["Flags"]=txJSON["Flags"].asUInt() | 2;
|
||||
@@ -806,16 +819,18 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}else if( txJSON["type"]=="OfferCreate" )
|
||||
}
|
||||
else if( txJSON["type"]=="OfferCreate" )
|
||||
{
|
||||
txJSON["TransactionType"]=7;
|
||||
if(!txJSON.isMember("Fee")) txJSON["Fee"]=(int)theConfig.FEE_DEFAULT;
|
||||
}else if( txJSON["type"]=="TrustSet")
|
||||
}
|
||||
else if( txJSON["type"]=="TrustSet")
|
||||
{
|
||||
txJSON["TransactionType"]=20;
|
||||
if(!txJSON.isMember("Fee")) txJSON["Fee"]=(int)theConfig.FEE_DEFAULT;
|
||||
}else if( txJSON["type"]=="OfferCancel")
|
||||
}
|
||||
else if( txJSON["type"]=="OfferCancel")
|
||||
{
|
||||
txJSON["TransactionType"]=8;
|
||||
if(!txJSON.isMember("Fee")) txJSON["Fee"]=(int)theConfig.FEE_DEFAULT;
|
||||
@@ -1332,55 +1347,57 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
|
||||
unsigned int iOptions;
|
||||
} commandsA[] = {
|
||||
// Request-response methods
|
||||
{ "accept_ledger", &RPCHandler::doAcceptLedger, 0, 0, true },
|
||||
{ "accept_ledger", &RPCHandler::doAcceptLedger, 0, 0, true, false, optNone },
|
||||
{ "account_info", &RPCHandler::doAccountInfo, 1, 2, false, false, optCurrent },
|
||||
{ "account_tx", &RPCHandler::doAccountTransactions, 2, 3, false, false, optNetwork },
|
||||
{ "connect", &RPCHandler::doConnect, 1, 2, true },
|
||||
{ "data_delete", &RPCHandler::doDataDelete, 1, 1, true },
|
||||
{ "data_fetch", &RPCHandler::doDataFetch, 1, 1, true },
|
||||
{ "data_store", &RPCHandler::doDataStore, 2, 2, true },
|
||||
{ "get_counts", &RPCHandler::doGetCounts, 0, 1, true },
|
||||
{ "connect", &RPCHandler::doConnect, 1, 2, true, false, optNone },
|
||||
{ "data_delete", &RPCHandler::doDataDelete, 1, 1, true, false, optNone },
|
||||
{ "data_fetch", &RPCHandler::doDataFetch, 1, 1, true, false, optNone },
|
||||
{ "data_store", &RPCHandler::doDataStore, 2, 2, true, false, optNone },
|
||||
{ "get_counts", &RPCHandler::doGetCounts, 0, 1, true, false, optNone },
|
||||
{ "ledger", &RPCHandler::doLedger, 0, 2, false, false, optNetwork },
|
||||
{ "ledger_accept", &RPCHandler::doLedgerAccept, 0, 0, true, false, optCurrent },
|
||||
{ "ledger_closed", &RPCHandler::doLedgerClosed, 0, 0, false, false, optClosed },
|
||||
{ "ledger_current", &RPCHandler::doLedgerCurrent, 0, 0, false, false, optCurrent },
|
||||
{ "ledger_entry", &RPCHandler::doLedgerEntry, -1, -1, false, false, optCurrent },
|
||||
{ "ledger_header", &RPCHandler::doLedgerHeader, -1, -1, false, false, optCurrent },
|
||||
{ "log_level", &RPCHandler::doLogLevel, 0, 2, true },
|
||||
{ "logrotate", &RPCHandler::doLogRotate, 0, 0, true },
|
||||
{ "ledger_entry", &RPCHandler::doLedgerEntry, -1, -1, false, false, optCurrent },
|
||||
{ "ledger_header", &RPCHandler::doLedgerHeader, -1, -1, false, false, optCurrent },
|
||||
{ "log_level", &RPCHandler::doLogLevel, 0, 2, true, false, optNone },
|
||||
{ "logrotate", &RPCHandler::doLogRotate, 0, 0, true, false, optNone },
|
||||
{ "nickname_info", &RPCHandler::doNicknameInfo, 1, 1, false, false, optCurrent },
|
||||
{ "owner_info", &RPCHandler::doOwnerInfo, 1, 2, false, false, optCurrent },
|
||||
{ "peers", &RPCHandler::doPeers, 0, 0, true },
|
||||
{ "path_find", &RPCHandler::doPathFind, -1, -1, false, false, optCurrent },
|
||||
{ "peers", &RPCHandler::doPeers, 0, 0, true, false, optNone },
|
||||
{ "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent },
|
||||
{ "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent },
|
||||
{ "submit", &RPCHandler::doSubmit, 2, 2, false, false, optCurrent },
|
||||
{ "submit_json", &RPCHandler::doSubmitJson, -1, -1, false, false, optCurrent },
|
||||
{ "server_info", &RPCHandler::doServerInfo, 0, 0, true },
|
||||
{ "stop", &RPCHandler::doStop, 0, 0, true },
|
||||
{ "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone },
|
||||
{ "stop", &RPCHandler::doStop, 0, 0, true, false, optNone },
|
||||
{ "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent },
|
||||
{ "tx", &RPCHandler::doTx, 1, 1, true },
|
||||
{ "tx_history", &RPCHandler::doTxHistory, 1, 1, false, },
|
||||
{ "tx", &RPCHandler::doTx, 1, 1, true, false, optNone },
|
||||
{ "tx_history", &RPCHandler::doTxHistory, 1, 1, false, false, optNone },
|
||||
|
||||
{ "unl_add", &RPCHandler::doUnlAdd, 1, 2, true },
|
||||
{ "unl_delete", &RPCHandler::doUnlDelete, 1, 1, true },
|
||||
{ "unl_list", &RPCHandler::doUnlList, 0, 0, true },
|
||||
{ "unl_load", &RPCHandler::doUnlLoad, 0, 0, true },
|
||||
{ "unl_network", &RPCHandler::doUnlNetwork, 0, 0, true },
|
||||
{ "unl_reset", &RPCHandler::doUnlReset, 0, 0, true },
|
||||
{ "unl_score", &RPCHandler::doUnlScore, 0, 0, true },
|
||||
{ "unl_add", &RPCHandler::doUnlAdd, 1, 2, true, false, optNone },
|
||||
{ "unl_delete", &RPCHandler::doUnlDelete, 1, 1, true, false, optNone },
|
||||
{ "unl_list", &RPCHandler::doUnlList, 0, 0, true, false, optNone },
|
||||
{ "unl_load", &RPCHandler::doUnlLoad, 0, 0, true, false, optNone },
|
||||
{ "unl_network", &RPCHandler::doUnlNetwork, 0, 0, true, false, optNone },
|
||||
{ "unl_reset", &RPCHandler::doUnlReset, 0, 0, true, false, optNone },
|
||||
{ "unl_score", &RPCHandler::doUnlScore, 0, 0, true, false, optNone },
|
||||
|
||||
{ "validation_create", &RPCHandler::doValidationCreate, 0, 1, false },
|
||||
{ "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false },
|
||||
{ "validation_create", &RPCHandler::doValidationCreate, 0, 1, false, false, optNone },
|
||||
{ "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false, false, optNone },
|
||||
|
||||
{ "wallet_accounts", &RPCHandler::doWalletAccounts, 1, 1, false, false, optCurrent },
|
||||
{ "wallet_propose", &RPCHandler::doWalletPropose, 0, 1, false, },
|
||||
{ "wallet_seed", &RPCHandler::doWalletSeed, 0, 1, false, },
|
||||
{ "wallet_propose", &RPCHandler::doWalletPropose, 0, 1, false, false, optNone },
|
||||
{ "wallet_seed", &RPCHandler::doWalletSeed, 0, 1, false, false, optNone },
|
||||
|
||||
{ "login", &RPCHandler::doLogin, 2, 2, true },
|
||||
{ "login", &RPCHandler::doLogin, 2, 2, true, false, optNone },
|
||||
|
||||
// Evented methods
|
||||
{ "subscribe", &RPCHandler::doSubscribe, -1, -1, false, true },
|
||||
{ "unsubscribe", &RPCHandler::doUnsubscribe, -1, -1, false, true }, };
|
||||
{ "subscribe", &RPCHandler::doSubscribe, -1, -1, false, true, optNone },
|
||||
{ "unsubscribe", &RPCHandler::doUnsubscribe, -1, -1, false, true, optNone },
|
||||
};
|
||||
|
||||
int i = NUMBER(commandsA);
|
||||
|
||||
@@ -1640,7 +1657,7 @@ Json::Value RPCHandler::doUnlList(const Json::Value& params)
|
||||
// Populate the UNL from a local validators.txt file.
|
||||
Json::Value RPCHandler::doUnlLoad(const Json::Value& params)
|
||||
{
|
||||
if (theConfig.UNL_DEFAULT.empty() || !theApp->getUNL().nodeLoad(theConfig.UNL_DEFAULT))
|
||||
if (theConfig.VALIDATORS_FILE.empty() || !theApp->getUNL().nodeLoad(theConfig.VALIDATORS_FILE))
|
||||
{
|
||||
return rpcError(rpcLOAD_FAILED);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ class RPCHandler
|
||||
|
||||
typedef Json::Value (RPCHandler::*doFuncPtr)(const Json::Value ¶ms);
|
||||
enum {
|
||||
optNone = 0,
|
||||
optNetwork = 1, // Need network
|
||||
optCurrent = 2+optNetwork, // Need current ledger
|
||||
optClosed = 4+optNetwork, // Need closed ledger
|
||||
@@ -50,6 +51,7 @@ class RPCHandler
|
||||
Json::Value doOwnerInfo(const Json::Value& params);
|
||||
|
||||
Json::Value doProfile(const Json::Value& params);
|
||||
Json::Value doPathFind(const Json::Value& params);
|
||||
Json::Value doPeers(const Json::Value& params);
|
||||
|
||||
Json::Value doRippleLinesGet(const Json::Value ¶ms);
|
||||
|
||||
@@ -281,6 +281,44 @@ public:
|
||||
|
||||
extern std::ostream& operator<<(std::ostream&, const SHAMapMissingNode&);
|
||||
|
||||
class SMAddNode
|
||||
{ // results of adding nodes
|
||||
protected:
|
||||
bool mInvalid, mUseful;
|
||||
|
||||
SMAddNode(bool i, bool u) : mInvalid(i), mUseful(u) { ; }
|
||||
|
||||
public:
|
||||
SMAddNode() : mInvalid(false), mUseful(false) { ; }
|
||||
|
||||
void setInvalid() { mInvalid = true; }
|
||||
void setUseful() { mUseful = true; }
|
||||
void reset() { mInvalid = false; mUseful = false; }
|
||||
|
||||
bool isInvalid() const { return mInvalid; }
|
||||
bool isUseful() const { return mUseful; }
|
||||
|
||||
bool combine(const SMAddNode& n)
|
||||
{
|
||||
if (n.mInvalid)
|
||||
{
|
||||
mInvalid = true;
|
||||
return false;
|
||||
}
|
||||
if (n.mUseful)
|
||||
mUseful = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
operator bool() const { return !mInvalid; }
|
||||
|
||||
static SMAddNode okay() { return SMAddNode(false, false); }
|
||||
static SMAddNode useful() { return SMAddNode(false, true); }
|
||||
static SMAddNode invalid() { return SMAddNode(true, false); }
|
||||
};
|
||||
|
||||
extern bool SMANCombine(SMAddNode& existing, const SMAddNode& additional);
|
||||
|
||||
class SHAMap : public IS_INSTANCE(SHAMap)
|
||||
{
|
||||
public:
|
||||
@@ -374,11 +412,11 @@ public:
|
||||
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
|
||||
std::list<std::vector<unsigned char> >& rawNode, bool fatRoot, bool fatLeaves);
|
||||
bool getRootNode(Serializer& s, SHANodeFormat format);
|
||||
bool addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SMAddNode addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SHAMapSyncFilter* filter);
|
||||
bool addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SMAddNode addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SHAMapSyncFilter* filter);
|
||||
bool addKnownNode(const SHAMapNode& nodeID, const std::vector<unsigned char>& rawNode,
|
||||
SMAddNode addKnownNode(const SHAMapNode& nodeID, const std::vector<unsigned char>& rawNode,
|
||||
SHAMapSyncFilter* filter);
|
||||
|
||||
// status functions
|
||||
|
||||
@@ -135,7 +135,8 @@ bool SHAMap::getRootNode(Serializer& s, SHANodeFormat format)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format, SHAMapSyncFilter* filter)
|
||||
SMAddNode SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SHAMapSyncFilter* filter)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
|
||||
@@ -143,12 +144,12 @@ bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeForm
|
||||
if (root->getNodeHash().isNonZero())
|
||||
{
|
||||
cLog(lsTRACE) << "got root node, already have one";
|
||||
return true;
|
||||
return SMAddNode::okay();
|
||||
}
|
||||
|
||||
SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>(SHAMapNode(), rootNode, 0, format);
|
||||
if (!node)
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
|
||||
#ifdef DEBUG
|
||||
node->dump();
|
||||
@@ -170,10 +171,10 @@ bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeForm
|
||||
filter->gotNode(*root, root->getNodeHash(), s.peekData(), root->getType());
|
||||
}
|
||||
|
||||
return true;
|
||||
return SMAddNode::useful();
|
||||
}
|
||||
|
||||
bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SMAddNode SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||
SHAMapSyncFilter* filter)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
@@ -183,14 +184,12 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>&
|
||||
{
|
||||
cLog(lsTRACE) << "got root node, already have one";
|
||||
assert(root->getNodeHash() == hash);
|
||||
return true;
|
||||
return SMAddNode::okay();
|
||||
}
|
||||
|
||||
SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>(SHAMapNode(), rootNode, 0, format);
|
||||
if (!node)
|
||||
return false;
|
||||
if (node->getNodeHash() != hash)
|
||||
return false;
|
||||
if (!node || node->getNodeHash() != hash)
|
||||
return SMAddNode::invalid();
|
||||
|
||||
returnNode(root, true);
|
||||
root = node;
|
||||
@@ -207,42 +206,42 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>&
|
||||
filter->gotNode(*root, root->getNodeHash(), s.peekData(), root->getType());
|
||||
}
|
||||
|
||||
return true;
|
||||
return SMAddNode::useful();
|
||||
}
|
||||
|
||||
bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned char>& rawNode,
|
||||
SMAddNode SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned char>& rawNode,
|
||||
SHAMapSyncFilter* filter)
|
||||
{ // return value: true=okay, false=error
|
||||
assert(!node.isRoot());
|
||||
if (!isSynching())
|
||||
{
|
||||
cLog(lsINFO) << "AddKnownNode while not synching";
|
||||
return true;
|
||||
return SMAddNode::okay();
|
||||
}
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
|
||||
if (checkCacheNode(node))
|
||||
return true;
|
||||
return SMAddNode::okay();
|
||||
|
||||
std::stack<SHAMapTreeNode::pointer> stack = getStack(node.getNodeID(), true, true);
|
||||
if (stack.empty())
|
||||
{
|
||||
cLog(lsWARNING) << "AddKnownNode with empty stack";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
|
||||
SHAMapTreeNode::pointer iNode = stack.top();
|
||||
if (!iNode)
|
||||
{ // we should always have a root
|
||||
assert(false);
|
||||
return true;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
|
||||
if (iNode->isLeaf() || (iNode->getDepth() >= node.getDepth()))
|
||||
{
|
||||
cLog(lsTRACE) << "got inner node, already had it (late)";
|
||||
return true;
|
||||
return SMAddNode::okay();
|
||||
}
|
||||
|
||||
if (iNode->getDepth() != (node.getDepth() - 1))
|
||||
@@ -250,25 +249,25 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
|
||||
cLog(lsWARNING) << "unable to hook node " << node;
|
||||
cLog(lsINFO) << " stuck at " << *iNode;
|
||||
cLog(lsINFO) << "got depth=" << node.getDepth() << ", walked to= " << iNode->getDepth();
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
|
||||
int branch = iNode->selectBranch(node.getNodeID());
|
||||
if (branch < 0)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
uint256 hash = iNode->getChildHash(branch);
|
||||
if (!hash)
|
||||
{
|
||||
cLog(lsWARNING) << "AddKnownNode for empty branch";
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
}
|
||||
|
||||
SHAMapTreeNode::pointer newNode = boost::make_shared<SHAMapTreeNode>(node, rawNode, mSeq, snfWIRE);
|
||||
if (hash != newNode->getNodeHash()) // these aren't the droids we're looking for
|
||||
return false;
|
||||
return SMAddNode::invalid();
|
||||
|
||||
if (filter)
|
||||
{
|
||||
@@ -279,7 +278,7 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
|
||||
|
||||
mTNByID[*newNode] = newNode;
|
||||
if (!newNode->isLeaf())
|
||||
return true; // only a leaf can fill a branch
|
||||
return SMAddNode::useful(); // only a leaf can fill a branch
|
||||
|
||||
// did this new leaf cause its parents to fill up
|
||||
do
|
||||
@@ -294,11 +293,11 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
|
||||
{
|
||||
SHAMapTreeNode::pointer nextNode = getNode(iNode->getChildNodeID(i), iNode->getChildHash(i), false);
|
||||
if (nextNode->isInner() && !nextNode->isFullBelow())
|
||||
return true;
|
||||
return SMAddNode::useful();
|
||||
}
|
||||
catch (SHAMapMissingNode&)
|
||||
{
|
||||
return true;
|
||||
return SMAddNode::useful();
|
||||
}
|
||||
}
|
||||
iNode->setFullBelow();
|
||||
@@ -306,7 +305,7 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
|
||||
|
||||
if (root->isFullBelow())
|
||||
clearSynching();
|
||||
return true;
|
||||
return SMAddNode::useful();
|
||||
}
|
||||
|
||||
bool SHAMap::deepCompare(SHAMap& other)
|
||||
@@ -486,6 +485,8 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
|
||||
cLog(lsFATAL) << "Didn't get root node " << gotNodes.size();
|
||||
BOOST_FAIL("NodeSize");
|
||||
}
|
||||
|
||||
SMAddNode node();
|
||||
if (!destination.addRootNode(*gotNodes.begin(), snfWIRE, NULL))
|
||||
{
|
||||
cLog(lsFATAL) << "AddRootNode fails";
|
||||
|
||||
@@ -15,11 +15,11 @@ Transactor::pointer Transactor::makeTransactor(const SerializedTransaction& txn,
|
||||
{
|
||||
switch(txn.getTxnType())
|
||||
{
|
||||
case ttPAYMENT:
|
||||
case ttPAYMENT:
|
||||
return( Transactor::pointer(new PaymentTransactor(txn,params,engine)) );
|
||||
case ttACCOUNT_SET:
|
||||
case ttACCOUNT_SET:
|
||||
return( Transactor::pointer(new AccountSetTransactor(txn,params,engine)) );
|
||||
case ttREGULAR_KEY_SET:
|
||||
case ttREGULAR_KEY_SET:
|
||||
return( Transactor::pointer(new RegularKeySetTransactor(txn,params,engine)) );
|
||||
case ttTRUST_SET:
|
||||
return( Transactor::pointer(new TrustSetTransactor(txn,params,engine)) );
|
||||
@@ -35,14 +35,11 @@ Transactor::pointer Transactor::makeTransactor(const SerializedTransaction& txn,
|
||||
}
|
||||
|
||||
|
||||
Transactor::Transactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : mTxn(txn), mParams(params), mEngine(engine)
|
||||
Transactor::Transactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : mTxn(txn), mEngine(engine), mParams(params)
|
||||
{
|
||||
mHasAuthKey=false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Transactor::calculateFee()
|
||||
{
|
||||
mFeeDue = theConfig.FEE_DEFAULT;
|
||||
@@ -61,7 +58,7 @@ TER Transactor::payFee()
|
||||
}
|
||||
|
||||
if( !saPaid ) return tesSUCCESS;
|
||||
|
||||
|
||||
// Deduct the fee, so it's not available during the transaction.
|
||||
// Will only write the account back, if the transaction succeeds.
|
||||
if (mSourceBalance < saPaid)
|
||||
@@ -73,12 +70,11 @@ TER Transactor::payFee()
|
||||
|
||||
return terINSUF_FEE_B;
|
||||
}
|
||||
|
||||
|
||||
mSourceBalance -= saPaid;
|
||||
mTxnAccount->setFieldAmount(sfBalance, mSourceBalance);
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +104,7 @@ TER Transactor::checkSig()
|
||||
|
||||
return temBAD_AUTH_MASTER;
|
||||
}
|
||||
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -133,11 +129,10 @@ TER Transactor::checkSeq()
|
||||
if (mEngine->getLedger()->hasTransaction(txID))
|
||||
return tefALREADY;
|
||||
}
|
||||
|
||||
|
||||
cLog(lsWARNING) << "applyTransaction: past sequence number";
|
||||
|
||||
return tefPAST_SEQ;
|
||||
|
||||
}else
|
||||
{
|
||||
mTxnAccount->setFieldU32(sfSequence, t_seq + 1);
|
||||
@@ -209,12 +204,13 @@ TER Transactor::apply()
|
||||
|
||||
terResult=checkSig();
|
||||
if(terResult != tesSUCCESS) return(terResult);
|
||||
|
||||
|
||||
terResult=checkSeq();
|
||||
if(terResult != tesSUCCESS) return(terResult);
|
||||
|
||||
mEngine->entryModify(mTxnAccount);
|
||||
|
||||
return doApply();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -1576,15 +1576,15 @@ void UniqueNodeList::nodeBootstrap()
|
||||
bool bLoaded = iDomains || iNodes;
|
||||
|
||||
// Always merge in the file specified in the config.
|
||||
if (!theConfig.UNL_DEFAULT.empty())
|
||||
if (!theConfig.VALIDATORS_FILE.empty())
|
||||
{
|
||||
cLog(lsINFO) << "Bootstrapping UNL: loading from unl_default.";
|
||||
|
||||
bLoaded = nodeLoad(theConfig.UNL_DEFAULT);
|
||||
bLoaded = nodeLoad(theConfig.VALIDATORS_FILE);
|
||||
}
|
||||
|
||||
// If never loaded anything try the current directory.
|
||||
if (!bLoaded && theConfig.UNL_DEFAULT.empty())
|
||||
if (!bLoaded && theConfig.VALIDATORS_FILE.empty())
|
||||
{
|
||||
cLog(lsINFO) << "Bootstrapping UNL: loading from '" VALIDATORS_FILE_NAME "'.";
|
||||
|
||||
|
||||
@@ -49,12 +49,15 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest)
|
||||
Json::Value jvResult(Json::objectValue);
|
||||
|
||||
// Regular RPC command
|
||||
jvResult["result"] = mRPCHandler.doCommand(
|
||||
jvRequest["command"].asString(),
|
||||
jvRequest.isMember("params")
|
||||
? jvRequest["params"]
|
||||
: jvRequest,
|
||||
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock());
|
||||
jvResult["result"] = mRPCHandler.doCommand(
|
||||
jvRequest["command"].asString(),
|
||||
jvRequest.isMember("params")
|
||||
? jvRequest["params"]
|
||||
: jvRequest,
|
||||
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
|
||||
}
|
||||
|
||||
// Currently we will simply unwrap errors returned by the RPC
|
||||
// API, in the future maybe we can make the responses
|
||||
|
||||
@@ -116,7 +116,14 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
send(cpClient, mMap[cpClient]->invokeCommand(jvRequest));
|
||||
boost::shared_ptr<WSConnection> conn;
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mMapLock);
|
||||
conn = mMap[cpClient];
|
||||
}
|
||||
if (!conn)
|
||||
return;
|
||||
send(cpClient, conn->invokeCommand(jvRequest));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ enum MessageType {
|
||||
mtHELLO = 1;
|
||||
mtERROR_MSG = 2;
|
||||
mtPING = 3;
|
||||
mtPOW = 4;
|
||||
|
||||
// network presence detection
|
||||
mtGET_CONTACTS = 10;
|
||||
@@ -32,20 +33,44 @@ enum MessageType {
|
||||
}
|
||||
|
||||
|
||||
// empty message (or just result) = request proof of work
|
||||
// token, iterations, target, challenge = give proof of work challenge
|
||||
// token, response = show proof of work
|
||||
// token, result = result of pow attempt
|
||||
message TMProofWork
|
||||
{
|
||||
optional string token = 1;
|
||||
optional uint32 iterations = 2;
|
||||
optional bytes target = 3;
|
||||
optional bytes challenge = 4;
|
||||
optional bytes response = 5;
|
||||
|
||||
enum POWResult
|
||||
{
|
||||
powrOK = 0;
|
||||
powrREUSED = 1;
|
||||
powrEXPIRED = 2; // You took too long solving
|
||||
powrTOOEASY = 3; // Difficulty went way up, sorry
|
||||
powrINVALID = 4;
|
||||
powrDISCONNECT = 5; // We are disconnecting
|
||||
}
|
||||
optional POWResult result = 6;
|
||||
}
|
||||
|
||||
// Sent on connect
|
||||
|
||||
|
||||
message TMHello {
|
||||
required uint32 protoVersion = 1;
|
||||
required uint32 protoVersionMin = 2;
|
||||
required bytes nodePublic = 3;
|
||||
required bytes nodeProof = 4;
|
||||
optional string fullVersion = 5;
|
||||
optional uint64 netTime = 6;
|
||||
optional uint32 ipv4Port = 7;
|
||||
optional uint32 ledgerIndex = 8;
|
||||
optional bytes ledgerClosed = 9; // our last closed ledger
|
||||
optional bytes ledgerPrevious = 10; // the ledger before the last closed ledger
|
||||
required uint32 protoVersion = 1;
|
||||
required uint32 protoVersionMin = 2;
|
||||
required bytes nodePublic = 3;
|
||||
required bytes nodeProof = 4;
|
||||
optional string fullVersion = 5;
|
||||
optional uint64 netTime = 6;
|
||||
optional uint32 ipv4Port = 7;
|
||||
optional uint32 ledgerIndex = 8;
|
||||
optional bytes ledgerClosed = 9; // our last closed ledger
|
||||
optional bytes ledgerPrevious = 10; // the ledger before the last closed ledger
|
||||
optional bool nodePrivate = 11; // Request to not forward IP.
|
||||
optional TMProofWork proofOfWork = 12; // request/provide proof of work
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user