Permalink
Browse files

Reworked inflation arithmetic using BigInteger.

Added few inflation tests.
Moving to latest stellar-lib revision.
  • Loading branch information...
marco89nish committed May 21, 2014
1 parent aef9589 commit 89506ac40b3477367de73519a4353323e24ed14a
Showing with 267 additions and 9 deletions.
  1. +1 −1 node_modules/stellar-lib
  2. +35 −7 src/ripple_app/transactors/InflationTransactor.cpp
  3. +231 −1 test/inflation.js
@@ -19,7 +19,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "InflationTransactor.h"
#define INFLATION_FREQUENCY (60*60*24*30) // every 30 days
#define INFLATION_RATE (1.01/(INFLATION_FREQUENCY/365)) // 1% a year
//inflation is 0.000817609695 per 30 days, or 1% a year
#define INFLATION_RATE_TRILLIONTHS 817609695L
#define TRILLION 1000000000000L
#define INFLATION_NUM_WINNERS 5
#define INFLATION_WIN_MIN_PERCENT .1
#define INFLATION_START_TIME (1397088000-946684800) // seconds since 1/1/2000
@@ -39,6 +41,12 @@ namespace ripple {
return p1.second > p2.second;
}
uint64 bigIntegerToUint64(beast::BigInteger& bigInt){
uint64 res = bigInt.getBitRangeAsInt(0, 32) + ( ((uint64)bigInt.getBitRangeAsInt(32, 32)) << 32 );
return res;
}
SETUP_LOG(InflationTransactor)
@@ -115,7 +123,8 @@ namespace ripple {
totalVoted += sortedVotes[n].second;
}else
{
maxIndex = n;
if (totalVoted)
maxIndex = n;
break;
}
}
@@ -128,13 +137,32 @@ namespace ripple {
}
}
uint64 coinsToDole = INFLATION_RATE*(mEngine->getLedger()->getFeePool()+mEngine->getLedger()->getTotalCoins());
//uint64 coinsLeft = coinsToDole;
// TODO: Is there better way to cast uint64 to signed int64? (There is no constructor using uint64)
beast::BigInteger biCoinsToDole { (int64) mEngine->getLedger()->getTotalCoins() };
beast::BigInteger inflRateMultiplier { (int64) INFLATION_RATE_TRILLIONTHS };
beast::BigInteger inflRateDivider { (int64) TRILLION };
beast::BigInteger poolFee { (int64) mEngine->getLedger()->getFeePool() };
/// coinsToDole = totalCoins * INFLATION_RATE + feePool
biCoinsToDole *= inflRateMultiplier;
biCoinsToDole /= inflRateDivider;
biCoinsToDole += poolFee;
beast::BigInteger biTotalVoted { (int64)totalVoted };
for (int n = 0; n < maxIndex; n++)
{
double share=sortedVotes[n].second/totalVoted;
uint64 coinsDoled = share*coinsToDole;
//coinsLeft -= coinsDoled;
/// coinsDoled = coinToDole * ( votes / totalVoted )
beast::BigInteger biCoinsDoled { (int64)sortedVotes[n].second };
biCoinsDoled *= biCoinsToDole;
biCoinsDoled /= biTotalVoted;
uint64 coinsDoled = bigIntegerToUint64(biCoinsDoled);
SLE::pointer account = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(sortedVotes[n].first));
if (account)
View
@@ -8,7 +8,12 @@ var config = testutils.init_config();
suite('Inflation', function() {
var $ = { };
var TOTAL_MONEY = 100000000000000000;
var INFLATION_RATE = 0.000817609695;
var INFLATION_ROUND = TOTAL_MONEY * INFLATION_RATE;
/* var INFLATION_UP_LIMIT = INFLATION_ROUND * 1.0001;
var INFLATION_DOWN_LIMIT = INFLATION_ROUND * 0.9999;
*/
setup(function(done) {
testutils.build_setup().call($, done);
});
@@ -71,6 +76,231 @@ suite('Inflation', function() {
done();
});
});
test('Inflation #1 - all to one destination', function(done) {
var self = this;
var start_balance = 0;
var tx_fee = 15; //TODO: get tx fee
var steps = [
function (callback) {
self.what = "Create accounts.";
testutils.create_accounts($.remote, "root", "10000.0", ["alice", "bob", "carol", "mtgox"], callback);
},
function (callback) {
self.what = "Set InflationDest #1";
$.remote.transaction()
.account_set("alice")
.inflation_dest($.remote.account('carol')._account_id)
.on('submitted', function (m) {
if (m.engine_result === 'tesSUCCESS') {
$.remote.ledger_accept(); // Move it along.
callback(null);
} else {
callback(new Error(m.engine_result));
}
})
.submit();
},
function (callback) {
self.what = "Set InflationDest #2";
$.remote.transaction()
.account_set("bob")
.inflation_dest($.remote.account('carol')._account_id)
.on('submitted', function (m) {
if (m.engine_result === 'tesSUCCESS') {
$.remote.ledger_accept(); // Move it along.
callback(null);
} else {
callback(new Error(m.engine_result));
}
})
.submit();
},
function (callback) {
self.what = "Check starting balance";
$.remote.requestAccountBalance($.remote.account('carol')._account_id, 'current', null)
.on('success', function (m) {
start_balance = m.node.Balance;
callback();
}).request();
},
function (callback) {
self.what = "Do inflation";
$.remote.transaction()
.inflation($.remote.account('root')._account_id, 1)
.on('submitted', function (m) {
if (m.engine_result === 'tesSUCCESS') {
callback(null);
} else {
callback(new Error(m.engine_result));
}
})
.on('error', function (m) {
console.log('error: %s', JSON.stringify(m));
callback(m);
})
.submit();
},
function (callback) {
self.what = "Check final balance";
$.remote.requestAccountBalance($.remote.account('carol')._account_id, 'current', null)
.on('success', function (m) {
var diff = m.node.Balance - start_balance;
assert( diff >= INFLATION_ROUND );
assert( diff < (INFLATION_ROUND + tx_fee*15) ); // 10 tx fees
callback();
}).request();
},
function(callback)
{
$.remote.ledger_accept(); // Move it along.
callback(null);
},
]
async.waterfall(steps,function (error) {
assert(!error, self.what);
done();
});
});
test('Inflation #2 - 50/50 split', function(done) {
var self = this;
var start_balance = 10000000000;
var tx_fee = 15; //TODO: get tx fee
var steps = [
function (callback) {
self.what = "Create accounts.";
testutils.create_accounts($.remote, "root", "10000.0", ["alice", "bob", "carol", "mtgox"], callback);
},
function (callback) {
self.what = "Set InflationDest #1";
$.remote.transaction()
.account_set("alice")
.inflation_dest($.remote.account('carol')._account_id)
.on('submitted', function (m) {
if (m.engine_result === 'tesSUCCESS') {
$.remote.ledger_accept(); // Move it along.
callback(null);
} else {
callback(new Error(m.engine_result));
}
})
.submit();
},
function (callback) {
self.what = "Set InflationDest #2";
$.remote.transaction()
.account_set("bob")
.inflation_dest($.remote.account('mtgox')._account_id)
.on('submitted', function (m) {
if (m.engine_result === 'tesSUCCESS') {
$.remote.ledger_accept(); // Move it along.
callback(null);
} else {
callback(new Error(m.engine_result));
}
})
.submit();
},
function (callback) {
self.what = "Do inflation";
$.remote.transaction()
.inflation($.remote.account('root')._account_id, 1)
.on('submitted', function (m) {
if (m.engine_result === 'tesSUCCESS') {
$.remote.ledger_accept(); // Move it along.
callback(null);
} else {
callback(new Error(m.engine_result));
}
})
.on('error', function (m) {
console.log('error: %s', JSON.stringify(m));
callback(m);
})
.submit();
},
function (callback) {
self.what = "Display ledger";
$.remote.request_ledger('current', true)
.on('success', function (m) {
//console.log("Ledger: %s", JSON.stringify(m, undefined, 2));
callback();
}).on('error', function(m) {
console.log("error: %s", JSON.stringify(m));
callback();
}).request();
},
function (callback) {
self.what = "Check mtgox's balance"; // async task, could take forever :)
$.remote.requestAccountBalance($.remote.account('mtgox')._account_id, 'current', null)
.on('success', function (m) {
var diff = m.node.Balance - start_balance; // diff == -850,000BTC
//console.log(diff);
assert( diff >= INFLATION_ROUND/2 );
assert( diff < (INFLATION_ROUND/2 + tx_fee*15) ); // 10 tx fees
callback();
}).request();
},
function (callback) {
self.what = "Check carol's balance";
$.remote.requestAccountBalance($.remote.account('carol')._account_id, 'current', null)
.on('success', function (m) {
var diff = m.node.Balance - start_balance;
//console.log(diff);
assert( diff >= INFLATION_ROUND/2 );
assert( diff < (INFLATION_ROUND/2 + tx_fee*15) ); // 10 tx fees
callback();
}).request();
},
]
async.waterfall(steps,function (error) {
assert(!error, self.what);
done();
});
});
});
// vim:sw=2:sts=2:ts=8:et

0 comments on commit 89506ac

Please sign in to comment.