Merge #330: add option to subtract fee from peg-out output amount

ed63547 add basic peg-out functional testing (Gregory Sanders)
0328059 add optional subtract fee argument to sendtomainchain (Gregory Sanders)
This commit is contained in:
Gregory Sanders 2018-04-05 16:38:26 -07:00
commit 0beeae51ce
No known key found for this signature in database
GPG key ID: F3F68E2D86A48FDB
3 changed files with 60 additions and 4 deletions

View file

@ -173,6 +173,13 @@ try:
addr = bitcoin.getnewaddress()
# First, blackhole all 21M bitcoin that already exist(and test subtractfrom)
assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == 21000000)
sidechain.sendtomainchain(addr, 21000000, True)
assert("bitcoin" not in sidechain.getwalletinfo()["balance"])
sidechain.generate(101)
addrs = sidechain.getpeginaddress()
txid1 = bitcoin.sendtoaddress(addrs["mainchain_address"], 24)
# 10+2 confirms required to get into mempool and confirm
@ -296,6 +303,48 @@ try:
# is awaiting further validation, nodes reject subsequent blocks
# even ones they create
sync_all(sidechain, sidechain2, False)
print("Now send funds out in two stages, partial, and full")
some_btc_addr = bitcoin.getnewaddress()
bal_1 = sidechain.getwalletinfo()["balance"]["bitcoin"]
try:
sidechain.sendtomainchain(some_btc_addr, bal_1 + 1)
raise Exception("Sending out too much; should have failed")
except JSONRPCException as e:
assert("Insufficient funds" in e.error["message"])
pass
assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == bal_1)
try:
sidechain.sendtomainchain(some_btc_addr+"b", bal_1 - 1)
raise Exception("Sending to invalid address; should have failed")
except JSONRPCException as e:
assert("Invalid Bitcoin address" in e.error["message"])
pass
assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == bal_1)
try:
sidechain.sendtomainchain("1Nro9WkpaKm9axmcfPVp79dAJU1Gx7VmMZ", bal_1 - 1)
raise Exception("Sending to mainchain address when should have been testnet; should have failed")
except JSONRPCException as e:
assert("Invalid Bitcoin address" in e.error["message"])
pass
assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == bal_1)
peg_out_txid = sidechain.sendtomainchain(some_btc_addr, 1)
peg_out_details = sidechain.decoderawtransaction(sidechain.getrawtransaction(peg_out_txid))
# peg-out, change, fee(which is the last)
assert(len(peg_out_details["vout"]) == 3)
assert(peg_out_details["vout"][0]["value"] == 1 or peg_out_details["vout"][1]["value"] == 1)
bal_2 = sidechain.getwalletinfo()["balance"]["bitcoin"]
# Make sure balance went down
assert(bal_2 + 1 < bal_1)
sidechain.sendtomainchain(some_btc_addr, bal_2, True)
assert("bitcoin" not in sidechain.getwalletinfo()["balance"])
print("Success!")

View file

@ -137,6 +137,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getmempooldescendants", 1, "verbose" },
{ "bumpfee", 1, "options" },
{ "testproposedblock", 1, "acceptnonstd" },
{ "sendtomainchain", 2, "subtractfeefromamount"},
// Echo with conversion (For testing only)
{ "echojson", 0, "arg0" },
{ "echojson", 1, "arg1" },

View file

@ -3446,14 +3446,15 @@ UniValue sendtomainchain(const JSONRPCRequest& request)
if (!EnsureWalletIsAvailable(request.fHelp))
return NullUniValue;
if (request.fHelp || request.params.size() != 2)
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
throw runtime_error(
"sendtomainchain mainchainaddress amount\n"
"sendtomainchain mainchainaddress amount ( subtractfeefromamount )\n"
"\nSends sidechain funds to the given mainchain address, through the federated withdraw mechanism\n"
+ HelpRequiringPassphrase() +
"\nArguments:\n"
"1. \"address\" (string, required) The destination address on Bitcoin mainchain\n"
"2. \"amount\" (numeric, required) The amount being sent to Bitcoin mainchain\n"
"3. \"subtractfeefromamount\" (boolean, optional, default=false) The fee will be deducted from the amount being pegged-out.\n"
"\nResult:\n"
"\"txid\" (string) Transaction ID of the resulting sidechain transaction\n"
"\nExamples:\n"
@ -3473,6 +3474,11 @@ UniValue sendtomainchain(const JSONRPCRequest& request)
if (nAmount <= 0)
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
bool subtract_fee = false;
if (request.params.size() > 2) {
subtract_fee = request.params[2].get_bool();
}
// Parse Bitcoin address for destination, embed script
CScript scriptPubKeyMainchain(GetScriptForDestination(address.Get()));
@ -3487,7 +3493,7 @@ UniValue sendtomainchain(const JSONRPCRequest& request)
EnsureWalletIsUnlocked();
CWalletTx wtxNew;
SendMoney(scriptPubKey, nAmount, Params().GetConsensus().pegged_asset, false, CPubKey(), wtxNew, true);
SendMoney(scriptPubKey, nAmount, Params().GetConsensus().pegged_asset, subtract_fee, CPubKey(), wtxNew, true);
std::string blinds;
for (unsigned int i=0; i<wtxNew.tx->vout.size(); i++) {
@ -4118,7 +4124,7 @@ static const CRPCCommand commands[] =
{ "wallet", "setaccount", &setaccount, true, {"address","account"} },
{ "wallet", "reissueasset", &reissueasset, true, {"asset", "assetamount"} },
{ "wallet", "signblock", &signblock, true, {} },
{ "wallet", "sendtomainchain", &sendtomainchain, false, {} },
{ "wallet", "sendtomainchain", &sendtomainchain, false, {"address", "amount", "subtractfeefromamount"} },
{ "wallet", "destroyamount", &destroyamount, false, {"asset", "amount", "comment"} },
{ "wallet", "settxfee", &settxfee, true, {"amount"} },
{ "wallet", "signmessage", &signmessage, true, {"address","message"} },