mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-12 15:15:50 +00:00
chore: Cleanup bin/ directory (#5660)
This change removes ancient and unused files from the `bin/` directory.
This commit is contained in:
470
bin/browser.js
470
bin/browser.js
@@ -1,470 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
//
|
|
||||||
// ledger?l=L
|
|
||||||
// transaction?h=H
|
|
||||||
// ledger_entry?l=L&h=H
|
|
||||||
// account?l=L&a=A
|
|
||||||
// directory?l=L&dir_root=H&i=I
|
|
||||||
// directory?l=L&o=A&i=I // owner directory
|
|
||||||
// offer?l=L&offer=H
|
|
||||||
// offer?l=L&account=A&i=I
|
|
||||||
// ripple_state=l=L&a=A&b=A&c=C
|
|
||||||
// account_lines?l=L&a=A
|
|
||||||
//
|
|
||||||
// A=address
|
|
||||||
// C=currency 3 letter code
|
|
||||||
// H=hash
|
|
||||||
// I=index
|
|
||||||
// L=current | closed | validated | index | hash
|
|
||||||
//
|
|
||||||
|
|
||||||
var async = require("async");
|
|
||||||
var extend = require("extend");
|
|
||||||
var http = require("http");
|
|
||||||
var url = require("url");
|
|
||||||
|
|
||||||
var Remote = require("ripple-lib").Remote;
|
|
||||||
|
|
||||||
var program = process.argv[1];
|
|
||||||
|
|
||||||
var httpd_response = function (res, opts) {
|
|
||||||
var self=this;
|
|
||||||
|
|
||||||
res.statusCode = opts.statusCode;
|
|
||||||
res.end(
|
|
||||||
"<HTML>"
|
|
||||||
+ "<HEAD><TITLE>Title</TITLE></HEAD>"
|
|
||||||
+ "<BODY BACKGROUND=\"#FFFFFF\">"
|
|
||||||
+ "State:" + self.state
|
|
||||||
+ "<UL>"
|
|
||||||
+ "<LI><A HREF=\"/\">home</A>"
|
|
||||||
+ "<LI>" + html_link('r4EM4gBQfr1QgQLXSPF4r7h84qE9mb6iCC')
|
|
||||||
// + "<LI><A HREF=\""+test+"\">rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh</A>"
|
|
||||||
+ "<LI><A HREF=\"/ledger\">ledger</A>"
|
|
||||||
+ "</UL>"
|
|
||||||
+ (opts.body || '')
|
|
||||||
+ '<HR><PRE>'
|
|
||||||
+ (opts.url || '')
|
|
||||||
+ '</PRE>'
|
|
||||||
+ "</BODY>"
|
|
||||||
+ "</HTML>"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
var html_link = function (generic) {
|
|
||||||
return '<A HREF="' + build_uri({ type: 'account', account: generic}) + '">' + generic + '</A>';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build a link to a type.
|
|
||||||
var build_uri = function (params, opts) {
|
|
||||||
var c;
|
|
||||||
|
|
||||||
if (params.type === 'account') {
|
|
||||||
c = {
|
|
||||||
pathname: 'account',
|
|
||||||
query: {
|
|
||||||
l: params.ledger,
|
|
||||||
a: params.account,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
} else if (params.type === 'ledger') {
|
|
||||||
c = {
|
|
||||||
pathname: 'ledger',
|
|
||||||
query: {
|
|
||||||
l: params.ledger,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
} else if (params.type === 'transaction') {
|
|
||||||
c = {
|
|
||||||
pathname: 'transaction',
|
|
||||||
query: {
|
|
||||||
h: params.hash,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
c = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
opts = opts || {};
|
|
||||||
|
|
||||||
c.protocol = "http";
|
|
||||||
c.hostname = opts.hostname || self.base.hostname;
|
|
||||||
c.port = opts.port || self.base.port;
|
|
||||||
|
|
||||||
return url.format(c);
|
|
||||||
};
|
|
||||||
|
|
||||||
var build_link = function (item, link) {
|
|
||||||
console.log(link);
|
|
||||||
return "<A HREF=" + link + ">" + item + "</A>";
|
|
||||||
};
|
|
||||||
|
|
||||||
var rewrite_field = function (type, obj, field, opts) {
|
|
||||||
if (field in obj) {
|
|
||||||
obj[field] = rewrite_type(type, obj[field], opts);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var rewrite_type = function (type, obj, opts) {
|
|
||||||
if ('amount' === type) {
|
|
||||||
if ('string' === typeof obj) {
|
|
||||||
// XRP.
|
|
||||||
return '<B>' + obj + '</B>';
|
|
||||||
|
|
||||||
} else {
|
|
||||||
rewrite_field('address', obj, 'issuer', opts);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
return build_link(
|
|
||||||
obj,
|
|
||||||
build_uri({
|
|
||||||
type: 'account',
|
|
||||||
account: obj
|
|
||||||
}, opts)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ('address' === type) {
|
|
||||||
return build_link(
|
|
||||||
obj,
|
|
||||||
build_uri({
|
|
||||||
type: 'account',
|
|
||||||
account: obj
|
|
||||||
}, opts)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ('ledger' === type) {
|
|
||||||
return build_link(
|
|
||||||
obj,
|
|
||||||
build_uri({
|
|
||||||
type: 'ledger',
|
|
||||||
ledger: obj,
|
|
||||||
}, opts)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ('node' === type) {
|
|
||||||
// A node
|
|
||||||
if ('PreviousTxnID' in obj)
|
|
||||||
obj.PreviousTxnID = rewrite_type('transaction', obj.PreviousTxnID, opts);
|
|
||||||
|
|
||||||
if ('Offer' === obj.LedgerEntryType) {
|
|
||||||
if ('NewFields' in obj) {
|
|
||||||
if ('TakerGets' in obj.NewFields)
|
|
||||||
obj.NewFields.TakerGets = rewrite_type('amount', obj.NewFields.TakerGets, opts);
|
|
||||||
|
|
||||||
if ('TakerPays' in obj.NewFields)
|
|
||||||
obj.NewFields.TakerPays = rewrite_type('amount', obj.NewFields.TakerPays, opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.LedgerEntryType = '<B>' + obj.LedgerEntryType + '</B>';
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
else if ('transaction' === type) {
|
|
||||||
// Reference to a transaction.
|
|
||||||
return build_link(
|
|
||||||
obj,
|
|
||||||
build_uri({
|
|
||||||
type: 'transaction',
|
|
||||||
hash: obj
|
|
||||||
}, opts)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'ERROR: ' + type;
|
|
||||||
};
|
|
||||||
|
|
||||||
var rewrite_object = function (obj, opts) {
|
|
||||||
var out = extend({}, obj);
|
|
||||||
|
|
||||||
rewrite_field('address', out, 'Account', opts);
|
|
||||||
|
|
||||||
rewrite_field('ledger', out, 'parent_hash', opts);
|
|
||||||
rewrite_field('ledger', out, 'ledger_index', opts);
|
|
||||||
rewrite_field('ledger', out, 'ledger_current_index', opts);
|
|
||||||
rewrite_field('ledger', out, 'ledger_hash', opts);
|
|
||||||
|
|
||||||
if ('ledger' in obj) {
|
|
||||||
// It's a ledger header.
|
|
||||||
out.ledger = rewrite_object(out.ledger, opts);
|
|
||||||
|
|
||||||
if ('ledger_hash' in out.ledger)
|
|
||||||
out.ledger.ledger_hash = '<B>' + out.ledger.ledger_hash + '</B>';
|
|
||||||
|
|
||||||
delete out.ledger.hash;
|
|
||||||
delete out.ledger.totalCoins;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('TransactionType' in obj) {
|
|
||||||
// It's a transaction.
|
|
||||||
out.TransactionType = '<B>' + obj.TransactionType + '</B>';
|
|
||||||
|
|
||||||
rewrite_field('amount', out, 'TakerGets', opts);
|
|
||||||
rewrite_field('amount', out, 'TakerPays', opts);
|
|
||||||
rewrite_field('ledger', out, 'inLedger', opts);
|
|
||||||
|
|
||||||
out.meta.AffectedNodes = out.meta.AffectedNodes.map(function (node) {
|
|
||||||
var kind = 'CreatedNode' in node
|
|
||||||
? 'CreatedNode'
|
|
||||||
: 'ModifiedNode' in node
|
|
||||||
? 'ModifiedNode'
|
|
||||||
: 'DeletedNode' in node
|
|
||||||
? 'DeletedNode'
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
if (kind) {
|
|
||||||
node[kind] = rewrite_type('node', node[kind], opts);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if ('node' in obj && 'LedgerEntryType' in obj.node) {
|
|
||||||
// Its a ledger entry.
|
|
||||||
|
|
||||||
if (obj.node.LedgerEntryType === 'AccountRoot') {
|
|
||||||
rewrite_field('address', out.node, 'Account', opts);
|
|
||||||
rewrite_field('transaction', out.node, 'PreviousTxnID', opts);
|
|
||||||
rewrite_field('ledger', out.node, 'PreviousTxnLgrSeq', opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
out.node.LedgerEntryType = '<B>' + out.node.LedgerEntryType + '</B>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
var augment_object = function (obj, opts, done) {
|
|
||||||
if (obj.node.LedgerEntryType == 'AccountRoot') {
|
|
||||||
var tx_hash = obj.node.PreviousTxnID;
|
|
||||||
var tx_ledger = obj.node.PreviousTxnLgrSeq;
|
|
||||||
|
|
||||||
obj.history = [];
|
|
||||||
|
|
||||||
async.whilst(
|
|
||||||
function () { return tx_hash; },
|
|
||||||
function (callback) {
|
|
||||||
// console.log("augment_object: request: %s %s", tx_hash, tx_ledger);
|
|
||||||
opts.remote.request_tx(tx_hash)
|
|
||||||
.on('success', function (m) {
|
|
||||||
tx_hash = undefined;
|
|
||||||
tx_ledger = undefined;
|
|
||||||
|
|
||||||
//console.log("augment_object: ", JSON.stringify(m));
|
|
||||||
m.meta.AffectedNodes.filter(function(n) {
|
|
||||||
// console.log("augment_object: ", JSON.stringify(n));
|
|
||||||
// if (n.ModifiedNode)
|
|
||||||
// console.log("augment_object: %s %s %s %s %s %s/%s", 'ModifiedNode' in n, n.ModifiedNode && (n.ModifiedNode.LedgerEntryType === 'AccountRoot'), n.ModifiedNode && n.ModifiedNode.FinalFields && (n.ModifiedNode.FinalFields.Account === obj.node.Account), Object.keys(n)[0], n.ModifiedNode && (n.ModifiedNode.LedgerEntryType), obj.node.Account, n.ModifiedNode && n.ModifiedNode.FinalFields && n.ModifiedNode.FinalFields.Account);
|
|
||||||
// if ('ModifiedNode' in n && n.ModifiedNode.LedgerEntryType === 'AccountRoot')
|
|
||||||
// {
|
|
||||||
// console.log("***: ", JSON.stringify(m));
|
|
||||||
// console.log("***: ", JSON.stringify(n));
|
|
||||||
// }
|
|
||||||
return 'ModifiedNode' in n
|
|
||||||
&& n.ModifiedNode.LedgerEntryType === 'AccountRoot'
|
|
||||||
&& n.ModifiedNode.FinalFields
|
|
||||||
&& n.ModifiedNode.FinalFields.Account === obj.node.Account;
|
|
||||||
})
|
|
||||||
.forEach(function (n) {
|
|
||||||
tx_hash = n.ModifiedNode.PreviousTxnID;
|
|
||||||
tx_ledger = n.ModifiedNode.PreviousTxnLgrSeq;
|
|
||||||
|
|
||||||
obj.history.push({
|
|
||||||
tx_hash: tx_hash,
|
|
||||||
tx_ledger: tx_ledger
|
|
||||||
});
|
|
||||||
console.log("augment_object: next: %s %s", tx_hash, tx_ledger);
|
|
||||||
});
|
|
||||||
|
|
||||||
callback();
|
|
||||||
})
|
|
||||||
.on('error', function (m) {
|
|
||||||
callback(m);
|
|
||||||
})
|
|
||||||
.request();
|
|
||||||
},
|
|
||||||
function (err) {
|
|
||||||
if (err) {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
async.forEach(obj.history, function (o, callback) {
|
|
||||||
opts.remote.request_account_info(obj.node.Account)
|
|
||||||
.ledger_index(o.tx_ledger)
|
|
||||||
.on('success', function (m) {
|
|
||||||
//console.log("augment_object: ", JSON.stringify(m));
|
|
||||||
o.Balance = m.account_data.Balance;
|
|
||||||
// o.account_data = m.account_data;
|
|
||||||
callback();
|
|
||||||
})
|
|
||||||
.on('error', function (m) {
|
|
||||||
o.error = m;
|
|
||||||
callback();
|
|
||||||
})
|
|
||||||
.request();
|
|
||||||
},
|
|
||||||
function (err) {
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (process.argv.length < 4 || process.argv.length > 7) {
|
|
||||||
console.log("Usage: %s ws_ip ws_port [<ip> [<port> [<start>]]]", program);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var ws_ip = process.argv[2];
|
|
||||||
var ws_port = process.argv[3];
|
|
||||||
var ip = process.argv.length > 4 ? process.argv[4] : "127.0.0.1";
|
|
||||||
var port = process.argv.length > 5 ? process.argv[5] : "8080";
|
|
||||||
|
|
||||||
// console.log("START");
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var remote = (new Remote({
|
|
||||||
websocket_ip: ws_ip,
|
|
||||||
websocket_port: ws_port,
|
|
||||||
trace: false
|
|
||||||
}))
|
|
||||||
.on('state', function (m) {
|
|
||||||
console.log("STATE: %s", m);
|
|
||||||
|
|
||||||
self.state = m;
|
|
||||||
})
|
|
||||||
// .once('ledger_closed', callback)
|
|
||||||
.connect()
|
|
||||||
;
|
|
||||||
|
|
||||||
self.base = {
|
|
||||||
hostname: ip,
|
|
||||||
port: port,
|
|
||||||
remote: remote,
|
|
||||||
};
|
|
||||||
|
|
||||||
// console.log("SERVE");
|
|
||||||
var server = http.createServer(function (req, res) {
|
|
||||||
var input = "";
|
|
||||||
|
|
||||||
req.setEncoding();
|
|
||||||
|
|
||||||
req.on('data', function (buffer) {
|
|
||||||
// console.log("DATA: %s", buffer);
|
|
||||||
input = input + buffer;
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('end', function () {
|
|
||||||
// console.log("URL: %s", req.url);
|
|
||||||
// console.log("HEADERS: %s", JSON.stringify(req.headers, undefined, 2));
|
|
||||||
|
|
||||||
var _parsed = url.parse(req.url, true);
|
|
||||||
var _url = JSON.stringify(_parsed, undefined, 2);
|
|
||||||
|
|
||||||
// console.log("HEADERS: %s", JSON.stringify(_parsed, undefined, 2));
|
|
||||||
if (_parsed.pathname === "/account") {
|
|
||||||
var request = remote
|
|
||||||
.request_ledger_entry('account_root')
|
|
||||||
.ledger_index(-1)
|
|
||||||
.account_root(_parsed.query.a)
|
|
||||||
.on('success', function (m) {
|
|
||||||
// console.log("account_root: %s", JSON.stringify(m, undefined, 2));
|
|
||||||
|
|
||||||
augment_object(m, self.base, function() {
|
|
||||||
httpd_response(res,
|
|
||||||
{
|
|
||||||
statusCode: 200,
|
|
||||||
url: _url,
|
|
||||||
body: "<PRE>"
|
|
||||||
+ JSON.stringify(rewrite_object(m, self.base), undefined, 2)
|
|
||||||
+ "</PRE>"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.request();
|
|
||||||
|
|
||||||
} else if (_parsed.pathname === "/ledger") {
|
|
||||||
var request = remote
|
|
||||||
.request_ledger(undefined, { expand: true, transactions: true })
|
|
||||||
.on('success', function (m) {
|
|
||||||
// console.log("Ledger: %s", JSON.stringify(m, undefined, 2));
|
|
||||||
|
|
||||||
httpd_response(res,
|
|
||||||
{
|
|
||||||
statusCode: 200,
|
|
||||||
url: _url,
|
|
||||||
body: "<PRE>"
|
|
||||||
+ JSON.stringify(rewrite_object(m, self.base), undefined, 2)
|
|
||||||
+"</PRE>"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
if (_parsed.query.l && _parsed.query.l.length === 64) {
|
|
||||||
request.ledger_hash(_parsed.query.l);
|
|
||||||
}
|
|
||||||
else if (_parsed.query.l) {
|
|
||||||
request.ledger_index(Number(_parsed.query.l));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
request.ledger_index(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
request.request();
|
|
||||||
|
|
||||||
} else if (_parsed.pathname === "/transaction") {
|
|
||||||
var request = remote
|
|
||||||
.request_tx(_parsed.query.h)
|
|
||||||
// .request_transaction_entry(_parsed.query.h)
|
|
||||||
// .ledger_select(_parsed.query.l)
|
|
||||||
.on('success', function (m) {
|
|
||||||
// console.log("transaction: %s", JSON.stringify(m, undefined, 2));
|
|
||||||
|
|
||||||
httpd_response(res,
|
|
||||||
{
|
|
||||||
statusCode: 200,
|
|
||||||
url: _url,
|
|
||||||
body: "<PRE>"
|
|
||||||
+ JSON.stringify(rewrite_object(m, self.base), undefined, 2)
|
|
||||||
+"</PRE>"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on('error', function (m) {
|
|
||||||
httpd_response(res,
|
|
||||||
{
|
|
||||||
statusCode: 200,
|
|
||||||
url: _url,
|
|
||||||
body: "<PRE>"
|
|
||||||
+ 'ERROR: ' + JSON.stringify(m, undefined, 2)
|
|
||||||
+"</PRE>"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.request();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var test = build_uri({
|
|
||||||
type: 'account',
|
|
||||||
ledger: 'closed',
|
|
||||||
account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
|
||||||
}, self.base);
|
|
||||||
|
|
||||||
httpd_response(res,
|
|
||||||
{
|
|
||||||
statusCode: req.url === "/" ? 200 : 404,
|
|
||||||
url: _url,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(port, ip, undefined,
|
|
||||||
function () {
|
|
||||||
console.log("Listening at: http://%s:%s", ip, port);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim:sw=2:sts=2:ts=8:et
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
var ripple = require('ripple-lib');
|
|
||||||
|
|
||||||
var v = {
|
|
||||||
seed: "snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
|
|
||||||
addr: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"
|
|
||||||
};
|
|
||||||
|
|
||||||
var remote = ripple.Remote.from_config({
|
|
||||||
"trusted" : true,
|
|
||||||
"websocket_ip" : "127.0.0.1",
|
|
||||||
"websocket_port" : 5006,
|
|
||||||
"websocket_ssl" : false,
|
|
||||||
"local_signing" : true
|
|
||||||
});
|
|
||||||
|
|
||||||
var tx_json = {
|
|
||||||
"Account" : v.addr,
|
|
||||||
"Amount" : "10000000",
|
|
||||||
"Destination" : "rEu2ULPiEQm1BAL8pYzmXnNX1aFX9sCks",
|
|
||||||
"Fee" : "10",
|
|
||||||
"Flags" : 0,
|
|
||||||
"Sequence" : 3,
|
|
||||||
"TransactionType" : "Payment"
|
|
||||||
|
|
||||||
//"SigningPubKey": '0396941B22791A448E5877A44CE98434DB217D6FB97D63F0DAD23BE49ED45173C9'
|
|
||||||
};
|
|
||||||
|
|
||||||
remote.on('connected', function () {
|
|
||||||
var req = remote.request_sign(v.seed, tx_json);
|
|
||||||
req.message.debug_signing = true;
|
|
||||||
req.on('success', function (result) {
|
|
||||||
console.log("SERVER RESULT");
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
var sim = {};
|
|
||||||
var tx = remote.transaction();
|
|
||||||
tx.tx_json = tx_json;
|
|
||||||
tx._secret = v.seed;
|
|
||||||
tx.complete();
|
|
||||||
var unsigned = tx.serialize().to_hex();
|
|
||||||
tx.sign();
|
|
||||||
|
|
||||||
sim.tx_blob = tx.serialize().to_hex();
|
|
||||||
sim.tx_json = tx.tx_json;
|
|
||||||
sim.tx_signing_hash = tx.signing_hash().to_hex();
|
|
||||||
sim.tx_unsigned = unsigned;
|
|
||||||
|
|
||||||
console.log("\nLOCAL RESULT");
|
|
||||||
console.log(sim);
|
|
||||||
|
|
||||||
remote.connect(false);
|
|
||||||
});
|
|
||||||
req.on('error', function (err) {
|
|
||||||
if (err.error === "remoteError" && err.remote.error === "srcActNotFound") {
|
|
||||||
console.log("Please fund account "+v.addr+" to run this test.");
|
|
||||||
} else {
|
|
||||||
console.log('error', err);
|
|
||||||
}
|
|
||||||
remote.connect(false);
|
|
||||||
});
|
|
||||||
req.request();
|
|
||||||
|
|
||||||
});
|
|
||||||
remote.connect();
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
//
|
|
||||||
// Returns a Gravatar style hash as per: http://en.gravatar.com/site/implement/hash/
|
|
||||||
//
|
|
||||||
|
|
||||||
if (3 != process.argv.length) {
|
|
||||||
process.stderr.write("Usage: " + process.argv[1] + " email_address\n\nReturns gravatar style hash.\n");
|
|
||||||
process.exit(1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var md5 = require('crypto').createHash('md5');
|
|
||||||
|
|
||||||
md5.update(process.argv[2].trim().toLowerCase());
|
|
||||||
|
|
||||||
process.stdout.write(md5.digest('hex') + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim:sw=2:sts=2:ts=8:et
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
//
|
|
||||||
// This program allows IE 9 ripple-clients to make websocket connections to
|
|
||||||
// rippled using flash. As IE 9 does not have websocket support, this required
|
|
||||||
// if you wish to support IE 9 ripple-clients.
|
|
||||||
//
|
|
||||||
// http://www.lightsphere.com/dev/articles/flash_socket_policy.html
|
|
||||||
//
|
|
||||||
// For better security, be sure to set the Port below to the port of your
|
|
||||||
// [websocket_public_port].
|
|
||||||
//
|
|
||||||
|
|
||||||
var net = require("net"),
|
|
||||||
port = "*",
|
|
||||||
domains = ["*:"+port]; // Domain:Port
|
|
||||||
|
|
||||||
net.createServer(
|
|
||||||
function(socket) {
|
|
||||||
socket.write("<?xml version='1.0' ?>\n");
|
|
||||||
socket.write("<!DOCTYPE cross-domain-policy SYSTEM 'http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd'>\n");
|
|
||||||
socket.write("<cross-domain-policy>\n");
|
|
||||||
domains.forEach(
|
|
||||||
function(domain) {
|
|
||||||
var parts = domain.split(':');
|
|
||||||
socket.write("\t<allow-access-from domain='" + parts[0] + "' to-ports='" + parts[1] + "' />\n");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
socket.write("</cross-domain-policy>\n");
|
|
||||||
socket.end();
|
|
||||||
}
|
|
||||||
).listen(843);
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# This script generates information about your rippled installation
|
|
||||||
# and system. It can be used to help debug issues that you may face
|
|
||||||
# in your installation. While this script endeavors to not display any
|
|
||||||
# sensitive information, it is recommended that you read the output
|
|
||||||
# before sharing with any third parties.
|
|
||||||
|
|
||||||
|
|
||||||
rippled_exe=/opt/ripple/bin/rippled
|
|
||||||
conf_file=/etc/opt/ripple/rippled.cfg
|
|
||||||
|
|
||||||
while getopts ":e:c:" opt; do
|
|
||||||
case $opt in
|
|
||||||
e)
|
|
||||||
rippled_exe=${OPTARG}
|
|
||||||
;;
|
|
||||||
c)
|
|
||||||
conf_file=${OPTARG}
|
|
||||||
;;
|
|
||||||
\?)
|
|
||||||
echo "Invalid option: -$OPTARG"
|
|
||||||
exit -1
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
tmp_loc=$(mktemp -d --tmpdir ripple_info.XXXXX)
|
|
||||||
chmod 751 ${tmp_loc}
|
|
||||||
awk_prog=${tmp_loc}/cfg.awk
|
|
||||||
summary_out=${tmp_loc}/rippled_info.md
|
|
||||||
printf "# rippled report info\n\n> generated at %s\n" "$(date -R)" > ${summary_out}
|
|
||||||
|
|
||||||
function log_section {
|
|
||||||
printf "\n## %s\n" "$*" >> ${summary_out}
|
|
||||||
|
|
||||||
while read -r l; do
|
|
||||||
echo " $l" >> ${summary_out}
|
|
||||||
done </dev/stdin
|
|
||||||
}
|
|
||||||
|
|
||||||
function join_by {
|
|
||||||
local IFS="$1"; shift; echo "$*";
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ -f ${conf_file} ]] ; then
|
|
||||||
exclude=( ips ips_fixed node_seed validation_seed validator_token )
|
|
||||||
cleaned_conf=${tmp_loc}/cleaned_rippled_cfg.txt
|
|
||||||
cat << 'EOP' >> ${awk_prog}
|
|
||||||
BEGIN {FS="[[:space:]]*=[[:space:]]*"; skip=0; db_path=""; print > OUT_FILE; split(exl,exa,"|")}
|
|
||||||
/^#/ {next}
|
|
||||||
save==2 && /^[[:space:]]*$/ {next}
|
|
||||||
/^\[.+\]$/ {
|
|
||||||
section=tolower(gensub(/^\[[[:space:]]*([a-zA-Z_]+)[[:space:]]*\]$/, "\\1", "g"))
|
|
||||||
skip = 0
|
|
||||||
for (i in exa) {
|
|
||||||
if (section == exa[i])
|
|
||||||
skip = 1
|
|
||||||
}
|
|
||||||
if (section == "database_path")
|
|
||||||
save = 1
|
|
||||||
}
|
|
||||||
skip==1 {next}
|
|
||||||
save==2 {save=0; db_path=$0}
|
|
||||||
save==1 {save=2}
|
|
||||||
$1 ~ /password/ {$0=$1"=<redacted>"}
|
|
||||||
{print >> OUT_FILE}
|
|
||||||
END {print db_path}
|
|
||||||
EOP
|
|
||||||
|
|
||||||
db=$(\
|
|
||||||
sed -r -e 's/\<s[[:alnum:]]{28}\>/<redactedsecret>/g;s/^[[:space:]]*//;s/[[:space:]]*$//' ${conf_file} |\
|
|
||||||
awk -v OUT_FILE=${cleaned_conf} -v exl="$(join_by '|' "${exclude[@]}")" -f ${awk_prog})
|
|
||||||
rm ${awk_prog}
|
|
||||||
cat ${cleaned_conf} | log_section "cleaned config file"
|
|
||||||
rm ${cleaned_conf}
|
|
||||||
echo "${db}" | log_section "database path"
|
|
||||||
df ${db} | log_section "df: database"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Send output from this script to a log file
|
|
||||||
## this captures any messages
|
|
||||||
## or errors from the script itself
|
|
||||||
|
|
||||||
log_file=${tmp_loc}/get_info.log
|
|
||||||
exec 3>&1 1>>${log_file} 2>&1
|
|
||||||
|
|
||||||
## Send all stdout files to /tmp
|
|
||||||
|
|
||||||
if [[ -x ${rippled_exe} ]] ; then
|
|
||||||
pgrep rippled && \
|
|
||||||
${rippled_exe} --conf ${conf_file} \
|
|
||||||
-- server_info | log_section "server info"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat /proc/meminfo | log_section "meminfo"
|
|
||||||
cat /proc/swaps | log_section "swap space"
|
|
||||||
ulimit -a | log_section "ulimit"
|
|
||||||
|
|
||||||
if command -v lshw >/dev/null 2>&1 ; then
|
|
||||||
lshw 2>/dev/null | log_section "hardware info"
|
|
||||||
else
|
|
||||||
lscpu > ${tmp_loc}/hw_info.txt
|
|
||||||
hwinfo >> ${tmp_loc}/hw_info.txt
|
|
||||||
lspci >> ${tmp_loc}/hw_info.txt
|
|
||||||
lsblk >> ${tmp_loc}/hw_info.txt
|
|
||||||
cat ${tmp_loc}/hw_info.txt | log_section "hardware info"
|
|
||||||
rm ${tmp_loc}/hw_info.txt
|
|
||||||
fi
|
|
||||||
|
|
||||||
if command -v iostat >/dev/null 2>&1 ; then
|
|
||||||
iostat -t -d -x 2 6 | log_section "iostat"
|
|
||||||
fi
|
|
||||||
|
|
||||||
df -h | log_section "free disk space"
|
|
||||||
drives=($(df | awk '$1 ~ /^\/dev\// {print $1}' | xargs -n 1 basename))
|
|
||||||
block_devs=($(ls /sys/block/))
|
|
||||||
for d in "${drives[@]}"; do
|
|
||||||
for dev in "${block_devs[@]}"; do
|
|
||||||
#echo "D: [$d], DEV: [$dev]"
|
|
||||||
if [[ $d =~ $dev ]]; then
|
|
||||||
# this file (if exists) has 0 for SSD and 1 for HDD
|
|
||||||
if [[ "$(cat /sys/block/${dev}/queue/rotational 2>/dev/null)" == 0 ]] ; then
|
|
||||||
echo "${d} : SSD" >> ${tmp_loc}/is_ssd.txt
|
|
||||||
else
|
|
||||||
echo "${d} : NO SSD" >> ${tmp_loc}/is_ssd.txt
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -f ${tmp_loc}/is_ssd.txt ]] ; then
|
|
||||||
cat ${tmp_loc}/is_ssd.txt | log_section "SSD"
|
|
||||||
rm ${tmp_loc}/is_ssd.txt
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat ${log_file} | log_section "script log"
|
|
||||||
|
|
||||||
cat << MSG | tee /dev/fd/3
|
|
||||||
####################################################
|
|
||||||
rippled info has been gathered. Please copy the
|
|
||||||
contents of ${summary_out}
|
|
||||||
to a github gist at https://gist.github.com/
|
|
||||||
|
|
||||||
PLEASE REVIEW THIS FILE FOR ANY SENSITIVE DATA
|
|
||||||
BEFORE POSTING! We have tried our best to omit
|
|
||||||
any sensitive information from this file, but you
|
|
||||||
should verify before posting.
|
|
||||||
####################################################
|
|
||||||
MSG
|
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
//
|
|
||||||
// Returns hex of lowercasing a string.
|
|
||||||
//
|
|
||||||
|
|
||||||
var stringToHex = function (s) {
|
|
||||||
return Array.prototype.map.call(s, function (c) {
|
|
||||||
var b = c.charCodeAt(0);
|
|
||||||
|
|
||||||
return b < 16 ? "0" + b.toString(16) : b.toString(16);
|
|
||||||
}).join("");
|
|
||||||
};
|
|
||||||
|
|
||||||
if (3 != process.argv.length) {
|
|
||||||
process.stderr.write("Usage: " + process.argv[1] + " string\n\nReturns hex of lowercasing string.\n");
|
|
||||||
process.exit(1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
process.stdout.write(stringToHex(process.argv[2].toLowerCase()) + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim:sw=2:sts=2:ts=8:et
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
//
|
|
||||||
// This is a tool to issue JSON-RPC requests from the command line.
|
|
||||||
//
|
|
||||||
// This can be used to test a JSON-RPC server.
|
|
||||||
//
|
|
||||||
// Requires: npm simple-jsonrpc
|
|
||||||
//
|
|
||||||
|
|
||||||
var jsonrpc = require('simple-jsonrpc');
|
|
||||||
|
|
||||||
var program = process.argv[1];
|
|
||||||
|
|
||||||
if (5 !== process.argv.length) {
|
|
||||||
console.log("Usage: %s <URL> <method> <json>", program);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var url = process.argv[2];
|
|
||||||
var method = process.argv[3];
|
|
||||||
var json_raw = process.argv[4];
|
|
||||||
var json;
|
|
||||||
|
|
||||||
try {
|
|
||||||
json = JSON.parse(json_raw);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.log("JSON parse error: %s", e.message);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
var client = jsonrpc.client(url);
|
|
||||||
|
|
||||||
client.call(method, json,
|
|
||||||
function (result) {
|
|
||||||
console.log(JSON.stringify(result, undefined, 2));
|
|
||||||
},
|
|
||||||
function (error) {
|
|
||||||
console.log(JSON.stringify(error, undefined, 2));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim:sw=2:sts=2:ts=8:et
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
//
|
|
||||||
// This is a tool to listen for JSON-RPC requests at an IP and port.
|
|
||||||
//
|
|
||||||
// This will report the request to console and echo back the request as the response.
|
|
||||||
//
|
|
||||||
|
|
||||||
var http = require("http");
|
|
||||||
|
|
||||||
var program = process.argv[1];
|
|
||||||
|
|
||||||
if (4 !== process.argv.length) {
|
|
||||||
console.log("Usage: %s <ip> <port>", program);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var ip = process.argv[2];
|
|
||||||
var port = process.argv[3];
|
|
||||||
|
|
||||||
var server = http.createServer(function (req, res) {
|
|
||||||
console.log("CONNECT");
|
|
||||||
var input = "";
|
|
||||||
|
|
||||||
req.setEncoding();
|
|
||||||
|
|
||||||
req.on('data', function (buffer) {
|
|
||||||
// console.log("DATA: %s", buffer);
|
|
||||||
input = input + buffer;
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('end', function () {
|
|
||||||
// console.log("END");
|
|
||||||
|
|
||||||
var json_req;
|
|
||||||
|
|
||||||
console.log("URL: %s", req.url);
|
|
||||||
console.log("HEADERS: %s", JSON.stringify(req.headers, undefined, 2));
|
|
||||||
|
|
||||||
try {
|
|
||||||
json_req = JSON.parse(input);
|
|
||||||
|
|
||||||
console.log("REQ: %s", JSON.stringify(json_req, undefined, 2));
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.log("BAD JSON: %s", e.message);
|
|
||||||
|
|
||||||
json_req = { error : e.message }
|
|
||||||
}
|
|
||||||
|
|
||||||
res.statusCode = 200;
|
|
||||||
res.end(JSON.stringify({
|
|
||||||
jsonrpc: "2.0",
|
|
||||||
result: { request : json_req },
|
|
||||||
id: req.id
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on('close', function () {
|
|
||||||
console.log("CLOSE");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(port, ip, undefined,
|
|
||||||
function () {
|
|
||||||
console.log("Listening at: %s:%s", ip, port);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim:sw=2:sts=2:ts=8:et
|
|
||||||
218
bin/physical.sh
218
bin/physical.sh
@@ -1,218 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
|
|
||||||
marker_base=985c80fbc6131f3a8cedd0da7e8af98dfceb13c7
|
|
||||||
marker_commit=${1:-${marker_base}}
|
|
||||||
|
|
||||||
if [ $(git merge-base ${marker_commit} ${marker_base}) != ${marker_base} ]; then
|
|
||||||
echo "first marker commit not an ancestor: ${marker_commit}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $(git merge-base ${marker_commit} HEAD) != $(git rev-parse --verify ${marker_commit}) ]; then
|
|
||||||
echo "given marker commit not an ancestor: ${marker_commit}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e Builds/CMake ]; then
|
|
||||||
echo move CMake
|
|
||||||
git mv Builds/CMake cmake
|
|
||||||
git add --update .
|
|
||||||
git commit -m 'Move CMake directory' --author 'Pretty Printer <cpp@ripple.com>'
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e src/ripple ]; then
|
|
||||||
|
|
||||||
echo move protocol buffers
|
|
||||||
mkdir -p include/xrpl
|
|
||||||
if [ -e src/ripple/proto ]; then
|
|
||||||
git mv src/ripple/proto include/xrpl
|
|
||||||
fi
|
|
||||||
|
|
||||||
extract_list() {
|
|
||||||
git show ${marker_commit}:Builds/CMake/RippledCore.cmake | \
|
|
||||||
awk "/END ${1}/ { p = 0 } p && /src\/ripple/; /BEGIN ${1}/ { p = 1 }" | \
|
|
||||||
sed -e 's#src/ripple/##' -e 's#[^a-z]\+$##'
|
|
||||||
}
|
|
||||||
|
|
||||||
move_files() {
|
|
||||||
oldroot="$1"; shift
|
|
||||||
newroot="$1"; shift
|
|
||||||
detail="$1"; shift
|
|
||||||
files=("$@")
|
|
||||||
for file in ${files[@]}; do
|
|
||||||
if [ ! -e ${oldroot}/${file} ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
dir=$(dirname ${file})
|
|
||||||
if [ $(basename ${dir}) == 'details' ]; then
|
|
||||||
dir=$(dirname ${dir})
|
|
||||||
fi
|
|
||||||
if [ $(basename ${dir}) == 'impl' ]; then
|
|
||||||
dir="$(dirname ${dir})/${detail}"
|
|
||||||
fi
|
|
||||||
mkdir -p ${newroot}/${dir}
|
|
||||||
git mv ${oldroot}/${file} ${newroot}/${dir}
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
echo move libxrpl headers
|
|
||||||
files=$(extract_list 'LIBXRPL HEADERS')
|
|
||||||
files+=(
|
|
||||||
basics/SlabAllocator.h
|
|
||||||
|
|
||||||
beast/asio/io_latency_probe.h
|
|
||||||
beast/container/aged_container.h
|
|
||||||
beast/container/aged_container_utility.h
|
|
||||||
beast/container/aged_map.h
|
|
||||||
beast/container/aged_multimap.h
|
|
||||||
beast/container/aged_multiset.h
|
|
||||||
beast/container/aged_set.h
|
|
||||||
beast/container/aged_unordered_map.h
|
|
||||||
beast/container/aged_unordered_multimap.h
|
|
||||||
beast/container/aged_unordered_multiset.h
|
|
||||||
beast/container/aged_unordered_set.h
|
|
||||||
beast/container/detail/aged_associative_container.h
|
|
||||||
beast/container/detail/aged_container_iterator.h
|
|
||||||
beast/container/detail/aged_ordered_container.h
|
|
||||||
beast/container/detail/aged_unordered_container.h
|
|
||||||
beast/container/detail/empty_base_optimization.h
|
|
||||||
beast/core/LockFreeStack.h
|
|
||||||
beast/insight/Collector.h
|
|
||||||
beast/insight/Counter.h
|
|
||||||
beast/insight/CounterImpl.h
|
|
||||||
beast/insight/Event.h
|
|
||||||
beast/insight/EventImpl.h
|
|
||||||
beast/insight/Gauge.h
|
|
||||||
beast/insight/GaugeImpl.h
|
|
||||||
beast/insight/Group.h
|
|
||||||
beast/insight/Groups.h
|
|
||||||
beast/insight/Hook.h
|
|
||||||
beast/insight/HookImpl.h
|
|
||||||
beast/insight/Insight.h
|
|
||||||
beast/insight/Meter.h
|
|
||||||
beast/insight/MeterImpl.h
|
|
||||||
beast/insight/NullCollector.h
|
|
||||||
beast/insight/StatsDCollector.h
|
|
||||||
beast/test/fail_counter.h
|
|
||||||
beast/test/fail_stream.h
|
|
||||||
beast/test/pipe_stream.h
|
|
||||||
beast/test/sig_wait.h
|
|
||||||
beast/test/string_iostream.h
|
|
||||||
beast/test/string_istream.h
|
|
||||||
beast/test/string_ostream.h
|
|
||||||
beast/test/test_allocator.h
|
|
||||||
beast/test/yield_to.h
|
|
||||||
beast/utility/hash_pair.h
|
|
||||||
beast/utility/maybe_const.h
|
|
||||||
beast/utility/temp_dir.h
|
|
||||||
|
|
||||||
# included by only json/impl/json_assert.h
|
|
||||||
json/json_errors.h
|
|
||||||
|
|
||||||
protocol/PayChan.h
|
|
||||||
protocol/RippleLedgerHash.h
|
|
||||||
protocol/messages.h
|
|
||||||
protocol/st.h
|
|
||||||
)
|
|
||||||
files+=(
|
|
||||||
basics/README.md
|
|
||||||
crypto/README.md
|
|
||||||
json/README.md
|
|
||||||
protocol/README.md
|
|
||||||
resource/README.md
|
|
||||||
)
|
|
||||||
move_files src/ripple include/xrpl detail ${files[@]}
|
|
||||||
|
|
||||||
echo move libxrpl sources
|
|
||||||
files=$(extract_list 'LIBXRPL SOURCES')
|
|
||||||
move_files src/ripple src/libxrpl "" ${files[@]}
|
|
||||||
|
|
||||||
echo check leftovers
|
|
||||||
dirs=$(cd include/xrpl; ls -d */)
|
|
||||||
dirs=$(cd src/ripple; ls -d ${dirs} 2>/dev/null || true)
|
|
||||||
files="$(cd src/ripple; find ${dirs} -type f)"
|
|
||||||
if [ -n "${files}" ]; then
|
|
||||||
echo "leftover files:"
|
|
||||||
echo ${files}
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo remove empty directories
|
|
||||||
empty_dirs="$(cd src/ripple; find ${dirs} -depth -type d)"
|
|
||||||
for dir in ${empty_dirs[@]}; do
|
|
||||||
if [ -e ${dir} ]; then
|
|
||||||
rmdir ${dir}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo move xrpld sources
|
|
||||||
files=$(
|
|
||||||
extract_list 'XRPLD SOURCES'
|
|
||||||
cd src/ripple
|
|
||||||
find * -regex '.*\.\(h\|ipp\|md\|pu\|uml\|png\)'
|
|
||||||
)
|
|
||||||
move_files src/ripple src/xrpld detail ${files[@]}
|
|
||||||
|
|
||||||
files="$(cd src/ripple; find . -type f)"
|
|
||||||
if [ -n "${files}" ]; then
|
|
||||||
echo "leftover files:"
|
|
||||||
echo ${files}
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf src/ripple
|
|
||||||
|
|
||||||
echo rename .hpp to .h
|
|
||||||
find include src -name '*.hpp' -exec bash -c 'f="{}"; git mv "${f}" "${f%hpp}h"' \;
|
|
||||||
|
|
||||||
echo move PerfLog.h
|
|
||||||
if [ -e include/xrpl/basics/PerfLog.h ]; then
|
|
||||||
git mv include/xrpl/basics/PerfLog.h src/xrpld/perflog
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure all protobuf includes have the correct prefix.
|
|
||||||
protobuf_replace='s:^#include\s*["<].*org/xrpl\([^">]\+\)[">]:#include <xrpl/proto/org/xrpl\1>:'
|
|
||||||
# Make sure first-party includes use angle brackets and .h extension.
|
|
||||||
ripple_replace='s:include\s*["<]ripple/\(.*\)\.h\(pp\)\?[">]:include <ripple/\1.h>:'
|
|
||||||
beast_replace='s:include\s*<beast/:include <xrpl/beast/:'
|
|
||||||
# Rename impl directories to detail.
|
|
||||||
impl_rename='s:\(<xrpl.*\)/impl\(/details\)\?/:\1/detail/:'
|
|
||||||
|
|
||||||
echo rewrite includes in libxrpl
|
|
||||||
find include/xrpl src/libxrpl -type f -exec sed -i \
|
|
||||||
-e "${protobuf_replace}" \
|
|
||||||
-e "${ripple_replace}" \
|
|
||||||
-e "${beast_replace}" \
|
|
||||||
-e 's:^#include <ripple/:#include <xrpl/:' \
|
|
||||||
-e "${impl_rename}" \
|
|
||||||
{} +
|
|
||||||
|
|
||||||
echo rewrite includes in xrpld
|
|
||||||
# # https://www.baeldung.com/linux/join-multiple-lines
|
|
||||||
libxrpl_dirs="$(cd include/xrpl; ls -d1 */ | sed 's:/$::')"
|
|
||||||
# libxrpl_dirs='a\nb\nc\n'
|
|
||||||
readarray -t libxrpl_dirs <<< "${libxrpl_dirs}"
|
|
||||||
# libxrpl_dirs=(a b c)
|
|
||||||
libxrpl_dirs=$(printf -v txt '%s\\|' "${libxrpl_dirs[@]}"; echo "${txt%\\|}")
|
|
||||||
# libxrpl_dirs='a\|b\|c'
|
|
||||||
find src/xrpld src/test -type f -exec sed -i \
|
|
||||||
-e "${protobuf_replace}" \
|
|
||||||
-e "${ripple_replace}" \
|
|
||||||
-e "${beast_replace}" \
|
|
||||||
-e "s:^#include <ripple/basics/PerfLog.h>:#include <xrpld/perflog/PerfLog.h>:" \
|
|
||||||
-e "s:^#include <ripple/\(${libxrpl_dirs}\)/:#include <xrpl/\1/:" \
|
|
||||||
-e 's:^#include <ripple/:#include <xrpld/:' \
|
|
||||||
-e "${impl_rename}" \
|
|
||||||
{} +
|
|
||||||
|
|
||||||
git commit -m 'Rearrange sources' --author 'Pretty Printer <cpp@ripple.com>'
|
|
||||||
find include src -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format-10 -i {} +
|
|
||||||
git add --update .
|
|
||||||
git commit -m 'Rewrite includes' --author 'Pretty Printer <cpp@ripple.com>'
|
|
||||||
./Builds/levelization/levelization.sh
|
|
||||||
git add --update .
|
|
||||||
git commit -m 'Recompute loops' --author 'Pretty Printer <cpp@ripple.com>'
|
|
||||||
252
bin/rlint.js
252
bin/rlint.js
@@ -1,252 +0,0 @@
|
|||||||
#!/usr/bin/node
|
|
||||||
|
|
||||||
var async = require('async');
|
|
||||||
var Remote = require('ripple-lib').Remote;
|
|
||||||
var Transaction = require('ripple-lib').Transaction;
|
|
||||||
var UInt160 = require('ripple-lib').UInt160;
|
|
||||||
var Amount = require('ripple-lib').Amount;
|
|
||||||
|
|
||||||
var book_key = function (book) {
|
|
||||||
return book.taker_pays.currency
|
|
||||||
+ ":" + book.taker_pays.issuer
|
|
||||||
+ ":" + book.taker_gets.currency
|
|
||||||
+ ":" + book.taker_gets.issuer;
|
|
||||||
};
|
|
||||||
|
|
||||||
var book_key_cross = function (book) {
|
|
||||||
return book.taker_gets.currency
|
|
||||||
+ ":" + book.taker_gets.issuer
|
|
||||||
+ ":" + book.taker_pays.currency
|
|
||||||
+ ":" + book.taker_pays.issuer;
|
|
||||||
};
|
|
||||||
|
|
||||||
var ledger_verify = function (ledger) {
|
|
||||||
var dir_nodes = ledger.accountState.filter(function (entry) {
|
|
||||||
return entry.LedgerEntryType === 'DirectoryNode' // Only directories
|
|
||||||
&& entry.index === entry.RootIndex // Only root nodes
|
|
||||||
&& 'TakerGetsCurrency' in entry; // Only offer directories
|
|
||||||
});
|
|
||||||
|
|
||||||
var books = {};
|
|
||||||
|
|
||||||
dir_nodes.forEach(function (node) {
|
|
||||||
var book = {
|
|
||||||
taker_gets: {
|
|
||||||
currency: UInt160.from_generic(node.TakerGetsCurrency).to_json(),
|
|
||||||
issuer: UInt160.from_generic(node.TakerGetsIssuer).to_json()
|
|
||||||
},
|
|
||||||
taker_pays: {
|
|
||||||
currency: UInt160.from_generic(node.TakerPaysCurrency).to_json(),
|
|
||||||
issuer: UInt160.from_generic(node.TakerPaysIssuer).to_json()
|
|
||||||
},
|
|
||||||
quality: Amount.from_quality(node.RootIndex),
|
|
||||||
index: node.RootIndex
|
|
||||||
};
|
|
||||||
|
|
||||||
books[book_key(book)] = book;
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(node, undefined, 2));
|
|
||||||
});
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(dir_entry, undefined, 2));
|
|
||||||
console.log("#%s books: %s", ledger.ledger_index, Object.keys(books).length);
|
|
||||||
|
|
||||||
Object.keys(books).forEach(function (key) {
|
|
||||||
var book = books[key];
|
|
||||||
var key_cross = book_key_cross(book);
|
|
||||||
var book_cross = books[key_cross];
|
|
||||||
|
|
||||||
if (book && book_cross && !book_cross.done)
|
|
||||||
{
|
|
||||||
var book_cross_quality_inverted = Amount.from_json("1.0/1/1").divide(book_cross.quality);
|
|
||||||
|
|
||||||
if (book_cross_quality_inverted.compareTo(book.quality) >= 0)
|
|
||||||
{
|
|
||||||
// Crossing books
|
|
||||||
console.log("crossing: #%s :: %s :: %s :: %s :: %s :: %s :: %s", ledger.ledger_index, key, book.quality.to_text(), book_cross.quality.to_text(), book_cross_quality_inverted.to_text(),
|
|
||||||
book.index, book_cross.index);
|
|
||||||
}
|
|
||||||
|
|
||||||
book_cross.done = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var ripple_selfs = {};
|
|
||||||
|
|
||||||
var accounts = {};
|
|
||||||
var counts = {};
|
|
||||||
|
|
||||||
ledger.accountState.forEach(function (entry) {
|
|
||||||
if (entry.LedgerEntryType === 'Offer')
|
|
||||||
{
|
|
||||||
counts[entry.Account] = (counts[entry.Account] || 0) + 1;
|
|
||||||
}
|
|
||||||
else if (entry.LedgerEntryType === 'RippleState')
|
|
||||||
{
|
|
||||||
if (entry.Flags & (0x10000 | 0x40000))
|
|
||||||
{
|
|
||||||
counts[entry.LowLimit.issuer] = (counts[entry.LowLimit.issuer] || 0) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.Flags & (0x20000 | 0x80000))
|
|
||||||
{
|
|
||||||
counts[entry.HighLimit.issuer] = (counts[entry.HighLimit.issuer] || 0) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.HighLimit.issuer === entry.LowLimit.issuer)
|
|
||||||
ripple_selfs[entry.Account] = entry;
|
|
||||||
}
|
|
||||||
else if (entry.LedgerEntryType == 'AccountRoot')
|
|
||||||
{
|
|
||||||
accounts[entry.Account] = entry;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var low = 0; // Accounts with too low a count.
|
|
||||||
var high = 0;
|
|
||||||
var missing_accounts = 0; // Objects with no referencing account.
|
|
||||||
var missing_objects = 0; // Accounts specifying an object but having none.
|
|
||||||
|
|
||||||
Object.keys(counts).forEach(function (account) {
|
|
||||||
if (account in accounts)
|
|
||||||
{
|
|
||||||
if (counts[account] !== accounts[account].OwnerCount)
|
|
||||||
{
|
|
||||||
if (counts[account] < accounts[account].OwnerCount)
|
|
||||||
{
|
|
||||||
high += 1;
|
|
||||||
console.log("%s: high count %s/%s", account, counts[account], accounts[account].OwnerCount);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
low += 1;
|
|
||||||
console.log("%s: low count %s/%s", account, counts[account], accounts[account].OwnerCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
missing_accounts += 1;
|
|
||||||
|
|
||||||
console.log("%s: missing : count %s", account, counts[account]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(accounts).forEach(function (account) {
|
|
||||||
if (!('OwnerCount' in accounts[account]))
|
|
||||||
{
|
|
||||||
console.log("%s: bad entry : %s", account, JSON.stringify(accounts[account], undefined, 2));
|
|
||||||
}
|
|
||||||
else if (!(account in counts) && accounts[account].OwnerCount)
|
|
||||||
{
|
|
||||||
missing_objects += 1;
|
|
||||||
|
|
||||||
console.log("%s: no objects : %s/%s", account, 0, accounts[account].OwnerCount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (low)
|
|
||||||
console.log("counts too low = %s", low);
|
|
||||||
|
|
||||||
if (high)
|
|
||||||
console.log("counts too high = %s", high);
|
|
||||||
|
|
||||||
if (missing_objects)
|
|
||||||
console.log("missing_objects = %s", missing_objects);
|
|
||||||
|
|
||||||
if (missing_accounts)
|
|
||||||
console.log("missing_accounts = %s", missing_accounts);
|
|
||||||
|
|
||||||
if (Object.keys(ripple_selfs).length)
|
|
||||||
console.log("RippleState selfs = %s", Object.keys(ripple_selfs).length);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var ledger_request = function (remote, ledger_index, done) {
|
|
||||||
remote.request_ledger(undefined, {
|
|
||||||
accounts: true,
|
|
||||||
expand: true,
|
|
||||||
})
|
|
||||||
.ledger_index(ledger_index)
|
|
||||||
.on('success', function (m) {
|
|
||||||
// console.log("ledger: ", ledger_index);
|
|
||||||
// console.log("ledger: ", JSON.stringify(m, undefined, 2));
|
|
||||||
done(m.ledger);
|
|
||||||
})
|
|
||||||
.on('error', function (m) {
|
|
||||||
console.log("error");
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
.request();
|
|
||||||
};
|
|
||||||
|
|
||||||
var usage = function () {
|
|
||||||
console.log("rlint.js _websocket_ip_ _websocket_port_ ");
|
|
||||||
};
|
|
||||||
|
|
||||||
var finish = function (remote) {
|
|
||||||
remote.disconnect();
|
|
||||||
|
|
||||||
// XXX Because remote.disconnect() doesn't work:
|
|
||||||
process.exit();
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log("args: ", process.argv.length);
|
|
||||||
console.log("args: ", process.argv);
|
|
||||||
|
|
||||||
if (process.argv.length < 4) {
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var remote = Remote.from_config({
|
|
||||||
websocket_ip: process.argv[2],
|
|
||||||
websocket_port: process.argv[3],
|
|
||||||
})
|
|
||||||
.once('ledger_closed', function (m) {
|
|
||||||
console.log("ledger_closed: ", JSON.stringify(m, undefined, 2));
|
|
||||||
|
|
||||||
if (process.argv.length === 5) {
|
|
||||||
var ledger_index = process.argv[4];
|
|
||||||
|
|
||||||
ledger_request(remote, ledger_index, function (l) {
|
|
||||||
if (l) {
|
|
||||||
ledger_verify(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
finish(remote);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if (process.argv.length === 6) {
|
|
||||||
var ledger_start = Number(process.argv[4]);
|
|
||||||
var ledger_end = Number(process.argv[5]);
|
|
||||||
var ledger_cursor = ledger_end;
|
|
||||||
|
|
||||||
async.whilst(
|
|
||||||
function () {
|
|
||||||
return ledger_start <= ledger_cursor && ledger_cursor <=ledger_end;
|
|
||||||
},
|
|
||||||
function (callback) {
|
|
||||||
// console.log(ledger_cursor);
|
|
||||||
|
|
||||||
ledger_request(remote, ledger_cursor, function (l) {
|
|
||||||
if (l) {
|
|
||||||
ledger_verify(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
--ledger_cursor;
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function (error) {
|
|
||||||
finish(remote);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
finish(remote);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
// vim:sw=2:sts=2:ts=8:et
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -exu
|
|
||||||
|
|
||||||
: ${TRAVIS_BUILD_DIR:=""}
|
|
||||||
: ${VCPKG_DIR:=".vcpkg"}
|
|
||||||
export VCPKG_ROOT=${VCPKG_DIR}
|
|
||||||
: ${VCPKG_DEFAULT_TRIPLET:="x64-windows-static"}
|
|
||||||
|
|
||||||
export VCPKG_DEFAULT_TRIPLET
|
|
||||||
|
|
||||||
EXE="vcpkg"
|
|
||||||
if [[ -z ${COMSPEC:-} ]]; then
|
|
||||||
EXE="${EXE}.exe"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -d "${VCPKG_DIR}" && -x "${VCPKG_DIR}/${EXE}" && -d "${VCPKG_DIR}/installed" ]] ; then
|
|
||||||
echo "Using cached vcpkg at ${VCPKG_DIR}"
|
|
||||||
${VCPKG_DIR}/${EXE} list
|
|
||||||
else
|
|
||||||
if [[ -d "${VCPKG_DIR}" ]] ; then
|
|
||||||
rm -rf "${VCPKG_DIR}"
|
|
||||||
fi
|
|
||||||
git clone --branch 2021.04.30 https://github.com/Microsoft/vcpkg.git ${VCPKG_DIR}
|
|
||||||
pushd ${VCPKG_DIR}
|
|
||||||
BSARGS=()
|
|
||||||
if [[ "$(uname)" == "Darwin" ]] ; then
|
|
||||||
BSARGS+=(--allowAppleClang)
|
|
||||||
fi
|
|
||||||
if [[ -z ${COMSPEC:-} ]]; then
|
|
||||||
chmod +x ./bootstrap-vcpkg.sh
|
|
||||||
time ./bootstrap-vcpkg.sh "${BSARGS[@]}"
|
|
||||||
else
|
|
||||||
time ./bootstrap-vcpkg.bat
|
|
||||||
fi
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TODO: bring boost in this way as well ?
|
|
||||||
# NOTE: can pin specific ports to a commit/version like this:
|
|
||||||
# git checkout <SOME COMMIT HASH> ports/boost
|
|
||||||
if [ $# -eq 0 ]; then
|
|
||||||
echo "No extra packages specified..."
|
|
||||||
PKGS=()
|
|
||||||
else
|
|
||||||
PKGS=( "$@" )
|
|
||||||
fi
|
|
||||||
for LIB in "${PKGS[@]}"; do
|
|
||||||
time ${VCPKG_DIR}/${EXE} --clean-after-build install ${LIB}
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
|
|
||||||
# NOTE: must be sourced from a shell so it can export vars
|
|
||||||
|
|
||||||
cat << BATCH > ./getenv.bat
|
|
||||||
CALL %*
|
|
||||||
ENV
|
|
||||||
BATCH
|
|
||||||
|
|
||||||
while read line ; do
|
|
||||||
IFS='"' read x path arg <<<"${line}"
|
|
||||||
if [ -f "${path}" ] ; then
|
|
||||||
echo "FOUND: $path"
|
|
||||||
export VCINSTALLDIR=$(./getenv.bat "${path}" ${arg} | grep "^VCINSTALLDIR=" | sed -E "s/^VCINSTALLDIR=//g")
|
|
||||||
if [ "${VCINSTALLDIR}" != "" ] ; then
|
|
||||||
echo "USING ${VCINSTALLDIR}"
|
|
||||||
export LIB=$(./getenv.bat "${path}" ${arg} | grep "^LIB=" | sed -E "s/^LIB=//g")
|
|
||||||
export LIBPATH=$(./getenv.bat "${path}" ${arg} | grep "^LIBPATH=" | sed -E "s/^LIBPATH=//g")
|
|
||||||
export INCLUDE=$(./getenv.bat "${path}" ${arg} | grep "^INCLUDE=" | sed -E "s/^INCLUDE=//g")
|
|
||||||
ADDPATH=$(./getenv.bat "${path}" ${arg} | grep "^PATH=" | sed -E "s/^PATH=//g")
|
|
||||||
export PATH="${ADDPATH}:${PATH}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done <<EOL
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio 15.0/VC/vcvarsall.bat" amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat" amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio 13.0/VC/vcvarsall.bat" amd64
|
|
||||||
"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat" amd64
|
|
||||||
EOL
|
|
||||||
# TODO: update the list above as needed to support newer versions of msvc tools
|
|
||||||
|
|
||||||
rm -f getenv.bat
|
|
||||||
|
|
||||||
if [ "${VCINSTALLDIR}" = "" ] ; then
|
|
||||||
echo "No compatible visual studio found!"
|
|
||||||
fi
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
"""A script to test rippled in an infinite loop of start-sync-stop.
|
|
||||||
|
|
||||||
- Requires Python 3.7+.
|
|
||||||
- Can be stopped with SIGINT.
|
|
||||||
- Has no dependencies outside the standard library.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
assert sys.version_info.major == 3 and sys.version_info.minor >= 7
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import asyncio
|
|
||||||
import configparser
|
|
||||||
import contextlib
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
import platform
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import urllib.error
|
|
||||||
import urllib.request
|
|
||||||
|
|
||||||
# Enable asynchronous subprocesses on Windows. The default changed in 3.8.
|
|
||||||
# https://docs.python.org/3.7/library/asyncio-platforms.html#subprocess-support-on-windows
|
|
||||||
if (platform.system() == 'Windows' and sys.version_info.major == 3
|
|
||||||
and sys.version_info.minor < 8):
|
|
||||||
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
|
||||||
|
|
||||||
DEFAULT_EXE = 'rippled'
|
|
||||||
DEFAULT_CONFIGURATION_FILE = 'rippled.cfg'
|
|
||||||
# Number of seconds to wait before forcefully terminating.
|
|
||||||
PATIENCE = 120
|
|
||||||
# Number of contiguous seconds in a sync state to be considered synced.
|
|
||||||
DEFAULT_SYNC_DURATION = 60
|
|
||||||
# Number of seconds between polls of state.
|
|
||||||
DEFAULT_POLL_INTERVAL = 5
|
|
||||||
SYNC_STATES = ('full', 'validating', 'proposing')
|
|
||||||
|
|
||||||
|
|
||||||
def read_config(config_file):
|
|
||||||
# strict = False: Allow duplicate keys, e.g. [rpc_startup].
|
|
||||||
# allow_no_value = True: Allow keys with no values. Generally, these
|
|
||||||
# instances use the "key" as the value, and the section name is the key,
|
|
||||||
# e.g. [debug_logfile].
|
|
||||||
# delimiters = ('='): Allow ':' as a character in Windows paths. Some of
|
|
||||||
# our "keys" are actually values, and we don't want to split them on ':'.
|
|
||||||
config = configparser.ConfigParser(
|
|
||||||
strict=False,
|
|
||||||
allow_no_value=True,
|
|
||||||
delimiters=('='),
|
|
||||||
)
|
|
||||||
config.read(config_file)
|
|
||||||
return config
|
|
||||||
|
|
||||||
|
|
||||||
def to_list(value, separator=','):
|
|
||||||
"""Parse a list from a delimited string value."""
|
|
||||||
return [s.strip() for s in value.split(separator) if s]
|
|
||||||
|
|
||||||
|
|
||||||
def find_log_file(config_file):
|
|
||||||
"""Try to figure out what log file the user has chosen. Raises all kinds
|
|
||||||
of exceptions if there is any possibility of ambiguity."""
|
|
||||||
config = read_config(config_file)
|
|
||||||
values = list(config['debug_logfile'].keys())
|
|
||||||
if len(values) < 1:
|
|
||||||
raise ValueError(
|
|
||||||
f'no [debug_logfile] in configuration file: {config_file}')
|
|
||||||
if len(values) > 1:
|
|
||||||
raise ValueError(
|
|
||||||
f'too many [debug_logfile] in configuration file: {config_file}')
|
|
||||||
return values[0]
|
|
||||||
|
|
||||||
|
|
||||||
def find_http_port(config_file):
|
|
||||||
config = read_config(config_file)
|
|
||||||
names = list(config['server'].keys())
|
|
||||||
for name in names:
|
|
||||||
server = config[name]
|
|
||||||
if 'http' in to_list(server.get('protocol', '')):
|
|
||||||
return int(server['port'])
|
|
||||||
raise ValueError(f'no server in [server] for "http" protocol')
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.asynccontextmanager
|
|
||||||
async def rippled(exe=DEFAULT_EXE, config_file=DEFAULT_CONFIGURATION_FILE):
|
|
||||||
"""A context manager for a rippled process."""
|
|
||||||
# Start the server.
|
|
||||||
process = await asyncio.create_subprocess_exec(
|
|
||||||
str(exe),
|
|
||||||
'--conf',
|
|
||||||
str(config_file),
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
logging.info(f'rippled started with pid {process.pid}')
|
|
||||||
try:
|
|
||||||
yield process
|
|
||||||
finally:
|
|
||||||
# Ask it to stop.
|
|
||||||
logging.info(f'asking rippled (pid: {process.pid}) to stop')
|
|
||||||
start = time.time()
|
|
||||||
process.terminate()
|
|
||||||
|
|
||||||
# Wait nicely.
|
|
||||||
try:
|
|
||||||
await asyncio.wait_for(process.wait(), PATIENCE)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
# Ask the operating system to kill it.
|
|
||||||
logging.warning(f'killing rippled ({process.pid})')
|
|
||||||
try:
|
|
||||||
process.kill()
|
|
||||||
except ProcessLookupError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
code = await process.wait()
|
|
||||||
end = time.time()
|
|
||||||
logging.info(
|
|
||||||
f'rippled stopped after {end - start:.1f} seconds with code {code}'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def sync(
|
|
||||||
port,
|
|
||||||
*,
|
|
||||||
duration=DEFAULT_SYNC_DURATION,
|
|
||||||
interval=DEFAULT_POLL_INTERVAL,
|
|
||||||
):
|
|
||||||
"""Poll rippled on an interval until it has been synced for a duration."""
|
|
||||||
start = time.perf_counter()
|
|
||||||
while (time.perf_counter() - start) < duration:
|
|
||||||
await asyncio.sleep(interval)
|
|
||||||
|
|
||||||
request = urllib.request.Request(
|
|
||||||
f'http://127.0.0.1:{port}',
|
|
||||||
data=json.dumps({
|
|
||||||
'method': 'server_state'
|
|
||||||
}).encode(),
|
|
||||||
headers={'Content-Type': 'application/json'},
|
|
||||||
)
|
|
||||||
with urllib.request.urlopen(request) as response:
|
|
||||||
try:
|
|
||||||
body = json.loads(response.read())
|
|
||||||
except urllib.error.HTTPError as cause:
|
|
||||||
logging.warning(f'server_state returned not JSON: {cause}')
|
|
||||||
start = time.perf_counter()
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
state = body['result']['state']['server_state']
|
|
||||||
except KeyError as cause:
|
|
||||||
logging.warning(f'server_state response missing key: {cause.key}')
|
|
||||||
start = time.perf_counter()
|
|
||||||
continue
|
|
||||||
logging.info(f'server_state: {state}')
|
|
||||||
if state not in SYNC_STATES:
|
|
||||||
# Require a contiguous sync state.
|
|
||||||
start = time.perf_counter()
|
|
||||||
|
|
||||||
|
|
||||||
async def loop(test,
|
|
||||||
*,
|
|
||||||
exe=DEFAULT_EXE,
|
|
||||||
config_file=DEFAULT_CONFIGURATION_FILE):
|
|
||||||
"""
|
|
||||||
Start-test-stop rippled in an infinite loop.
|
|
||||||
|
|
||||||
Moves log to a different file after each iteration.
|
|
||||||
"""
|
|
||||||
log_file = find_log_file(config_file)
|
|
||||||
id = 0
|
|
||||||
while True:
|
|
||||||
logging.info(f'iteration: {id}')
|
|
||||||
async with rippled(exe, config_file) as process:
|
|
||||||
start = time.perf_counter()
|
|
||||||
exited = asyncio.create_task(process.wait())
|
|
||||||
tested = asyncio.create_task(test())
|
|
||||||
# Try to sync as long as the process is running.
|
|
||||||
done, pending = await asyncio.wait(
|
|
||||||
{exited, tested},
|
|
||||||
return_when=asyncio.FIRST_COMPLETED,
|
|
||||||
)
|
|
||||||
if done == {exited}:
|
|
||||||
code = exited.result()
|
|
||||||
logging.warning(
|
|
||||||
f'server halted for unknown reason with code {code}')
|
|
||||||
else:
|
|
||||||
assert done == {tested}
|
|
||||||
assert tested.exception() is None
|
|
||||||
end = time.perf_counter()
|
|
||||||
logging.info(f'synced after {end - start:.0f} seconds')
|
|
||||||
os.replace(log_file, f'debug.{id}.log')
|
|
||||||
id += 1
|
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(
|
|
||||||
format='%(asctime)s %(levelname)-8s %(message)s',
|
|
||||||
level=logging.INFO,
|
|
||||||
datefmt='%Y-%m-%d %H:%M:%S',
|
|
||||||
)
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
||||||
parser.add_argument(
|
|
||||||
'rippled',
|
|
||||||
type=Path,
|
|
||||||
nargs='?',
|
|
||||||
default=DEFAULT_EXE,
|
|
||||||
help='Path to rippled.',
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--conf',
|
|
||||||
type=Path,
|
|
||||||
default=DEFAULT_CONFIGURATION_FILE,
|
|
||||||
help='Path to configuration file.',
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--duration',
|
|
||||||
type=int,
|
|
||||||
default=DEFAULT_SYNC_DURATION,
|
|
||||||
help='Number of contiguous seconds required in a synchronized state.',
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--interval',
|
|
||||||
type=int,
|
|
||||||
default=DEFAULT_POLL_INTERVAL,
|
|
||||||
help='Number of seconds to wait between polls of state.',
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
port = find_http_port(args.conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test():
|
|
||||||
return sync(port, duration=args.duration, interval=args.interval)
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
asyncio.run(loop(test, exe=args.rippled, config_file=args.conf))
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
# Squelch the message. This is a normal mode of exit.
|
|
||||||
pass
|
|
||||||
133
bin/stop-test.js
133
bin/stop-test.js
@@ -1,133 +0,0 @@
|
|||||||
/* -------------------------------- REQUIRES -------------------------------- */
|
|
||||||
|
|
||||||
var child = require("child_process");
|
|
||||||
var assert = require("assert");
|
|
||||||
|
|
||||||
/* --------------------------------- CONFIG --------------------------------- */
|
|
||||||
|
|
||||||
if (process.argv[2] == null) {
|
|
||||||
[
|
|
||||||
'Usage: ',
|
|
||||||
'',
|
|
||||||
' `node bin/stop-test.js i,j [rippled_path] [rippled_conf]`',
|
|
||||||
'',
|
|
||||||
' Launch rippled and stop it after n seconds for all n in [i, j}',
|
|
||||||
' For all even values of n launch rippled with `--fg`',
|
|
||||||
' For values of n where n % 3 == 0 launch rippled with `--fg`\n',
|
|
||||||
'Examples: ',
|
|
||||||
'',
|
|
||||||
' $ node bin/stop-test.js 5,10',
|
|
||||||
(' $ node bin/stop-test.js 1,4 ' +
|
|
||||||
'build/clang.debug/rippled $HOME/.confs/rippled.cfg')
|
|
||||||
]
|
|
||||||
.forEach(function(l){console.log(l)});
|
|
||||||
|
|
||||||
process.exit();
|
|
||||||
} else {
|
|
||||||
var testRange = process.argv[2].split(',').map(Number);
|
|
||||||
var rippledPath = process.argv[3] || 'build/rippled'
|
|
||||||
var rippledConf = process.argv[4] || 'rippled.cfg'
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
env: process.env,
|
|
||||||
stdio: 'ignore' // we could dump the child io when it fails abnormally
|
|
||||||
};
|
|
||||||
|
|
||||||
// default args
|
|
||||||
var conf_args = ['--conf='+rippledConf];
|
|
||||||
var start_args = conf_args.concat([/*'--net'*/])
|
|
||||||
var stop_args = conf_args.concat(['stop']);
|
|
||||||
|
|
||||||
/* --------------------------------- HELPERS -------------------------------- */
|
|
||||||
|
|
||||||
function start(args) {
|
|
||||||
return child.spawn(rippledPath, args, options);
|
|
||||||
}
|
|
||||||
function stop(rippled) { child.execFile(rippledPath, stop_args, options)}
|
|
||||||
function secs_l8r(ms, f) {setTimeout(f, ms * 1000); }
|
|
||||||
|
|
||||||
function show_results_and_exit(results) {
|
|
||||||
console.log(JSON.stringify(results, undefined, 2));
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeTakes = function (range) {
|
|
||||||
function sumRange(n) {return (n+1) * n /2}
|
|
||||||
var ret = sumRange(range[1]);
|
|
||||||
if (range[0] > 1) {
|
|
||||||
ret = ret - sumRange(range[0] - 1)
|
|
||||||
}
|
|
||||||
var stopping = (range[1] - range[0]) * 0.5;
|
|
||||||
return ret + stopping;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------- TEST ---------------------------------- */
|
|
||||||
|
|
||||||
console.log("Test will take ~%s seconds", timeTakes(testRange));
|
|
||||||
|
|
||||||
(function oneTest(n /* seconds */, results) {
|
|
||||||
if (n >= testRange[1]) {
|
|
||||||
// show_results_and_exit(results);
|
|
||||||
console.log(JSON.stringify(results, undefined, 2));
|
|
||||||
oneTest(testRange[0], []);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = start_args;
|
|
||||||
if (n % 2 == 0) {args = args.concat(['--fg'])}
|
|
||||||
if (n % 3 == 0) {args = args.concat(['--net'])}
|
|
||||||
|
|
||||||
var result = {args: args, alive_for: n};
|
|
||||||
results.push(result);
|
|
||||||
|
|
||||||
console.log("\nLaunching `%s` with `%s` for %d seconds",
|
|
||||||
rippledPath, JSON.stringify(args), n);
|
|
||||||
|
|
||||||
rippled = start(args);
|
|
||||||
console.log("Rippled pid: %d", rippled.pid);
|
|
||||||
|
|
||||||
// defaults
|
|
||||||
var b4StopSent = false;
|
|
||||||
var stopSent = false;
|
|
||||||
var stop_took = null;
|
|
||||||
|
|
||||||
rippled.once('exit', function(){
|
|
||||||
if (!stopSent && !b4StopSent) {
|
|
||||||
console.warn('\nRippled exited itself b4 stop issued');
|
|
||||||
process.exit();
|
|
||||||
};
|
|
||||||
|
|
||||||
// The io handles close AFTER exit, may have implications for
|
|
||||||
// `stdio:'inherit'` option to `child.spawn`.
|
|
||||||
rippled.once('close', function() {
|
|
||||||
result.stop_took = (+new Date() - stop_took) / 1000; // seconds
|
|
||||||
console.log("Stopping after %d seconds took %s seconds",
|
|
||||||
n, result.stop_took);
|
|
||||||
oneTest(n+1, results);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
secs_l8r(n, function(){
|
|
||||||
console.log("Stopping rippled after %d seconds", n);
|
|
||||||
|
|
||||||
// possible race here ?
|
|
||||||
// seems highly unlikely, but I was having issues at one point
|
|
||||||
b4StopSent=true;
|
|
||||||
stop_took = (+new Date());
|
|
||||||
// when does `exit` actually get sent?
|
|
||||||
stop();
|
|
||||||
stopSent=true;
|
|
||||||
|
|
||||||
// Sometimes we want to attach with a debugger.
|
|
||||||
if (process.env.ABORT_TESTS_ON_STALL != null) {
|
|
||||||
// We wait 30 seconds, and if it hasn't stopped, we abort the process
|
|
||||||
secs_l8r(30, function() {
|
|
||||||
if (result.stop_took == null) {
|
|
||||||
console.log("rippled has stalled");
|
|
||||||
process.exit();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}(testRange[0], []));
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
/**
|
|
||||||
* bin/update_bintypes.js
|
|
||||||
*
|
|
||||||
* This unholy abomination of a script generates the JavaScript file
|
|
||||||
* src/js/bintypes.js from various parts of the C++ source code.
|
|
||||||
*
|
|
||||||
* This should *NOT* be part of any automatic build process unless the C++
|
|
||||||
* source data are brought into a more easily parseable format. Until then,
|
|
||||||
* simply run this script manually and fix as needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// XXX: Process LedgerFormats.(h|cpp) as well.
|
|
||||||
|
|
||||||
var filenameProto = __dirname + '/../src/cpp/ripple/SerializeProto.h',
|
|
||||||
filenameTxFormatsH = __dirname + '/../src/cpp/ripple/TransactionFormats.h',
|
|
||||||
filenameTxFormats = __dirname + '/../src/cpp/ripple/TransactionFormats.cpp';
|
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
var output = [];
|
|
||||||
|
|
||||||
// Stage 1: Get the field types and codes from SerializeProto.h
|
|
||||||
var types = {},
|
|
||||||
fields = {};
|
|
||||||
String(fs.readFileSync(filenameProto)).split('\n').forEach(function (line) {
|
|
||||||
line = line.replace(/^\s+|\s+$/g, '').replace(/\s+/g, '');
|
|
||||||
if (!line.length || line.slice(0, 2) === '//' || line.slice(-1) !== ')') return;
|
|
||||||
|
|
||||||
var tmp = line.slice(0, -1).split('('),
|
|
||||||
type = tmp[0],
|
|
||||||
opts = tmp[1].split(',');
|
|
||||||
|
|
||||||
if (type === 'TYPE') types[opts[1]] = [opts[0], +opts[2]];
|
|
||||||
else if (type === 'FIELD') fields[opts[0]] = [types[opts[1]][0], +opts[2]];
|
|
||||||
});
|
|
||||||
|
|
||||||
output.push('var ST = require("./serializedtypes");');
|
|
||||||
output.push('');
|
|
||||||
output.push('var REQUIRED = exports.REQUIRED = 0,');
|
|
||||||
output.push(' OPTIONAL = exports.OPTIONAL = 1,');
|
|
||||||
output.push(' DEFAULT = exports.DEFAULT = 2;');
|
|
||||||
output.push('');
|
|
||||||
|
|
||||||
function pad(s, n) { while (s.length < n) s += ' '; return s; }
|
|
||||||
function padl(s, n) { while (s.length < n) s = ' '+s; return s; }
|
|
||||||
|
|
||||||
Object.keys(types).forEach(function (type) {
|
|
||||||
output.push(pad('ST.'+types[type][0]+'.id', 25) + ' = '+types[type][1]+';');
|
|
||||||
});
|
|
||||||
output.push('');
|
|
||||||
|
|
||||||
// Stage 2: Get the transaction type IDs from TransactionFormats.h
|
|
||||||
var ttConsts = {};
|
|
||||||
String(fs.readFileSync(filenameTxFormatsH)).split('\n').forEach(function (line) {
|
|
||||||
var regex = /tt([A-Z_]+)\s+=\s+([0-9-]+)/;
|
|
||||||
var match = line.match(regex);
|
|
||||||
if (match) ttConsts[match[1]] = +match[2];
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stage 3: Get the transaction formats from TransactionFormats.cpp
|
|
||||||
var base = [],
|
|
||||||
sections = [],
|
|
||||||
current = base;
|
|
||||||
String(fs.readFileSync(filenameTxFormats)).split('\n').forEach(function (line) {
|
|
||||||
line = line.replace(/^\s+|\s+$/g, '').replace(/\s+/g, '');
|
|
||||||
|
|
||||||
var d_regex = /DECLARE_TF\(([A-Za-z]+),tt([A-Z_]+)/;
|
|
||||||
var d_match = line.match(d_regex);
|
|
||||||
|
|
||||||
var s_regex = /SOElement\(sf([a-z]+),SOE_(REQUIRED|OPTIONAL|DEFAULT)/i;
|
|
||||||
var s_match = line.match(s_regex);
|
|
||||||
|
|
||||||
if (d_match) sections.push(current = [d_match[1], ttConsts[d_match[2]]]);
|
|
||||||
else if (s_match) current.push([s_match[1], s_match[2]]);
|
|
||||||
});
|
|
||||||
|
|
||||||
function removeFinalComma(arr) {
|
|
||||||
arr[arr.length-1] = arr[arr.length-1].slice(0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
output.push('var base = [');
|
|
||||||
base.forEach(function (field) {
|
|
||||||
var spec = fields[field[0]];
|
|
||||||
output.push(' [ '+
|
|
||||||
pad("'"+field[0]+"'", 21)+', '+
|
|
||||||
pad(field[1], 8)+', '+
|
|
||||||
padl(""+spec[1], 2)+', '+
|
|
||||||
'ST.'+pad(spec[0], 3)+
|
|
||||||
' ],');
|
|
||||||
});
|
|
||||||
removeFinalComma(output);
|
|
||||||
output.push('];');
|
|
||||||
output.push('');
|
|
||||||
|
|
||||||
|
|
||||||
output.push('exports.tx = {');
|
|
||||||
sections.forEach(function (section) {
|
|
||||||
var name = section.shift(),
|
|
||||||
ttid = section.shift();
|
|
||||||
|
|
||||||
output.push(' '+name+': ['+ttid+'].concat(base, [');
|
|
||||||
section.forEach(function (field) {
|
|
||||||
var spec = fields[field[0]];
|
|
||||||
output.push(' [ '+
|
|
||||||
pad("'"+field[0]+"'", 21)+', '+
|
|
||||||
pad(field[1], 8)+', '+
|
|
||||||
padl(""+spec[1], 2)+', '+
|
|
||||||
'ST.'+pad(spec[0], 3)+
|
|
||||||
' ],');
|
|
||||||
});
|
|
||||||
removeFinalComma(output);
|
|
||||||
output.push(' ]),');
|
|
||||||
});
|
|
||||||
removeFinalComma(output);
|
|
||||||
output.push('};');
|
|
||||||
output.push('');
|
|
||||||
|
|
||||||
console.log(output.join('\n'));
|
|
||||||
|
|
||||||
@@ -117,7 +117,6 @@ class Xrpl(ConanFile):
|
|||||||
|
|
||||||
exports_sources = (
|
exports_sources = (
|
||||||
'CMakeLists.txt',
|
'CMakeLists.txt',
|
||||||
'bin/getRippledInfo',
|
|
||||||
'cfg/*',
|
'cfg/*',
|
||||||
'cmake/*',
|
'cmake/*',
|
||||||
'external/*',
|
'external/*',
|
||||||
|
|||||||
Reference in New Issue
Block a user