mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
62
js/remote.js
62
js/remote.js
@@ -12,11 +12,12 @@ var util = require('util');
|
||||
var WebSocket = require('ws');
|
||||
|
||||
// --> trusted: truthy, if remote is trusted
|
||||
var Remote = function (trusted, websocket_ip, websocket_port, trace) {
|
||||
var Remote = function (trusted, websocket_ip, websocket_port, config, trace) {
|
||||
this.trusted = trusted;
|
||||
this.websocket_ip = websocket_ip;
|
||||
this.websocket_port = websocket_port;
|
||||
this.id = 0;
|
||||
this.config = config;
|
||||
this.trace = trace;
|
||||
this.ledger_closed = undefined;
|
||||
this.ledger_current_index = undefined;
|
||||
@@ -40,7 +41,18 @@ var Remote = function (trusted, websocket_ip, websocket_port, trace) {
|
||||
|
||||
var remoteConfig = function (config, server, trace) {
|
||||
var serverConfig = config.servers[server];
|
||||
return new Remote(serverConfig.trusted, serverConfig.websocket_ip, serverConfig.websocket_port, trace);
|
||||
return new Remote(serverConfig.trusted, serverConfig.websocket_ip, serverConfig.websocket_port, config, trace);
|
||||
};
|
||||
|
||||
var flags = {
|
||||
// OfferCreate flags:
|
||||
'tfPassive' : 0x00010000,
|
||||
|
||||
// Payment flags:
|
||||
'tfCreateAccount' : 0x00010000,
|
||||
'tfPartialPayment' : 0x00020000,
|
||||
'tfLimitQuality' : 0x00040000,
|
||||
'tfNoRippleDirect' : 0x00080000,
|
||||
};
|
||||
|
||||
// XXX This needs to be determined from the network.
|
||||
@@ -257,13 +269,10 @@ Remote.method('request_ledger_entry', function (req, onDone, onFailure) {
|
||||
// Submit a json transaction.
|
||||
// done(value)
|
||||
// XXX <-> value: { 'status', status, 'result' : result, ... }
|
||||
Remote.method('submit', function (request, onDone, onFailure) {
|
||||
if (this.trace) console.log("remote: submit: %s", request);
|
||||
Remote.method('submit', function (req, onDone, onFailure) {
|
||||
if (this.trace) console.log("remote: submit: %s", JSON.stringify(req));
|
||||
|
||||
var req = {};
|
||||
|
||||
req.command = 'submit';
|
||||
req.request = request;
|
||||
|
||||
if (req.secret && !this.trusted)
|
||||
{
|
||||
@@ -308,7 +317,7 @@ Remote.method('account_seq', function (account, advance, onDone, onFailure) {
|
||||
|
||||
if (advance) account_root_entry.seq += 1;
|
||||
|
||||
onDone(advance);
|
||||
onDone(seq);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -323,9 +332,9 @@ Remote.method('account_seq', function (account, advance, onDone, onFailure) {
|
||||
// Extract the seqence number from the account root entry.
|
||||
var seq = node.Sequence;
|
||||
|
||||
if (!self.accounts[account]) self.accounts[account] = {};
|
||||
if (!account_root_entry) self.accounts[account] = {};
|
||||
|
||||
self.accounts[account].seq = seq + 1;
|
||||
self.accounts[account].seq = seq + !!advance;
|
||||
|
||||
onDone(seq);
|
||||
},
|
||||
@@ -335,14 +344,14 @@ Remote.method('account_seq', function (account, advance, onDone, onFailure) {
|
||||
});
|
||||
|
||||
// A submit that fills in the sequence number.
|
||||
Remote.method('submit_seq', function (transaction, onDirty, onDone, onFailure) {
|
||||
Remote.method('submit_seq', function (trans, onDirty, onDone, onFailure) {
|
||||
var self = this;
|
||||
|
||||
// Get the next sequence number for the account.
|
||||
this.account_seq(transaction.fields.Signer, true,
|
||||
this.account_seq(trans.transaction.Account, true,
|
||||
function (seq) {
|
||||
transaction.seq = seq;
|
||||
self.submit(transaction, onDone, onFailure);
|
||||
trans.transaction.Sequence = seq;
|
||||
self.submit(trans, onDone, onFailure);
|
||||
},
|
||||
onFailure);
|
||||
});
|
||||
@@ -352,8 +361,33 @@ Remote.method('dirty_account_root', function (account) {
|
||||
delete this.ledgers.current.account_root.account;
|
||||
});
|
||||
|
||||
//
|
||||
// Transactions
|
||||
//
|
||||
|
||||
Remote.method('send_xns', function (secret, src, dst, amount, create, onDone) {
|
||||
var secret = this.config.accounts[src] ? this.config.accounts[src].secret : secret;
|
||||
var src_account = this.config.accounts[src] ? this.config.accounts[src].account : src;
|
||||
var dst_account = this.config.accounts[dst] ? this.config.accounts[dst].account : dst;
|
||||
|
||||
this.submit_seq(
|
||||
{
|
||||
'transaction' : {
|
||||
'TransactionType' : 'Payment',
|
||||
'Account' : src_account,
|
||||
'Destination' : dst_account,
|
||||
'Fee' : create ? fees.account_create : fees['default'],
|
||||
'Flags' : create ? flags.tfCreateAccount : 0,
|
||||
'Amount' : amount,
|
||||
},
|
||||
'secret' : secret,
|
||||
}, function () {
|
||||
}, onDone);
|
||||
});
|
||||
|
||||
exports.Remote = Remote;
|
||||
exports.remoteConfig = remoteConfig;
|
||||
exports.fees = fees;
|
||||
exports.flags = flags;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
|
||||
191
src/WSDoor.cpp
191
src/WSDoor.cpp
@@ -5,7 +5,6 @@
|
||||
#include "Config.h"
|
||||
#include "Log.h"
|
||||
#include "NetworkOPs.h"
|
||||
#include "NetworkOPs.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <iostream>
|
||||
@@ -60,14 +59,15 @@ protected:
|
||||
|
||||
WSServerHandler<websocketpp::WSDOOR_SERVER>* mHandler;
|
||||
connection_ptr mConnection;
|
||||
NetworkOPs& mNetwork;
|
||||
|
||||
public:
|
||||
WSConnection()
|
||||
: mHandler((WSServerHandler<websocketpp::WSDOOR_SERVER>*)(NULL)),
|
||||
mConnection(connection_ptr()) { ; }
|
||||
// WSConnection()
|
||||
// : mHandler((WSServerHandler<websocketpp::WSDOOR_SERVER>*)(NULL)),
|
||||
// mConnection(connection_ptr()) { ; }
|
||||
|
||||
WSConnection(WSServerHandler<websocketpp::WSDOOR_SERVER>* wshpHandler, connection_ptr cpConnection)
|
||||
: mHandler(wshpHandler), mConnection(cpConnection) { ; }
|
||||
: mHandler(wshpHandler), mConnection(cpConnection), mNetwork(theApp->getOPs()) { ; }
|
||||
|
||||
virtual ~WSConnection();
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
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);
|
||||
void doSubmit(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
|
||||
// Streaming Commands
|
||||
void doAccountInfoSubscribe(Json::Value& jvResult, const Json::Value& jvRequest);
|
||||
@@ -305,6 +306,7 @@ Json::Value WSConnection::invokeCommand(const Json::Value& jvRequest)
|
||||
{ "ledger_closed", &WSConnection::doLedgerClosed },
|
||||
{ "ledger_current", &WSConnection::doLedgerCurrent },
|
||||
{ "ledger_entry", &WSConnection::doLedgerEntry },
|
||||
{ "submit", &WSConnection::doSubmit },
|
||||
|
||||
// Streaming commands:
|
||||
{ "account_info_subscribe", &WSConnection::doAccountInfoSubscribe },
|
||||
@@ -422,7 +424,7 @@ void WSConnection::doAccountInfoSubscribe(Json::Value& jvResult, const Json::Val
|
||||
mSubAccountInfo.insert(naAccountID);
|
||||
}
|
||||
|
||||
theApp->getOPs().subAccountInfo(this, usnaAccoundIds);
|
||||
mNetwork.subAccountInfo(this, usnaAccoundIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,7 +456,7 @@ void WSConnection::doAccountInfoUnsubscribe(Json::Value& jvResult, const Json::V
|
||||
mSubAccountInfo.erase(naAccountID);
|
||||
}
|
||||
|
||||
theApp->getOPs().unsubAccountInfo(this, usnaAccoundIds);
|
||||
mNetwork.unsubAccountInfo(this, usnaAccoundIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -486,7 +488,7 @@ void WSConnection::doAccountTransactionSubscribe(Json::Value& jvResult, const Js
|
||||
mSubAccountTransaction.insert(naAccountID);
|
||||
}
|
||||
|
||||
theApp->getOPs().subAccountTransaction(this, usnaAccoundIds);
|
||||
mNetwork.subAccountTransaction(this, usnaAccoundIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -518,14 +520,14 @@ void WSConnection::doAccountTransactionUnsubscribe(Json::Value& jvResult, const
|
||||
mSubAccountTransaction.erase(naAccountID);
|
||||
}
|
||||
|
||||
theApp->getOPs().unsubAccountTransaction(this, usnaAccoundIds);
|
||||
mNetwork.unsubAccountTransaction(this, usnaAccoundIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WSConnection::doLedgerAccountsSubcribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().subLedgerAccounts(this))
|
||||
if (!mNetwork.subLedgerAccounts(this))
|
||||
{
|
||||
jvResult["error"] = "ledgerAccountsSubscribed";
|
||||
}
|
||||
@@ -533,7 +535,7 @@ void WSConnection::doLedgerAccountsSubcribe(Json::Value& jvResult, const Json::V
|
||||
|
||||
void WSConnection::doLedgerAccountsUnsubscribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().unsubLedgerAccounts(this))
|
||||
if (!mNetwork.unsubLedgerAccounts(this))
|
||||
{
|
||||
jvResult["error"] = "ledgerAccountsNotSubscribed";
|
||||
}
|
||||
@@ -541,20 +543,20 @@ void WSConnection::doLedgerAccountsUnsubscribe(Json::Value& jvResult, const Json
|
||||
|
||||
void WSConnection::doLedgerClosed(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
uint256 uLedger = theApp->getOPs().getClosedLedger();
|
||||
uint256 uLedger = mNetwork.getClosedLedger();
|
||||
|
||||
jvResult["ledger_closed_index"] = theApp->getOPs().getLedgerID(uLedger);
|
||||
jvResult["ledger_closed_index"] = mNetwork.getLedgerID(uLedger);
|
||||
jvResult["ledger_closed"] = uLedger.ToString();
|
||||
}
|
||||
|
||||
void WSConnection::doLedgerCurrent(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
jvResult["ledger_current_index"] = theApp->getOPs().getCurrentLedgerID();
|
||||
jvResult["ledger_current_index"] = mNetwork.getCurrentLedgerID();
|
||||
}
|
||||
|
||||
void WSConnection::doLedgerEntry(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
NetworkOPs& noNetwork = theApp->getOPs();
|
||||
NetworkOPs& noNetwork = mNetwork;
|
||||
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;
|
||||
|
||||
@@ -781,7 +783,7 @@ void WSConnection::doLedgerEntry(Json::Value& jvResult, const Json::Value& jvReq
|
||||
|
||||
void WSConnection::doServerSubscribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().subLedger(this))
|
||||
if (!mNetwork.subLedger(this))
|
||||
{
|
||||
jvResult["error"] = "serverSubscribed";
|
||||
}
|
||||
@@ -792,22 +794,169 @@ void WSConnection::doServerSubscribe(Json::Value& jvResult, const Json::Value& j
|
||||
|
||||
// XXX Make sure these values are available before returning them.
|
||||
// XXX return connected status.
|
||||
jvResult["ledger_closed"] = theApp->getOPs().getClosedLedger().ToString();
|
||||
jvResult["ledger_current_index"] = theApp->getOPs().getCurrentLedgerID();
|
||||
jvResult["ledger_closed"] = mNetwork.getClosedLedger().ToString();
|
||||
jvResult["ledger_current_index"] = mNetwork.getCurrentLedgerID();
|
||||
}
|
||||
}
|
||||
|
||||
void WSConnection::doServerUnsubscribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().unsubLedger(this))
|
||||
if (!mNetwork.unsubLedger(this))
|
||||
{
|
||||
jvResult["error"] = "serverNotSubscribed";
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Current requires secret. Allow signed transaction as an alternative.
|
||||
void WSConnection::doSubmit(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
NewcoinAddress naAccount;
|
||||
|
||||
if (!jvRequest.isMember("transaction"))
|
||||
{
|
||||
jvResult["error"] = "fieldNotFoundTransaction";
|
||||
}
|
||||
else if (!jvRequest["transaction"].isMember("Account"))
|
||||
{
|
||||
jvResult["error"] = "fieldNotFoundAccount";
|
||||
}
|
||||
else if (!naAccount.setAccountID(jvRequest["transaction"]["Account"].asString()))
|
||||
{
|
||||
jvResult["error"] = "malformedAccount";
|
||||
}
|
||||
else if (!jvRequest.isMember("secret"))
|
||||
{
|
||||
jvResult["error"] = "fieldNotFoundSecret";
|
||||
}
|
||||
else
|
||||
{
|
||||
Ledger::pointer lpCurrent = mNetwork.getCurrentLedger();
|
||||
SLE::pointer sleAccountRoot = mNetwork.getSLE(lpCurrent, Ledger::getAccountRootIndex(naAccount.getAccountID()));
|
||||
|
||||
if (!sleAccountRoot)
|
||||
{
|
||||
// XXX Ignore transactions for accounts not created.
|
||||
|
||||
jvResult["error"] = "accountNotFound";
|
||||
return;
|
||||
}
|
||||
|
||||
bool bHaveAuthKey = false;
|
||||
NewcoinAddress naAuthorizedPublic;
|
||||
#if 0
|
||||
|
||||
if (sleAccountRoot->isFieldPresent(sfAuthorizedKey))
|
||||
{
|
||||
naAuthorizedPublic = mLedgerEntry->getFieldAccount(sfAuthorizedKey);
|
||||
// Json::Value obj = getMasterGenerator(uLedger, naRegularSeed, naMasterGenerator);
|
||||
}
|
||||
#endif
|
||||
|
||||
NewcoinAddress naSecret = NewcoinAddress::createSeedGeneric(jvRequest["secret"].asString());
|
||||
NewcoinAddress naMasterGenerator = NewcoinAddress::createGeneratorPublic(naSecret);
|
||||
|
||||
// Find the index of Account from the master generator, so we can generate the public and private keys.
|
||||
NewcoinAddress naMasterAccountPublic;
|
||||
unsigned int iIndex = 0;
|
||||
bool bFound = false;
|
||||
|
||||
// Don't look at ledger entries to determine if the account exists. Don't want to leak to thin server that these accounts are
|
||||
// related.
|
||||
while (!bFound && iIndex != theConfig.ACCOUNT_PROBE_MAX)
|
||||
{
|
||||
naMasterAccountPublic.setAccountPublic(naMasterGenerator, iIndex);
|
||||
|
||||
Log(lsWARNING) << "authorize: " << iIndex << " : " << naMasterAccountPublic.humanAccountID() << " : " << naAccount.humanAccountID();
|
||||
|
||||
bFound = naAccount.getAccountID() == naMasterAccountPublic.getAccountID();
|
||||
if (!bFound)
|
||||
++iIndex;
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
jvResult["error"] = "accountNotMatched";
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the generator to determine the associated public and private keys.
|
||||
NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naSecret);
|
||||
NewcoinAddress naAccountPublic = NewcoinAddress::createAccountPublic(naGenerator, iIndex);
|
||||
NewcoinAddress naAccountPrivate = NewcoinAddress::createAccountPrivate(naGenerator, naSecret, iIndex);
|
||||
|
||||
if (bHaveAuthKey
|
||||
// The generated pair must match authorized...
|
||||
&& naAuthorizedPublic.getAccountID() != naAccountPublic.getAccountID()
|
||||
// ... or the master key must have been used.
|
||||
&& naAccount.getAccountID() != naAccountPublic.getAccountID())
|
||||
{
|
||||
// std::cerr << "iIndex: " << iIndex << std::endl;
|
||||
// std::cerr << "sfAuthorizedKey: " << strHex(asSrc->getAuthorizedKey().getAccountID()) << std::endl;
|
||||
// std::cerr << "naAccountPublic: " << strHex(naAccountPublic.getAccountID()) << std::endl;
|
||||
|
||||
jvResult["error"] = "passwordChanged";
|
||||
return;
|
||||
}
|
||||
|
||||
std::auto_ptr<STObject> sopTrans;
|
||||
|
||||
try
|
||||
{
|
||||
sopTrans = STObject::parseJson(jvRequest["transaction"]);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
jvResult["error"] = "malformedTransaction";
|
||||
jvResult["error_exception"] = e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
sopTrans->setFieldVL(sfSigningPubKey, naAccountPublic.getAccountPublic());
|
||||
|
||||
SerializedTransaction::pointer stpTrans = boost::make_shared<SerializedTransaction>(*sopTrans);
|
||||
|
||||
stpTrans->sign(naAccountPrivate);
|
||||
|
||||
Transaction::pointer tpTrans;
|
||||
|
||||
try
|
||||
{
|
||||
tpTrans = boost::make_shared<Transaction>(stpTrans, false);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
jvResult["error"] = "internalTransaction";
|
||||
jvResult["error_exception"] = e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
tpTrans = mNetwork.submitTransaction(tpTrans);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
jvResult["error"] = "internalSubmit";
|
||||
jvResult["error_exception"] = e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
jvResult["submitted"] = tpTrans->getJson(0);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
jvResult["error"] = "internalJson";
|
||||
jvResult["error_exception"] = e.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WSConnection::doTransactionSubcribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().subTransaction(this))
|
||||
if (!mNetwork.subTransaction(this))
|
||||
{
|
||||
jvResult["error"] = "TransactionsSubscribed";
|
||||
}
|
||||
@@ -815,7 +964,7 @@ void WSConnection::doTransactionSubcribe(Json::Value& jvResult, const Json::Valu
|
||||
|
||||
void WSConnection::doTransactionUnsubscribe(Json::Value& jvResult, const Json::Value& jvRequest)
|
||||
{
|
||||
if (!theApp->getOPs().unsubTransaction(this))
|
||||
if (!mNetwork.unsubTransaction(this))
|
||||
{
|
||||
jvResult["error"] = "TransactionsNotSubscribed";
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ Server.method('serverSpawnSync', function() {
|
||||
config.newcoind,
|
||||
[
|
||||
"-a",
|
||||
"-v",
|
||||
"--conf=newcoind.cfg"
|
||||
],
|
||||
{
|
||||
|
||||
@@ -184,6 +184,16 @@ buster.testCase("Websocket commands", {
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'create account' :
|
||||
function (done) {
|
||||
alpha.send_xns(undefined, 'root', 'alice', 10000, true, function (r) {
|
||||
console.log(r);
|
||||
|
||||
buster.refute(r.error);
|
||||
done();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
|
||||
Reference in New Issue
Block a user