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

Conflicts:
	src/Application.cpp
This commit is contained in:
jed
2012-10-09 03:05:21 -07:00
49 changed files with 2677 additions and 716 deletions

6
.gitmodules vendored
View File

@@ -1,3 +1,9 @@
[submodule "websocketpp"]
path = websocketpp
url = https://github.com/zaphoyd/websocketpp.git
[submodule "js/cryptojs"]
path = js/cryptojs
url = git://github.com/gwjjeff/cryptojs.git
[submodule "js/sjcl"]
path = js/sjcl
url = git://github.com/bitwiseshiftleft/sjcl.git

8
README
View File

@@ -2,5 +2,9 @@ Dependancies:
- boost 1.47
- Google protocol buffers 2.4.1
- openssl
- mysql
- websocketpp
Sub modules:
- websocketpp: https://github.com/zaphoyd/websocketpp
- sjcl: https://github.com/bitwiseshiftleft/sjcl
- cryptojs: https://github.com/gwjjeff/cryptojs
aka http://code.google.com/p/crypto-js/

View File

@@ -3,16 +3,22 @@
#
import glob
import platform
CTAGS = '/usr/bin/exuberant-ctags'
OSX = bool(platform.mac_ver()[0])
if OSX:
CTAGS = '/usr/bin/ctags'
else:
CTAGS = '/usr/bin/exuberant-ctags'
#
# scons tools
#
env = Environment(
tools = ['default', 'protoc']
)
tools = ['default', 'protoc']
)
# Use clang
#env.Replace(CC = 'clang')
@@ -23,73 +29,83 @@ env = Environment(
#
ctags = Builder(action = '$CTAGS $CTAGSOPTIONS -f $TARGET $SOURCES')
env.Append(BUILDERS = { 'CTags' : ctags })
env.Replace(CTAGS = CTAGS, CTAGSOPTIONS = '--tag-relative')
if OSX:
env.Replace(CTAGS = CTAGS)
else:
env.Replace(CTAGS = CTAGS, CTAGSOPTIONS = '--tag-relative')
#
# Put objects files in their own directory.
#
for dir in ['src', 'database', 'json', 'websocketpp']:
VariantDir('obj/'+dir, dir, duplicate=0)
VariantDir('obj/'+dir, dir, duplicate=0)
# Use openssl
env.ParseConfig('pkg-config --cflags --libs openssl')
env.Append(LIBS = [
'boost_date_time-mt',
'boost_filesystem-mt',
'boost_program_options-mt',
'boost_regex-mt',
'boost_system-mt',
'boost_thread-mt',
'protobuf',
'dl', # dynamic linking
'z'
])
env.Append(
LIBS = [
'boost_date_time-mt',
'boost_filesystem-mt',
'boost_program_options-mt',
'boost_regex-mt',
'boost_system-mt',
'boost_thread-mt',
'protobuf',
'dl', # dynamic linking
'z'
]
)
DEBUGFLAGS = ['-g', '-DDEBUG']
BOOSTFLAGS = ['-DBOOST_TEST_DYN_LINK', '-DBOOST_FILESYSTEM_NO_DEPRECATED']
DEBUGFLAGS = ['-g', '-DDEBUG']
BOOSTFLAGS = ['-DBOOST_TEST_DYN_LINK', '-DBOOST_FILESYSTEM_NO_DEPRECATED']
env.Append(LINKFLAGS = ['-rdynamic', '-pthread'])
env.Append(CCFLAGS = ['-pthread', '-Wall', '-Wno-sign-compare', '-Wno-char-subscripts', '-DSQLITE_THREADSAFE'])
env.Append(CXXFLAGS = ['-O0', '-pthread', '-Wno-invalid-offsetof', '-Wformat']+BOOSTFLAGS+DEBUGFLAGS)
DB_SRCS = glob.glob('database/*.c') + glob.glob('database/*.cpp')
JSON_SRCS = glob.glob('json/*.cpp')
WEBSOCKETPP_SRCS = [
'websocketpp/src/base64/base64.cpp',
'websocketpp/src/md5/md5.c',
'websocketpp/src/messages/data.cpp',
'websocketpp/src/network_utilities.cpp',
'websocketpp/src/processors/hybi_header.cpp',
'websocketpp/src/processors/hybi_util.cpp',
'websocketpp/src/sha1/sha1.cpp',
'websocketpp/src/uri.cpp'
]
if OSX:
env.Append(LINKFLAGS = ['-L/usr/local/Cellar/openssl/1.0.1c/lib'])
env.Append(CXXFLAGS = ['-I/usr/local/Cellar/openssl/1.0.1c/include'])
NEWCOIN_SRCS = glob.glob('src/*.cpp')
PROTO_SRCS = env.Protoc([], 'src/newcoin.proto', PROTOCOUTDIR='obj', PROTOCPYTHONOUTDIR=None)
DB_SRCS = glob.glob('database/*.c') + glob.glob('database/*.cpp')
JSON_SRCS = glob.glob('json/*.cpp')
WEBSOCKETPP_SRCS = [
'websocketpp/src/base64/base64.cpp',
'websocketpp/src/md5/md5.c',
'websocketpp/src/messages/data.cpp',
'websocketpp/src/network_utilities.cpp',
'websocketpp/src/processors/hybi_header.cpp',
'websocketpp/src/processors/hybi_util.cpp',
'websocketpp/src/sha1/sha1.cpp',
'websocketpp/src/uri.cpp'
]
NEWCOIN_SRCS = glob.glob('src/*.cpp')
PROTO_SRCS = env.Protoc([], 'src/newcoin.proto', PROTOCOUTDIR='obj', PROTOCPYTHONOUTDIR=None)
env.Clean(PROTO_SRCS, 'site_scons/site_tools/protoc.pyc')
# Remove unused source files.
UNUSED_SRCS = ['src/HttpReply.cpp']
UNUSED_SRCS = ['src/HttpReply.cpp']
for file in UNUSED_SRCS:
NEWCOIN_SRCS.remove(file)
NEWCOIN_SRCS.remove(file)
NEWCOIN_SRCS += DB_SRCS + JSON_SRCS + WEBSOCKETPP_SRCS
NEWCOIN_SRCS += DB_SRCS + JSON_SRCS + WEBSOCKETPP_SRCS
# Derive the object files from the source files.
NEWCOIN_OBJS = []
NEWCOIN_OBJS = []
for file in NEWCOIN_SRCS:
NEWCOIN_OBJS.append('obj/' + file)
NEWCOIN_OBJS.append('obj/' + file)
NEWCOIN_OBJS += PROTO_SRCS
NEWCOIN_OBJS += PROTO_SRCS
newcoind = env.Program('newcoind', NEWCOIN_OBJS)
newcoind = env.Program('newcoind', NEWCOIN_OBJS)
tags = env.CTags('obj/tags', NEWCOIN_SRCS)
tags = env.CTags('obj/tags', NEWCOIN_SRCS)
Default(newcoind, tags)

210
js/amount.js Normal file
View File

@@ -0,0 +1,210 @@
// Represent Newcoin amounts and currencies.
var utils = require("./utils.js");
var UInt160 = function () {
// Internal form:
// 0, 1, 'iXXXXX', 20 byte string, or NaN.
// XXX Should standardize on 'i' format or 20 format.
};
// Returns NaN on error.
UInt160.prototype.parse_json = function (j) {
// Canonicalize and validate
switch (j) {
case undefined:
case "0":
case exports.consts.address_xns:
case exports.consts.uint160_xns:
case exports.consts.hex_xns:
this.value = 0;
break;
case "1":
case exports.consts.address_one:
case exports.consts.uint160_one:
case exports.consts.hex_one:
this.value = 1;
break;
default:
if ('string' !== typeof j) {
this.value = NaN;
}
else if (20 === j.length) {
this.value = j;
}
else if (40 === j.length) {
this.value = utils.hexToString(j);
}
else if (j[0] === "i") {
// XXX Do more checking convert to string.
this.value = j;
}
else {
this.value = NaN;
}
}
return this.value;
};
// Convert from internal form.
// XXX Json form should allow 0 and 1, C++ doesn't currently allow it.
UInt160.prototype.to_json = function () {
if ("0" === this.value) {
return exports.consts.hex_xns;
}
else if ("1" === this.value)
{
return exports.consts.hex_one;
}
else if (20 === this.value.length) {
return utils.stringToHex(this.value);
}
else
{
return this.value;
}
};
var Currency = function () {
// Internal form: 0 = XNS. 3 letter-code.
// XXX Internal should be 0 or hex.
// Json form:
// '', 'XNS', '0': 0
// 3-letter code: ...
// XXX Should support hex, C++ doesn't currently allow it.
}
// Returns NaN on error.
Currency.prototype.parse_json = function (j) {
if ("" === j || "0" === j || "XNS" === j) {
this.value = 0;
}
else if ('string' != typeof j || 3 !== j.length) {
this.value = NaN;
}
else {
this.value = j;
}
return this.value;
};
Currency.prototype.to_json = function () {
return this.value ? this.value : 'XNS';
};
Currency.prototype.to_human = function() {
return this.value ? this.value : 'XNS';
};
var Amount = function () {
// Json format:
// integer : XNS
// { 'value' : ..., 'currency' : ..., 'issuer' : ...}
this.value = 0;
this.offset = 0;
this.is_native = false;
this.is_negative = false;
this.currency = new Currency();
this.issuer = new UInt160();
};
// Convert only value to JSON text.
Amount.prototype.to_text = function() {
// XXX Needs to work for native and non-native.
return this.is_negative ? -this.value : this.value; // XXX Use biginteger.
};
Amount.prototype.to_json = function() {
if (this.is_native) {
return this.to_text();
}
else
{
return {
'value' : this.to_text(),
'currency' : this.currency.to_json(),
'issuer' : this.issuer.to_json(),
};
}
};
// Parse a native value.
Amount.prototype.parse_native = function(j) {
if ('integer' === typeof j) {
// XNS
this.value = j >= 0 ? j : -j; // XXX Use biginteger.
this.offset = 0;
this.is_native = true;
this.is_negative = j < 0;
}
else if ('string' === typeof j) {
this.value = j >= 0 ? j : -j; // XXX Use biginteger.
this.offset = 0;
this.is_native = true;
this.is_negative = j < 0;
}
else {
this.value = NaN;
}
};
// Parse a non-native value.
Amount.prototype.parse_value = function(j) {
if ('integer' === typeof j) {
this.value = j >= 0 ? j : -j; // XXX Use biginteger.
this.offset = 0;
this.is_native = false;
this.is_negative = j < 0;
}
else if ('string' === typeof j) {
this.value = j >= 0 ? j : -j; // XXX Use biginteger.
this.offset = 0;
this.is_native = false;
this.is_negative = j < 0;
}
else {
this.value = NaN;
}
};
// <-> j
Amount.prototype.parse_json = function(j) {
if ('object' === typeof j && j.currency) {
this.parse_value(j);
this.currency.parse_json(j.currency);
this.issuer.parse_json(j.issuer);
}
else {
this.parse_native(j);
this.currency = 0;
this.issuer = 0;
}
};
exports.Amount = Amount;
exports.Currency = Currency;
exports.UInt160 = UInt160;
exports.consts = {
'address_xns' : "iiiiiiiiiiiiiiiiiiiiihoLvTp",
'address_one' : "iiiiiiiiiiiiiiiiiiiiBZbvjr",
'currency_xns' : 0,
'currency_one' : 1,
'uint160_xns' : hexToString("0000000000000000000000000000000000000000"),
'uint160_one' : hexToString("0000000000000000000000000000000000000001"),
'hex_xns' : "0000000000000000000000000000000000000000",
'hex_one' : "0000000000000000000000000000000000000001",
};
// vim:sw=2:sts=2:ts=8

1
js/cryptojs Submodule

Submodule js/cryptojs added at c3c843c513

559
js/jsbn/jsbn.js Normal file
View File

@@ -0,0 +1,559 @@
// Copyright (c) 2005 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// Basic JavaScript BN library - subset useful for RSA encryption.
// Bits per digit
var dbits;
// JavaScript engine analysis
var canary = 0xdeadbeefcafe;
var j_lm = ((canary&0xffffff)==0xefcafe);
// (public) Constructor
function BigInteger(a,b,c) {
if(a != null)
if("number" == typeof a) this.fromNumber(a,b,c);
else if(b == null && "string" != typeof a) this.fromString(a,256);
else this.fromString(a,b);
}
// return new, unset BigInteger
function nbi() { return new BigInteger(null); }
// am: Compute w_j += (x*this_i), propagate carries,
// c is initial carry, returns final carry.
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
// We need to select the fastest one that works in this environment.
// am1: use a single mult and divide to get the high bits,
// max digit bits should be 26 because
// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
function am1(i,x,w,j,c,n) {
while(--n >= 0) {
var v = x*this[i++]+w[j]+c;
c = Math.floor(v/0x4000000);
w[j++] = v&0x3ffffff;
}
return c;
}
// am2 avoids a big mult-and-extract completely.
// Max digit bits should be <= 30 because we do bitwise ops
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
function am2(i,x,w,j,c,n) {
var xl = x&0x7fff, xh = x>>15;
while(--n >= 0) {
var l = this[i]&0x7fff;
var h = this[i++]>>15;
var m = xh*l+h*xl;
l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
w[j++] = l&0x3fffffff;
}
return c;
}
// Alternately, set max digit bits to 28 since some
// browsers slow down when dealing with 32-bit numbers.
function am3(i,x,w,j,c,n) {
var xl = x&0x3fff, xh = x>>14;
while(--n >= 0) {
var l = this[i]&0x3fff;
var h = this[i++]>>14;
var m = xh*l+h*xl;
l = xl*l+((m&0x3fff)<<14)+w[j]+c;
c = (l>>28)+(m>>14)+xh*h;
w[j++] = l&0xfffffff;
}
return c;
}
if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
BigInteger.prototype.am = am2;
dbits = 30;
}
else if(j_lm && (navigator.appName != "Netscape")) {
BigInteger.prototype.am = am1;
dbits = 26;
}
else { // Mozilla/Netscape seems to prefer am3
BigInteger.prototype.am = am3;
dbits = 28;
}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = ((1<<dbits)-1);
BigInteger.prototype.DV = (1<<dbits);
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2,BI_FP);
BigInteger.prototype.F1 = BI_FP-dbits;
BigInteger.prototype.F2 = 2*dbits-BI_FP;
// Digit conversions
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array();
var rr,vv;
rr = "0".charCodeAt(0);
for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
rr = "a".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
rr = "A".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
function int2char(n) { return BI_RM.charAt(n); }
function intAt(s,i) {
var c = BI_RC[s.charCodeAt(i)];
return (c==null)?-1:c;
}
// (protected) copy this to r
function bnpCopyTo(r) {
for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
r.t = this.t;
r.s = this.s;
}
// (protected) set from integer value x, -DV <= x < DV
function bnpFromInt(x) {
this.t = 1;
this.s = (x<0)?-1:0;
if(x > 0) this[0] = x;
else if(x < -1) this[0] = x+DV;
else this.t = 0;
}
// return bigint initialized to value
function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
// (protected) set from string and radix
function bnpFromString(s,b) {
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 256) k = 8; // byte array
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else { this.fromRadix(s,b); return; }
this.t = 0;
this.s = 0;
var i = s.length, mi = false, sh = 0;
while(--i >= 0) {
var x = (k==8)?s[i]&0xff:intAt(s,i);
if(x < 0) {
if(s.charAt(i) == "-") mi = true;
continue;
}
mi = false;
if(sh == 0)
this[this.t++] = x;
else if(sh+k > this.DB) {
this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
this[this.t++] = (x>>(this.DB-sh));
}
else
this[this.t-1] |= x<<sh;
sh += k;
if(sh >= this.DB) sh -= this.DB;
}
if(k == 8 && (s[0]&0x80) != 0) {
this.s = -1;
if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
}
this.clamp();
if(mi) BigInteger.ZERO.subTo(this,this);
}
// (protected) clamp off excess high words
function bnpClamp() {
var c = this.s&this.DM;
while(this.t > 0 && this[this.t-1] == c) --this.t;
}
// (public) return string representation in given radix
function bnToString(b) {
if(this.s < 0) return "-"+this.negate().toString(b);
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else return this.toRadix(b);
var km = (1<<k)-1, d, m = false, r = "", i = this.t;
var p = this.DB-(i*this.DB)%k;
if(i-- > 0) {
if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
while(i >= 0) {
if(p < k) {
d = (this[i]&((1<<p)-1))<<(k-p);
d |= this[--i]>>(p+=this.DB-k);
}
else {
d = (this[i]>>(p-=k))&km;
if(p <= 0) { p += this.DB; --i; }
}
if(d > 0) m = true;
if(m) r += int2char(d);
}
}
return m?r:"0";
}
// (public) -this
function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
// (public) |this|
function bnAbs() { return (this.s<0)?this.negate():this; }
// (public) return + if this > a, - if this < a, 0 if equal
function bnCompareTo(a) {
var r = this.s-a.s;
if(r != 0) return r;
var i = this.t;
r = i-a.t;
if(r != 0) return (this.s<0)?-r:r;
while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
return 0;
}
// returns bit length of the integer x
function nbits(x) {
var r = 1, t;
if((t=x>>>16) != 0) { x = t; r += 16; }
if((t=x>>8) != 0) { x = t; r += 8; }
if((t=x>>4) != 0) { x = t; r += 4; }
if((t=x>>2) != 0) { x = t; r += 2; }
if((t=x>>1) != 0) { x = t; r += 1; }
return r;
}
// (public) return the number of bits in "this"
function bnBitLength() {
if(this.t <= 0) return 0;
return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
}
// (protected) r = this << n*DB
function bnpDLShiftTo(n,r) {
var i;
for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
for(i = n-1; i >= 0; --i) r[i] = 0;
r.t = this.t+n;
r.s = this.s;
}
// (protected) r = this >> n*DB
function bnpDRShiftTo(n,r) {
for(var i = n; i < this.t; ++i) r[i-n] = this[i];
r.t = Math.max(this.t-n,0);
r.s = this.s;
}
// (protected) r = this << n
function bnpLShiftTo(n,r) {
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<cbs)-1;
var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
for(i = this.t-1; i >= 0; --i) {
r[i+ds+1] = (this[i]>>cbs)|c;
c = (this[i]&bm)<<bs;
}
for(i = ds-1; i >= 0; --i) r[i] = 0;
r[ds] = c;
r.t = this.t+ds+1;
r.s = this.s;
r.clamp();
}
// (protected) r = this >> n
function bnpRShiftTo(n,r) {
r.s = this.s;
var ds = Math.floor(n/this.DB);
if(ds >= this.t) { r.t = 0; return; }
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<bs)-1;
r[0] = this[ds]>>bs;
for(var i = ds+1; i < this.t; ++i) {
r[i-ds-1] |= (this[i]&bm)<<cbs;
r[i-ds] = this[i]>>bs;
}
if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
r.t = this.t-ds;
r.clamp();
}
// (protected) r = this - a
function bnpSubTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]-a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
if(a.t < this.t) {
c -= a.s;
while(i < this.t) {
c += this[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += this.s;
}
else {
c += this.s;
while(i < a.t) {
c -= a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c -= a.s;
}
r.s = (c<0)?-1:0;
if(c < -1) r[i++] = this.DV+c;
else if(c > 0) r[i++] = c;
r.t = i;
r.clamp();
}
// (protected) r = this * a, r != this,a (HAC 14.12)
// "this" should be the larger one if appropriate.
function bnpMultiplyTo(a,r) {
var x = this.abs(), y = a.abs();
var i = x.t;
r.t = i+y.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
r.s = 0;
r.clamp();
if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
}
// (protected) r = this^2, r != this (HAC 14.16)
function bnpSquareTo(r) {
var x = this.abs();
var i = r.t = 2*x.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < x.t-1; ++i) {
var c = x.am(i,x[i],r,2*i,0,1);
if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
r[i+x.t] -= x.DV;
r[i+x.t+1] = 1;
}
}
if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
r.s = 0;
r.clamp();
}
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
// r != q, this != m. q or r may be null.
function bnpDivRemTo(m,q,r) {
var pm = m.abs();
if(pm.t <= 0) return;
var pt = this.abs();
if(pt.t < pm.t) {
if(q != null) q.fromInt(0);
if(r != null) this.copyTo(r);
return;
}
if(r == null) r = nbi();
var y = nbi(), ts = this.s, ms = m.s;
var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
else { pm.copyTo(y); pt.copyTo(r); }
var ys = y.t;
var y0 = y[ys-1];
if(y0 == 0) return;
var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
var i = r.t, j = i-ys, t = (q==null)?nbi():q;
y.dlShiftTo(j,t);
if(r.compareTo(t) >= 0) {
r[r.t++] = 1;
r.subTo(t,r);
}
BigInteger.ONE.dlShiftTo(ys,t);
t.subTo(y,y); // "negative" y so we can replace sub with am later
while(y.t < ys) y[y.t++] = 0;
while(--j >= 0) {
// Estimate quotient digit
var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
y.dlShiftTo(j,t);
r.subTo(t,r);
while(r[i] < --qd) r.subTo(t,r);
}
}
if(q != null) {
r.drShiftTo(ys,q);
if(ts != ms) BigInteger.ZERO.subTo(q,q);
}
r.t = ys;
r.clamp();
if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
if(ts < 0) BigInteger.ZERO.subTo(r,r);
}
// (public) this mod a
function bnMod(a) {
var r = nbi();
this.abs().divRemTo(a,null,r);
if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
return r;
}
// Modular reduction using "classic" algorithm
function Classic(m) { this.m = m; }
function cConvert(x) {
if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
else return x;
}
function cRevert(x) { return x; }
function cReduce(x) { x.divRemTo(this.m,null,x); }
function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
// justification:
// xy == 1 (mod m)
// xy = 1+km
// xy(2-xy) = (1+km)(1-km)
// x[y(2-xy)] = 1-k^2m^2
// x[y(2-xy)] == 1 (mod m^2)
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
// JS multiply "overflows" differently from C/C++, so care is needed here.
function bnpInvDigit() {
if(this.t < 1) return 0;
var x = this[0];
if((x&1) == 0) return 0;
var y = x&3; // y == 1/x mod 2^2
y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
// last step - calculate inverse mod DV directly;
// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
// we really want the negative inverse, and -DV < y < DV
return (y>0)?this.DV-y:-y;
}
// Montgomery reduction
function Montgomery(m) {
this.m = m;
this.mp = m.invDigit();
this.mpl = this.mp&0x7fff;
this.mph = this.mp>>15;
this.um = (1<<(m.DB-15))-1;
this.mt2 = 2*m.t;
}
// xR mod m
function montConvert(x) {
var r = nbi();
x.abs().dlShiftTo(this.m.t,r);
r.divRemTo(this.m,null,r);
if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
return r;
}
// x/R mod m
function montRevert(x) {
var r = nbi();
x.copyTo(r);
this.reduce(r);
return r;
}
// x = x/R mod m (HAC 14.32)
function montReduce(x) {
while(x.t <= this.mt2) // pad x so am has enough room later
x[x.t++] = 0;
for(var i = 0; i < this.m.t; ++i) {
// faster way of calculating u0 = x[i]*mp mod DV
var j = x[i]&0x7fff;
var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
// use am to combine the multiply-shift-add into one call
j = i+this.m.t;
x[j] += this.m.am(0,u0,x,i,0,this.m.t);
// propagate carry
while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
}
x.clamp();
x.drShiftTo(this.m.t,x);
if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
}
// r = "x^2/R mod m"; x != r
function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
// r = "xy/R mod m"; x,y != r
function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
// (protected) true iff this is even
function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
function bnpExp(e,z) {
if(e > 0xffffffff || e < 1) return BigInteger.ONE;
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
g.copyTo(r);
while(--i >= 0) {
z.sqrTo(r,r2);
if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
else { var t = r; r = r2; r2 = t; }
}
return z.revert(r);
}
// (public) this^e % m, 0 <= e < 2^32
function bnModPowInt(e,m) {
var z;
if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
return this.exp(e,z);
}
// protected
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
// public
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
// "constants"
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);

656
js/jsbn/jsbn2.js Normal file
View File

@@ -0,0 +1,656 @@
// Copyright (c) 2005-2009 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// Extended JavaScript BN functions, required for RSA private ops.
// Version 1.1: new BigInteger("0", 10) returns "proper" zero
// Version 1.2: square() API, isProbablePrime fix
// (public)
function bnClone() { var r = nbi(); this.copyTo(r); return r; }
// (public) return value as integer
function bnIntValue() {
if(this.s < 0) {
if(this.t == 1) return this[0]-this.DV;
else if(this.t == 0) return -1;
}
else if(this.t == 1) return this[0];
else if(this.t == 0) return 0;
// assumes 16 < DB < 32
return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
}
// (public) return value as byte
function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
// (public) return value as short (assumes DB>=16)
function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
// (protected) return x s.t. r^x < DV
function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
// (public) 0 if this == 0, 1 if this > 0
function bnSigNum() {
if(this.s < 0) return -1;
else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
else return 1;
}
// (protected) convert to radix string
function bnpToRadix(b) {
if(b == null) b = 10;
if(this.signum() == 0 || b < 2 || b > 36) return "0";
var cs = this.chunkSize(b);
var a = Math.pow(b,cs);
var d = nbv(a), y = nbi(), z = nbi(), r = "";
this.divRemTo(d,y,z);
while(y.signum() > 0) {
r = (a+z.intValue()).toString(b).substr(1) + r;
y.divRemTo(d,y,z);
}
return z.intValue().toString(b) + r;
}
// (protected) convert from radix string
function bnpFromRadix(s,b) {
this.fromInt(0);
if(b == null) b = 10;
var cs = this.chunkSize(b);
var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
for(var i = 0; i < s.length; ++i) {
var x = intAt(s,i);
if(x < 0) {
if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
continue;
}
w = b*w+x;
if(++j >= cs) {
this.dMultiply(d);
this.dAddOffset(w,0);
j = 0;
w = 0;
}
}
if(j > 0) {
this.dMultiply(Math.pow(b,j));
this.dAddOffset(w,0);
}
if(mi) BigInteger.ZERO.subTo(this,this);
}
// (protected) alternate constructor
function bnpFromNumber(a,b,c) {
if("number" == typeof b) {
// new BigInteger(int,int,RNG)
if(a < 2) this.fromInt(1);
else {
this.fromNumber(a,c);
if(!this.testBit(a-1)) // force MSB set
this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
if(this.isEven()) this.dAddOffset(1,0); // force odd
while(!this.isProbablePrime(b)) {
this.dAddOffset(2,0);
if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
}
}
}
else {
// new BigInteger(int,RNG)
var x = new Array(), t = a&7;
x.length = (a>>3)+1;
b.nextBytes(x);
if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
this.fromString(x,256);
}
}
// (public) convert to bigendian byte array
function bnToByteArray() {
var i = this.t, r = new Array();
r[0] = this.s;
var p = this.DB-(i*this.DB)%8, d, k = 0;
if(i-- > 0) {
if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
r[k++] = d|(this.s<<(this.DB-p));
while(i >= 0) {
if(p < 8) {
d = (this[i]&((1<<p)-1))<<(8-p);
d |= this[--i]>>(p+=this.DB-8);
}
else {
d = (this[i]>>(p-=8))&0xff;
if(p <= 0) { p += this.DB; --i; }
}
if((d&0x80) != 0) d |= -256;
if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
if(k > 0 || d != this.s) r[k++] = d;
}
}
return r;
}
function bnEquals(a) { return(this.compareTo(a)==0); }
function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
// (protected) r = this op a (bitwise)
function bnpBitwiseTo(a,op,r) {
var i, f, m = Math.min(a.t,this.t);
for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
if(a.t < this.t) {
f = a.s&this.DM;
for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
r.t = this.t;
}
else {
f = this.s&this.DM;
for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
r.t = a.t;
}
r.s = op(this.s,a.s);
r.clamp();
}
// (public) this & a
function op_and(x,y) { return x&y; }
function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
// (public) this | a
function op_or(x,y) { return x|y; }
function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
// (public) this ^ a
function op_xor(x,y) { return x^y; }
function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
// (public) this & ~a
function op_andnot(x,y) { return x&~y; }
function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
// (public) ~this
function bnNot() {
var r = nbi();
for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
r.t = this.t;
r.s = ~this.s;
return r;
}
// (public) this << n
function bnShiftLeft(n) {
var r = nbi();
if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
return r;
}
// (public) this >> n
function bnShiftRight(n) {
var r = nbi();
if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
return r;
}
// return index of lowest 1-bit in x, x < 2^31
function lbit(x) {
if(x == 0) return -1;
var r = 0;
if((x&0xffff) == 0) { x >>= 16; r += 16; }
if((x&0xff) == 0) { x >>= 8; r += 8; }
if((x&0xf) == 0) { x >>= 4; r += 4; }
if((x&3) == 0) { x >>= 2; r += 2; }
if((x&1) == 0) ++r;
return r;
}
// (public) returns index of lowest 1-bit (or -1 if none)
function bnGetLowestSetBit() {
for(var i = 0; i < this.t; ++i)
if(this[i] != 0) return i*this.DB+lbit(this[i]);
if(this.s < 0) return this.t*this.DB;
return -1;
}
// return number of 1 bits in x
function cbit(x) {
var r = 0;
while(x != 0) { x &= x-1; ++r; }
return r;
}
// (public) return number of set bits
function bnBitCount() {
var r = 0, x = this.s&this.DM;
for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
return r;
}
// (public) true iff nth bit is set
function bnTestBit(n) {
var j = Math.floor(n/this.DB);
if(j >= this.t) return(this.s!=0);
return((this[j]&(1<<(n%this.DB)))!=0);
}
// (protected) this op (1<<n)
function bnpChangeBit(n,op) {
var r = BigInteger.ONE.shiftLeft(n);
this.bitwiseTo(r,op,r);
return r;
}
// (public) this | (1<<n)
function bnSetBit(n) { return this.changeBit(n,op_or); }
// (public) this & ~(1<<n)
function bnClearBit(n) { return this.changeBit(n,op_andnot); }
// (public) this ^ (1<<n)
function bnFlipBit(n) { return this.changeBit(n,op_xor); }
// (protected) r = this + a
function bnpAddTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]+a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
if(a.t < this.t) {
c += a.s;
while(i < this.t) {
c += this[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += this.s;
}
else {
c += this.s;
while(i < a.t) {
c += a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += a.s;
}
r.s = (c<0)?-1:0;
if(c > 0) r[i++] = c;
else if(c < -1) r[i++] = this.DV+c;
r.t = i;
r.clamp();
}
// (public) this + a
function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
// (public) this - a
function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
// (public) this * a
function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
// (public) this^2
function bnSquare() { var r = nbi(); this.squareTo(r); return r; }
// (public) this / a
function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
// (public) this % a
function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
// (public) [this/a,this%a]
function bnDivideAndRemainder(a) {
var q = nbi(), r = nbi();
this.divRemTo(a,q,r);
return new Array(q,r);
}
// (protected) this *= n, this >= 0, 1 < n < DV
function bnpDMultiply(n) {
this[this.t] = this.am(0,n-1,this,0,0,this.t);
++this.t;
this.clamp();
}
// (protected) this += n << w words, this >= 0
function bnpDAddOffset(n,w) {
if(n == 0) return;
while(this.t <= w) this[this.t++] = 0;
this[w] += n;
while(this[w] >= this.DV) {
this[w] -= this.DV;
if(++w >= this.t) this[this.t++] = 0;
++this[w];
}
}
// A "null" reducer
function NullExp() {}
function nNop(x) { return x; }
function nMulTo(x,y,r) { x.multiplyTo(y,r); }
function nSqrTo(x,r) { x.squareTo(r); }
NullExp.prototype.convert = nNop;
NullExp.prototype.revert = nNop;
NullExp.prototype.mulTo = nMulTo;
NullExp.prototype.sqrTo = nSqrTo;
// (public) this^e
function bnPow(e) { return this.exp(e,new NullExp()); }
// (protected) r = lower n words of "this * a", a.t <= n
// "this" should be the larger one if appropriate.
function bnpMultiplyLowerTo(a,n,r) {
var i = Math.min(this.t+a.t,n);
r.s = 0; // assumes a,this >= 0
r.t = i;
while(i > 0) r[--i] = 0;
var j;
for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
r.clamp();
}
// (protected) r = "this * a" without lower n words, n > 0
// "this" should be the larger one if appropriate.
function bnpMultiplyUpperTo(a,n,r) {
--n;
var i = r.t = this.t+a.t-n;
r.s = 0; // assumes a,this >= 0
while(--i >= 0) r[i] = 0;
for(i = Math.max(n-this.t,0); i < a.t; ++i)
r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
r.clamp();
r.drShiftTo(1,r);
}
// Barrett modular reduction
function Barrett(m) {
// setup Barrett
this.r2 = nbi();
this.q3 = nbi();
BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
this.mu = this.r2.divide(m);
this.m = m;
}
function barrettConvert(x) {
if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
else if(x.compareTo(this.m) < 0) return x;
else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
}
function barrettRevert(x) { return x; }
// x = x mod m (HAC 14.42)
function barrettReduce(x) {
x.drShiftTo(this.m.t-1,this.r2);
if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
x.subTo(this.r2,x);
while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
}
// r = x^2 mod m; x != r
function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
// r = x*y mod m; x,y != r
function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Barrett.prototype.convert = barrettConvert;
Barrett.prototype.revert = barrettRevert;
Barrett.prototype.reduce = barrettReduce;
Barrett.prototype.mulTo = barrettMulTo;
Barrett.prototype.sqrTo = barrettSqrTo;
// (public) this^e % m (HAC 14.85)
function bnModPow(e,m) {
var i = e.bitLength(), k, r = nbv(1), z;
if(i <= 0) return r;
else if(i < 18) k = 1;
else if(i < 48) k = 3;
else if(i < 144) k = 4;
else if(i < 768) k = 5;
else k = 6;
if(i < 8)
z = new Classic(m);
else if(m.isEven())
z = new Barrett(m);
else
z = new Montgomery(m);
// precomputation
var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
g[1] = z.convert(this);
if(k > 1) {
var g2 = nbi();
z.sqrTo(g[1],g2);
while(n <= km) {
g[n] = nbi();
z.mulTo(g2,g[n-2],g[n]);
n += 2;
}
}
var j = e.t-1, w, is1 = true, r2 = nbi(), t;
i = nbits(e[j])-1;
while(j >= 0) {
if(i >= k1) w = (e[j]>>(i-k1))&km;
else {
w = (e[j]&((1<<(i+1))-1))<<(k1-i);
if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
}
n = k;
while((w&1) == 0) { w >>= 1; --n; }
if((i -= n) < 0) { i += this.DB; --j; }
if(is1) { // ret == 1, don't bother squaring or multiplying it
g[w].copyTo(r);
is1 = false;
}
else {
while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
z.mulTo(r2,g[w],r);
}
while(j >= 0 && (e[j]&(1<<i)) == 0) {
z.sqrTo(r,r2); t = r; r = r2; r2 = t;
if(--i < 0) { i = this.DB-1; --j; }
}
}
return z.revert(r);
}
// (public) gcd(this,a) (HAC 14.54)
function bnGCD(a) {
var x = (this.s<0)?this.negate():this.clone();
var y = (a.s<0)?a.negate():a.clone();
if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
var i = x.getLowestSetBit(), g = y.getLowestSetBit();
if(g < 0) return x;
if(i < g) g = i;
if(g > 0) {
x.rShiftTo(g,x);
y.rShiftTo(g,y);
}
while(x.signum() > 0) {
if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
if(x.compareTo(y) >= 0) {
x.subTo(y,x);
x.rShiftTo(1,x);
}
else {
y.subTo(x,y);
y.rShiftTo(1,y);
}
}
if(g > 0) y.lShiftTo(g,y);
return y;
}
// (protected) this % n, n < 2^26
function bnpModInt(n) {
if(n <= 0) return 0;
var d = this.DV%n, r = (this.s<0)?n-1:0;
if(this.t > 0)
if(d == 0) r = this[0]%n;
else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
return r;
}
// (public) 1/this % m (HAC 14.61)
function bnModInverse(m) {
var ac = m.isEven();
if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
var u = m.clone(), v = this.clone();
var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
while(u.signum() != 0) {
while(u.isEven()) {
u.rShiftTo(1,u);
if(ac) {
if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
a.rShiftTo(1,a);
}
else if(!b.isEven()) b.subTo(m,b);
b.rShiftTo(1,b);
}
while(v.isEven()) {
v.rShiftTo(1,v);
if(ac) {
if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
c.rShiftTo(1,c);
}
else if(!d.isEven()) d.subTo(m,d);
d.rShiftTo(1,d);
}
if(u.compareTo(v) >= 0) {
u.subTo(v,u);
if(ac) a.subTo(c,a);
b.subTo(d,b);
}
else {
v.subTo(u,v);
if(ac) c.subTo(a,c);
d.subTo(b,d);
}
}
if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
if(d.compareTo(m) >= 0) return d.subtract(m);
if(d.signum() < 0) d.addTo(m,d); else return d;
if(d.signum() < 0) return d.add(m); else return d;
}
var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];
var lplim = (1<<26)/lowprimes[lowprimes.length-1];
// (public) test primality with certainty >= 1-.5^t
function bnIsProbablePrime(t) {
var i, x = this.abs();
if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
for(i = 0; i < lowprimes.length; ++i)
if(x[0] == lowprimes[i]) return true;
return false;
}
if(x.isEven()) return false;
i = 1;
while(i < lowprimes.length) {
var m = lowprimes[i], j = i+1;
while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
m = x.modInt(m);
while(i < j) if(m%lowprimes[i++] == 0) return false;
}
return x.millerRabin(t);
}
// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
function bnpMillerRabin(t) {
var n1 = this.subtract(BigInteger.ONE);
var k = n1.getLowestSetBit();
if(k <= 0) return false;
var r = n1.shiftRight(k);
t = (t+1)>>1;
if(t > lowprimes.length) t = lowprimes.length;
var a = nbi();
for(var i = 0; i < t; ++i) {
//Pick bases at random, instead of starting at 2
a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);
var y = a.modPow(r,this);
if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
var j = 1;
while(j++ < k && y.compareTo(n1) != 0) {
y = y.modPowInt(2,this);
if(y.compareTo(BigInteger.ONE) == 0) return false;
}
if(y.compareTo(n1) != 0) return false;
}
}
return true;
}
// protected
BigInteger.prototype.chunkSize = bnpChunkSize;
BigInteger.prototype.toRadix = bnpToRadix;
BigInteger.prototype.fromRadix = bnpFromRadix;
BigInteger.prototype.fromNumber = bnpFromNumber;
BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
BigInteger.prototype.changeBit = bnpChangeBit;
BigInteger.prototype.addTo = bnpAddTo;
BigInteger.prototype.dMultiply = bnpDMultiply;
BigInteger.prototype.dAddOffset = bnpDAddOffset;
BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
BigInteger.prototype.modInt = bnpModInt;
BigInteger.prototype.millerRabin = bnpMillerRabin;
// public
BigInteger.prototype.clone = bnClone;
BigInteger.prototype.intValue = bnIntValue;
BigInteger.prototype.byteValue = bnByteValue;
BigInteger.prototype.shortValue = bnShortValue;
BigInteger.prototype.signum = bnSigNum;
BigInteger.prototype.toByteArray = bnToByteArray;
BigInteger.prototype.equals = bnEquals;
BigInteger.prototype.min = bnMin;
BigInteger.prototype.max = bnMax;
BigInteger.prototype.and = bnAnd;
BigInteger.prototype.or = bnOr;
BigInteger.prototype.xor = bnXor;
BigInteger.prototype.andNot = bnAndNot;
BigInteger.prototype.not = bnNot;
BigInteger.prototype.shiftLeft = bnShiftLeft;
BigInteger.prototype.shiftRight = bnShiftRight;
BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
BigInteger.prototype.bitCount = bnBitCount;
BigInteger.prototype.testBit = bnTestBit;
BigInteger.prototype.setBit = bnSetBit;
BigInteger.prototype.clearBit = bnClearBit;
BigInteger.prototype.flipBit = bnFlipBit;
BigInteger.prototype.add = bnAdd;
BigInteger.prototype.subtract = bnSubtract;
BigInteger.prototype.multiply = bnMultiply;
BigInteger.prototype.divide = bnDivide;
BigInteger.prototype.remainder = bnRemainder;
BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
BigInteger.prototype.modPow = bnModPow;
BigInteger.prototype.modInverse = bnModInverse;
BigInteger.prototype.pow = bnPow;
BigInteger.prototype.gcd = bnGCD;
BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
// JSBN-specific extension
BigInteger.prototype.square = bnSquare;
// BigInteger interfaces not implemented in jsbn:
// BigInteger(int signum, byte[] magnitude)
// double doubleValue()
// float floatValue()
// int hashCode()
// long longValue()
// static BigInteger valueOf(long val)

View File

@@ -12,18 +12,25 @@ 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;
this.stand_alone = undefined;
// Cache information for accounts.
this.account = {};
this.accounts = {
// Consider sequence numbers stable if you know you're not generating bad transactions.
// Otherwise, clear it to have it automatically refreshed from the network.
// account : { seq : __ }
};
// Cache for various ledgers.
// XXX Clear when ledger advances.
@@ -34,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.
@@ -45,15 +63,7 @@ var fees = {
'offer' : 100,
};
// For accounts we cache things like sequence numbers.
var accounts = {
// Consider sequence numbers stable if you know you're not generating bad transactions.
// Otherwise, clear it to have it automatically refreshed from the network.
// acount : { seq : __ }
};
Remote.method('connect_helper', function () {
Remote.prototype.connect_helper = function () {
var self = this;
if (this.trace) console.log("remote: connect: %s", this.url);
@@ -78,11 +88,13 @@ Remote.method('connect_helper', function () {
if (self.expire) {
if (this.trace) console.log("remote: was expired");
self.done(ws.readyState);
} else {
// Delay and retry.
setTimeout(function () {
if (this.trace) console.log("remote: retry");
self.connect_helper();
}, 50); // Retry rate 50ms.
}
@@ -91,6 +103,7 @@ Remote.method('connect_helper', function () {
// Covers failure to open.
ws.onclose = function () {
if (this.trace) console.log("remote: onclose: %s", ws.readyState);
ws.onerror = undefined;
self.done(ws.readyState);
};
@@ -102,6 +115,7 @@ Remote.method('connect_helper', function () {
if (message.type !== 'response') {
console.log("unexpected message: %s", json);
} else {
var done = ws.response[message.id];
if (done) {
@@ -111,12 +125,12 @@ Remote.method('connect_helper', function () {
}
}
});
});
};
// Target state is connectted.
// done(readyState):
// --> readyState: OPEN, CLOSED
Remote.method('connect', function (done, timeout) {
Remote.prototype.connect = function (done, timeout) {
var self = this;
this.url = util.format("ws://%s:%s", this.websocket_ip, this.websocket_port);
@@ -128,7 +142,7 @@ Remote.method('connect', function (done, timeout) {
this.expire = false;
setTimeout(function () {
if (this.trace) console.log("remote: expire: timeout");
if (self.trace) console.log("remote: expire: timeout");
self.expire = true;
}, timeout);
} else {
@@ -137,31 +151,32 @@ Remote.method('connect', function (done, timeout) {
}
this.connect_helper();
});
};
// Target stated is disconnected.
Remote.method('disconnect', function (done) {
var ws = this.ws;
Remote.prototype.disconnect = function (done) {
var self = this;
var ws = this.ws;
ws.onclose = function () {
if (this.trace) console.log("remote: onclose: %s", ws.readyState);
if (self.trace) console.log("remote: onclose: %s", ws.readyState);
done(ws.readyState);
};
ws.close();
});
};
// Send a request. The request should lack the id.
// <-> request: what to send, consumed.
Remote.prototype.request = function (request, onDone, onFailure) {
var self = this;
// Send a command. The comman should lack the id.
// <-> command: what to send, consumed.
Remote.method('request', function (request, onDone, onFailure) {
this.id += 1; // Advance id.
var ws = this.ws;
request.id = this.id;
ws.response[request.id] = function (response) {
if (this.trace) console.log("remote: response: %s", JSON.stringify(response));
this.ws.response[request.id] = function (response) {
if (self.trace) console.log("remote: response: %s", JSON.stringify(response));
if (onFailure && response.error)
{
@@ -175,25 +190,27 @@ Remote.method('request', function (request, onDone, onFailure) {
if (this.trace) console.log("remote: request: %s", JSON.stringify(request));
ws.send(JSON.stringify(request));
});
this.ws.send(JSON.stringify(request));
};
Remote.method('request_ledger_closed', function (onDone, onFailure) {
Remote.prototype.request_ledger_closed = function (onDone, onFailure) {
assert(this.trusted); // If not trusted, need to check proof.
this.request({ 'command' : 'ledger_closed' }, onDone, onFailure);
});
};
// Get the current proposed ledger entry. May be closed (and revised) at any time (even before returning).
// Only for use by unit tests.
Remote.method('request_ledger_current', function (onDone, onFailure) {
Remote.prototype.request_ledger_current = function (onDone, onFailure) {
this.request({ 'command' : 'ledger_current' }, onDone, onFailure);
});
};
// <-> request:
// --> ledger : optional
// --> ledger_index : optional
// --> type
Remote.method('request_ledger_entry', function (req, onDone, onFailure) {
Remote.prototype.request_ledger_entry = function (req, onDone, onFailure) {
var self = this;
assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.
req.command = 'ledger_entry';
@@ -203,7 +220,8 @@ Remote.method('request_ledger_entry', function (req, onDone, onFailure) {
// XXX Initial implementation no caching.
this.request(req, onDone, onFailure);
}
else if (req.ledger_index)
// else if (req.ledger_index)
else
{
// Current
// XXX Only allow with standalone mode. Must sync response with advance.
@@ -218,7 +236,7 @@ Remote.method('request_ledger_entry', function (req, onDone, onFailure) {
cache = this.ledgers.current.account_root = {};
}
var entry = this.ledgers.current.account_root[req.account];
entry = this.ledgers.current.account_root[req.account];
break;
default:
@@ -235,32 +253,32 @@ Remote.method('request_ledger_entry', function (req, onDone, onFailure) {
// Submit request
this.request(req, function (r) {
// Got result.
switch (req.type) {
case 'account_root':
this.ledgers.current.account_root.account = r;
break;
default:
// This type not cached.
}
onDone(r);
}, onFailure);
// Got result.
switch (req.type) {
case 'account_root':
self.ledgers.current.account_root[r.node.Account] = r.node;
break;
default:
// This type not cached.
// nothing();
break;
}
onDone(r.node);
}, onFailure);
}
}
});
};
// Submit a json transaction.
// done(value)
// <-> value: { 'status', status, 'result' : result, ... }
// done may be called up to 3 times.
Remote.method('submit', function (json, private_key, onDone, onFailure) {
var req = {};
// XXX <-> value: { 'status', status, 'result' : result, ... }
Remote.prototype.submit = function (req, onDone, onFailure) {
if (this.trace) console.log("remote: submit: %s", JSON.stringify(req));
req.command = 'submit';
req.json = json;
if (private_key && !this.trusted)
if (req.secret && !this.trusted)
{
onFailure({ 'error' : 'untrustedSever', 'request' : req });
}
@@ -268,7 +286,7 @@ Remote.method('submit', function (json, private_key, onDone, onFailure) {
{
this.request(req, onDone, onFailure);
}
});
};
//
// Higher level functions.
@@ -276,54 +294,123 @@ Remote.method('submit', function (json, private_key, onDone, onFailure) {
// Subscribe to a server to get the current and closed ledger.
// XXX Set up routine to update on notification.
Remote.method('server_subscribe', function (onDone, onFailure) {
Remote.prototype.server_subscribe = function (onDone, onFailure) {
var self = this;
this.request(
{ 'command' : 'server_subscribe' },
function (r) {
this.ledger_current_index = r.ledger_current_index;
this.ledger_closed = r.ledger_closed;
this.stand_alone = r.stand_alone;
onDone();
function (r) {
self.ledger_current_index = r.ledger_current_index;
self.ledger_closed = r.ledger_closed;
self.stand_alone = r.stand_alone;
onDone();
},
onFailure
);
});
};
// Refresh accounts[account].seq
// done(result);
Remote.method('account_seq', function (account, onDone, onFailure) {
Remote.prototype.account_seq = function (account, advance, onDone, onFailure) {
var self = this;
var account_root_entry = this.accounts[account];
if (account_root_entry && account_root_entry.seq)
{
onDone(account_root_entry.seq);
var seq = account_root_entry.seq;
if (advance) account_root_entry.seq += 1;
onDone(seq);
}
else
{
// Need to get the ledger entry.
this.request_ledger_entry(
{
'ledger' : this.ledger_closed,
'account_root' : account
'ledger' : this.ledger_closed,
'type' : 'account_root',
'account_root' : account
},
function (r) {
function (node) {
// Extract the seqence number from the account root entry.
this.accounts[account].seq = r.seq;
onDone(r.seq);
var seq = node.Sequence;
if (!account_root_entry) self.accounts[account] = {};
self.accounts[account].seq = seq + !!advance;
onDone(seq);
},
onFailure
);
}
});
};
// A submit that fills in the sequence number.
Remote.method('submit_seq', function (onDone, onFailure) {
Remote.prototype.submit_seq = function (trans, onDirty, onDone, onFailure) {
var self = this;
});
// Get the next sequence number for the account.
this.account_seq(trans.transaction.Account, true,
function (seq) {
trans.transaction.Sequence = seq;
self.submit(trans, onDone, onFailure);
},
onFailure);
};
// Mark an account's root node as dirty.
Remote.prototype.dirty_account_root = function (account) {
delete this.ledgers.current.account_root.account;
};
//
// Transactions
//
Remote.prototype.ripple_line_set = function (secret, src, dst, amount, 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' : 'CreditSet',
'Account' : src_account,
'Destination' : dst_account,
'Fee' : create ? fees.account_create : fees['default'],
'Amount' : amount,
},
'secret' : secret,
}, function () {
}, onDone);
};
Remote.prototype.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.accounts = accounts;
exports.flags = flags;
// vim:sw=2:sts=2:ts=8

1
js/sjcl Submodule

Submodule js/sjcl added at d04d0bdccd

View File

@@ -4,127 +4,151 @@ var fs = require("fs");
var path = require("path");
Function.prototype.method = function(name,func) {
this.prototype[name] = func;
this.prototype[name] = func;
return this;
return this;
};
var filterErr = function(code, done) {
return function(e) {
done(e.code !== code ? e : undefined);
};
return function(e) {
done(e.code !== code ? e : undefined);
};
};
var throwErr = function(done) {
return function(e) {
if (e)
throw e;
done();
};
return function(e) {
if (e)
throw e;
done();
};
};
// apply function to elements of array. Return first true value to done or undefined.
var mapOr = function(func, array, done) {
if (array.length) {
func(array[array.length-1], function(v) {
if (v) {
done(v);
}
else {
array.length -= 1;
mapOr(func, array, done);
}
});
}
else {
done();
}
if (array.length) {
func(array[array.length-1], function(v) {
if (v) {
done(v);
}
else {
array.length -= 1;
mapOr(func, array, done);
}
});
}
else {
done();
}
};
// Make a directory and sub-directories.
var mkPath = function(dirPath, mode, done) {
fs.mkdir(dirPath, typeof mode === "string" ? parseInt(mode, 8) : mode, function(e) {
if (!e || e.code === "EEXIST") {
// Created or already exists, done.
done();
}
else if (e.code === "ENOENT") {
// Missing sub dir.
fs.mkdir(dirPath, typeof mode === "string" ? parseInt(mode, 8) : mode, function(e) {
if (!e || e.code === "EEXIST") {
// Created or already exists, done.
done();
}
else if (e.code === "ENOENT") {
// Missing sub dir.
mkPath(path.dirname(dirPath), mode, function(e) {
if (e) {
throw e;
}
else {
mkPath(dirPath, mode, done);
}
});
mkPath(path.dirname(dirPath), mode, function(e) {
if (e) {
throw e;
}
else {
throw e;
mkPath(dirPath, mode, done);
}
});
});
}
else {
throw e;
}
});
};
// Empty a directory.
var emptyPath = function(dirPath, done) {
fs.readdir(dirPath, function(err, files) {
if (err) {
done(err);
}
else {
mapOr(rmPath, files.map(function(f) { return path.join(dirPath, f); }), done);
}
});
fs.readdir(dirPath, function(err, files) {
if (err) {
done(err);
}
else {
mapOr(rmPath, files.map(function(f) { return path.join(dirPath, f); }), done);
}
});
};
// Remove path recursively.
var rmPath = function(dirPath, done) {
// console.log("rmPath: %s", dirPath);
fs.lstat(dirPath, function(err, stats) {
if (err && err.code == "ENOENT") {
done();
}
if (err) {
done(err);
}
else if (stats.isDirectory()) {
emptyPath(dirPath, function(e) {
if (e) {
done(e);
}
else {
// console.log("rmdir: %s", dirPath); done();
fs.rmdir(dirPath, done);
}
});
}
else {
// console.log("unlink: %s", dirPath); done();
fs.unlink(dirPath, done);
}
});
fs.lstat(dirPath, function(err, stats) {
if (err && err.code == "ENOENT") {
done();
}
if (err) {
done(err);
}
else if (stats.isDirectory()) {
emptyPath(dirPath, function(e) {
if (e) {
done(e);
}
else {
// console.log("rmdir: %s", dirPath); done();
fs.rmdir(dirPath, done);
}
});
}
else {
// console.log("unlink: %s", dirPath); done();
fs.unlink(dirPath, done);
}
});
};
// Create directory if needed and empty if needed.
var resetPath = function(dirPath, mode, done) {
mkPath(dirPath, mode, function(e) {
if (e) {
done(e);
}
else {
emptyPath(dirPath, done);
}
});
mkPath(dirPath, mode, function(e) {
if (e) {
done(e);
}
else {
emptyPath(dirPath, done);
}
});
};
var trace = function(comment, func) {
return function() {
console.log("%s: %s", trace, arguments.toString);
func(arguments);
};
return function() {
console.log("%s: %s", trace, arguments.toString);
func(arguments);
};
};
var hexToString = function (h) {
var a = [];
var i = 0;
if (h.length % 2) {
a.push(String.fromCharCode(parseInt(h.substring(0, 1), 16)));
i = 1;
}
for (; i != h.length; i += 2) {
a.push(String.fromCharCode(parseInt(h.substring(i, i+2), 16)));
}
return a.join("");
};
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("");
};
exports.emptyPath = emptyPath;
@@ -133,5 +157,7 @@ exports.mkPath = mkPath;
exports.resetPath = resetPath;
exports.rmPath = rmPath;
exports.trace = trace;
exports.hexToString = hexToString;
exports.stringToHex = stringToHex;
// vim:ts=4
// vim:sw=2:sts=2:ts=8

View File

@@ -18,6 +18,7 @@ SField sfLedgerEntry(STI_LEDGERENTRY, 1, "LedgerEntry");
SField sfTransaction(STI_TRANSACTION, 1, "Transaction");
SField sfValidation(STI_VALIDATION, 1, "Validation");
SField sfID(STI_HASH256, 257, "id");
SField sfIndex(STI_HASH256, 258, "index");
#define FIELD(name, type, index) SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
#define TYPE(name, type, index)
@@ -26,6 +27,12 @@ SField sfID(STI_HASH256, 257, "id");
#undef TYPE
SField::SField(SerializedTypeID tid, int fv) : fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv)
{ // call with the map mutex
fieldName = lexical_cast_i(tid) + "/" + lexical_cast_i(fv);
codeToField[fieldCode] = this;
}
SField::ref SField::getField(int code)
{
int type = code >> 16;
@@ -33,16 +40,18 @@ SField::ref SField::getField(int code)
if ((type <= 0) || (field <= 0))
return sfInvalid;
{ //JED: Did this to fix a deadlock. david you should check. Line after this block also has a scoped lock
// why doe sthis thing even need a mutex?
boost::mutex::scoped_lock sl(mapMutex);
std::map<int, SField::ptr>::iterator it = codeToField.find(code);
if (it != codeToField.end())
return *(it->second);
boost::mutex::scoped_lock sl(mapMutex);
switch (type)
{ // types we are willing to dynamically extend
std::map<int, SField::ptr>::iterator it = codeToField.find(code);
if (it != codeToField.end())
return *(it->second);
if (field > 255) // don't dynamically extend types that have no binary encoding
return sfInvalid;
switch (type)
{ // types we are willing to dynamically extend
#define FIELD(name, type, index)
#define TYPE(name, type, index) case STI_##type:
@@ -51,14 +60,11 @@ SField::ref SField::getField(int code)
#undef TYPE
break;
default:
return sfInvalid;
}
default:
return sfInvalid;
}
}// end scope lock
std::string dynName = lexical_cast_i(type) + "/" + lexical_cast_i(field);
return *(new SField(code, static_cast<SerializedTypeID>(type), field, dynName.c_str()));
return *(new SField(static_cast<SerializedTypeID>(type), field));
}
int SField::compare(SField::ref f1, SField::ref f2)

View File

@@ -43,6 +43,8 @@ protected:
static std::map<int, ptr> codeToField;
static boost::mutex mapMutex;
SField(SerializedTypeID id, int val);
public:
const int fieldCode; // (type<<16)|index
@@ -80,6 +82,7 @@ public:
bool isInvalid() const { return fieldCode == -1; }
bool isKnown() const { return fieldType != STI_UNKNOWN; }
bool isBinary() const { return fieldValue < 256; }
bool isDiscardable() const { return fieldValue > 256; }
bool operator==(const SField& f) const { return fieldCode == f.fieldCode; }
bool operator!=(const SField& f) const { return fieldCode != f.fieldCode; }

View File

@@ -8,6 +8,8 @@
#include "Application.h"
#include "Log.h"
SETUP_LOG();
HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) :
mCache(cacheSize, cacheAge), mWritePending(false)
{
@@ -22,9 +24,7 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
if (!theApp->getHashNodeDB()) return true;
if (mCache.touch(hash))
{
#ifdef HS_DEBUG
Log(lsTRACE) << "HOS: " << hash << " store: incache";
#endif
cLog(lsTRACE) << "HOS: " << hash << " store: incache";
return false;
}
@@ -53,7 +53,7 @@ void HashedObjectStore::bulkWrite()
mWriteSet.swap(set);
mWritePending = false;
}
Log(lsINFO) << "HOS: BulkWrite " << set.size();
cLog(lsINFO) << "HOS: BulkWrite " << set.size();
static boost::format fExists("SELECT ObjType FROM CommittedObjects WHERE Hash = '%s';");
static boost::format
@@ -94,7 +94,7 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
obj = mCache.fetch(hash);
if (obj)
{
Log(lsTRACE) << "HOS: " << hash << " fetch: incache";
cLog(lsTRACE) << "HOS: " << hash << " fetch: incache";
return obj;
}
}
@@ -111,7 +111,7 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
if (!db->executeSQL(sql) || !db->startIterRows())
{
Log(lsTRACE) << "HOS: " << hash << " fetch: not in db";
cLog(lsTRACE) << "HOS: " << hash << " fetch: not in db";
return HashedObject::pointer();
}
@@ -136,14 +136,14 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
case 'A': htype = hotACCOUNT_NODE; break;
case 'N': htype = hotTRANSACTION_NODE; break;
default:
Log(lsERROR) << "Invalid hashed object";
cLog(lsERROR) << "Invalid hashed object";
return HashedObject::pointer();
}
obj = boost::make_shared<HashedObject>(htype, index, data, hash);
mCache.canonicalize(hash, obj);
}
Log(lsTRACE) << "HOS: " << hash << " fetch: in db";
cLog(lsTRACE) << "HOS: " << hash << " fetch: in db";
return obj;
}

View File

@@ -19,6 +19,7 @@
#include "HashPrefixes.h"
#include "Log.h"
SETUP_LOG();
Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount), mLedgerSeq(1),
mCloseTime(0), mParentCloseTime(0), mCloseResolution(LEDGER_TIME_ACCURACY), mCloseFlags(0),
@@ -427,11 +428,13 @@ Ledger::pointer Ledger::getSQL(const std::string& sql,bool isMutable)
closeFlags, closeResolution, ledgerSeq,isMutable));
if (ret->getHash() != ledgerHash)
{
Json::StyledStreamWriter ssw;
Log(lsERROR) << "Failed on ledger";
Json::Value p;
ret->addJson(p, LEDGER_JSON_FULL);
ssw.write(Log(lsERROR).ref(), p);
if (sLog(lsERROR))
{
Log(lsERROR) << "Failed on ledger";
Json::Value p;
ret->addJson(p, LEDGER_JSON_FULL);
Log(lsERROR) << p;
}
assert(false);
return Ledger::pointer();
}

View File

@@ -142,9 +142,8 @@ public:
boost::posix_time::ptime getCloseTime() const;
// low level functions
SHAMap::pointer peekTransactionMap() { return mTransactionMap; }
SHAMap::pointer peekAccountStateMap() { return mAccountStateMap; }
Ledger::pointer snapShot(bool isMutable);
SHAMap::ref peekTransactionMap() { return mTransactionMap; }
SHAMap::ref peekAccountStateMap() { return mAccountStateMap; }
// ledger sync functions
void setAcquiring(void);

View File

@@ -146,7 +146,7 @@ void LedgerAcquire::trigger(Peer::ref peer, bool timer)
if (mAborted || mComplete || mFailed)
return;
#ifdef LA_DEBUG
if(peer) Log(lsTRACE) << "Trigger acquiring ledger " << mHash << " from " << peer->getIP();
if (peer) Log(lsTRACE) << "Trigger acquiring ledger " << mHash << " from " << peer->getIP();
else Log(lsTRACE) << "Trigger acquiring ledger " << mHash;
if (mComplete || mFailed)
Log(lsTRACE) << "complete=" << mComplete << " failed=" << mFailed;

View File

@@ -23,6 +23,8 @@
typedef std::pair<const uint160, LedgerProposal::pointer> u160_prop_pair;
typedef std::pair<const uint256, LCTransaction::pointer> u256_lct_pair;
SETUP_LOG();
TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, TX_ACQUIRE_TIMEOUT), mHaveRoot(false)
{
mMap = boost::make_shared<SHAMap>(hash);
@@ -32,7 +34,7 @@ void TransactionAcquire::done()
{
if (mFailed)
{
Log(lsWARNING) << "Failed to acquire TXs " << mHash;
cLog(lsWARNING) << "Failed to acquire TXs " << mHash;
theApp->getOPs().mapComplete(mHash, SHAMap::pointer());
}
else
@@ -51,12 +53,12 @@ void TransactionAcquire::trigger(Peer::ref peer, bool timer)
{
if (mComplete || mFailed)
{
Log(lsINFO) << "complete or failed";
cLog(lsINFO) << "complete or failed";
return;
}
if (!mHaveRoot)
{
Log(lsINFO) << "have no root";
cLog(lsINFO) << "have no root";
newcoin::TMGetLedger tmGL;
tmGL.set_ledgerhash(mHash.begin(), mHash.size());
tmGL.set_itype(newcoin::liTS_CANDIDATE);
@@ -110,7 +112,7 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
{
if (mHaveRoot)
{
Log(lsWARNING) << "Got root TXS node, already have it";
cLog(lsWARNING) << "Got root TXS node, already have it";
return false;
}
if (!mMap->addRootNode(getHash(), *nodeDatait, snfWIRE))
@@ -129,7 +131,7 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
}
catch (...)
{
Log(lsERROR) << "Peer sends us junky transaction node data";
cLog(lsERROR) << "Peer sends us junky transaction node data";
return false;
}
}
@@ -143,25 +145,25 @@ void LCTransaction::setVote(const uint160& peer, bool votesYes)
{ // new vote
if (votesYes)
{
Log(lsTRACE) << "Peer " << peer << " votes YES on " << mTransactionID;
cLog(lsTRACE) << "Peer " << peer << " votes YES on " << mTransactionID;
++mYays;
}
else
{
Log(lsTRACE) << "Peer " << peer << " votes NO on " << mTransactionID;
cLog(lsTRACE) << "Peer " << peer << " votes NO on " << mTransactionID;
++mNays;
}
}
else if (votesYes && !res.first->second)
{ // changes vote to yes
Log(lsTRACE) << "Peer " << peer << " now votes YES on " << mTransactionID;
cLog(lsTRACE) << "Peer " << peer << " now votes YES on " << mTransactionID;
--mNays;
++mYays;
res.first->second = true;
}
else if (!votesYes && res.first->second)
{ // changes vote to no
Log(lsTRACE) << "Peer " << peer << " now votes NO on " << mTransactionID;
cLog(lsTRACE) << "Peer " << peer << " now votes NO on " << mTransactionID;
++mNays;
--mYays;
res.first->second = false;
@@ -209,13 +211,13 @@ bool LCTransaction::updateVote(int percentTime, bool proposing)
if (newPosition == mOurVote)
{
#ifdef LC_DEBUG
Log(lsTRACE) << "No change (" << (mOurVote ? "YES" : "NO") << ") : weight "
cLog(lsTRACE) << "No change (" << (mOurVote ? "YES" : "NO") << ") : weight "
<< weight << ", percent " << percentTime;
#endif
return false;
}
mOurVote = newPosition;
Log(lsTRACE) << "We now vote " << (mOurVote ? "YES" : "NO") << " on " << mTransactionID;
cLog(lsTRACE) << "We now vote " << (mOurVote ? "YES" : "NO") << " on " << mTransactionID;
return true;
}
@@ -224,8 +226,8 @@ LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::ref previou
mValSeed(theConfig.VALIDATION_SEED), mCurrentMSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false),
mConsensusStartTime(boost::posix_time::microsec_clock::universal_time())
{
Log(lsDEBUG) << "Creating consensus object";
Log(lsTRACE) << "LCL:" << previousLedger->getHash() <<", ct=" << closeTime;
cLog(lsDEBUG) << "Creating consensus object";
cLog(lsTRACE) << "LCL:" << previousLedger->getHash() <<", ct=" << closeTime;
mPreviousProposers = theApp->getOPs().getPreviousProposers();
mPreviousMSeconds = theApp->getOPs().getPreviousConvergeTime();
assert(mPreviousMSeconds);
@@ -235,21 +237,21 @@ LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::ref previou
if (mValSeed.isValid())
{
Log(lsINFO) << "Entering consensus process, validating";
cLog(lsINFO) << "Entering consensus process, validating";
mValidating = true;
mProposing = theApp->getOPs().getOperatingMode() == NetworkOPs::omFULL;
}
else
{
Log(lsINFO) << "Entering consensus process, watching";
cLog(lsINFO) << "Entering consensus process, watching";
mProposing = mValidating = false;
}
handleLCL(prevLCLHash);
if (!mHaveCorrectLCL)
{
Log(lsINFO) << "Entering consensus with: " << previousLedger->getHash();
Log(lsINFO) << "Correct LCL is: " << prevLCLHash;
cLog(lsINFO) << "Entering consensus with: " << previousLedger->getHash();
cLog(lsINFO) << "Correct LCL is: " << prevLCLHash;
}
}
@@ -282,13 +284,13 @@ void LedgerConsensus::checkLCL()
default: status = "unknown";
}
Log(lsWARNING) << "View of consensus changed during consensus (" << netLgrCount << ") status="
cLog(lsWARNING) << "View of consensus changed during consensus (" << netLgrCount << ") status="
<< status << ", " << (mHaveCorrectLCL ? "CorrectLCL" : "IncorrectLCL");
Log(lsWARNING) << mPrevLedgerHash << " to " << netLgr;
cLog(lsWARNING) << mPrevLedgerHash << " to " << netLgr;
#ifdef DEBUG
BOOST_FOREACH(u256_cvc_pair& it, vals)
Log(lsDEBUG) << "V: " << it.first << ", " << it.second.first;
cLog(lsDEBUG) << "V: " << it.first << ", " << it.second.first;
#endif
if (mHaveCorrectLCL)
@@ -310,7 +312,7 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
return;
else
{
Log(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash;
cLog(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash;
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash);
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
@@ -333,7 +335,7 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
if (mHaveCorrectLCL && mProposing && mOurPosition)
{
Log(lsINFO) << "Bowing out of consensus";
cLog(lsINFO) << "Bowing out of consensus";
mOurPosition->bowOut();
propose();
}
@@ -348,7 +350,7 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
return;
}
Log(lsINFO) << "Acquired the consensus ledger " << mPrevLedgerHash;
cLog(lsINFO) << "Acquired the consensus ledger " << mPrevLedgerHash;
mHaveCorrectLCL = true;
mAcquiringLedger = LedgerAcquire::pointer();
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution(
@@ -361,7 +363,7 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger)
{
SHAMap::pointer initialSet = initialLedger.peekTransactionMap()->snapShot(false);
uint256 txSet = initialSet->getHash();
Log(lsINFO) << "initial position " << txSet;
cLog(lsINFO) << "initial position " << txSet;
mapComplete(txSet, initialSet, false);
if (mValidating)
@@ -415,14 +417,13 @@ void LedgerConsensus::createDisputes(SHAMap::ref m1, SHAMap::ref m2)
void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::ref map, bool acquired)
{
if (acquired)
Log(lsINFO) << "We have acquired TXS " << hash;
tLog(acquired, lsINFO) << "We have acquired TXS " << hash;
if (!map)
{ // this is an invalid/corrupt map
mAcquired[hash] = map;
mAcquiring.erase(hash);
Log(lsWARNING) << "A trusted node directed us to acquire an invalid TXN map";
cLog(lsWARNING) << "A trusted node directed us to acquire an invalid TXN map";
return;
}
assert(hash == map->getHash());
@@ -456,8 +457,7 @@ void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::ref map, bool acq
}
if (!peers.empty())
adjustCount(map, peers);
else if (acquired)
Log(lsWARNING) << "By the time we got the map " << hash << " no peers were proposing it";
else tLog(acquired, lsWARNING) << "By the time we got the map " << hash << " no peers were proposing it";
sendHaveTxSet(hash, true);
}
@@ -496,7 +496,7 @@ void LedgerConsensus::statusChange(newcoin::NodeEvent event, Ledger& ledger)
s.set_ledgerhash(hash.begin(), hash.size());
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(s, newcoin::mtSTATUS_CHANGE);
theApp->getConnectionPool().relayMessage(NULL, packet);
Log(lsINFO) << "send status change to peer";
cLog(lsINFO) << "send status change to peer";
}
int LedgerConsensus::startup()
@@ -527,15 +527,20 @@ void LedgerConsensus::statePreClose()
}
if (ContinuousLedgerTiming::shouldClose(anyTransactions, mPreviousProposers, proposersClosed,
mPreviousMSeconds, sinceClose, idleInterval))
{ // it is time to close the ledger
mPreviousMSeconds, sinceClose, idleInterval))
{
closeLedger();
}
}
void LedgerConsensus::closeLedger()
{
mState = lcsESTABLISH;
mConsensusStartTime = boost::posix_time::microsec_clock::universal_time();
mCloseTime = theApp->getOPs().getCloseTimeNC();
theApp->getOPs().setLastCloseTime(mCloseTime);
statusChange(newcoin::neCLOSING_LEDGER, *mPreviousLedger);
takeInitialPosition(*theApp->getMasterLedger().closeLedger());
}
}
void LedgerConsensus::stateEstablish()
@@ -545,14 +550,13 @@ void LedgerConsensus::stateEstablish()
updateOurPositions();
if (!mHaveCloseTimeConsensus)
{
if (haveConsensus())
Log(lsINFO) << "We have TX consensus but not CT consensus";
tLog(haveConsensus(), lsINFO) << "We have TX consensus but not CT consensus";
}
else if (haveConsensus())
{
Log(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)";
cLog(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)";
mState = lcsFINISHED;
beginAccept();
beginAccept(false);
}
}
@@ -605,7 +609,7 @@ void LedgerConsensus::updateOurPositions()
if (it->second->isStale(peerCutoff))
{ // proposal is stale
uint160 peerID = it->second->getPeerID();
Log(lsWARNING) << "Removing stale proposal from " << peerID;
cLog(lsWARNING) << "Removing stale proposal from " << peerID;
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
it.second->unVote(peerID);
mPeerPositions.erase(it++);
@@ -670,18 +674,17 @@ void LedgerConsensus::updateOurPositions()
for (std::map<uint32, int>::iterator it = closeTimes.begin(), end = closeTimes.end(); it != end; ++it)
{
Log(lsINFO) << "CCTime: " << it->first << " has " << it->second << ", " << thresh << " required";
cLog(lsINFO) << "CCTime: " << it->first << " has " << it->second << ", " << thresh << " required";
if (it->second > thresh)
{
Log(lsINFO) << "Close time consensus reached: " << it->first;
cLog(lsINFO) << "Close time consensus reached: " << it->first;
mHaveCloseTimeConsensus = true;
closeTime = it->first;
thresh = it->second;
}
}
if (!mHaveCloseTimeConsensus)
Log(lsDEBUG) << "No CT consensus: Proposers:" << mPeerPositions.size() << " Proposing:" <<
(mProposing ? "yes" : "no") << " Thresh:" << thresh << " Pos:" << closeTime;
tLog(!mHaveCloseTimeConsensus, lsDEBUG) << "No CT consensus: Proposers:" << mPeerPositions.size()
<< " Proposing:" << (mProposing ? "yes" : "no") << " Thresh:" << thresh << " Pos:" << closeTime;
}
if ((!changes) &&
@@ -696,7 +699,7 @@ void LedgerConsensus::updateOurPositions()
if (changes)
{
uint256 newHash = ourPosition->getHash();
Log(lsINFO) << "Position change: CTime " << closeTime << ", tx " << newHash;
cLog(lsINFO) << "Position change: CTime " << closeTime << ", tx " << newHash;
if (mOurPosition->changePosition(newHash, closeTime))
{
if (mProposing)
@@ -724,7 +727,7 @@ bool LedgerConsensus::haveConsensus()
int currentValidations = theApp->getValidations().getNodesAfter(mPrevLedgerHash);
#ifdef LC_DEBUG
Log(lsINFO) << "Checking for TX consensus: agree=" << agree << ", disagree=" << disagree;
cLog(lsINFO) << "Checking for TX consensus: agree=" << agree << ", disagree=" << disagree;
#endif
return ContinuousLedgerTiming::haveConsensus(mPreviousProposers, agree + disagree, agree, currentValidations,
@@ -742,7 +745,7 @@ SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool do
SHAMap::pointer currentMap = theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap();
if (currentMap->getHash() == hash)
{
Log(lsINFO) << "node proposes our open transaction set";
cLog(lsINFO) << "node proposes our open transaction set";
currentMap = currentMap->snapShot(false);
mapComplete(hash, currentMap, false);
return currentMap;
@@ -803,7 +806,7 @@ void LedgerConsensus::startAcquiring(const TransactionAcquire::pointer& acquire)
void LedgerConsensus::propose()
{
Log(lsTRACE) << "We propose: " << mOurPosition->getCurrentHash();
cLog(lsTRACE) << "We propose: " << mOurPosition->getCurrentHash();
newcoin::TMProposeSet prop;
prop.set_currenttxhash(mOurPosition->getCurrentHash().begin(), 256 / 8);
prop.set_proposeseq(mOurPosition->getProposeSeq());
@@ -819,7 +822,7 @@ void LedgerConsensus::propose()
void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vector<unsigned char>& tx)
{
Log(lsTRACE) << "Transaction " << txID << " is disputed";
cLog(lsTRACE) << "Transaction " << txID << " is disputed";
boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.find(txID);
if (it != mDisputes.end())
return;
@@ -861,7 +864,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
uint160 peerID = newPosition->getPeerID();
if (mDeadNodes.find(peerID) != mDeadNodes.end())
{
Log(lsINFO) << "Position from dead node";
cLog(lsINFO) << "Position from dead node";
return false;
}
@@ -876,7 +879,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
if (newPosition->getProposeSeq() == 0)
{ // new initial close time estimate
Log(lsTRACE) << "Peer reports close time as " << newPosition->getCloseTime();
cLog(lsTRACE) << "Peer reports close time as " << newPosition->getCloseTime();
++mCloseTimes[newPosition->getCloseTime()];
}
else if (newPosition->getProposeSeq() == LedgerProposal::seqLeave)
@@ -889,7 +892,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
}
Log(lsINFO) << "Processing peer proposal " << newPosition->getProposeSeq() << "/" << newPosition->getCurrentHash();
cLog(lsINFO) << "Processing peer proposal " << newPosition->getProposeSeq() << "/" << newPosition->getCurrentHash();
currentPosition = newPosition;
SHAMap::pointer set = getTransactionTree(newPosition->getCurrentHash(), true);
@@ -899,7 +902,7 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
it.second->setVote(peerID, set->hasItem(it.first));
}
else
Log(lsTRACE) << "Don't have that tx set";
cLog(lsTRACE) << "Don't have that tx set";
return true;
}
@@ -931,18 +934,21 @@ bool LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
return set->takeNodes(nodeIDs, nodeData, peer);
}
void LedgerConsensus::beginAccept()
void LedgerConsensus::beginAccept(bool synchronous)
{
SHAMap::pointer consensusSet = mAcquired[mOurPosition->getCurrentHash()];
if (!consensusSet)
{
Log(lsFATAL) << "We don't have a consensus set";
cLog(lsFATAL) << "We don't have a consensus set";
abort();
return;
}
theApp->getOPs().newLCL(mPeerPositions.size(), mCurrentMSeconds, mNewLedgerHash);
theApp->getIOService().post(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet));
if (synchronous)
accept(consensusSet);
else
theApp->getIOService().post(boost::bind(&LedgerConsensus::Saccept, shared_from_this(), consensusSet));
}
void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::pointer txSet)
@@ -970,7 +976,7 @@ void LedgerConsensus::playbackProposals()
proposal->setPrevLedger(mPrevLedgerHash);
if (proposal->checkSign())
{
Log(lsINFO) << "Applying deferred proposal";
cLog(lsINFO) << "Applying deferred proposal";
peerPosition(proposal);
}
}
@@ -991,18 +997,18 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, const Serializ
TER result = engine.applyTransaction(*txn, parms);
if (isTerRetry(result))
{
Log(lsINFO) << " retry";
cLog(lsINFO) << " retry";
assert(!ledger->hasTransaction(txn->getTransactionID()));
failedTransactions.push_back(txn);
}
else if (isTepSuccess(result)) // FIXME: Need to do partial success
{
Log(lsTRACE) << " success";
cLog(lsTRACE) << " success";
assert(ledger->hasTransaction(txn->getTransactionID()));
}
else if (isTemMalformed(result) || isTefFailure(result))
{
Log(lsINFO) << " hard fail";
cLog(lsINFO) << " hard fail";
}
else
assert(false);
@@ -1010,7 +1016,7 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, const Serializ
}
catch (...)
{
Log(lsWARNING) << " Throws";
cLog(lsWARNING) << " Throws";
}
#endif
}
@@ -1025,7 +1031,7 @@ void LedgerConsensus::applyTransactions(SHAMap::ref set, Ledger::ref applyLedger
{
if (!checkLedger->hasTransaction(item->getTag()))
{
Log(lsINFO) << "Processing candidate transaction: " << item->getTag();
cLog(lsINFO) << "Processing candidate transaction: " << item->getTag();
#ifndef TRUST_NETWORK
try
{
@@ -1037,7 +1043,7 @@ void LedgerConsensus::applyTransactions(SHAMap::ref set, Ledger::ref applyLedger
}
catch (...)
{
Log(lsWARNING) << " Throws";
cLog(lsWARNING) << " Throws";
}
#endif
}
@@ -1065,7 +1071,7 @@ void LedgerConsensus::applyTransactions(SHAMap::ref set, Ledger::ref applyLedger
}
catch (...)
{
Log(lsWARNING) << " Throws";
cLog(lsWARNING) << " Throws";
it = failedTransactions.erase(it);
}
}
@@ -1083,11 +1089,11 @@ void LedgerConsensus::accept(SHAMap::ref set)
uint32 closeTime = roundCloseTime(mOurPosition->getCloseTime());
Log(lsINFO) << "Computing new LCL based on network consensus";
cLog(lsINFO) << "Computing new LCL based on network consensus";
if (mHaveCorrectLCL)
{
Log(lsINFO) << "CNF tx " << mOurPosition->getCurrentHash() << ", close " << closeTime;
Log(lsINFO) << "CNF mode " << theApp->getOPs().getOperatingMode() << ", oldLCL " << mPrevLedgerHash;
cLog(lsINFO) << "CNF tx " << mOurPosition->getCurrentHash() << ", close " << closeTime;
cLog(lsINFO) << "CNF mode " << theApp->getOPs().getOperatingMode() << ", oldLCL " << mPrevLedgerHash;
}
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
@@ -1102,7 +1108,7 @@ void LedgerConsensus::accept(SHAMap::ref set)
{ // we agreed to disagree
closeTimeCorrect = false;
closeTime = mPreviousLedger->getCloseTimeNC() + 1;
Log(lsINFO) << "CNF badclose " << closeTime;
cLog(lsINFO) << "CNF badclose " << closeTime;
}
newLCL->setAccepted(closeTime, mCloseResolution, closeTimeCorrect);
@@ -1120,10 +1126,10 @@ void LedgerConsensus::accept(SHAMap::ref set)
val.set_validation(&validation[0], validation.size());
int j = theApp->getConnectionPool().relayMessage(NULL,
boost::make_shared<PackedMessage>(val, newcoin::mtVALIDATION));
Log(lsINFO) << "CNF Val " << newLCLHash << " to " << j << " peers";
cLog(lsINFO) << "CNF Val " << newLCLHash << " to " << j << " peers";
}
else
Log(lsINFO) << "CNF newLCL " << newLCLHash;
cLog(lsINFO) << "CNF newLCL " << newLCLHash;
Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL));
ScopedLock sl = theApp->getMasterLedger().getLock();
@@ -1136,19 +1142,19 @@ void LedgerConsensus::accept(SHAMap::ref set)
{ // we voted NO
try
{
Log(lsINFO) << "Test applying disputed transaction that did not get in";
cLog(lsINFO) << "Test applying disputed transaction that did not get in";
SerializerIterator sit(it.second->peekTransaction());
SerializedTransaction::pointer txn = boost::make_shared<SerializedTransaction>(boost::ref(sit));
applyTransaction(engine, txn, newOL, failedTransactions, true);
}
catch (...)
{
Log(lsINFO) << "Failed to apply transaction we voted NO on";
cLog(lsINFO) << "Failed to apply transaction we voted NO on";
}
}
}
Log(lsINFO) << "Applying transactions from current ledger";
cLog(lsINFO) << "Applying transactions from current ledger";
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), newOL, newLCL,
failedTransactions, true);
theApp->getMasterLedger().pushLedger(newLCL, newOL);
@@ -1158,12 +1164,12 @@ void LedgerConsensus::accept(SHAMap::ref set)
if (mValidating)
{ // see how close our close time is to other node's close time reports
Log(lsINFO) << "We closed at " << boost::lexical_cast<std::string>(mCloseTime);
cLog(lsINFO) << "We closed at " << boost::lexical_cast<std::string>(mCloseTime);
uint64 closeTotal = mCloseTime;
int closeCount = 1;
for (std::map<uint32, int>::iterator it = mCloseTimes.begin(), end = mCloseTimes.end(); it != end; ++it)
{ // FIXME: Use median, not average
Log(lsINFO) << boost::lexical_cast<std::string>(it->second) << " time votes for "
cLog(lsINFO) << boost::lexical_cast<std::string>(it->second) << " time votes for "
<< boost::lexical_cast<std::string>(it->first);
closeCount += it->second;
closeTotal += static_cast<uint64>(it->first) * static_cast<uint64>(it->second);
@@ -1171,19 +1177,17 @@ void LedgerConsensus::accept(SHAMap::ref set)
closeTotal += (closeCount / 2);
closeTotal /= closeCount;
int offset = static_cast<int>(closeTotal) - static_cast<int>(mCloseTime);
Log(lsINFO) << "Our close offset is estimated at " << offset << " (" << closeCount << ")";
cLog(lsINFO) << "Our close offset is estimated at " << offset << " (" << closeCount << ")";
theApp->getOPs().closeTimeOffset(offset);
}
#ifdef DEBUG
if (sLog(lsTRACE))
{
Json::StyledStreamWriter ssw;
Log(lsTRACE) << "newLCL";
Json::Value p;
newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
ssw.write(Log(lsTRACE).ref(), p);
Log(lsTRACE) << p;
}
#endif
}
void LedgerConsensus::endConsensus()
@@ -1191,6 +1195,16 @@ void LedgerConsensus::endConsensus()
theApp->getOPs().endConsensus(mHaveCorrectLCL);
}
void LedgerConsensus::simulate()
{
cLog(lsINFO) << "Simulating consensus";
closeLedger();
mCurrentMSeconds = 100;
beginAccept(true);
endConsensus();
cLog(lsINFO) << "Simulation complete";
}
Json::Value LedgerConsensus::getJson()
{
Json::Value ret(Json::objectValue);

View File

@@ -148,8 +148,9 @@ protected:
void updateOurPositions();
void playbackProposals();
int getThreshold();
void closeLedger();
void beginAccept();
void beginAccept(bool synchronous);
void endConsensus();
public:
@@ -189,6 +190,8 @@ public:
void swapDefer(boost::unordered_map< uint160, std::list<LedgerProposal::pointer> > &n)
{ mDeferredProposals.swap(n); }
// test/debug
void simulate();
};

View File

@@ -5,6 +5,8 @@
#include "Log.h"
SETUP_LOG();
// #define META_DEBUG
// Small for testing, should likely be 32 or 64.
@@ -297,7 +299,7 @@ bool LedgerEntrySet::threadTx(const NewcoinAddress& threadTo, Ledger::ref ledger
boost::unordered_map<uint256, SLE::pointer>& newMods)
{
#ifdef META_DEBUG
Log(lsTRACE) << "Thread to " << threadTo.getAccountID();
cLog(lsTRACE) << "Thread to " << threadTo.getAccountID();
#endif
SLE::pointer sle = getForMod(Ledger::getAccountRootIndex(threadTo.getAccountID()), ledger, newMods);
if (!sle)
@@ -326,14 +328,14 @@ bool LedgerEntrySet::threadOwners(SLE::ref node, Ledger::ref ledger, boost::unor
if (node->hasOneOwner()) // thread to owner's account
{
#ifdef META_DEBUG
Log(lsTRACE) << "Thread to single owner";
cLog(lsTRACE) << "Thread to single owner";
#endif
return threadTx(node->getOwner(), ledger, newMods);
}
else if (node->hasTwoOwners()) // thread to owner's accounts]
{
#ifdef META_DEBUG
Log(lsTRACE) << "Thread to two owners";
cLog(lsTRACE) << "Thread to two owners";
#endif
return
threadTx(node->getFirstOwner(), ledger, newMods) &&
@@ -358,21 +360,21 @@ void LedgerEntrySet::calcRawMeta(Serializer& s)
{
case taaMODIFY:
#ifdef META_DEBUG
Log(lsTRACE) << "Modified Node " << it->first;
cLog(lsTRACE) << "Modified Node " << it->first;
#endif
nType = TMNModifiedNode;
break;
case taaDELETE:
#ifdef META_DEBUG
Log(lsTRACE) << "Deleted Node " << it->first;
cLog(lsTRACE) << "Deleted Node " << it->first;
#endif
nType = TMNDeletedNode;
break;
case taaCREATE:
#ifdef META_DEBUG
Log(lsTRACE) << "Created Node " << it->first;
cLog(lsTRACE) << "Created Node " << it->first;
#endif
nType = TMNCreatedNode;
break;
@@ -466,7 +468,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s)
entryModify(it->second);
#ifdef META_DEBUG
Log(lsINFO) << "Metadata:" << mSet.getJson(0);
cLog(lsINFO) << "Metadata:" << mSet.getJson(0);
#endif
mSet.addRaw(s);
@@ -557,10 +559,10 @@ TER LedgerEntrySet::dirAdd(
svIndexes.peekValue().push_back(uLedgerIndex); // Append entry.
sleNode->setFieldV256(sfIndexes, svIndexes); // Save entry.
Log(lsINFO) << "dirAdd: creating: root: " << uRootIndex.ToString();
Log(lsINFO) << "dirAdd: appending: Entry: " << uLedgerIndex.ToString();
Log(lsINFO) << "dirAdd: appending: Node: " << strHex(uNodeDir);
// Log(lsINFO) << "dirAdd: appending: PREV: " << svIndexes.peekValue()[0].ToString();
cLog(lsINFO) << "dirAdd: creating: root: " << uRootIndex.ToString();
cLog(lsINFO) << "dirAdd: appending: Entry: " << uLedgerIndex.ToString();
cLog(lsINFO) << "dirAdd: appending: Node: " << strHex(uNodeDir);
// cLog(lsINFO) << "dirAdd: appending: PREV: " << svIndexes.peekValue()[0].ToString();
return tesSUCCESS;
}
@@ -580,7 +582,7 @@ TER LedgerEntrySet::dirDelete(
if (!sleNode)
{
Log(lsWARNING) << "dirDelete: no such node";
cLog(lsWARNING) << "dirDelete: no such node";
return tefBAD_LEDGER;
}
@@ -596,7 +598,7 @@ TER LedgerEntrySet::dirDelete(
{
assert(false);
Log(lsWARNING) << "dirDelete: no such entry";
cLog(lsWARNING) << "dirDelete: no such entry";
return tefBAD_LEDGER;
}
@@ -688,14 +690,14 @@ TER LedgerEntrySet::dirDelete(
if (!slePrevious)
{
Log(lsWARNING) << "dirDelete: previous node is missing";
cLog(lsWARNING) << "dirDelete: previous node is missing";
return tefBAD_LEDGER;
}
if (!sleNext)
{
Log(lsWARNING) << "dirDelete: next node is missing";
cLog(lsWARNING) << "dirDelete: next node is missing";
return tefBAD_LEDGER;
}
@@ -789,7 +791,7 @@ bool LedgerEntrySet::dirNext(
}
uEntryIndex = vuiIndexes[uDirEntry++];
Log(lsINFO) << boost::str(boost::format("dirNext: uDirEntry=%d uEntryIndex=%s") % uDirEntry % uEntryIndex);
cLog(lsINFO) << boost::str(boost::format("dirNext: uDirEntry=%d uEntryIndex=%s") % uDirEntry % uEntryIndex);
return true;
}
@@ -836,7 +838,7 @@ STAmount LedgerEntrySet::rippleOwed(const uint160& uToAccountID, const uint160&
}
else
{
Log(lsINFO) << "rippleOwed: No credit line between "
cLog(lsINFO) << "rippleOwed: No credit line between "
<< NewcoinAddress::createHumanAccountID(uFromAccountID)
<< " and "
<< NewcoinAddress::createHumanAccountID(uToAccountID)
@@ -876,7 +878,7 @@ uint32 LedgerEntrySet::rippleTransferRate(const uint160& uIssuerID)
? sleAccount->getFieldU32(sfTransferRate)
: QUALITY_ONE;
Log(lsINFO) << boost::str(boost::format("rippleTransferRate: uIssuerID=%s account_exists=%d transfer_rate=%f")
cLog(lsINFO) << boost::str(boost::format("rippleTransferRate: uIssuerID=%s account_exists=%d transfer_rate=%f")
% NewcoinAddress::createHumanAccountID(uIssuerID)
% !!sleAccount
% (uQuality/1000000000.0));
@@ -888,8 +890,6 @@ uint32 LedgerEntrySet::rippleTransferRate(const uint160& uIssuerID)
uint32 LedgerEntrySet::rippleTransferRate(const uint160& uSenderID, const uint160& uReceiverID, const uint160& uIssuerID)
{
uint32 uQuality;
return uSenderID == uIssuerID || uReceiverID == uIssuerID
? QUALITY_ONE
: rippleTransferRate(uIssuerID);
@@ -922,7 +922,7 @@ uint32 LedgerEntrySet::rippleQualityIn(const uint160& uToAccountID, const uint16
}
}
Log(lsINFO) << boost::str(boost::format("rippleQuality: %s uToAccountID=%s uFromAccountID=%s uCurrencyID=%s bLine=%d uQuality=%f")
cLog(lsINFO) << boost::str(boost::format("rippleQuality: %s uToAccountID=%s uFromAccountID=%s uCurrencyID=%s bLine=%d uQuality=%f")
% (sfLow == sfLowQualityIn ? "in" : "out")
% NewcoinAddress::createHumanAccountID(uToAccountID)
% NewcoinAddress::createHumanAccountID(uFromAccountID)
@@ -969,7 +969,7 @@ STAmount LedgerEntrySet::accountHolds(const uint160& uAccountID, const uint160&
saAmount = rippleHolds(uAccountID, uCurrencyID, uIssuerID);
}
Log(lsINFO) << boost::str(boost::format("accountHolds: uAccountID=%s saAmount=%s")
cLog(lsINFO) << boost::str(boost::format("accountHolds: uAccountID=%s saAmount=%s")
% NewcoinAddress::createHumanAccountID(uAccountID)
% saAmount.getFullText());
@@ -989,7 +989,7 @@ STAmount LedgerEntrySet::accountFunds(const uint160& uAccountID, const STAmount&
{
saFunds = saDefault;
Log(lsINFO) << boost::str(boost::format("accountFunds: uAccountID=%s saDefault=%s SELF-FUNDED")
cLog(lsINFO) << boost::str(boost::format("accountFunds: uAccountID=%s saDefault=%s SELF-FUNDED")
% NewcoinAddress::createHumanAccountID(uAccountID)
% saDefault.getFullText());
}
@@ -997,7 +997,7 @@ STAmount LedgerEntrySet::accountFunds(const uint160& uAccountID, const STAmount&
{
saFunds = accountHolds(uAccountID, saDefault.getCurrency(), saDefault.getIssuer());
Log(lsINFO) << boost::str(boost::format("accountFunds: uAccountID=%s saDefault=%s saFunds=%s")
cLog(lsINFO) << boost::str(boost::format("accountFunds: uAccountID=%s saDefault=%s saFunds=%s")
% NewcoinAddress::createHumanAccountID(uAccountID)
% saDefault.getFullText()
% saFunds.getFullText());
@@ -1040,7 +1040,7 @@ void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uRece
if (!sleRippleState)
{
Log(lsINFO) << "rippleCredit: Creating ripple line: " << uIndex.ToString();
cLog(lsINFO) << "rippleCredit: Creating ripple line: " << uIndex.ToString();
STAmount saBalance = saAmount;
@@ -1124,7 +1124,7 @@ void LedgerEntrySet::accountSend(const uint160& uSenderID, const uint160& uRecei
? entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uReceiverID))
: SLE::pointer();
Log(lsINFO) << boost::str(boost::format("accountSend> %s (%s) -> %s (%s) : %s")
cLog(lsINFO) << boost::str(boost::format("accountSend> %s (%s) -> %s (%s) : %s")
% NewcoinAddress::createHumanAccountID(uSenderID)
% (sleSender ? (sleSender->getFieldAmount(sfBalance)).getFullText() : "-")
% NewcoinAddress::createHumanAccountID(uReceiverID)
@@ -1143,7 +1143,7 @@ void LedgerEntrySet::accountSend(const uint160& uSenderID, const uint160& uRecei
entryModify(sleReceiver);
}
Log(lsINFO) << boost::str(boost::format("accountSend< %s (%s) -> %s (%s) : %s")
cLog(lsINFO) << boost::str(boost::format("accountSend< %s (%s) -> %s (%s) : %s")
% NewcoinAddress::createHumanAccountID(uSenderID)
% (sleSender ? (sleSender->getFieldAmount(sfBalance)).getFullText() : "-")
% NewcoinAddress::createHumanAccountID(uReceiverID)

View File

@@ -43,8 +43,6 @@ public:
// The finalized ledger is the last closed/accepted ledger
Ledger::pointer getClosedLedger() { return mFinalizedLedger; }
void runStandAlone() { mFinalizedLedger = mCurrentLedger; }
TER doTransaction(const SerializedTransaction& txn, TransactionEngineParams params);
void pushLedger(Ledger::ref newLedger);

View File

@@ -13,6 +13,8 @@ std::ofstream* Log::outStream = NULL;
boost::filesystem::path *Log::pathToLog = NULL;
uint32 Log::logRotateCounter = 0;
LogPartition* LogPartition::headLog = NULL;
Log::~Log()
{
std::string logMsg = boost::posix_time::to_simple_string(boost::posix_time::second_clock::universal_time());
@@ -79,6 +81,7 @@ void Log::setMinSeverity(LogSeverity s)
{
boost::recursive_mutex::scoped_lock sl(sLock);
sMinSeverity = s;
LogPartition::setSeverity(s);
}
void Log::setLogFile(boost::filesystem::path path)
@@ -99,3 +102,19 @@ void Log::setLogFile(boost::filesystem::path path)
pathToLog = new boost::filesystem::path(path);
}
void LogPartition::setSeverity(const char *partition, LogSeverity severity)
{
for (LogPartition *p = headLog; p != NULL; p = p->mNextLog)
if (p->mName == partition)
{
p->mMinSeverity = severity;
return;
}
}
void LogPartition::setSeverity(LogSeverity severity)
{
for (LogPartition *p = headLog; p != NULL; p = p->mNextLog)
p->mMinSeverity = severity;
}

View File

@@ -2,6 +2,8 @@
#define __LOG__
#include <sstream>
#include <string>
#include <limits>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/filesystem.hpp>
@@ -10,16 +12,54 @@
#include "../json/json.h"
#include "types.h"
#include <limits>
// Put at the beginning of a C++ file that needs its own log partition
#define SETUP_LOG() static LogPartition logPartition(__FILE__)
// Standard conditional log
#define cLog(x) if (!logPartition.doLog(x)) do {} while (0); else Log(x)
// Log only if an additional condition 'c' is true. Condition is not computed if not needed
#define tLog(c,x) if (!logPartition.doLog(x) || !(c)) do {} while(0); else Log(x)
// Check if should log
#define sLog(x) (logPartition.doLog(x))
enum LogSeverity
{
lsTRACE = 0,
lsDEBUG = 1,
lsINFO = 2,
lsWARNING = 3,
lsERROR = 4,
lsFATAL = 5
lsTRACE = 0, // Very low-level progress information, details inside an operation
lsDEBUG = 1, // Function-level progress information, operations
lsINFO = 2, // Server-level progress information, major operations
lsWARNING = 3, // Conditions that warrant human attention, may indicate a problem
lsERROR = 4, // A condition that indicates a problem
lsFATAL = 5 // A severe condition that indicates a server problem
};
class LogPartition
{
protected:
static LogPartition* headLog;
LogPartition* mNextLog;
LogSeverity mMinSeverity;
std::string mName;
public:
LogPartition(const char *name) : mNextLog(headLog), mMinSeverity(lsWARNING)
{
const char *ptr = strrchr(name, '/');
mName = (ptr == NULL) ? name : ptr;
headLog = this;
}
bool doLog(enum LogSeverity s)
{
return s >= mMinSeverity;
}
static void setSeverity(const char *partition, LogSeverity severity);
static void setSeverity(LogSeverity severity);
};
class Log

View File

@@ -23,6 +23,8 @@
// code assumes this node is synched (and will continue to do so until
// there's a functional network.
SETUP_LOG();
NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) :
mMode(omDISCONNECTED),mNetTimer(io_service), mLedgerMaster(pLedgerMaster), mCloseTimeOffset(0),
mLastCloseProposers(0), mLastCloseConvergeTime(1000 * LEDGER_IDLE_INTERVAL), mLastValidationTime(0)
@@ -63,8 +65,7 @@ void NetworkOPs::closeTimeOffset(int offset)
mCloseTimeOffset += (offset - 3) / 4;
else
mCloseTimeOffset = (mCloseTimeOffset * 3) / 4;
if (mCloseTimeOffset)
Log(lsINFO) << "Close time offset now " << mCloseTimeOffset;
tLog(mCloseTimeOffset != 0, lsINFO) << "Close time offset now " << mCloseTimeOffset;
}
uint32 NetworkOPs::getLedgerID(const uint256& hash)
@@ -90,9 +91,9 @@ Transaction::pointer NetworkOPs::submitTransaction(const Transaction::pointer& t
if(!tpTransNew->getSTransaction()->isEquivalent(*tpTrans->getSTransaction()))
{
Log(lsFATAL) << "Transaction reconstruction failure";
Log(lsFATAL) << tpTransNew->getSTransaction()->getJson(0);
Log(lsFATAL) << tpTrans->getSTransaction()->getJson(0);
cLog(lsFATAL) << "Transaction reconstruction failure";
cLog(lsFATAL) << tpTransNew->getSTransaction()->getJson(0);
cLog(lsFATAL) << tpTrans->getSTransaction()->getJson(0);
assert(false);
}
@@ -108,7 +109,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
if (!trans->checkSign())
{
Log(lsINFO) << "Transaction has bad signature";
cLog(lsINFO) << "Transaction has bad signature";
trans->setStatus(INVALID);
return trans;
}
@@ -119,8 +120,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
if (r != tesSUCCESS)
{
std::string token, human;
if (transResultInfo(r, token, human))
Log(lsINFO) << "TransactionResult: " << token << ": " << human;
tLog(transResultInfo(r, token, human), lsINFO) << "TransactionResult: " << token << ": " << human;
}
#endif
@@ -129,7 +129,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
if (r == terPRE_SEQ)
{ // transaction should be held
Log(lsDEBUG) << "Transaction should be held";
cLog(lsDEBUG) << "Transaction should be held";
trans->setStatus(HELD);
theApp->getMasterTransaction().canonicalize(trans, true);
mLedgerMaster->addHeldTransaction(trans);
@@ -137,14 +137,14 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
}
if ((r == tefPAST_SEQ))
{ // duplicate or conflict
Log(lsINFO) << "Transaction is obsolete";
cLog(lsINFO) << "Transaction is obsolete";
trans->setStatus(OBSOLETE);
return trans;
}
if (r == tesSUCCESS)
{
Log(lsINFO) << "Transaction is now included";
cLog(lsINFO) << "Transaction is now included";
trans->setStatus(INCLUDED);
theApp->getMasterTransaction().canonicalize(trans, true);
@@ -162,12 +162,12 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(tx, newcoin::mtTRANSACTION);
int sentTo = theApp->getConnectionPool().relayMessage(source, packet);
Log(lsINFO) << "Transaction relayed to " << sentTo << " node(s)";
cLog(lsINFO) << "Transaction relayed to " << sentTo << " node(s)";
return trans;
}
Log(lsDEBUG) << "Status other than success " << r;
cLog(lsDEBUG) << "Status other than success " << r;
if ((mMode != omFULL) && (mMode != omTRACKING) && (theApp->isNew(trans->getID())))
{
newcoin::TMTransaction tx;
@@ -255,21 +255,21 @@ STVector256 NetworkOPs::getDirNodeInfo(
if (sleNode)
{
Log(lsDEBUG) << "getDirNodeInfo: node index: " << uNodeIndex.ToString();
cLog(lsDEBUG) << "getDirNodeInfo: node index: " << uNodeIndex.ToString();
Log(lsTRACE) << "getDirNodeInfo: first: " << strHex(sleNode->getFieldU64(sfIndexPrevious));
Log(lsTRACE) << "getDirNodeInfo: last: " << strHex(sleNode->getFieldU64(sfIndexNext));
cLog(lsTRACE) << "getDirNodeInfo: first: " << strHex(sleNode->getFieldU64(sfIndexPrevious));
cLog(lsTRACE) << "getDirNodeInfo: last: " << strHex(sleNode->getFieldU64(sfIndexNext));
uNodePrevious = sleNode->getFieldU64(sfIndexPrevious);
uNodeNext = sleNode->getFieldU64(sfIndexNext);
svIndexes = sleNode->getFieldV256(sfIndexes);
Log(lsTRACE) << "getDirNodeInfo: first: " << strHex(uNodePrevious);
Log(lsTRACE) << "getDirNodeInfo: last: " << strHex(uNodeNext);
cLog(lsTRACE) << "getDirNodeInfo: first: " << strHex(uNodePrevious);
cLog(lsTRACE) << "getDirNodeInfo: last: " << strHex(uNodeNext);
}
else
{
Log(lsINFO) << "getDirNodeInfo: node index: NOT FOUND: " << uNodeIndex.ToString();
cLog(lsINFO) << "getDirNodeInfo: node index: NOT FOUND: " << uNodeIndex.ToString();
uNodePrevious = 0;
uNodeNext = 0;
@@ -403,7 +403,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
if (mMode != omDISCONNECTED)
{
setMode(omDISCONNECTED);
Log(lsWARNING) << "Node count (" << peerList.size() <<
cLog(lsWARNING) << "Node count (" << peerList.size() <<
") has fallen below quorum (" << theConfig.NETWORK_QUORUM << ").";
}
return;
@@ -411,7 +411,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
if (mMode == omDISCONNECTED)
{
setMode(omCONNECTED);
Log(lsINFO) << "Node count (" << peerList.size() << ") is sufficient.";
cLog(lsINFO) << "Node count (" << peerList.size() << ") is sufficient.";
}
if (mConsensus)
@@ -443,7 +443,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
// check if the ledger is good enough to go to omFULL
// Note: Do not go to omFULL if we don't have the previous ledger
// check if the ledger is bad enough to go to omCONNECTED -- TODO
if (theApp->getOPs().getNetworkTimeNC() < theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC())
if (theApp->getOPs().getNetworkTimeNC() < mLedgerMaster->getCurrentLedger()->getCloseTimeNC())
setMode(omFULL);
}
@@ -454,7 +454,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
}
if ((!mConsensus) && (mMode != omDISCONNECTED))
beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger());
beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger());
if (mConsensus)
mConsensus->timerEntry();
}
@@ -467,7 +467,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
// FIXME: We may have a ledger with many recent validations but that no directly-connected
// node is using. THis is kind of fundamental.
Log(lsTRACE) << "NetworkOPs::checkLastClosedLedger";
cLog(lsTRACE) << "NetworkOPs::checkLastClosedLedger";
Ledger::pointer ourClosed = mLedgerMaster->getClosedLedger();
if(!ourClosed) return(false);
@@ -503,7 +503,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
{
if (!it)
{
Log(lsDEBUG) << "NOP::CS Dead pointer in peer list";
cLog(lsDEBUG) << "NOP::CS Dead pointer in peer list";
}
else if (it->isConnected())
{
@@ -525,14 +525,13 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
for (boost::unordered_map<uint256, ValidationCount>::iterator it = ledgers.begin(), end = ledgers.end();
it != end; ++it)
{
Log(lsTRACE) << "L: " << it->first << " t=" << it->second.trustedValidations <<
cLog(lsTRACE) << "L: " << it->first << " t=" << it->second.trustedValidations <<
", n=" << it->second.nodesUsing;
// Temporary logging to make sure tiebreaking isn't broken
if (it->second.trustedValidations > 0)
Log(lsTRACE) << " TieBreakTV: " << it->second.highValidation;
else if (it->second.nodesUsing > 0)
Log(lsTRACE) << " TieBreakNU: " << it->second.highNodeUsing;
cLog(lsTRACE) << " TieBreakTV: " << it->second.highValidation;
else tLog(it->second.nodesUsing > 0, lsTRACE) << " TieBreakNU: " << it->second.highNodeUsing;
if (it->second > bestVC)
{
@@ -544,7 +543,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
if (switchLedgers && (closedLedger == prevClosedLedger))
{ // don't switch to our own previous ledger
Log(lsINFO) << "We won't switch to our own previous ledger";
cLog(lsINFO) << "We won't switch to our own previous ledger";
networkClosed = ourClosed->getHash();
switchLedgers = false;
}
@@ -562,22 +561,22 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
return false;
}
Log(lsWARNING) << "We are not running on the consensus ledger";
Log(lsINFO) << "Our LCL " << ourClosed->getHash();
Log(lsINFO) << "Net LCL " << closedLedger;
cLog(lsWARNING) << "We are not running on the consensus ledger";
cLog(lsINFO) << "Our LCL " << ourClosed->getHash();
cLog(lsINFO) << "Net LCL " << closedLedger;
if ((mMode == omTRACKING) || (mMode == omFULL))
setMode(omCONNECTED);
Ledger::pointer consensus = mLedgerMaster->getLedgerByHash(closedLedger);
if (!consensus)
{
Log(lsINFO) << "Acquiring consensus ledger " << closedLedger;
cLog(lsINFO) << "Acquiring consensus ledger " << closedLedger;
if (!mAcquiringLedger || (mAcquiringLedger->getHash() != closedLedger))
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger);
if (!mAcquiringLedger || mAcquiringLedger->isFailed())
{
theApp->getMasterLedgerAcquire().dropLedger(closedLedger);
Log(lsERROR) << "Network ledger cannot be acquired";
cLog(lsERROR) << "Network ledger cannot be acquired";
return true;
}
if (!mAcquiringLedger->isComplete())
@@ -614,9 +613,9 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger, bool duringCo
{ // set the newledger as our last closed ledger -- this is abnormal code
if (duringConsensus)
Log(lsERROR) << "JUMPdc last closed ledger to " << newLedger->getHash();
cLog(lsERROR) << "JUMPdc last closed ledger to " << newLedger->getHash();
else
Log(lsERROR) << "JUMP last closed ledger to " << newLedger->getHash();
cLog(lsERROR) << "JUMP last closed ledger to " << newLedger->getHash();
newLedger->setClosed();
Ledger::pointer openLedger = boost::make_shared<Ledger>(false, boost::ref(*newLedger));
@@ -636,13 +635,13 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger, bool duringCo
int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer closingLedger)
{
Log(lsINFO) << "Consensus time for ledger " << closingLedger->getLedgerSeq();
Log(lsINFO) << " LCL is " << closingLedger->getParentHash();
cLog(lsINFO) << "Consensus time for ledger " << closingLedger->getLedgerSeq();
cLog(lsINFO) << " LCL is " << closingLedger->getParentHash();
Ledger::pointer prevLedger = mLedgerMaster->getLedgerByHash(closingLedger->getParentHash());
if (!prevLedger)
{ // this shouldn't happen unless we jump ledgers
Log(lsWARNING) << "Don't have LCL, going to tracking";
cLog(lsWARNING) << "Don't have LCL, going to tracking";
setMode(omTRACKING);
return 3;
}
@@ -653,10 +652,10 @@ int NetworkOPs::beginConsensus(const uint256& networkClosed, Ledger::pointer clo
assert(!mConsensus);
prevLedger->setImmutable();
mConsensus = boost::make_shared<LedgerConsensus>(
networkClosed, prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC());
networkClosed, prevLedger, mLedgerMaster->getCurrentLedger()->getCloseTimeNC());
mConsensus->swapDefer(mDeferredProposals);
Log(lsDEBUG) << "Initiating consensus engine";
cLog(lsDEBUG) << "Initiating consensus engine";
return mConsensus->startup();
}
@@ -672,8 +671,8 @@ bool NetworkOPs::haveConsensusObject()
bool ledgerChange = checkLastClosedLedger(peerList, networkClosed);
if (!ledgerChange)
{
Log(lsWARNING) << "Beginning consensus due to peer action";
beginConsensus(networkClosed, theApp->getMasterLedger().getCurrentLedger());
cLog(lsWARNING) << "Beginning consensus due to peer action";
beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger());
}
return mConsensus;
}
@@ -702,14 +701,14 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, cons
if (!haveConsensusObject())
{
Log(lsINFO) << "Received proposal outside consensus window";
cLog(lsINFO) << "Received proposal outside consensus window";
return mMode != omFULL;
}
// Is this node on our UNL?
if (!theApp->getUNL().nodeInUNL(naPeerPublic))
{
Log(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " << proposeHash;
cLog(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " << proposeHash;
return true;
}
@@ -719,7 +718,7 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, cons
boost::make_shared<LedgerProposal>(prevLedger, proposeSeq, proposeHash, closeTime, naPeerPublic);
if (!proposal->checkSign(signature))
{
Log(lsWARNING) << "New-style ledger proposal fails signature check";
cLog(lsWARNING) << "New-style ledger proposal fails signature check";
return false;
}
if (prevLedger == mConsensus->getLCL())
@@ -732,7 +731,7 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, cons
boost::make_shared<LedgerProposal>(mConsensus->getLCL(), proposeSeq, proposeHash, closeTime, naPeerPublic);
if (!proposal->checkSign(signature))
{ // Note that if the LCL is different, the signature check will fail
Log(lsWARNING) << "Ledger proposal fails signature check";
cLog(lsWARNING) << "Ledger proposal fails signature check";
proposal->setSignature(signature);
mConsensus->deferProposal(proposal, nodePublic);
return false;
@@ -759,7 +758,7 @@ bool NetworkOPs::hasTXSet(const boost::shared_ptr<Peer>& peer, const uint256& se
{
if (!haveConsensusObject())
{
Log(lsINFO) << "Peer has TX set, not during consensus";
cLog(lsINFO) << "Peer has TX set, not during consensus";
return false;
}
return mConsensus->peerHasSet(peer, set, status);
@@ -773,12 +772,12 @@ void NetworkOPs::mapComplete(const uint256& hash, SHAMap::ref map)
void NetworkOPs::endConsensus(bool correctLCL)
{
uint256 deadLedger = theApp->getMasterLedger().getClosedLedger()->getParentHash();
uint256 deadLedger = mLedgerMaster->getClosedLedger()->getParentHash();
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
BOOST_FOREACH(Peer::ref it, peerList)
if (it && (it->getClosedLedgerHash() == deadLedger))
{
Log(lsTRACE) << "Killing obsolete peer status";
cLog(lsTRACE) << "Killing obsolete peer status";
it->cycleStatus();
}
mConsensus->swapDefer(mDeferredProposals);
@@ -853,7 +852,7 @@ std::vector<NewcoinAddress>
bool NetworkOPs::recvValidation(const SerializedValidation::pointer& val)
{
Log(lsINFO) << "recvValidation " << val->getLedgerHash();
cLog(lsINFO) << "recvValidation " << val->getLedgerHash();
return theApp->getValidations().addValidation(val);
}
@@ -1225,6 +1224,12 @@ void NetworkOPs::newLCL(int proposers, int convergeTime, const uint256& ledgerHa
mLastCloseHash = ledgerHash;
}
uint32 NetworkOPs::acceptLedger()
{ // accept the current transaction tree, return the new ledger's sequence
beginConsensus(mLedgerMaster->getClosedLedger()->getHash(), mLedgerMaster->getCurrentLedger());
mConsensus->simulate();
return mLedgerMaster->getCurrentLedger()->getLedgerSeq();
}
#if 0
void NetworkOPs::subAccountChanges(InfoSub* ispListener, const uint256 uLedgerHash)

View File

@@ -190,6 +190,7 @@ public:
uint32 getLastCloseTime() { return mLastCloseTime; }
void setLastCloseTime(uint32 t) { mLastCloseTime = t; }
Json::Value getServerInfo();
uint32 acceptLedger();
// client information retrieval functions
std::vector< std::pair<uint32, uint256> >

View File

@@ -16,6 +16,8 @@
#include "utils.h"
#include "Log.h"
SETUP_LOG();
// Don't try to run past receiving nonsense from a peer
#define TRUST_NETWORK
@@ -28,7 +30,7 @@ Peer::Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx)
mSocketSsl(io_service, ctx),
mVerifyTimer(io_service)
{
// Log(lsDEBUG) << "CREATING PEER: " << ADDRESS(this);
// cLog(lsDEBUG) << "CREATING PEER: " << ADDRESS(this);
}
void Peer::handle_write(const boost::system::error_code& error, size_t bytes_transferred)
@@ -47,7 +49,7 @@ void Peer::handle_write(const boost::system::error_code& error, size_t bytes_tra
}
else if (error)
{
Log(lsINFO) << "Peer: Write: Error: " << ADDRESS(this) << ": bytes=" << bytes_transferred << ": " << error.category().name() << ": " << error.message() << ": " << error;
cLog(lsINFO) << "Peer: Write: Error: " << ADDRESS(this) << ": bytes=" << bytes_transferred << ": " << error.category().name() << ": " << error.message() << ": " << error;
detach("hw");
}
@@ -67,7 +69,7 @@ void Peer::setIpPort(const std::string& strIP, int iPort)
{
mIpPort = make_pair(strIP, iPort);
Log(lsDEBUG) << "Peer: Set: "
cLog(lsDEBUG) << "Peer: Set: "
<< ADDRESS(this) << "> "
<< (mNodePublic.isValid() ? mNodePublic.humanNodePublic() : "-") << " " << getIP() << " " << getPort();
}
@@ -78,7 +80,7 @@ void Peer::detach(const char *rsn)
{
mDetaching = true; // Race is ok.
/*
Log(lsDEBUG) << "Peer: Detach: "
cLog(lsDEBUG) << "Peer: Detach: "
<< ADDRESS(this) << "> "
<< rsn << ": "
<< (mNodePublic.isValid() ? mNodePublic.humanNodePublic() : "-") << " " << getIP() << " " << getPort();
@@ -105,7 +107,7 @@ void Peer::detach(const char *rsn)
mIpPort.first.clear(); // Be idempotent.
}
/*
Log(lsDEBUG) << "Peer: Detach: "
cLog(lsDEBUG) << "Peer: Detach: "
<< ADDRESS(this) << "< "
<< rsn << ": "
<< (mNodePublic.isValid() ? mNodePublic.humanNodePublic() : "-") << " " << getIP() << " " << getPort();
@@ -124,14 +126,14 @@ void Peer::handleVerifyTimer(const boost::system::error_code& ecResult)
}
else if (ecResult)
{
Log(lsINFO) << "Peer verify timer error";
cLog(lsINFO) << "Peer verify timer error";
// Can't do anything sound.
abort();
}
else
{
//Log(lsINFO) << "Peer: Verify: Peer failed to verify in time.";
//cLog(lsINFO) << "Peer: Verify: Peer failed to verify in time.";
detach("hvt");
}
@@ -157,7 +159,7 @@ void Peer::connect(const std::string& strIp, int iPort)
if (err || itrEndpoint == boost::asio::ip::tcp::resolver::iterator())
{
Log(lsWARNING) << "Peer: Connect: Bad IP: " << strIp;
cLog(lsWARNING) << "Peer: Connect: Bad IP: " << strIp;
detach("c");
return;
}
@@ -168,7 +170,7 @@ void Peer::connect(const std::string& strIp, int iPort)
if (err)
{
Log(lsWARNING) << "Peer: Connect: Failed to set timer.";
cLog(lsWARNING) << "Peer: Connect: Failed to set timer.";
detach("c2");
return;
}
@@ -176,7 +178,7 @@ void Peer::connect(const std::string& strIp, int iPort)
if (!err)
{
Log(lsINFO) << "Peer: Connect: Outbound: " << ADDRESS(this) << ": " << mIpPort.first << " " << mIpPort.second;
cLog(lsINFO) << "Peer: Connect: Outbound: " << ADDRESS(this) << ": " << mIpPort.first << " " << mIpPort.second;
boost::asio::async_connect(
getSocket(),
@@ -197,7 +199,7 @@ void Peer::handleStart(const boost::system::error_code& error)
{
if (error)
{
Log(lsINFO) << "Peer: Handshake: Error: " << error.category().name() << ": " << error.message() << ": " << error;
cLog(lsINFO) << "Peer: Handshake: Error: " << error.category().name() << ": " << error.message() << ": " << error;
detach("hs");
}
else
@@ -212,7 +214,7 @@ void Peer::handleConnect(const boost::system::error_code& error, boost::asio::ip
{
if (error)
{
Log(lsINFO) << "Peer: Connect: Error: " << error.category().name() << ": " << error.message() << ": " << error;
cLog(lsINFO) << "Peer: Connect: Error: " << error.category().name() << ": " << error.message() << ": " << error;
detach("hc");
}
else
@@ -244,7 +246,7 @@ void Peer::connected(const boost::system::error_code& error)
{
// Not redundant ip and port, handshake, and start.
Log(lsINFO) << "Peer: Inbound: Accepted: " << ADDRESS(this) << ": " << strIp << " " << iPort;
cLog(lsINFO) << "Peer: Inbound: Accepted: " << ADDRESS(this) << ": " << strIp << " " << iPort;
mSocketSsl.set_verify_mode(boost::asio::ssl::verify_none);
@@ -253,7 +255,7 @@ void Peer::connected(const boost::system::error_code& error)
}
else if (!mDetaching)
{
Log(lsINFO) << "Peer: Inbound: Error: " << ADDRESS(this) << ": " << strIp << " " << iPort << " : " << error.category().name() << ": " << error.message() << ": " << error;
cLog(lsINFO) << "Peer: Inbound: Error: " << ADDRESS(this) << ": " << strIp << " " << iPort << " : " << error.category().name() << ": " << error.message() << ": " << error;
detach("ctd");
}
@@ -334,7 +336,7 @@ void Peer::handle_read_header(const boost::system::error_code& error)
}
else
{
Log(lsINFO) << "Peer: Header: Error: " << ADDRESS(this) << ": " << error.category().name() << ": " << error.message() << ": " << error;
cLog(lsINFO) << "Peer: Header: Error: " << ADDRESS(this) << ": " << error.category().name() << ": " << error.message() << ": " << error;
detach("hrh2");
}
}
@@ -353,7 +355,7 @@ void Peer::handle_read_body(const boost::system::error_code& error)
}
else
{
Log(lsINFO) << "Peer: Body: Error: " << ADDRESS(this) << ": " << error.category().name() << ": " << error.message() << ": " << error;
cLog(lsINFO) << "Peer: Body: Error: " << ADDRESS(this) << ": " << error.category().name() << ": " << error.message() << ": " << error;
detach("hrb");
}
}
@@ -370,7 +372,7 @@ void Peer::processReadBuffer()
// If connected and get a mtHELLO or if not connected and get a non-mtHELLO, wrong message was sent.
if (mHelloed == (type == newcoin::mtHELLO))
{
Log(lsWARNING) << "Wrong message type: " << type;
cLog(lsWARNING) << "Wrong message type: " << type;
detach("prb1");
}
else
@@ -579,36 +581,40 @@ void Peer::recvHello(newcoin::TMHello& packet)
{
int64 to = ourTime;
to -= packet.nettime();
Log(lsDEBUG) << "Connect: time offset " << to;
cLog(lsDEBUG) << "Connect: time offset " << to;
}
#endif
if (packet.has_nettime() && ((packet.nettime() < minTime) || (packet.nettime() > maxTime)))
{
if (packet.nettime() > maxTime)
Log(lsINFO) << "Recv(Hello): " << getIP() << " :Clock far off +" << packet.nettime() - ourTime;
{
cLog(lsINFO) << "Recv(Hello): " << getIP() << " :Clock far off +" << packet.nettime() - ourTime;
}
else if(packet.nettime() < minTime)
Log(lsINFO) << "Recv(Hello): " << getIP() << " :Clock far off -" << ourTime - packet.nettime();
{
cLog(lsINFO) << "Recv(Hello): " << getIP() << " :Clock far off -" << ourTime - packet.nettime();
}
}
else if (packet.protoversionmin() < MAKE_VERSION_INT(MIN_PROTO_MAJOR, MIN_PROTO_MINOR))
{
Log(lsINFO) << "Recv(Hello): Server requires protocol version " <<
cLog(lsINFO) << "Recv(Hello): Server requires protocol version " <<
GET_VERSION_MAJOR(packet.protoversion()) << "." << GET_VERSION_MINOR(packet.protoversion())
<< " we run " << PROTO_VERSION_MAJOR << "." << PROTO_VERSION_MINOR;
}
else if (!mNodePublic.setNodePublic(packet.nodepublic()))
{
Log(lsINFO) << "Recv(Hello): Disconnect: Bad node public key.";
cLog(lsINFO) << "Recv(Hello): Disconnect: Bad node public key.";
}
else if (!mNodePublic.verifyNodePublic(mCookieHash, packet.nodeproof()))
{ // Unable to verify they have private key for claimed public key.
Log(lsINFO) << "Recv(Hello): Disconnect: Failed to verify session.";
cLog(lsINFO) << "Recv(Hello): Disconnect: Failed to verify session.";
}
else
{ // Successful connection.
Log(lsINFO) << "Recv(Hello): Connect: " << mNodePublic.humanNodePublic();
if (packet.protoversion() != MAKE_VERSION_INT(PROTO_VERSION_MAJOR, PROTO_VERSION_MINOR))
Log(lsINFO) << "Peer speaks version " <<
cLog(lsINFO) << "Recv(Hello): Connect: " << mNodePublic.humanNodePublic();
tLog(packet.protoversion() != MAKE_VERSION_INT(PROTO_VERSION_MAJOR, PROTO_VERSION_MINOR), lsINFO)
<< "Peer speaks version " <<
(packet.protoversion() >> 16) << "." << (packet.protoversion() & 0xFF);
mHello = packet;
@@ -620,7 +626,7 @@ void Peer::recvHello(newcoin::TMHello& packet)
if (!theApp->getConnectionPool().peerConnected(shared_from_this(), mNodePublic, getIP(), getPort()))
{ // Already connected, self, or some other reason.
Log(lsINFO) << "Recv(Hello): Disconnect: Extraneous connection.";
cLog(lsINFO) << "Recv(Hello): Disconnect: Extraneous connection.";
}
else
{
@@ -716,7 +722,7 @@ void Peer::recvPropose(newcoin::TMProposeSet& packet)
if ((packet.currenttxhash().size() != 32) || (packet.nodepubkey().size() < 28) ||
(packet.signature().size() < 56))
{
Log(lsWARNING) << "Received proposal is malformed";
cLog(lsWARNING) << "Received proposal is malformed";
return;
}
@@ -756,7 +762,7 @@ void Peer::recvValidation(newcoin::TMValidation& packet)
{
if (packet.validation().size() < 50)
{
Log(lsWARNING) << "Too small validation from peer";
cLog(lsWARNING) << "Too small validation from peer";
punishPeer(PP_UNKNOWN_REQUEST);
return;
}
@@ -774,13 +780,13 @@ void Peer::recvValidation(newcoin::TMValidation& packet)
uint256 signingHash = val->getSigningHash();
if (!theApp->isNew(signingHash))
{
Log(lsTRACE) << "Validation is duplicate";
cLog(lsTRACE) << "Validation is duplicate";
return;
}
if (!val->isValid(signingHash))
{
Log(lsWARNING) << "Validation is invalid";
cLog(lsWARNING) << "Validation is invalid";
punishPeer(PP_UNKNOWN_REQUEST);
return;
}
@@ -794,7 +800,7 @@ void Peer::recvValidation(newcoin::TMValidation& packet)
//#ifndef TRUST_NETWORK
catch (...)
{
Log(lsWARNING) << "Exception processing validation";
cLog(lsWARNING) << "Exception processing validation";
punishPeer(PP_UNKNOWN_REQUEST);
}
//#endif
@@ -837,7 +843,7 @@ void Peer::recvGetPeers(newcoin::TMGetPeers& packet)
addr->set_ipv4(inet_addr(strIP.c_str()));
addr->set_ipv4port(iPort);
//Log(lsINFO) << "Peer: Teaching: " << ADDRESS(this) << ": " << n << ": " << strIP << " " << iPort;
//cLog(lsINFO) << "Peer: Teaching: " << ADDRESS(this) << ": " << n << ": " << strIP << " " << iPort;
}
PackedMessage::pointer message = boost::make_shared<PackedMessage>(peers, newcoin::mtPEERS);
@@ -859,7 +865,7 @@ void Peer::recvPeers(newcoin::TMPeers& packet)
if (strIP != "0.0.0.0" && strIP != "127.0.0.1")
{
//Log(lsINFO) << "Peer: Learning: " << ADDRESS(this) << ": " << i << ": " << strIP << " " << iPort;
//cLog(lsINFO) << "Peer: Learning: " << ADDRESS(this) << ": " << i << ": " << strIP << " " << iPort;
theApp->getConnectionPool().savePeer(strIP, iPort, UniqueNodeList::vsTold);
}
@@ -900,7 +906,7 @@ void Peer::recvAccount(newcoin::TMAccount& packet)
void Peer::recvStatus(newcoin::TMStatusChange& packet)
{
Log(lsTRACE) << "Received status change from peer " << getIP();
cLog(lsTRACE) << "Received status change from peer " << getIP();
if (!packet.has_networktime())
packet.set_networktime(theApp->getOPs().getNetworkTimeNC());
@@ -917,7 +923,7 @@ void Peer::recvStatus(newcoin::TMStatusChange& packet)
{
if (!mClosedLedgerHash.isZero())
{
Log(lsTRACE) << "peer has lost sync " << getIP();
cLog(lsTRACE) << "peer has lost sync " << getIP();
mClosedLedgerHash.zero();
}
mPreviousLedgerHash.zero();
@@ -927,11 +933,11 @@ void Peer::recvStatus(newcoin::TMStatusChange& packet)
{ // a peer has changed ledgers
memcpy(mClosedLedgerHash.begin(), packet.ledgerhash().data(), 256 / 8);
addLedger(mClosedLedgerHash);
Log(lsTRACE) << "peer LCL is " << mClosedLedgerHash << " " << getIP();
cLog(lsTRACE) << "peer LCL is " << mClosedLedgerHash << " " << getIP();
}
else
{
Log(lsTRACE) << "peer has no ledger hash" << getIP();
cLog(lsTRACE) << "peer has no ledger hash" << getIP();
mClosedLedgerHash.zero();
}
@@ -951,7 +957,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
if (packet.itype() == newcoin::liTS_CANDIDATE)
{ // Request is for a transaction candidate set
Log(lsINFO) << "Received request for TX candidate set data " << getIP();
cLog(lsINFO) << "Received request for TX candidate set data " << getIP();
if ((!packet.has_ledgerhash() || packet.ledgerhash().size() != 32))
{
punishPeer(PP_INVALID_REQUEST);
@@ -962,7 +968,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
map = theApp->getOPs().getTXMap(txHash);
if (!map)
{
Log(lsERROR) << "We do not have the map our peer wants";
cLog(lsERROR) << "We do not have the map our peer wants";
punishPeer(PP_INVALID_REQUEST);
return;
}
@@ -974,7 +980,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
}
else
{ // Figure out what ledger they want
Log(lsINFO) << "Received request for ledger data " << getIP();
cLog(lsINFO) << "Received request for ledger data " << getIP();
Ledger::pointer ledger;
if (packet.has_ledgerhash())
{
@@ -982,13 +988,12 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
if (packet.ledgerhash().size() != 32)
{
punishPeer(PP_INVALID_REQUEST);
Log(lsWARNING) << "Invalid request";
cLog(lsWARNING) << "Invalid request";
return;
}
memcpy(ledgerhash.begin(), packet.ledgerhash().data(), 32);
ledger = theApp->getMasterLedger().getLedgerByHash(ledgerhash);
if (!ledger)
Log(lsINFO) << "Don't have ledger " << ledgerhash;
tLog(!ledger, lsINFO) << "Don't have ledger " << ledgerhash;
}
else if (packet.has_ledgerseq())
ledger = theApp->getMasterLedger().getLedgerBySeq(packet.ledgerseq());
@@ -1003,14 +1008,14 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
else
{
punishPeer(PP_INVALID_REQUEST);
Log(lsWARNING) << "Can't figure out what ledger they want";
cLog(lsWARNING) << "Can't figure out what ledger they want";
return;
}
if ((!ledger) || (packet.has_ledgerseq() && (packet.ledgerseq() != ledger->getLedgerSeq())))
{
punishPeer(PP_UNKNOWN_REQUEST);
Log(lsWARNING) << "Can't find the ledger they want";
cLog(lsWARNING) << "Can't find the ledger they want";
return;
}
@@ -1022,14 +1027,14 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
if(packet.itype() == newcoin::liBASE)
{ // they want the ledger base data
Log(lsTRACE) << "Want ledger base data";
cLog(lsTRACE) << "Want ledger base data";
Serializer nData(128);
ledger->addRaw(nData);
reply.add_nodes()->set_nodedata(nData.getDataPtr(), nData.getLength());
if (packet.nodeids().size() != 0)
{ // new-style root request
Log(lsINFO) << "Ledger root w/map roots request";
cLog(lsINFO) << "Ledger root w/map roots request";
SHAMap::pointer map = ledger->peekAccountStateMap();
if (map)
{ // return account state root node if possible
@@ -1063,7 +1068,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
if ((!map) || (packet.nodeids_size() == 0))
{
Log(lsWARNING) << "Can't find map or empty request";
cLog(lsWARNING) << "Can't find map or empty request";
punishPeer(PP_INVALID_REQUEST);
return;
}
@@ -1128,7 +1133,7 @@ void Peer::recvLedger(newcoin::TMLedgerData& packet)
const newcoin::TMLedgerNode& node = packet.nodes(i);
if (!node.has_nodeid() || !node.has_nodedata() || (node.nodeid().size() != 33))
{
Log(lsWARNING) << "LedgerData request with invalid node ID";
cLog(lsWARNING) << "LedgerData request with invalid node ID";
punishPeer(PP_INVALID_REQUEST);
return;
}
@@ -1288,7 +1293,7 @@ Json::Value Peer::getJson()
case newcoin::nsMONITORING: ret["status"] = "monitoring"; break;
case newcoin::nsVALIDATING: ret["status"] = "validating"; break;
case newcoin::nsSHUTTING: ret["status"] = "shutting"; break;
default: Log(lsWARNING) << "Peer has unknown status: " << mLastStatus.newstatus();
default: cLog(lsWARNING) << "Peer has unknown status: " << mLastStatus.newstatus();
}
}

View File

@@ -28,10 +28,12 @@
#include "../json/reader.h"
#include "../json/writer.h"
SETUP_LOG();
RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork)
: mNetOps(nopNetwork), mSocket(io_service)
{
mRole=GUEST;
mRole = GUEST;
}
Json::Value RPCServer::RPCError(int iError)
@@ -68,6 +70,7 @@ Json::Value RPCServer::RPCError(int iError)
{ rpcNO_GEN_DECRPYT, "noGenDectypt", "Password failed to decrypt master public generator." },
{ rpcNO_NETWORK, "noNetwork", "Network not available." },
{ rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." },
{ rpcNOT_STANDALONE, "notStandAlone", "Operation valid in debug mode only." },
{ rpcPASSWD_CHANGED, "passwdChanged", "Wrong key, password changed." },
{ rpcPAYS_ACT_MALFORMED, "paysActMalformed", "Pays account malformed." },
{ rpcPAYS_AMT_MALFORMED, "paysAmtMalformed", "Pays amount malformed." },
@@ -175,13 +178,12 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
else if (!valParams.isArray())
return(HTTPReply(400, "parms unparseable"));
Json::StyledStreamWriter w;
w.write(Log(lsTRACE).ref(), valParams);
Json::Value result(doCommand(strMethod, valParams));
w.write(Log(lsTRACE).ref(), result);
cLog(lsTRACE) << valParams;
Json::Value result = doCommand(strMethod, valParams);
cLog(lsTRACE) << result;
std::string strReply = JSONRPCReply(result, Json::Value(), id);
return( HTTPReply(200, strReply) );
return HTTPReply(200, strReply);
}
int RPCServer::getParamCount(const Json::Value& params)
@@ -418,6 +420,16 @@ Json::Value RPCServer::accountFromString(const uint256& uLedger, NewcoinAddress&
return Json::Value(Json::objectValue);
}
Json::Value RPCServer::doAcceptLedger(const Json::Value &params)
{
if (!theConfig.RUN_STANDALONE)
return RPCError(rpcNOT_STANDALONE);
Json::Value obj(Json::objectValue);
obj["newLedger"] = theApp->getOPs().acceptLedger();
return obj;
}
// account_domain_set <seed> <paying_account> [<domain>]
Json::Value RPCServer::doAccountDomainSet(const Json::Value &params)
{
@@ -2640,6 +2652,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
bool mAdminRequired;
unsigned int iOptions;
} commandsA[] = {
{ "accept_ledger", &RPCServer::doAcceptLedger, 0, 0, true },
{ "account_domain_set", &RPCServer::doAccountDomainSet, 2, 3, false, optCurrent },
{ "account_email_set", &RPCServer::doAccountEmailSet, 2, 3, false, optCurrent },
{ "account_info", &RPCServer::doAccountInfo, 1, 2, false, optCurrent },

View File

@@ -23,6 +23,7 @@ public:
// Misc failure
rpcLOAD_FAILED,
rpcNO_PERMISSION,
rpcNOT_STANDALONE,
// Networking
rpcNO_CLOSED,
@@ -128,6 +129,7 @@ private:
Json::Value accountFromString(const uint256& uLedger, NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex);
Json::Value doAcceptLedger(const Json::Value &params);
Json::Value doAccountDomainSet(const Json::Value &params);
Json::Value doAccountEmailSet(const Json::Value &params);
Json::Value doAccountInfo(const Json::Value& params);

View File

@@ -8,6 +8,8 @@
#include "../json/writer.h"
SETUP_LOG();
std::size_t hash_value(const aciSource& asValue)
{
std::size_t seed = 0;
@@ -69,7 +71,7 @@ TER RippleCalc::calcNodeAdvance(
bDirectAdvance = !sleDirectDir;
bDirectDirDirty = true;
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: Initialize node: uDirectTip=%s uDirectEnd=%s bDirectAdvance=%d") % uDirectTip % uDirectEnd % bDirectAdvance);
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: Initialize node: uDirectTip=%s uDirectEnd=%s bDirectAdvance=%d") % uDirectTip % uDirectEnd % bDirectAdvance);
}
if (bDirectAdvance)
@@ -82,13 +84,13 @@ TER RippleCalc::calcNodeAdvance(
if (!!uDirectTip)
{
// Have another quality directory.
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: Quality advance: uDirectTip=%s") % uDirectTip);
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: Quality advance: uDirectTip=%s") % uDirectTip);
sleDirectDir = lesActive.entryCache(ltDIR_NODE, uDirectTip);
}
else if (bReverse)
{
Log(lsINFO) << "calcNodeAdvance: No more offers.";
cLog(lsINFO) << "calcNodeAdvance: No more offers.";
uOfferIndex = 0;
break;
@@ -96,7 +98,7 @@ TER RippleCalc::calcNodeAdvance(
else
{
// No more offers. Should be done rather than fall off end of book.
Log(lsINFO) << "calcNodeAdvance: Unreachable: Fell off end of order book.";
cLog(lsINFO) << "calcNodeAdvance: Unreachable: Fell off end of order book.";
assert(false);
terResult = tefEXCEPTION;
@@ -109,7 +111,7 @@ TER RippleCalc::calcNodeAdvance(
uEntry = 0;
bEntryAdvance = true;
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: directory dirty: saOfrRate=%s") % saOfrRate);
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: directory dirty: saOfrRate=%s") % saOfrRate);
}
if (!bEntryAdvance)
@@ -122,11 +124,11 @@ TER RippleCalc::calcNodeAdvance(
saOfferFunds = lesActive.accountFunds(uOfrOwnerID, saTakerGets); // Funds left.
bFundsDirty = false;
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: directory dirty: saOfrRate=%s") % saOfrRate);
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: directory dirty: saOfrRate=%s") % saOfrRate);
}
else
{
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: as is"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: as is"));
nothing();
}
}
@@ -139,12 +141,12 @@ TER RippleCalc::calcNodeAdvance(
// Do another cur directory iff bMultiQuality
if (bMultiQuality)
{
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: next quality"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: next quality"));
bDirectAdvance = true;
}
else if (!bReverse)
{
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: unreachable: ran out of offers"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: unreachable: ran out of offers"));
assert(false); // Can't run out of offers in forward direction.
terResult = tefEXCEPTION;
}
@@ -157,12 +159,12 @@ TER RippleCalc::calcNodeAdvance(
const aciSource asLine = boost::make_tuple(uOfrOwnerID, uCurCurrencyID, uCurIssuerID);
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: uOfrOwnerID=%s") % NewcoinAddress::createHumanAccountID(uOfrOwnerID));
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: uOfrOwnerID=%s") % NewcoinAddress::createHumanAccountID(uOfrOwnerID));
if (sleOffer->isFieldPresent(sfExpiration) && sleOffer->getFieldU32(sfExpiration) <= lesActive.getLedger()->getParentCloseTimeNC())
{
// Offer is expired.
Log(lsINFO) << "calcNodeAdvance: expired offer";
cLog(lsINFO) << "calcNodeAdvance: expired offer";
assert(musUnfundedFound.find(uOfferIndex) != musUnfundedFound.end()); // Verify reverse found it too.
bEntryAdvance = true;
@@ -177,7 +179,7 @@ TER RippleCalc::calcNodeAdvance(
if (bFoundForward && itForward->second != uIndex)
{
// Temporarily unfunded. Another node uses this source, ignore in this offer.
Log(lsINFO) << "calcNodeAdvance: temporarily unfunded offer (forward)";
cLog(lsINFO) << "calcNodeAdvance: temporarily unfunded offer (forward)";
bEntryAdvance = true;
continue;
@@ -189,7 +191,7 @@ TER RippleCalc::calcNodeAdvance(
if (bFoundPast && itPast->second != uIndex)
{
// Temporarily unfunded. Another node uses this source, ignore in this offer.
Log(lsINFO) << "calcNodeAdvance: temporarily unfunded offer (past)";
cLog(lsINFO) << "calcNodeAdvance: temporarily unfunded offer (past)";
bEntryAdvance = true;
continue;
@@ -201,7 +203,7 @@ TER RippleCalc::calcNodeAdvance(
if (bFoundReverse && itReverse->second != uIndex)
{
// Temporarily unfunded. Another node uses this source, ignore in this offer.
Log(lsINFO) << "calcNodeAdvance: temporarily unfunded offer (reverse)";
cLog(lsINFO) << "calcNodeAdvance: temporarily unfunded offer (reverse)";
bEntryAdvance = true;
continue;
@@ -215,7 +217,7 @@ TER RippleCalc::calcNodeAdvance(
if (!saOfferFunds.isPositive())
{
// Offer is unfunded.
Log(lsINFO) << "calcNodeAdvance: unfunded offer";
cLog(lsINFO) << "calcNodeAdvance: unfunded offer";
if (bReverse && !bFoundReverse && !bFoundPast)
{
@@ -233,7 +235,7 @@ TER RippleCalc::calcNodeAdvance(
&& !bFoundReverse) // Not mentioned for pass.
{
// Consider source mentioned by current path state.
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: remember=%s/%s/%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: remember=%s/%s/%s")
% NewcoinAddress::createHumanAccountID(uOfrOwnerID)
% STAmount::createHumanCurrency(uCurCurrencyID)
% NewcoinAddress::createHumanAccountID(uCurIssuerID));
@@ -249,11 +251,11 @@ TER RippleCalc::calcNodeAdvance(
if (tesSUCCESS == terResult)
{
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: uOfferIndex=%s") % uOfferIndex);
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: uOfferIndex=%s") % uOfferIndex);
}
else
{
Log(lsINFO) << boost::str(boost::format("calcNodeAdvance: terResult=%s") % transToken(terResult));
cLog(lsINFO) << boost::str(boost::format("calcNodeAdvance: terResult=%s") % transToken(terResult));
}
return terResult;
@@ -308,7 +310,7 @@ TER RippleCalc::calcNodeDeliverRev(
const STAmount saOutFeeRate = uOfrOwnerID == uCurIssuerID || uOutAccountID == uCurIssuerID // Issuer receiving or sending.
? saOne // No fee.
: saTransferRate; // Transfer rate of issuer.
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: uOfrOwnerID=%s uOutAccountID=%s uCurIssuerID=%s saTransferRate=%s saOutFeeRate=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: uOfrOwnerID=%s uOutAccountID=%s uCurIssuerID=%s saTransferRate=%s saOutFeeRate=%s")
% NewcoinAddress::createHumanAccountID(uOfrOwnerID)
% NewcoinAddress::createHumanAccountID(uOutAccountID)
% NewcoinAddress::createHumanAccountID(uCurIssuerID)
@@ -320,14 +322,14 @@ TER RippleCalc::calcNodeDeliverRev(
// Set initial rate.
saRateMax = saOutFeeRate;
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Set initial rate: saRateMax=%s saOutFeeRate=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Set initial rate: saRateMax=%s saOutFeeRate=%s")
% saRateMax
% saOutFeeRate);
}
else if (saRateMax < saOutFeeRate)
{
// Offer exceeds initial rate.
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Offer exceeds initial rate: saRateMax=%s saOutFeeRate=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Offer exceeds initial rate: saRateMax=%s saOutFeeRate=%s")
% saRateMax
% saOutFeeRate);
@@ -340,14 +342,14 @@ TER RippleCalc::calcNodeDeliverRev(
saRateMax = saOutFeeRate;
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Reducing rate: saRateMax=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Reducing rate: saRateMax=%s")
% saRateMax);
}
STAmount saOutPass = std::min(std::min(saOfferFunds, saTakerGets), saOutReq-saOutAct); // Offer maximum out - assuming no out fees.
STAmount saOutPlusFees = STAmount::multiply(saOutPass, saOutFeeRate); // Offer out with fees.
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: saOutReq=%s saOutAct=%s saTakerGets=%s saOutPass=%s saOutPlusFees=%s saOfferFunds=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: saOutReq=%s saOutAct=%s saTakerGets=%s saOutPass=%s saOutPlusFees=%s saOfferFunds=%s")
% saOutReq
% saOutAct
% saTakerGets
@@ -362,7 +364,7 @@ TER RippleCalc::calcNodeDeliverRev(
saOutPlusFees = saOfferFunds;
saOutPass = STAmount::divide(saOutPlusFees, saOutFeeRate);
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Total exceeds fees: saOutPass=%s saOutPlusFees=%s saOfferFunds=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: Total exceeds fees: saOutPass=%s saOutPlusFees=%s saOfferFunds=%s")
% saOutPass
% saOutPlusFees
% saOfferFunds);
@@ -373,7 +375,7 @@ TER RippleCalc::calcNodeDeliverRev(
STAmount saInPassReq = STAmount::multiply(saOutPass, saOfrRate, saTakerPays);
STAmount saInPassAct;
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: saInPassReq=%s saOfrRate=%s saOutPass=%s saOutPlusFees=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: saInPassReq=%s saOfrRate=%s saOutPass=%s saOutPlusFees=%s")
% saInPassReq
% saOfrRate
% saOutPass
@@ -390,7 +392,7 @@ TER RippleCalc::calcNodeDeliverRev(
saInPassAct = saInPassReq;
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: account --> OFFER --> ? : saInPassAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: account --> OFFER --> ? : saInPassAct=%s")
% saPrvDlvReq);
}
else
@@ -405,7 +407,7 @@ TER RippleCalc::calcNodeDeliverRev(
saInPassReq,
saInPassAct);
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: offer --> OFFER --> ? : saInPassAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: offer --> OFFER --> ? : saInPassAct=%s")
% saInPassAct);
}
@@ -418,7 +420,7 @@ TER RippleCalc::calcNodeDeliverRev(
saOutPass = STAmount::divide(saInPassAct, saOfrRate, saTakerGets);
saOutPlusFees = STAmount::multiply(saOutPass, saOutFeeRate);
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: adjusted: saOutPass=%s saOutPlusFees=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: adjusted: saOutPass=%s saOutPlusFees=%s")
% saOutPass
% saOutPlusFees);
}
@@ -438,7 +440,7 @@ TER RippleCalc::calcNodeDeliverRev(
if (saOutPass == saTakerGets)
{
// Offer became unfunded.
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: offer became unfunded."));
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: offer became unfunded."));
bEntryAdvance = true;
}
@@ -516,7 +518,7 @@ TER RippleCalc::calcNodeDeliverFwd(
STAmount saInPassFees;
STAmount saOutPassAct;
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: saOutFunded=%s saInFunded=%s saInTotal=%s saInSum=%s saInPassAct=%s saOutPassMax=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: saOutFunded=%s saInFunded=%s saInTotal=%s saInSum=%s saInPassAct=%s saOutPassMax=%s")
% saOutFunded
% saInFunded
% saInTotal
@@ -538,7 +540,7 @@ TER RippleCalc::calcNodeDeliverFwd(
saOutPassAct = saOutPassMax;
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: ? --> OFFER --> account: saOutPassAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: ? --> OFFER --> account: saOutPassAct=%s")
% saOutPassAct);
}
else
@@ -564,7 +566,7 @@ TER RippleCalc::calcNodeDeliverFwd(
saInPassFees = STAmount::multiply(saInFunded, saInFeeRate)-saInPassAct;
}
Log(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: saTakerGets=%s saTakerPays=%s saInPassAct=%s saOutPassAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: saTakerGets=%s saTakerPays=%s saInPassAct=%s saOutPassAct=%s")
% saTakerGets.getFullText()
% saTakerPays.getFullText()
% saInPassAct.getFullText()
@@ -696,7 +698,7 @@ void RippleCalc::calcNodeRipple(
STAmount& saCurAct, // <-> out limit achieved.
uint64& uRateMax)
{
Log(lsINFO) << boost::str(boost::format("calcNodeRipple> uQualityIn=%d uQualityOut=%d saPrvReq=%s saCurReq=%s saPrvAct=%s saCurAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple> uQualityIn=%d uQualityOut=%d saPrvReq=%s saCurReq=%s saPrvAct=%s saCurAct=%s")
% uQualityIn
% uQualityOut
% saPrvReq.getFullText()
@@ -711,7 +713,7 @@ void RippleCalc::calcNodeRipple(
const STAmount saCur = saCurReq-saCurAct;
#if 0
Log(lsINFO) << boost::str(boost::format("calcNodeRipple: bPrvUnlimited=%d saPrv=%s saCur=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple: bPrvUnlimited=%d saPrv=%s saCur=%s")
% bPrvUnlimited
% saPrv.getFullText()
% saCur.getFullText());
@@ -720,7 +722,7 @@ void RippleCalc::calcNodeRipple(
if (uQualityIn >= uQualityOut)
{
// No fee.
Log(lsINFO) << boost::str(boost::format("calcNodeRipple: No fees"));
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple: No fees"));
if (!uRateMax || STAmount::uRateOne <= uRateMax)
{
@@ -736,7 +738,7 @@ void RippleCalc::calcNodeRipple(
else
{
// Fee.
Log(lsINFO) << boost::str(boost::format("calcNodeRipple: Fee"));
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple: Fee"));
uint64 uRate = STAmount::getRate(STAmount(uQualityIn), STAmount(uQualityOut));
@@ -748,19 +750,19 @@ void RippleCalc::calcNodeRipple(
STAmount saCurIn = STAmount::divide(STAmount::multiply(saCur, uQualityOut, uCurrencyID, uCurIssuerID), uQualityIn, uCurrencyID, uCurIssuerID);
Log(lsINFO) << boost::str(boost::format("calcNodeRipple: bPrvUnlimited=%d saPrv=%s saCurIn=%s") % bPrvUnlimited % saPrv.getFullText() % saCurIn.getFullText());
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple: bPrvUnlimited=%d saPrv=%s saCurIn=%s") % bPrvUnlimited % saPrv.getFullText() % saCurIn.getFullText());
if (bPrvUnlimited || saCurIn <= saPrv)
{
// All of cur. Some amount of prv.
saCurAct += saCur;
saPrvAct += saCurIn;
Log(lsINFO) << boost::str(boost::format("calcNodeRipple:3c: saCurReq=%s saPrvAct=%s") % saCurReq.getFullText() % saPrvAct.getFullText());
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple:3c: saCurReq=%s saPrvAct=%s") % saCurReq.getFullText() % saPrvAct.getFullText());
}
else
{
// A part of cur. All of prv. (cur as driver)
STAmount saCurOut = STAmount::divide(STAmount::multiply(saPrv, uQualityIn, uCurrencyID, uCurIssuerID), uQualityOut, uCurrencyID, uCurIssuerID);
Log(lsINFO) << boost::str(boost::format("calcNodeRipple:4: saCurReq=%s") % saCurReq.getFullText());
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple:4: saCurReq=%s") % saCurReq.getFullText());
saCurAct += saCurOut;
saPrvAct = saPrvReq;
@@ -771,7 +773,7 @@ void RippleCalc::calcNodeRipple(
}
}
Log(lsINFO) << boost::str(boost::format("calcNodeRipple< uQualityIn=%d uQualityOut=%d saPrvReq=%s saCurReq=%s saPrvAct=%s saCurAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeRipple< uQualityIn=%d uQualityOut=%d saPrvReq=%s saCurReq=%s saPrvAct=%s saCurAct=%s")
% uQualityIn
% uQualityOut
% saPrvReq.getFullText()
@@ -819,7 +821,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
? lesActive.rippleOwed(uCurAccountID, uNxtAccountID, uCurrencyID)
: STAmount(uCurrencyID, uCurAccountID);
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev> uIndex=%d/%d uPrvAccountID=%s uCurAccountID=%s uNxtAccountID=%s uCurrencyID=%s uQualityIn=%d uQualityOut=%d saPrvOwed=%s saPrvLimit=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev> uIndex=%d/%d uPrvAccountID=%s uCurAccountID=%s uNxtAccountID=%s uCurrencyID=%s uQualityIn=%d uQualityOut=%d saPrvOwed=%s saPrvLimit=%s")
% uIndex
% uLast
% NewcoinAddress::createHumanAccountID(uPrvAccountID)
@@ -854,16 +856,18 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
const STAmount& saCurDeliverReq = pnCur.saRevDeliver;
STAmount saCurDeliverAct(saCurDeliverReq.getCurrency(), saCurDeliverReq.getIssuer());
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: saPrvRedeemReq=%s saPrvIssueReq=%s saCurRedeemReq=%s saNxtOwed=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: saPrvRedeemReq=%s saPrvIssueReq=%s saCurRedeemReq=%s saNxtOwed=%s")
% saPrvRedeemReq.getFullText()
% saPrvIssueReq.getFullText()
% saCurRedeemReq.getFullText()
% saNxtOwed.getFullText());
Log(lsINFO) << pspCur->getJson();
cLog(lsINFO) << pspCur->getJson();
assert(!saCurRedeemReq || (-saNxtOwed) >= saCurRedeemReq); // Current redeem req can't be more than IOUs on hand.
assert(!saCurIssueReq || !saNxtOwed.isPositive() || saNxtOwed == saCurRedeemReq); // If issue req, then redeem req must consume all owed.
assert(!saCurIssueReq // If not issuing, fine.
|| !saNxtOwed.isNegative() // Not hold next IOUs: owed is >= 0
|| saNxtOwed == saCurRedeemReq); // If issue req, then redeem req must consume all owed.
if (bPrvAccount && bNxtAccount)
{
@@ -882,14 +886,14 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
: pspCur->saOutReq; // Previous is an offer, no limit: redeem own IOUs.
STAmount saCurWantedAct(saCurWantedReq.getCurrency(), saCurWantedReq.getIssuer());
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: account --> ACCOUNT --> $ : saCurWantedReq=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: account --> ACCOUNT --> $ : saCurWantedReq=%s")
% saCurWantedReq.getFullText());
// Calculate redeem
if (saPrvRedeemReq) // Previous has IOUs to redeem.
{
// Redeem at 1:1
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Redeem at 1:1"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Redeem at 1:1"));
saCurWantedAct = std::min(saPrvRedeemReq, saCurWantedReq);
saPrvRedeemAct = saCurWantedAct;
@@ -902,7 +906,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
&& saPrvIssueReq) // Will accept IOUs from prevous.
{
// Rate: quality in : 1.0
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate: quality in : 1.0"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate: quality in : 1.0"));
// If we previously redeemed and this has a poorer rate, this won't be included the current increment.
calcNodeRipple(uQualityIn, QUALITY_ONE, saPrvIssueReq, saCurWantedReq, saPrvIssueAct, saCurWantedAct, uRateMax);
@@ -923,7 +927,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
&& saPrvRedeemReq) // Previous has IOUs to redeem.
{
// Rate : 1.0 : quality out
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate : 1.0 : quality out"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate : 1.0 : quality out"));
calcNodeRipple(QUALITY_ONE, uQualityOut, saPrvRedeemReq, saCurRedeemReq, saPrvRedeemAct, saCurRedeemAct, uRateMax);
}
@@ -933,7 +937,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
&& saPrvRedeemAct == saPrvRedeemReq) // Previous has no IOUs to redeem remaining.
{
// Rate: quality in : quality out
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate: quality in : quality out"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate: quality in : quality out"));
calcNodeRipple(uQualityIn, uQualityOut, saPrvIssueReq, saCurRedeemReq, saPrvIssueAct, saCurRedeemAct, uRateMax);
}
@@ -944,7 +948,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
&& saPrvRedeemAct != saPrvRedeemReq) // Did not complete redeeming previous IOUs.
{
// Rate : 1.0 : transfer_rate
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate : 1.0 : transfer_rate"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate : 1.0 : transfer_rate"));
calcNodeRipple(QUALITY_ONE, lesActive.rippleTransferRate(uCurAccountID), saPrvRedeemReq, saCurIssueReq, saPrvRedeemAct, saCurIssueAct, uRateMax);
}
@@ -955,7 +959,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
&& saPrvRedeemReq == saPrvRedeemAct) // Previously redeemed all owed IOUs.
{
// Rate: quality in : 1.0
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate: quality in : 1.0"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: Rate: quality in : 1.0"));
calcNodeRipple(uQualityIn, QUALITY_ONE, saPrvIssueReq, saCurIssueReq, saPrvIssueAct, saCurIssueAct, uRateMax);
}
@@ -966,7 +970,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
terResult = tepPATH_DRY;
}
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: ^|account --> ACCOUNT --> account : saCurRedeemReq=%s saCurIssueReq=%s saPrvOwed=%s saCurRedeemAct=%s saCurIssueAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: ^|account --> ACCOUNT --> account : saCurRedeemReq=%s saCurIssueReq=%s saPrvOwed=%s saCurRedeemAct=%s saCurIssueAct=%s")
% saCurRedeemReq.getFullText()
% saCurIssueReq.getFullText()
% saPrvOwed.getFullText()
@@ -978,7 +982,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
{
// account --> ACCOUNT --> offer
// Note: deliver is always issue as ACCOUNT is the issuer for the offer input.
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: account --> ACCOUNT --> offer"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: account --> ACCOUNT --> offer"));
// redeem -> deliver/issue.
if (saPrvOwed.isPositive() // Previous has IOUs to redeem.
@@ -1002,7 +1006,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
terResult = tepPATH_DRY;
}
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: saCurDeliverReq=%s saCurDeliverAct=%s saPrvOwed=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: saCurDeliverReq=%s saCurDeliverAct=%s saPrvOwed=%s")
% saCurDeliverReq.getFullText()
% saCurDeliverAct.getFullText()
% saPrvOwed.getFullText());
@@ -1017,7 +1021,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
: pspCur->saOutReq; // Previous is an offer, no limit: redeem own IOUs.
STAmount saCurWantedAct(saCurWantedReq.getCurrency(), saCurWantedReq.getIssuer());
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: offer --> ACCOUNT --> $ : saCurWantedReq=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: offer --> ACCOUNT --> $ : saCurWantedReq=%s")
% saCurWantedReq.getFullText());
// Rate: quality in : 1.0
@@ -1033,7 +1037,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
{
// offer --> ACCOUNT --> account
// Note: offer is always delivering(redeeming) as account is issuer.
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: offer --> ACCOUNT --> account"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: offer --> ACCOUNT --> account"));
// deliver -> redeem
if (saCurRedeemReq) // Next wants us to redeem.
@@ -1050,7 +1054,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
calcNodeRipple(QUALITY_ONE, lesActive.rippleTransferRate(uCurAccountID), saPrvDeliverReq, saCurIssueReq, saPrvDeliverAct, saCurIssueAct, uRateMax);
}
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: saCurRedeemReq=%s saCurIssueAct=%s saCurIssueReq=%s saPrvDeliverAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: saCurRedeemReq=%s saCurIssueAct=%s saCurIssueReq=%s saPrvDeliverAct=%s")
% saCurRedeemReq.getFullText()
% saCurRedeemAct.getFullText()
% saCurIssueReq.getFullText()
@@ -1067,7 +1071,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uIndex, const PathState::p
{
// offer --> ACCOUNT --> offer
// deliver/redeem -> deliver/issue.
Log(lsINFO) << boost::str(boost::format("calcNodeAccountRev: offer --> ACCOUNT --> offer"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountRev: offer --> ACCOUNT --> offer"));
// Rate : 1.0 : transfer_rate
calcNodeRipple(QUALITY_ONE, lesActive.rippleTransferRate(uCurAccountID), saPrvDeliverReq, saCurDeliverReq, saPrvDeliverAct, saCurDeliverAct, uRateMax);
@@ -1136,7 +1140,7 @@ TER RippleCalc::calcNodeAccountFwd(
const STAmount& saCurDeliverReq = pnCur.saRevDeliver;
STAmount& saCurDeliverAct = pnCur.saFwdDeliver;
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd> uIndex=%d/%d saPrvRedeemReq=%s saPrvIssueReq=%s saPrvDeliverReq=%s saCurRedeemReq=%s saCurIssueReq=%s saCurDeliverReq=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd> uIndex=%d/%d saPrvRedeemReq=%s saPrvIssueReq=%s saPrvDeliverReq=%s saCurRedeemReq=%s saCurIssueReq=%s saCurDeliverReq=%s")
% uIndex
% uLast
% saPrvRedeemReq.getFullText()
@@ -1192,7 +1196,7 @@ TER RippleCalc::calcNodeAccountFwd(
}
saCurSendMaxAct += saCurIssueAct;
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: ^ --> ACCOUNT --> account : saCurSendMaxReq=%s saCurRedeemAct=%s saCurIssueReq=%s saCurIssueAct=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: ^ --> ACCOUNT --> account : saCurSendMaxReq=%s saCurRedeemAct=%s saCurIssueReq=%s saCurIssueAct=%s")
% saCurSendMaxReq.getFullText()
% saCurRedeemAct.getFullText()
% saCurIssueReq.getFullText()
@@ -1201,7 +1205,7 @@ TER RippleCalc::calcNodeAccountFwd(
else if (uIndex == uLast)
{
// account --> ACCOUNT --> $
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> $ : uPrvAccountID=%s uCurAccountID=%s saPrvRedeemReq=%s saPrvIssueReq=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> $ : uPrvAccountID=%s uCurAccountID=%s saPrvRedeemReq=%s saPrvIssueReq=%s")
% NewcoinAddress::createHumanAccountID(uPrvAccountID)
% NewcoinAddress::createHumanAccountID(uCurAccountID)
% saPrvRedeemReq.getFullText()
@@ -1224,7 +1228,7 @@ TER RippleCalc::calcNodeAccountFwd(
else
{
// account --> ACCOUNT --> account
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> account"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> account"));
// Previous redeem part 1: redeem -> redeem
if (saPrvRedeemReq != saPrvRedeemAct) // Previous wants to redeem. To next must be ok.
@@ -1267,7 +1271,7 @@ TER RippleCalc::calcNodeAccountFwd(
else if (bPrvAccount && !bNxtAccount)
{
// account --> ACCOUNT --> offer
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> offer"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> offer"));
// redeem -> issue.
// wants to redeem and current would and can issue.
@@ -1295,7 +1299,7 @@ TER RippleCalc::calcNodeAccountFwd(
if (uIndex == uLast)
{
// offer --> ACCOUNT --> $
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: offer --> ACCOUNT --> $"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: offer --> ACCOUNT --> $"));
STAmount& saCurReceive = pspCur->saOutAct;
@@ -1307,7 +1311,7 @@ TER RippleCalc::calcNodeAccountFwd(
else
{
// offer --> ACCOUNT --> account
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: offer --> ACCOUNT --> account"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: offer --> ACCOUNT --> account"));
// deliver -> redeem
if (saPrvDeliverReq) // Previous wants to deliver.
@@ -1333,7 +1337,7 @@ TER RippleCalc::calcNodeAccountFwd(
{
// offer --> ACCOUNT --> offer
// deliver/redeem -> deliver/issue.
Log(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: offer --> ACCOUNT --> offer"));
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: offer --> ACCOUNT --> offer"));
if (saPrvDeliverReq // Previous wants to deliver
&& saCurIssueReq) // Current wants issue.
@@ -1377,7 +1381,7 @@ TER PathState::pushImply(
const PaymentNode& pnPrv = vpnNodes.back();
TER terResult = tesSUCCESS;
Log(lsINFO) << "pushImply> "
cLog(lsINFO) << "pushImply> "
<< NewcoinAddress::createHumanAccountID(uAccountID)
<< " " << STAmount::createHumanCurrency(uCurrencyID)
<< " " << NewcoinAddress::createHumanAccountID(uIssuerID);
@@ -1410,7 +1414,7 @@ TER PathState::pushImply(
uIssuerID);
}
Log(lsINFO) << "pushImply< " << terResult;
cLog(lsINFO) << "pushImply< " << terResult;
return terResult;
}
@@ -1423,7 +1427,7 @@ TER PathState::pushNode(
const uint160& uCurrencyID,
const uint160& uIssuerID)
{
Log(lsINFO) << "pushNode> "
cLog(lsINFO) << "pushNode> "
<< NewcoinAddress::createHumanAccountID(uAccountID)
<< " " << STAmount::createHumanCurrency(uCurrencyID)
<< "/" << NewcoinAddress::createHumanAccountID(uIssuerID);
@@ -1443,7 +1447,7 @@ TER PathState::pushNode(
if (iType & ~STPathElement::typeValidBits)
{
Log(lsINFO) << "pushNode: bad bits.";
cLog(lsINFO) << "pushNode: bad bits.";
terResult = temBAD_PATH;
}
@@ -1477,7 +1481,7 @@ TER PathState::pushNode(
if (!sleRippleState)
{
Log(lsINFO) << "pushNode: No credit line between "
cLog(lsINFO) << "pushNode: No credit line between "
<< NewcoinAddress::createHumanAccountID(pnBck.uAccountID)
<< " and "
<< NewcoinAddress::createHumanAccountID(pnCur.uAccountID)
@@ -1485,13 +1489,13 @@ TER PathState::pushNode(
<< STAmount::createHumanCurrency(pnPrv.uCurrencyID)
<< "." ;
Log(lsINFO) << getJson();
cLog(lsINFO) << getJson();
terResult = terNO_LINE;
}
else
{
Log(lsINFO) << "pushNode: Credit line found between "
cLog(lsINFO) << "pushNode: Credit line found between "
<< NewcoinAddress::createHumanAccountID(pnBck.uAccountID)
<< " and "
<< NewcoinAddress::createHumanAccountID(pnCur.uAccountID)
@@ -1531,7 +1535,7 @@ TER PathState::pushNode(
vpnNodes.push_back(pnCur);
}
}
Log(lsINFO) << "pushNode< " << terResult;
cLog(lsINFO) << "pushNode< " << terResult;
return terResult;
}
@@ -1608,7 +1612,7 @@ PathState::PathState(
else if (!umForward.insert(std::make_pair(boost::make_tuple(pnCur.uAccountID, pnCur.uCurrencyID, pnCur.uIssuerID), uIndex)).second)
{
// Failed to insert. Have a loop.
Log(lsINFO) << boost::str(boost::format("PathState: loop detected: %s")
cLog(lsINFO) << boost::str(boost::format("PathState: loop detected: %s")
% getJson());
terStatus = temBAD_PATH_LOOP;
@@ -1616,7 +1620,7 @@ PathState::PathState(
}
}
Log(lsINFO) << boost::str(boost::format("PathState: in=%s/%s out=%s/%s %s")
cLog(lsINFO) << boost::str(boost::format("PathState: in=%s/%s out=%s/%s %s")
% STAmount::createHumanCurrency(uInCurrencyID)
% NewcoinAddress::createHumanAccountID(uInIssuerID)
% STAmount::createHumanCurrency(uOutCurrencyID)
@@ -1697,7 +1701,7 @@ TER RippleCalc::calcNodeFwd(const unsigned int uIndex, const PathState::pointer&
const PaymentNode& pnCur = pspCur->vpnNodes[uIndex];
const bool bCurAccount = isSetBit(pnCur.uFlags, STPathElement::typeAccount);
Log(lsINFO) << boost::str(boost::format("calcNodeFwd> uIndex=%d") % uIndex);
cLog(lsINFO) << boost::str(boost::format("calcNodeFwd> uIndex=%d") % uIndex);
TER terResult = bCurAccount
? calcNodeAccountFwd(uIndex, pspCur, bMultiQuality)
@@ -1708,7 +1712,7 @@ TER RippleCalc::calcNodeFwd(const unsigned int uIndex, const PathState::pointer&
terResult = calcNodeFwd(uIndex+1, pspCur, bMultiQuality);
}
Log(lsINFO) << boost::str(boost::format("calcNodeFwd< uIndex=%d terResult=%d") % uIndex % terResult);
cLog(lsINFO) << boost::str(boost::format("calcNodeFwd< uIndex=%d terResult=%d") % uIndex % terResult);
return terResult;
}
@@ -1734,7 +1738,7 @@ TER RippleCalc::calcNodeRev(const unsigned int uIndex, const PathState::pointer&
saTransferRate = STAmount::saFromRate(lesActive.rippleTransferRate(uCurIssuerID));
Log(lsINFO) << boost::str(boost::format("calcNodeRev> uIndex=%d uIssuerID=%s saTransferRate=%s")
cLog(lsINFO) << boost::str(boost::format("calcNodeRev> uIndex=%d uIssuerID=%s saTransferRate=%s")
% uIndex
% NewcoinAddress::createHumanAccountID(uCurIssuerID)
% saTransferRate.getFullText());
@@ -1756,7 +1760,7 @@ TER RippleCalc::calcNodeRev(const unsigned int uIndex, const PathState::pointer&
terResult = calcNodeRev(uIndex-1, pspCur, bMultiQuality);
}
Log(lsINFO) << boost::str(boost::format("calcNodeRev< uIndex=%d terResult=%s/%d") % uIndex % transToken(terResult) % terResult);
cLog(lsINFO) << boost::str(boost::format("calcNodeRev< uIndex=%d terResult=%s/%d") % uIndex % transToken(terResult) % terResult);
return terResult;
}
@@ -1771,7 +1775,7 @@ void RippleCalc::pathNext(const PathState::pointer& pspCur, const int iPaths, co
const bool bMultiQuality = iPaths == 1;
const unsigned int uLast = pspCur->vpnNodes.size() - 1;
Log(lsINFO) << "Path In: " << pspCur->getJson();
cLog(lsINFO) << "Path In: " << pspCur->getJson();
assert(pspCur->vpnNodes.size() >= 2);
@@ -1783,7 +1787,7 @@ void RippleCalc::pathNext(const PathState::pointer& pspCur, const int iPaths, co
pspCur->terStatus = calcNodeRev(uLast, pspCur, bMultiQuality);
Log(lsINFO) << "Path after reverse: " << pspCur->getJson();
cLog(lsINFO) << "Path after reverse: " << pspCur->getJson();
if (tesSUCCESS == pspCur->terStatus)
{
@@ -1797,7 +1801,7 @@ void RippleCalc::pathNext(const PathState::pointer& pspCur, const int iPaths, co
? STAmount::getRate(pspCur->saOutAct, pspCur->saInAct) // Calculate relative quality.
: 0; // Mark path as inactive.
Log(lsINFO) << "Path after forward: " << pspCur->getJson();
cLog(lsINFO) << "Path after forward: " << pspCur->getJson();
}
}
@@ -1824,7 +1828,7 @@ TER RippleCalc::rippleCalc(
if (bNoRippleDirect && spsPaths.isEmpty())
{
Log(lsINFO) << "doPayment: Invalid transaction: No paths and direct ripple not allowed.";
cLog(lsINFO) << "doPayment: Invalid transaction: No paths and direct ripple not allowed.";
return temRIPPLE_EMPTY;
}
@@ -1836,7 +1840,7 @@ TER RippleCalc::rippleCalc(
{
// Direct path.
// XXX Might also make a stamp bridge by default.
Log(lsINFO) << "doPayment: Build direct:";
cLog(lsINFO) << "doPayment: Build direct:";
PathState::pointer pspDirect = PathState::createPathState(
vpsPaths.size(),
@@ -1863,11 +1867,11 @@ TER RippleCalc::rippleCalc(
}
}
Log(lsINFO) << "doPayment: Paths in set: " << spsPaths.getPathCount();
cLog(lsINFO) << "doPayment: Paths in set: " << spsPaths.getPathCount();
BOOST_FOREACH(const STPath& spPath, spsPaths)
{
Log(lsINFO) << "doPayment: Build path:";
cLog(lsINFO) << "doPayment: Build path:";
PathState::pointer pspExpanded = PathState::createPathState(
vpsPaths.size(),
@@ -2099,7 +2103,7 @@ void TransactionEngine::calcOfferBridgeNext(
if (sleOffer->isFieldPresent(sfExpiration) && sleOffer->getFieldU32(sfExpiration) <= mLedger->getParentCloseTimeNC())
{
// Offer is expired.
Log(lsINFO) << "calcOfferFirst: encountered expired offer";
cLog(lsINFO) << "calcOfferFirst: encountered expired offer";
}
else
{
@@ -2133,7 +2137,7 @@ void TransactionEngine::calcOfferBridgeNext(
if (!saOfferFunds.isPositive())
{
// Offer is unfunded.
Log(lsINFO) << "calcOfferFirst: offer unfunded: delete";
cLog(lsINFO) << "calcOfferFirst: offer unfunded: delete";
}
else if (saOfferFunds >= saOfferPays)
{

View File

@@ -1,7 +1,11 @@
#include "RippleLines.h"
#include <boost/foreach.hpp>
#include "Application.h"
#include "Log.h"
#include <boost/foreach.hpp>
SETUP_LOG();
RippleLines::RippleLines(const uint160& accountID, Ledger::pointer ledger)
{
@@ -47,7 +51,7 @@ void RippleLines::fillLines(const uint160& accountID, Ledger::pointer ledger)
}
else
{
Log(lsWARNING) << "doRippleLinesGet: Bad index: " << uNode.ToString();
cLog(lsWARNING) << "doRippleLinesGet: Bad index: " << uNode.ToString();
}
}
}

View File

@@ -15,6 +15,8 @@
#include "SHAMap.h"
#include "Application.h"
SETUP_LOG();
std::size_t hash_value(const SHAMapNode& mn)
{
std::size_t seed = theApp->getNonceST();
@@ -662,7 +664,7 @@ bool SHAMap::updateGiveItem(const SHAMapItem::pointer& item, bool isTransaction,
if (!node->setItem(item, !isTransaction ? SHAMapTreeNode::tnACCOUNT_STATE :
(hasMeta ? SHAMapTreeNode::tnTRANSACTION_MD : SHAMapTreeNode::tnTRANSACTION_NM)))
{
Log(lsWARNING) << "SHAMap setItem, no change";
cLog(lsWARNING) << "SHAMap setItem, no change";
return true;
}
@@ -695,7 +697,7 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, const ui
}
catch (...)
{
Log(lsWARNING) << "fetchNodeExternal gets an invalid node: " << hash;
cLog(lsWARNING) << "fetchNodeExternal gets an invalid node: " << hash;
throw SHAMapMissingNode(id, hash);
}
}
@@ -792,7 +794,7 @@ BOOST_AUTO_TEST_SUITE(SHAMap_suite)
BOOST_AUTO_TEST_CASE( SHAMap_test )
{ // h3 and h4 differ only in the leaf, same terminal node (level 19)
Log(lsTRACE) << "SHAMap test";
cLog(lsTRACE) << "SHAMap test";
uint256 h1, h2, h3, h4, h5;
h1.SetHex("092891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
h2.SetHex("436ccbac3347baa1f1e53baeef1f43334da88f1f6d70d963b833afd6dfa289fe");
@@ -828,7 +830,7 @@ BOOST_AUTO_TEST_CASE( SHAMap_test )
i = sMap.peekNextItem(i->getTag());
if (i) BOOST_FAIL("bad traverse");
Log(lsTRACE) << "SHAMap snap test";
cLog(lsTRACE) << "SHAMap snap test";
uint256 mapHash = sMap.getHash();
SHAMap::pointer map2 = sMap.snapShot(false);
if (sMap.getHash() != mapHash) BOOST_FAIL("bad snapshot");

View File

@@ -23,10 +23,6 @@ class SHAMap;
class SHAMapNode
{ // Identifies a node in a SHA256 hash
public:
typedef boost::shared_ptr<SHAMapNode> pointer;
typedef const boost::shared_ptr<SHAMapNode>& ref;
private:
static uint256 smMasks[65]; // AND with hash to get node id
@@ -84,7 +80,8 @@ inline std::ostream& operator<<(std::ostream& out, const SHAMapNode& node) { ret
class SHAMapItem
{ // an item stored in a SHAMap
public:
typedef boost::shared_ptr<SHAMapItem> pointer;
typedef boost::shared_ptr<SHAMapItem> pointer;
typedef const boost::shared_ptr<SHAMapItem>& ref;
private:
uint256 mTag;
@@ -136,7 +133,8 @@ class SHAMapTreeNode : public SHAMapNode
friend class SHAMap;
public:
typedef boost::shared_ptr<SHAMapTreeNode> pointer;
typedef boost::shared_ptr<SHAMapTreeNode> pointer;
typedef const boost::shared_ptr<SHAMapTreeNode>& ref;
enum TNType
{
@@ -163,7 +161,7 @@ private:
public:
SHAMapTreeNode(uint32 seq, const SHAMapNode& nodeID); // empty node
SHAMapTreeNode(const SHAMapTreeNode& node, uint32 seq); // copy node from older tree
SHAMapTreeNode(const SHAMapNode& nodeID, const SHAMapItem::pointer& item, TNType type, uint32 seq);
SHAMapTreeNode(const SHAMapNode& nodeID, SHAMapItem::ref item, TNType type, uint32 seq);
// raw node functions
SHAMapTreeNode(const SHAMapNode& id, const std::vector<unsigned char>& data, uint32 seq, SHANodeFormat format);
@@ -200,7 +198,7 @@ public:
// item node function
bool hasItem() const { return !!mItem; }
SHAMapItem::pointer peekItem() { return mItem; }
SHAMapItem::ref peekItem() { return mItem; }
SHAMapItem::pointer getItem() const;
bool setItem(const SHAMapItem::pointer& i, TNType type);
const uint256& getTag() const { return mItem->getTag(); }
@@ -292,7 +290,7 @@ protected:
SHAMapItem::pointer onlyBelow(SHAMapTreeNode*);
void eraseChildren(SHAMapTreeNode::pointer);
bool walkBranch(SHAMapTreeNode* node, SHAMapItem::pointer otherMapItem, bool isFirstMap,
bool walkBranch(SHAMapTreeNode* node, SHAMapItem::ref otherMapItem, bool isFirstMap,
SHAMapDiff& differences, int& maxCount);
public:
@@ -321,8 +319,8 @@ public:
uint256 getHash() { return root->getNodeHash(); }
// save a copy if you have a temporary anyway
bool updateGiveItem(const SHAMapItem::pointer&, bool isTransaction, bool hasMeta);
bool addGiveItem(const SHAMapItem::pointer&, bool isTransaction, bool hasMeta);
bool updateGiveItem(SHAMapItem::ref, bool isTransaction, bool hasMeta);
bool addGiveItem(SHAMapItem::ref, bool isTransaction, bool hasMeta);
// save a copy if you only need a temporary
SHAMapItem::pointer peekItem(const uint256& id);

View File

@@ -20,13 +20,15 @@ class SHAMapDiffNode
mNodeID(id), mOurHash(ourHash), mOtherHash(otherHash) { ; }
};
bool SHAMap::walkBranch(SHAMapTreeNode* node, SHAMapItem::pointer otherMapItem, bool isFirstMap,
bool SHAMap::walkBranch(SHAMapTreeNode* node, SHAMapItem::ref otherMapItem, bool isFirstMap,
SHAMapDiff& differences, int& maxCount)
{
// Walk a branch of a SHAMap that's matched by an empty branch or single item in the other map
std::stack<SHAMapTreeNode*> nodeStack;
nodeStack.push(node);
bool emptyBranch = !otherMapItem;
while (!nodeStack.empty())
{
SHAMapTreeNode* node = nodeStack.top();
@@ -41,7 +43,7 @@ bool SHAMap::walkBranch(SHAMapTreeNode* node, SHAMapItem::pointer otherMapItem,
{ // This is a leaf node, process its item
SHAMapItem::pointer item = node->getItem();
if (otherMapItem && (otherMapItem->getTag() < item->getTag()))
if (!emptyBranch && (otherMapItem->getTag() < item->getTag()))
{ // this item comes after the item from the other map, so add the other item
if (isFirstMap) // this is first map, so other item is from second
differences.insert(std::make_pair(otherMapItem->getTag(),
@@ -49,11 +51,12 @@ bool SHAMap::walkBranch(SHAMapTreeNode* node, SHAMapItem::pointer otherMapItem,
else
differences.insert(std::make_pair(otherMapItem->getTag(),
std::make_pair(otherMapItem, SHAMapItem::pointer())));
if (--maxCount <= 0) return false;
otherMapItem = SHAMapItem::pointer();
if (--maxCount <= 0)
return false;
emptyBranch = true;
}
if ((!otherMapItem) || (item->getTag() < otherMapItem->getTag()))
if (emptyBranch || (item->getTag() < otherMapItem->getTag()))
{ // unmatched
if (isFirstMap)
differences.insert(std::make_pair(item->getTag(), std::make_pair(item, SHAMapItem::pointer())));
@@ -77,7 +80,7 @@ bool SHAMap::walkBranch(SHAMapTreeNode* node, SHAMapItem::pointer otherMapItem,
}
}
if (otherMapItem)
if (!emptyBranch)
{ // otherMapItem was unmatched, must add
if (isFirstMap) // this is first map, so other item is from second
differences.insert(std::make_pair(otherMapItem->getTag(),

View File

@@ -11,6 +11,8 @@
#include "Log.h"
SETUP_LOG();
void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max,
SHAMapSyncFilter* filter)
{
@@ -26,7 +28,7 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
if (!root->isInner())
{
Log(lsWARNING) << "synching empty tree";
cLog(lsWARNING) << "synching empty tree";
return;
}
@@ -61,12 +63,12 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
d = boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq, snfPREFIX);
if (childHash != d->getNodeHash())
{
Log(lsERROR) << "Wrong hash from cached object";
cLog(lsERROR) << "Wrong hash from cached object";
d = SHAMapTreeNode::pointer();
}
else
{
Log(lsTRACE) << "Got sync node from cache: " << *d;
cLog(lsTRACE) << "Got sync node from cache: " << *d;
mTNByID[*d] = d;
}
}
@@ -136,7 +138,7 @@ bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeForm
// we already have a root node
if (root->getNodeHash().isNonZero())
{
Log(lsTRACE) << "got root node, already have one";
cLog(lsTRACE) << "got root node, already have one";
return true;
}
@@ -168,7 +170,7 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>&
// we already have a root node
if (root->getNodeHash().isNonZero())
{
Log(lsTRACE) << "got root node, already have one";
cLog(lsTRACE) << "got root node, already have one";
assert(root->getNodeHash() == hash);
return true;
}
@@ -216,15 +218,15 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
if (iNode->isLeaf() || (iNode->getDepth() == node.getDepth()))
{
Log(lsTRACE) << "got inner node, already had it (late)";
cLog(lsTRACE) << "got inner node, already had it (late)";
return true;
}
if (iNode->getDepth() != (node.getDepth() - 1))
{ // Either this node is broken or we didn't request it (yet)
Log(lsINFO) << "unable to hook node " << node;
Log(lsINFO) << " stuck at " << *iNode;
Log(lsINFO) << "got depth=" << node.getDepth() << ", walked to= " << iNode->getDepth();
cLog(lsINFO) << "unable to hook node " << node;
cLog(lsINFO) << " stuck at " << *iNode;
cLog(lsINFO) << "got depth=" << node.getDepth() << ", walked to= " << iNode->getDepth();
return false;
}
@@ -295,16 +297,16 @@ bool SHAMap::deepCompare(SHAMap& other)
if (!otherNode)
{
Log(lsINFO) << "unable to fetch node";
cLog(lsINFO) << "unable to fetch node";
return false;
}
else if (otherNode->getNodeHash() != node->getNodeHash())
{
Log(lsWARNING) << "node hash mismatch";
cLog(lsWARNING) << "node hash mismatch";
return false;
}
// Log(lsTRACE) << "Comparing inner nodes " << *node;
// cLog(lsTRACE) << "Comparing inner nodes " << *node;
if (node->getNodeHash() != otherNode->getNodeHash())
return false;
@@ -329,7 +331,7 @@ bool SHAMap::deepCompare(SHAMap& other)
SHAMapTreeNode::pointer next = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if (!next)
{
Log(lsWARNING) << "unable to fetch inner node";
cLog(lsWARNING) << "unable to fetch inner node";
return false;
}
stack.push(next);
@@ -365,7 +367,7 @@ static bool confuseMap(SHAMap &map, int count)
items.push_back(item->getTag());
if (!map.addItem(*item, false, false))
{
Log(lsFATAL) << "Unable to add item to map";
cLog(lsFATAL) << "Unable to add item to map";
return false;
}
}
@@ -374,14 +376,14 @@ static bool confuseMap(SHAMap &map, int count)
{
if (!map.delItem(*it))
{
Log(lsFATAL) << "Unable to remove item from map";
cLog(lsFATAL) << "Unable to remove item from map";
return false;
}
}
if (beforeHash != map.getHash())
{
Log(lsFATAL) << "Hashes do not match";
cLog(lsFATAL) << "Hashes do not match";
return false;
}
@@ -412,26 +414,26 @@ BOOST_AUTO_TEST_SUITE( SHAMapSync )
BOOST_AUTO_TEST_CASE( SHAMapSync_test )
{
Log(lsTRACE) << "being sync test";
cLog(lsTRACE) << "being sync test";
unsigned int seed;
RAND_pseudo_bytes(reinterpret_cast<unsigned char *>(&seed), sizeof(seed));
srand(seed);
Log(lsTRACE) << "Constructing maps";
cLog(lsTRACE) << "Constructing maps";
SHAMap source, destination;
// add random data to the source map
Log(lsTRACE) << "Adding random data";
cLog(lsTRACE) << "Adding random data";
int items = 10000;
for (int i = 0; i < items; ++i)
source.addItem(*makeRandomAS(), false, false);
Log(lsTRACE) << "Adding items, then removing them";
cLog(lsTRACE) << "Adding items, then removing them";
if (!confuseMap(source, 500)) BOOST_FAIL("ConfuseMap");
source.setImmutable();
Log(lsTRACE) << "SOURCE COMPLETE, SYNCHING";
cLog(lsTRACE) << "SOURCE COMPLETE, SYNCHING";
std::vector<SHAMapNode> nodeIDs, gotNodeIDs;
std::list< std::vector<unsigned char> > gotNodes;
@@ -447,23 +449,23 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
if (!source.getNodeFat(SHAMapNode(), nodeIDs, gotNodes, (rand() % 2) == 0, (rand() % 2) == 0))
{
Log(lsFATAL) << "GetNodeFat(root) fails";
cLog(lsFATAL) << "GetNodeFat(root) fails";
BOOST_FAIL("GetNodeFat");
}
if (gotNodes.size() < 1)
{
Log(lsFATAL) << "Didn't get root node " << gotNodes.size();
cLog(lsFATAL) << "Didn't get root node " << gotNodes.size();
BOOST_FAIL("NodeSize");
}
if (!destination.addRootNode(*gotNodes.begin(), snfWIRE))
{
Log(lsFATAL) << "AddRootNode fails";
cLog(lsFATAL) << "AddRootNode fails";
BOOST_FAIL("AddRootNode");
}
nodeIDs.clear();
gotNodes.clear();
Log(lsINFO) << "ROOT COMPLETE, INNER SYNCHING";
cLog(lsINFO) << "ROOT COMPLETE, INNER SYNCHING";
#ifdef SMS_DEBUG
int bytes = 0;
#endif
@@ -477,14 +479,14 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
destination.getMissingNodes(nodeIDs, hashes, 2048, NULL);
if (nodeIDs.empty()) break;
Log(lsINFO) << nodeIDs.size() << " needed nodes";
cLog(lsINFO) << nodeIDs.size() << " needed nodes";
// get as many nodes as possible based on this information
for (nodeIDIterator = nodeIDs.begin(); nodeIDIterator != nodeIDs.end(); ++nodeIDIterator)
{
if (!source.getNodeFat(*nodeIDIterator, gotNodeIDs, gotNodes, (rand() % 2) == 0, (rand() % 2) == 0))
{
Log(lsFATAL) << "GetNodeFat fails";
cLog(lsFATAL) << "GetNodeFat fails";
BOOST_FAIL("GetNodeFat");
}
}
@@ -494,11 +496,11 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
if (gotNodeIDs.empty())
{
Log(lsFATAL) << "No nodes gotten";
cLog(lsFATAL) << "No nodes gotten";
BOOST_FAIL("Got Node ID");
}
Log(lsTRACE) << gotNodeIDs.size() << " found nodes";
cLog(lsTRACE) << gotNodeIDs.size() << " found nodes";
for (nodeIDIterator = gotNodeIDs.begin(), rawNodeIterator = gotNodes.begin();
nodeIDIterator != gotNodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
{
@@ -508,7 +510,7 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
#endif
if (!destination.addKnownNode(*nodeIDIterator, *rawNodeIterator, NULL))
{
Log(lsTRACE) << "AddKnownNode fails";
cLog(lsTRACE) << "AddKnownNode fails";
BOOST_FAIL("AddKnownNode");
}
}
@@ -520,18 +522,18 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
destination.clearSynching();
#ifdef SMS_DEBUG
Log(lsINFO) << "SYNCHING COMPLETE " << items << " items, " << nodes << " nodes, " <<
cLog(lsINFO) << "SYNCHING COMPLETE " << items << " items, " << nodes << " nodes, " <<
bytes / 1024 << " KB";
#endif
if (!source.deepCompare(destination))
{
Log(lsFATAL) << "DeepCompare fails";
cLog(lsFATAL) << "DeepCompare fails";
BOOST_FAIL("Deep Compare");
}
#ifdef SMS_DEBUG
Log(lsINFO) << "SHAMapSync test passed: " << items << " items, " <<
cLog(lsINFO) << "SHAMapSync test passed: " << items << " items, " <<
passes << " passes, " << nodes << " nodes";
#endif

View File

@@ -30,7 +30,6 @@
FIELD(TransactionType, UINT16, 2)
// 32-bit integers (common)
FIELD(ObjectType, UINT32, 1)
FIELD(Flags, UINT32, 2)
FIELD(SourceTag, UINT32, 3)
FIELD(Sequence, UINT32, 4)
@@ -91,7 +90,7 @@
FIELD(Fee, AMOUNT, 8)
FIELD(SendMax, AMOUNT, 9)
// current amount (uncommon)
// currency amount (uncommon)
FIELD(MinimumOffer, AMOUNT, 16)
FIELD(RippleEscrow, AMOUNT, 17)
@@ -113,8 +112,6 @@
FIELD(Owner, ACCOUNT, 2)
FIELD(Destination, ACCOUNT, 3)
FIELD(Issuer, ACCOUNT, 4)
FIELD(HighID, ACCOUNT, 5)
FIELD(LowID, ACCOUNT, 6)
FIELD(Target, ACCOUNT, 7)
FIELD(AuthorizedKey, ACCOUNT, 8)

View File

@@ -11,6 +11,7 @@
#include "Log.h"
#include "LedgerFormats.h"
#include "TransactionFormats.h"
#include "SerializedTransaction.h"
std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, SField::ref name)
{
@@ -153,7 +154,7 @@ bool STObject::setType(const std::vector<SOElement::ptr> &type)
{
if (elem->flags != SOE_OPTIONAL)
{
Log(lsTRACE) << "setType !valid missing";
Log(lsWARNING) << "setType !valid missing " << elem->e_field.fieldName;
valid = false;
}
newData.push_back(makeNonPresentObject(elem->e_field));
@@ -163,8 +164,14 @@ bool STObject::setType(const std::vector<SOElement::ptr> &type)
}
if (mData.size() != 0)
{
Log(lsTRACE) << "setType !valid leftover";
valid = false;
BOOST_FOREACH(const SerializedType& t, mData)
{
if (!t.getFName().isDiscardable())
{
Log(lsWARNING) << "setType !valid leftover: " << t.getFName().getName();
valid = false;
}
}
}
mData.swap(newData);
return valid;
@@ -367,11 +374,15 @@ const SerializedType* STObject::peekAtPField(SField::ref field) const
return peekAtPIndex(index);
}
SerializedType* STObject::getPField(SField::ref field)
SerializedType* STObject::getPField(SField::ref field, bool createOkay)
{
int index = getFieldIndex(field);
if (index == -1)
{
if (createOkay && isFree())
return getPIndex(giveObject(makeDefaultObject(field)));
return NULL;
}
return getPIndex(index);
}
@@ -385,7 +396,7 @@ bool STObject::isFieldPresent(SField::ref field) const
bool STObject::setFlag(uint32 f)
{
STUInt32* t = dynamic_cast<STUInt32*>(getPField(sfFlags));
STUInt32* t = dynamic_cast<STUInt32*>(getPField(sfFlags, true));
if (!t)
return false;
t->setValue(t->getValue() | f);
@@ -413,7 +424,11 @@ SerializedType* STObject::makeFieldPresent(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
throw std::runtime_error("Field not found");
{
if (!isFree())
throw std::runtime_error("Field not found");
return getPIndex(giveObject(makeNonPresentObject(field)));
}
SerializedType* f = getPIndex(index);
if (f->getSType() != STI_NOTPRESENT)
@@ -619,7 +634,7 @@ STVector256 STObject::getFieldV256(SField::ref field) const
void STObject::setFieldU8(SField::ref field, unsigned char v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STUInt8* cf = dynamic_cast<STUInt8*>(rf);
@@ -629,7 +644,7 @@ void STObject::setFieldU8(SField::ref field, unsigned char v)
void STObject::setFieldU16(SField::ref field, uint16 v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STUInt16* cf = dynamic_cast<STUInt16*>(rf);
@@ -639,7 +654,7 @@ void STObject::setFieldU16(SField::ref field, uint16 v)
void STObject::setFieldU32(SField::ref field, uint32 v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STUInt32* cf = dynamic_cast<STUInt32*>(rf);
@@ -649,7 +664,7 @@ void STObject::setFieldU32(SField::ref field, uint32 v)
void STObject::setFieldU64(SField::ref field, uint64 v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STUInt64* cf = dynamic_cast<STUInt64*>(rf);
@@ -659,7 +674,7 @@ void STObject::setFieldU64(SField::ref field, uint64 v)
void STObject::setFieldH128(SField::ref field, const uint128& v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STHash128* cf = dynamic_cast<STHash128*>(rf);
@@ -669,7 +684,7 @@ void STObject::setFieldH128(SField::ref field, const uint128& v)
void STObject::setFieldH160(SField::ref field, const uint160& v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STHash160* cf = dynamic_cast<STHash160*>(rf);
@@ -679,7 +694,7 @@ void STObject::setFieldH160(SField::ref field, const uint160& v)
void STObject::setFieldH256(SField::ref field, const uint256& v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STHash256* cf = dynamic_cast<STHash256*>(rf);
@@ -689,7 +704,7 @@ void STObject::setFieldH256(SField::ref field, const uint256& v)
void STObject::setFieldV256(SField::ref field, const STVector256& v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STVector256* cf = dynamic_cast<STVector256*>(rf);
@@ -699,7 +714,7 @@ void STObject::setFieldV256(SField::ref field, const STVector256& v)
void STObject::setFieldAccount(SField::ref field, const uint160& v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STAccount* cf = dynamic_cast<STAccount*>(rf);
@@ -709,7 +724,7 @@ void STObject::setFieldAccount(SField::ref field, const uint160& v)
void STObject::setFieldVL(SField::ref field, const std::vector<unsigned char>& v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STVariableLength* cf = dynamic_cast<STVariableLength*>(rf);
@@ -719,7 +734,7 @@ void STObject::setFieldVL(SField::ref field, const std::vector<unsigned char>& v
void STObject::setFieldAmount(SField::ref field, const STAmount &v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STAmount* cf = dynamic_cast<STAmount*>(rf);
@@ -729,7 +744,7 @@ void STObject::setFieldAmount(SField::ref field, const STAmount &v)
void STObject::setFieldPathSet(SField::ref field, const STPathSet &v)
{
SerializedType* rf = getPField(field);
SerializedType* rf = getPField(field, true);
if (!rf) throw std::runtime_error("Field not found");
if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field);
STPathSet* cf = dynamic_cast<STPathSet*>(rf);
@@ -939,7 +954,7 @@ std::auto_ptr<STObject> STObject::parseJson(const Json::Value& object, SField::r
case STI_UINT64:
if (value.isString())
data.push_back(new STUInt64(field, lexical_cast_st<uint64>(value.asString())));
data.push_back(new STUInt64(field, uintFromHex(value.asString())));
else if (value.isInt())
data.push_back(new STUInt64(field,
range_check_cast<uint64>(value.asInt(), 0, 18446744073709551615ull)));
@@ -1116,6 +1131,7 @@ std::auto_ptr<STObject> STObject::parseJson(const Json::Value& object, SField::r
throw std::runtime_error("Invalid field type");
}
}
return std::auto_ptr<STObject>(new STObject(*name, data));
}

View File

@@ -51,6 +51,7 @@ public:
bool setType(const std::vector<SOElement::ptr>& type);
bool isValidForType();
bool isFieldAllowed(SField::ref);
bool isFree() const { return mType.empty(); }
void set(const std::vector<SOElement::ptr>&);
bool set(SerializerIterator& u, int depth = 0);
@@ -95,7 +96,7 @@ public:
const SerializedType& peekAtField(SField::ref field) const;
SerializedType& getField(SField::ref field);
const SerializedType* peekAtPField(SField::ref field) const;
SerializedType* getPField(SField::ref field);
SerializedType* getPField(SField::ref field, bool createOkay = false);
// these throw if the field type doesn't match, or return default values if the
// field is optional but not present

View File

@@ -17,6 +17,19 @@ SerializedTransaction::SerializedTransaction(TransactionType type) : STObject(sf
setFieldU16(sfTransactionType, mFormat->t_type);
}
SerializedTransaction::SerializedTransaction(const STObject& object) : STObject(object)
{
mType = static_cast<TransactionType>(getFieldU16(sfTransactionType));
mFormat = TransactionFormat::getTxnFormat(mType);
if (!mFormat)
throw std::runtime_error("invalid transaction type");
if (!setType(mFormat->elements))
{
assert(false);
throw std::runtime_error("transaction not valid");
}
}
SerializedTransaction::SerializedTransaction(SerializerIterator& sit) : STObject(sfTransaction)
{
int length = sit.getBytesLeft();
@@ -209,9 +222,9 @@ BOOST_AUTO_TEST_CASE( STrans_test )
Log(lsFATAL) << copy.getJson(0);
BOOST_FAIL("Transaction fails serialize/deserialize test");
}
Log(lsINFO) << "ORIG: " << j.getJson(0);
std::auto_ptr<STObject> new_obj = STObject::parseJson(j.getJson(0), sfGeneric);
if (new_obj.get() == NULL) BOOST_FAIL("Unable to build object from json");
Log(lsINFO) << "ORIG: " << j.getJson(0);
Log(lsINFO) << "BUILT " << new_obj->getJson(0);
}

View File

@@ -31,6 +31,7 @@ protected:
public:
SerializedTransaction(SerializerIterator& sit);
SerializedTransaction(TransactionType type);
SerializedTransaction(const STObject &object);
// STObject functions
SerializedTypeID getSType() const { return STI_TRANSACTION; }

View File

@@ -64,6 +64,11 @@ std::string STUInt8::getText() const
return boost::lexical_cast<std::string>(value);
}
Json::Value STUInt8::getJson(int) const
{
return value;
}
bool STUInt8::isEquivalent(const SerializedType& t) const
{
const STUInt8* v = dynamic_cast<const STUInt8*>(&t);
@@ -92,6 +97,23 @@ std::string STUInt16::getText() const
return boost::lexical_cast<std::string>(value);
}
Json::Value STUInt16::getJson(int) const
{
if (getFName() == sfLedgerEntryType)
{
LedgerEntryFormat *f = LedgerEntryFormat::getLgrFormat(value);
if (f != NULL)
return f->t_name;
}
if (getFName() == sfTransactionType)
{
TransactionFormat *f = TransactionFormat::getTxnFormat(value);
if (f != NULL)
return f->t_name;
}
return value;
}
bool STUInt16::isEquivalent(const SerializedType& t) const
{
const STUInt16* v = dynamic_cast<const STUInt16*>(&t);
@@ -108,6 +130,11 @@ std::string STUInt32::getText() const
return boost::lexical_cast<std::string>(value);
}
Json::Value STUInt32::getJson(int) const
{
return value;
}
bool STUInt32::isEquivalent(const SerializedType& t) const
{
const STUInt32* v = dynamic_cast<const STUInt32*>(&t);
@@ -124,6 +151,11 @@ std::string STUInt64::getText() const
return boost::lexical_cast<std::string>(value);
}
Json::Value STUInt64::getJson(int) const
{
return strHex(value);
}
bool STUInt64::isEquivalent(const SerializedType& t) const
{
const STUInt64* v = dynamic_cast<const STUInt64*>(&t);

View File

@@ -97,6 +97,7 @@ public:
SerializedTypeID getSType() const { return STI_UINT8; }
std::string getText() const;
Json::Value getJson(int) const;
void add(Serializer& s) const { s.add8(value); }
unsigned char getValue() const { return value; }
@@ -123,6 +124,7 @@ public:
SerializedTypeID getSType() const { return STI_UINT16; }
std::string getText() const;
Json::Value getJson(int) const;
void add(Serializer& s) const { s.add16(value); }
uint16 getValue() const { return value; }
@@ -149,6 +151,7 @@ public:
SerializedTypeID getSType() const { return STI_UINT32; }
std::string getText() const;
Json::Value getJson(int) const;
void add(Serializer& s) const { s.add32(value); }
uint32 getValue() const { return value; }
@@ -175,6 +178,7 @@ public:
SerializedTypeID getSType() const { return STI_UINT64; }
std::string getText() const;
Json::Value getJson(int) const;
void add(Serializer& s) const { s.add64(value); }
uint64 getValue() const { return value; }

View File

@@ -13,6 +13,8 @@
#include "TransactionFormats.h"
#include "utils.h"
SETUP_LOG();
void TransactionEngine::txnWrite()
{
// Write back the account states
@@ -32,7 +34,7 @@ void TransactionEngine::txnWrite()
case taaCREATE:
{
Log(lsINFO) << "applyTransaction: taaCREATE: " << sleEntry->getText();
cLog(lsINFO) << "applyTransaction: taaCREATE: " << sleEntry->getText();
if (mLedger->writeBack(lepCREATE, sleEntry) & lepERROR)
assert(false);
@@ -41,7 +43,7 @@ void TransactionEngine::txnWrite()
case taaMODIFY:
{
Log(lsINFO) << "applyTransaction: taaMODIFY: " << sleEntry->getText();
cLog(lsINFO) << "applyTransaction: taaMODIFY: " << sleEntry->getText();
if (mLedger->writeBack(lepNONE, sleEntry) & lepERROR)
assert(false);
@@ -50,7 +52,7 @@ void TransactionEngine::txnWrite()
case taaDELETE:
{
Log(lsINFO) << "applyTransaction: taaDELETE: " << sleEntry->getText();
cLog(lsINFO) << "applyTransaction: taaDELETE: " << sleEntry->getText();
if (!mLedger->peekAccountStateMap()->delItem(it->first))
assert(false);
@@ -62,7 +64,7 @@ void TransactionEngine::txnWrite()
TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineParams params)
{
Log(lsTRACE) << "applyTransaction>";
cLog(lsTRACE) << "applyTransaction>";
assert(mLedger);
mNodes.init(mLedger, txn.getTransactionID(), mLedger->getLedgerSeq());
@@ -75,10 +77,10 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
SerializedTransaction s2(sit);
if (!s2.isEquivalent(txn))
{
Log(lsFATAL) << "Transaction serdes mismatch";
cLog(lsFATAL) << "Transaction serdes mismatch";
Json::StyledStreamWriter ssw;
ssw.write(Log(lsINFO).ref(), txn.getJson(0));
ssw.write(Log(lsFATAL).ref(), s2.getJson(0));
cLog(lsINFO) << txn.getJson(0);
cLog(lsFATAL) << s2.getJson(0);
assert(false);
}
}
@@ -88,7 +90,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
uint256 txID = txn.getTransactionID();
if (!txID)
{
Log(lsWARNING) << "applyTransaction: invalid transaction id";
cLog(lsWARNING) << "applyTransaction: invalid transaction id";
terResult = temINVALID;
}
@@ -110,7 +112,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
// Consistency: really signed.
if ((tesSUCCESS == terResult) && !isSetBit(params, tapNO_CHECK_SIGN) && !txn.checkSign(naSigningPubKey))
{
Log(lsWARNING) << "applyTransaction: Invalid transaction: bad signature";
cLog(lsWARNING) << "applyTransaction: Invalid transaction: bad signature";
terResult = temINVALID;
}
@@ -153,12 +155,12 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
break;
case ttINVALID:
Log(lsWARNING) << "applyTransaction: Invalid transaction: ttINVALID transaction type";
cLog(lsWARNING) << "applyTransaction: Invalid transaction: ttINVALID transaction type";
terResult = temINVALID;
break;
default:
Log(lsWARNING) << "applyTransaction: Invalid transaction: unknown transaction type";
cLog(lsWARNING) << "applyTransaction: Invalid transaction: unknown transaction type";
terResult = temUNKNOWN;
break;
}
@@ -173,7 +175,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
// Only check fee is sufficient when the ledger is open.
if (isSetBit(params, tapOPEN_LEDGER) && saPaid < saCost)
{
Log(lsINFO) << "applyTransaction: insufficient fee";
cLog(lsINFO) << "applyTransaction: insufficient fee";
terResult = telINSUF_FEE_P;
}
@@ -183,7 +185,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
if (saPaid)
{
// Transaction is malformed.
Log(lsWARNING) << "applyTransaction: fee not allowed";
cLog(lsWARNING) << "applyTransaction: fee not allowed";
terResult = temINSUF_FEE_P;
}
@@ -194,7 +196,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
mTxnAccountID = txn.getSourceAccount().getAccountID();
if (tesSUCCESS == terResult && !mTxnAccountID)
{
Log(lsWARNING) << "applyTransaction: bad source id";
cLog(lsWARNING) << "applyTransaction: bad source id";
terResult = temINVALID;
}
@@ -215,7 +217,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
if (!mTxnAccount)
{
Log(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") %
cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") %
txn.getSourceAccount().humanAccountID());
terResult = terNO_ACCOUNT;
@@ -234,7 +236,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
case ttCLAIM:
if (bHaveAuthKey)
{
Log(lsWARNING) << "applyTransaction: Account already claimed.";
cLog(lsWARNING) << "applyTransaction: Account already claimed.";
terResult = tefCLAIMED;
}
@@ -257,8 +259,8 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
if (naSigningPubKey.getAccountID() != mTxnAccountID)
{
// Signing Pub Key must be for Source Account ID.
Log(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID();
Log(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID();
cLog(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID();
cLog(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID();
terResult = tefBAD_CLAIM_ID;
}
@@ -270,8 +272,8 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
if (naSigningPubKey.getAccountID() != mTxnAccountID)
{
// Signing Pub Key must be for Source Account ID.
Log(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID();
Log(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID();
cLog(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID();
cLog(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID();
terResult = temBAD_SET_ID;
}
@@ -291,13 +293,13 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
}
else if (bHaveAuthKey)
{
Log(lsINFO) << "applyTransaction: Delay: Not authorized to use account.";
cLog(lsINFO) << "applyTransaction: Delay: Not authorized to use account.";
terResult = tefBAD_AUTH;
}
else
{
Log(lsINFO) << "applyTransaction: Invalid: Not authorized to use account.";
cLog(lsINFO) << "applyTransaction: Invalid: Not authorized to use account.";
terResult = temBAD_AUTH_MASTER;
}
@@ -313,7 +315,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
}
else if (saSrcBalance < saPaid)
{
Log(lsINFO)
cLog(lsINFO)
<< boost::str(boost::format("applyTransaction: Delay: insufficient balance: balance=%s paid=%s")
% saSrcBalance.getText()
% saPaid.getText());
@@ -334,13 +336,13 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
{
uint32 a_seq = mTxnAccount->getFieldU32(sfSequence);
Log(lsTRACE) << "Aseq=" << a_seq << ", Tseq=" << t_seq;
cLog(lsTRACE) << "Aseq=" << a_seq << ", Tseq=" << t_seq;
if (t_seq != a_seq)
{
if (a_seq < t_seq)
{
Log(lsINFO) << "applyTransaction: future sequence number";
cLog(lsINFO) << "applyTransaction: future sequence number";
terResult = terPRE_SEQ;
}
@@ -348,7 +350,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
terResult = tefALREADY;
else
{
Log(lsWARNING) << "applyTransaction: past sequence number";
cLog(lsWARNING) << "applyTransaction: past sequence number";
terResult = tefPAST_SEQ;
}
@@ -360,11 +362,11 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
}
else
{
Log(lsINFO) << "applyTransaction: Zero cost transaction";
cLog(lsINFO) << "applyTransaction: Zero cost transaction";
if (t_seq)
{
Log(lsINFO) << "applyTransaction: bad sequence for pre-paid transaction";
cLog(lsINFO) << "applyTransaction: bad sequence for pre-paid transaction";
terResult = tefPAST_SEQ;
}
@@ -389,7 +391,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
break;
case ttINVALID:
Log(lsINFO) << "applyTransaction: invalid type";
cLog(lsINFO) << "applyTransaction: invalid type";
terResult = temINVALID;
break;
@@ -443,7 +445,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
transResultInfo(terResult, strToken, strHuman);
Log(lsINFO) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman;
cLog(lsINFO) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman;
if (isTepPartial(terResult) && isSetBit(params, tapRETRY))
{

View File

@@ -42,6 +42,8 @@
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
SETUP_LOG();
UniqueNodeList::UniqueNodeList(boost::asio::io_service& io_service) :
mdtScoreTimer(io_service),
mFetchActive(0),
@@ -612,7 +614,7 @@ void UniqueNodeList::processIps(const std::string& strSite, const NewcoinAddress
std::string strEscNodePublic = sqlEscape(naNodePublic.humanNodePublic());
Log(lsINFO)
cLog(lsDEBUG)
<< str(boost::format("Validator: '%s' processing %d ips.")
% strSite % ( pmtVecStrIps ? pmtVecStrIps->size() : 0));
@@ -716,7 +718,7 @@ int UniqueNodeList::processValidators(const std::string& strSite, const std::str
if (!boost::regex_match(strReferral, smMatch, reReferral))
{
Log(lsWARNING) << str(boost::format("Bad validator: syntax error: %s: %s") % strSite % strReferral);
cLog(lsWARNING) << str(boost::format("Bad validator: syntax error: %s: %s") % strSite % strReferral);
}
else
{
@@ -727,7 +729,7 @@ int UniqueNodeList::processValidators(const std::string& strSite, const std::str
if (naValidator.setSeedGeneric(strRefered))
{
Log(lsWARNING) << str(boost::format("Bad validator: domain or public key required: %s %s") % strRefered % strComment);
cLog(lsWARNING) << str(boost::format("Bad validator: domain or public key required: %s %s") % strRefered % strComment);
}
else if (naValidator.setNodePublic(strRefered))
{
@@ -735,7 +737,7 @@ int UniqueNodeList::processValidators(const std::string& strSite, const std::str
// XXX Schedule for CAS lookup.
nodeAddPublic(naValidator, vsWhy, strComment);
Log(lsINFO) << str(boost::format("Node Public: %s %s") % strRefered % strComment);
cLog(lsINFO) << str(boost::format("Node Public: %s %s") % strRefered % strComment);
if (naNodePublic.isValid())
vstrValues.push_back(str(boost::format("('%s',%d,'%s')") % strNodePublic % iValues % naValidator.humanNodePublic()));
@@ -747,7 +749,7 @@ int UniqueNodeList::processValidators(const std::string& strSite, const std::str
// A domain: need to look it up.
nodeAddDomain(strRefered, vsWhy, strComment);
Log(lsINFO) << str(boost::format("Node Domain: %s %s") % strRefered % strComment);
cLog(lsINFO) << str(boost::format("Node Domain: %s %s") % strRefered % strComment);
if (naNodePublic.isValid())
vstrValues.push_back(str(boost::format("('%s',%d,%s)") % strNodePublic % iValues % sqlEscape(strRefered)));
@@ -1577,7 +1579,7 @@ void UniqueNodeList::nodeBootstrap()
// Always merge in the file specified in the config.
if (!theConfig.UNL_DEFAULT.empty())
{
Log(lsINFO) << "Bootstrapping UNL: loading from unl_default.";
cLog(lsINFO) << "Bootstrapping UNL: loading from unl_default.";
bLoaded = nodeLoad(theConfig.UNL_DEFAULT);
}
@@ -1585,7 +1587,7 @@ void UniqueNodeList::nodeBootstrap()
// If never loaded anything try the current directory.
if (!bLoaded && theConfig.UNL_DEFAULT.empty())
{
Log(lsINFO) << "Bootstrapping UNL: loading from '" VALIDATORS_FILE_NAME "'.";
cLog(lsINFO) << "Bootstrapping UNL: loading from '" VALIDATORS_FILE_NAME "'.";
bLoaded = nodeLoad(VALIDATORS_FILE_NAME);
}
@@ -1595,7 +1597,7 @@ void UniqueNodeList::nodeBootstrap()
{
NewcoinAddress naInvalid; // Don't want a referrer on added entries.
Log(lsINFO) << "Bootstrapping UNL: loading from " CONFIG_FILE_NAME ".";
cLog(lsINFO) << "Bootstrapping UNL: loading from " CONFIG_FILE_NAME ".";
if (processValidators("local", CONFIG_FILE_NAME, naInvalid, vsConfig, &theConfig.VALIDATORS))
bLoaded = true;
@@ -1603,7 +1605,7 @@ void UniqueNodeList::nodeBootstrap()
if (!bLoaded)
{
Log(lsINFO) << "Bootstrapping UNL: loading from " << theConfig.VALIDATORS_SITE << ".";
cLog(lsINFO) << "Bootstrapping UNL: loading from " << theConfig.VALIDATORS_SITE << ".";
nodeNetwork();
}

View File

@@ -7,7 +7,7 @@
#include "LedgerTiming.h"
#include "Log.h"
// #define VC_DEBUG
SETUP_LOG();
bool ValidationCollection::addValidation(const SerializedValidation::pointer& val)
{
@@ -21,9 +21,14 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va
if ((now > (valClose - LEDGER_EARLY_INTERVAL)) && (now < (valClose + LEDGER_VAL_INTERVAL)))
isCurrent = true;
else
Log(lsWARNING) << "Received stale validation now=" << now << ", close=" << valClose;
{
cLog(lsWARNING) << "Received stale validation now=" << now << ", close=" << valClose;
}
}
else
{
cLog(lsINFO) << "Node " << signer.humanNodePublic() << " not in UNL";
}
else Log(lsINFO) << "Node " << signer.humanNodePublic() << " not in UNL";
uint256 hash = val->getLedgerHash();
uint160 node = signer.getNodeID();
@@ -49,7 +54,7 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va
}
}
Log(lsINFO) << "Val for " << hash << " from " << signer.humanNodePublic()
cLog(lsINFO) << "Val for " << hash << " from " << signer.humanNodePublic()
<< " added " << (val->isTrusted() ? "trusted/" : "UNtrusted/") << (isCurrent ? "current" : "stale");
return isCurrent;
}
@@ -84,9 +89,7 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren
isTrusted = false;
else
{
#ifdef VC_DEBUG
Log(lsINFO) << "VC: Untrusted due to time " << ledger;
#endif
cLog(lsTRACE) << "VC: Untrusted due to time " << ledger;
}
}
if (isTrusted)
@@ -95,9 +98,7 @@ void ValidationCollection::getValidationCount(const uint256& ledger, bool curren
++untrusted;
}
}
#ifdef VC_DEBUG
Log(lsINFO) << "VC: " << ledger << "t:" << trusted << " u:" << untrusted;
#endif
cLog(lsTRACE) << "VC: " << ledger << "t:" << trusted << " u:" << untrusted;
}
int ValidationCollection::getTrustedValidationCount(const uint256& ledger)

View File

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

View File

@@ -2,6 +2,7 @@
#include "uint256.h"
#include <boost/asio.hpp>
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
//
@@ -67,6 +68,16 @@ std::vector<unsigned char> strUnHex(const std::string& strSrc)
return strCopy(strTmp);
}
uint64_t uintFromHex(const std::string& strSrc)
{
uint64_t uValue = 0;
BOOST_FOREACH(char c, strSrc)
uValue = (uValue << 4) | charUnHex(c);
return uValue;
}
//
// Misc string
//

View File

@@ -25,11 +25,22 @@ extern uint64_t be64toh(uint64_t value);
extern uint32_t htobe32(uint32_t value);
extern uint32_t be32toh(uint32_t value);
#elif __APPLE__
#define be16toh(x) betoh16(x)
#define be32toh(x) betoh32(x)
#define be64toh(x) betoh64(x)
#define h64tobe(x) htobe64(x)
#define h32tobe(x) htobe32(x)
#include <libkern/OSByteOrder.h>
#define htobe16(x) OSSwapHostToBigInt16(x)
#define htole16(x) OSSwapHostToLittleInt16(x)
#define be16toh(x) OSSwapBigToHostInt16(x)
#define le16toh(x) OSSwapLittleToHostInt16(x)
#define htobe32(x) OSSwapHostToBigInt32(x)
#define htole32(x) OSSwapHostToLittleInt32(x)
#define be32toh(x) OSSwapBigToHostInt32(x)
#define le32toh(x) OSSwapLittleToHostInt32(x)
#define htobe64(x) OSSwapHostToBigInt64(x)
#define htole64(x) OSSwapHostToLittleInt64(x)
#define be64toh(x) OSSwapBigToHostInt64(x)
#define le64toh(x) OSSwapLittleToHostInt64(x)
#endif
@@ -151,6 +162,8 @@ bool isZero(Iterator first, int iSize)
int charUnHex(char cDigit);
void strUnHex(std::string& strDst, const std::string& strSrc);
uint64_t uintFromHex(const std::string& strSrc);
std::vector<unsigned char> strUnHex(const std::string& strSrc);
std::vector<unsigned char> strCopy(const std::string& strSrc);

View File

@@ -28,37 +28,37 @@ exports.accounts = {
// Users
'alice' : {
'account' : 'iG1QQv2nh2gi7RCZ1P8YYcBUKCCN633jCn',
'passphrase' : 'alice',
'secret' : 'alice',
},
'bob' : {
'account' : 'iPMh7Pr9ct699rZUTWaytJUoHcJ7cgyzrK',
'passphrase' : 'bob',
'secret' : 'bob',
},
'carol' : {
'account' : 'iH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW',
'passphrase' : 'carol',
'secret' : 'carol',
},
// Nexuses
'bitstamp' : {
'account' : 'i4jKmc2nQb5yEU6eycefrNKGHTU5NQJASx',
'passphrase' : 'bitstamp',
'secret' : 'bitstamp',
},
'mtgox' : {
'account' : 'iGrhwhaqU8g7ahwAvTq6rX5ivsfcbgZw6v',
'passphrase' : 'mtgox',
'secret' : 'mtgox',
},
// Merchants
'amazon' : {
'account' : 'ihheXqX7bDnXePJeMHhubDDvw2uUTtenPd',
'passphrase' : 'amazon',
'secret' : 'amazon',
},
// Master account
'root' : {
'account' : 'iHb9CJAWyB4ij91VRWn96DkukG4bwdtyTh',
'passphrase' : 'masterpassphrase',
'secret' : 'masterpassphrase',
},
};

View File

@@ -52,6 +52,7 @@ Server.method('serverSpawnSync', function() {
config.newcoind,
[
"-a",
"-v",
"--conf=newcoind.cfg"
],
{

View File

@@ -1,17 +1,35 @@
var fs = require("fs");
var buster = require("buster");
var server = require("./server.js");
var remote = require("../js/remote.js");
var config = require("./config.js");
var server = require("./server.js");
var remote = require("../js/remote.js");
var utils = require("../js/utils.js");
var config = require("./config.js");
// How long to wait for server to start.
var serverDelay = 1500;
buster.testRunner.timeout = 5000;
buster.testCase("Utils", {
"hexToString and stringToHex" : {
"Even: 123456" : function () {
buster.assert.equals("123456", utils.stringToHex(utils.hexToString("123456")));
},
"Odd: 12345" : function () {
buster.assert.equals("012345", utils.stringToHex(utils.hexToString("12345")));
},
"Under 10: 0" : function () {
buster.assert.equals("00", utils.stringToHex(utils.hexToString("0")));
},
"Under 10: 1" : function () {
buster.assert.equals("01", utils.stringToHex(utils.hexToString("1")));
}
}
});
buster.testCase("Standalone server startup", {
"server start and stop": function (done) {
"server start and stop" : function (done) {
server.start("alpha",
function (e) {
buster.refute(e);
@@ -184,6 +202,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