Browse Source

Added primitive zcrawkeygen/zcrawpour implementations

pull/4/head
Sean Bowe 9 years ago
parent
commit
730790f7a4
  1. 1
      qa/pull-tester/rpc-tests.sh
  2. 2
      qa/rpc-tests/test_framework/authproxy.py
  3. 71
      qa/rpc-tests/zcpour.py
  4. 4
      src/rpcclient.cpp
  5. 2
      src/rpcserver.cpp
  6. 2
      src/rpcserver.h
  7. 119
      src/wallet/rpcwallet.cpp

1
qa/pull-tester/rpc-tests.sh

@ -27,6 +27,7 @@ testScripts=(
'merkle_blocks.py'
'signrawtransactions.py'
'walletbackup.py'
'zcpour.py'
);
testScriptsExt=(
'bipdersig-p2p.py'

2
qa/rpc-tests/test_framework/authproxy.py

@ -49,7 +49,7 @@ except ImportError:
USER_AGENT = "AuthServiceProxy/0.1"
HTTP_TIMEOUT = 30
HTTP_TIMEOUT = 600
log = logging.getLogger("BitcoinRPC")

71
qa/rpc-tests/zcpour.py

@ -0,0 +1,71 @@
#!/usr/bin/env python2
#
# Test Pour semantics
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from decimal import Decimal
import os
import shutil
import sys
class PourTxTest(BitcoinTestFramework):
def setup_network(self):
# Start with split network:
return super(PourTxTest, self).setup_network(True)
def run_test(self):
# All nodes should start with 1,250 BTC:
starting_balance = 1250
for i in range(4):
assert_equal(self.nodes[i].getbalance(), starting_balance)
self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress!
# Generate zcaddress keypairs
zckeypair1 = self.nodes[0].zcrawkeygen()
zcsecretkey1 = zckeypair1["zcsecretkey"]
zcaddress1 = zckeypair1["zcaddress"]
zckeypair2 = self.nodes[0].zcrawkeygen()
zcsecretkey2 = zckeypair2["zcsecretkey"]
zcaddress2 = zckeypair2["zcaddress"]
self.nodes[0].move("", "foo", 1220)
self.nodes[0].move("", "bar", 30)
assert_equal(self.nodes[0].getbalance(""), 0)
change_address = self.nodes[0].getnewaddress("foo")
# Pour some of our money into this address
(total_in, inputs) = gather_inputs(self.nodes[0], 1210)
outputs = {}
outputs[change_address] = 78
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
pour_inputs = {}
pour_outputs = {}
pour_outputs[zcaddress1] = 100
pour_outputs[zcaddress2] = 800
exception_triggered = False
try:
pour_result = self.nodes[0].zcrawpour(rawtx, pour_inputs, pour_outputs, 0, 0)
except JSONRPCException:
exception_triggered = True
# We expect it to fail; the pour's balance equation isn't adding up.
assert_equal(exception_triggered, True)
pour_outputs[zcaddress1] = 370
pour_result = self.nodes[0].zcrawpour(rawtx, pour_inputs, pour_outputs, 1200, 30)
# This should succeed to construct a pour: the math adds up!
signed_tx_pour = self.nodes[0].signrawtransaction(pour_result["rawtxn"])
print signed_tx_pour
self.nodes[0].sendrawtransaction(signed_tx_pour["hex"])
if __name__ == '__main__':
PourTxTest().main()

4
src/rpcclient.cpp

@ -91,6 +91,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "estimatepriority", 0 },
{ "prioritisetransaction", 1 },
{ "prioritisetransaction", 2 },
{ "zcrawpour", 1 },
{ "zcrawpour", 2 },
{ "zcrawpour", 3 },
{ "zcrawpour", 4 }
};
class CRPCConvertTable

2
src/rpcserver.cpp

@ -376,6 +376,8 @@ static const CRPCCommand vRPCCommands[] =
{ "wallet", "walletlock", &walletlock, true },
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
{ "wallet", "walletpassphrase", &walletpassphrase, true },
{ "wallet", "zcrawkeygen", &zc_raw_keygen, true },
{ "wallet", "zcrawpour", &zc_raw_pour, true },
#endif // ENABLE_WALLET
};

2
src/rpcserver.h

@ -208,6 +208,8 @@ extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bo
extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value zc_raw_pour(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);

119
src/wallet/rpcwallet.cpp

@ -2343,3 +2343,122 @@ Value listunspent(const Array& params, bool fHelp)
return results;
}
Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
{
/*
zcrawpour <rawtx> {<bucket>: <zcsecretkey>, ...} {<zcaddress>: <value>, ...} vpub_old vpub_new
*/
//RPCTypeCheck(params, boost::assign::list_of(str_type)(obj_type)(obj_type)(int_type)(int_type));
CTransaction tx;
if (!DecodeHexTx(tx, params[0].get_str()))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
Object inputs = params[1].get_obj();
Object outputs = params[2].get_obj();
CAmount vpub_old(0);
CAmount vpub_new(0);
if (params[3].get_real() != 0.0)
vpub_old = AmountFromValue(params[3]);
if (params[4].get_real() != 0.0)
vpub_new = AmountFromValue(params[4]);
std::vector<PourInput> vpourin;
std::vector<PourOutput> vpourout;
/*
BOOST_FOREACH(const Pair& s, inputs)
{
// TODO
}
*/
// TODO
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
BOOST_FOREACH(const Pair& s, outputs)
{
libzerocash::PublicAddress addrTo;
{
vector<unsigned char> decoded(ParseHex(s.name_));
CDataStream ssData(decoded, SER_NETWORK, PROTOCOL_VERSION);
std::vector<unsigned char> pubAddressSecret;
std::string encryptionPublicKey;
ssData >> pubAddressSecret;
ssData >> encryptionPublicKey;
addrTo = libzerocash::PublicAddress(pubAddressSecret, encryptionPublicKey);
}
CAmount nAmount = AmountFromValue(s.value_);
libzerocash::Coin coin(addrTo, nAmount);
libzerocash::PourOutput output(coin, addrTo);
vpourout.push_back(output);
}
while (vpourout.size() < 2) {
vpourout.push_back(PourOutput(0));
}
// TODO
if (vpourout.size() > 2 || vpourin.size() > 2) {
throw runtime_error("unsupported");
}
uint256 anchor; // TODO
CScript scriptPubKey;
CPourTx pourtx(*pzerocashParams,
scriptPubKey,
anchor,
{vpourin[0], vpourin[1]},
{vpourout[0], vpourout[1]},
vpub_old,
vpub_new);
CMutableTransaction mtx(tx);
mtx.nVersion = 2;
mtx.vpour.push_back(pourtx);
CTransaction rawTx(mtx);
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << rawTx;
Object result;
result.push_back(Pair("encryptedbucket1", HexStr(pourtx.ciphertexts[0].begin(), pourtx.ciphertexts[0].end())));
result.push_back(Pair("encryptedbucket2", HexStr(pourtx.ciphertexts[1].begin(), pourtx.ciphertexts[1].end())));
result.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
return result;
}
Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp)
{
auto zckeypair = libzerocash::Address::CreateNewRandomAddress();
CDataStream pub(SER_NETWORK, PROTOCOL_VERSION);
CDataStream priv(SER_NETWORK, PROTOCOL_VERSION);
pub << zckeypair.getPublicAddress().getPublicAddressSecret(); // a_pk
pub << zckeypair.getPublicAddress().getEncryptionPublicKey(); // pk_enc
priv << zckeypair.getPrivateAddress().getAddressSecret(); // a_sk
priv << zckeypair.getPrivateAddress().getEncryptionSecretKey(); // sk_enc
std::string pub_hex = HexStr(pub.begin(), pub.end());
std::string priv_hex = HexStr(priv.begin(), priv.end());
Object result;
result.push_back(Pair("zcaddress", pub_hex));
result.push_back(Pair("zcsecretkey", priv_hex));
return result;
}
Loading…
Cancel
Save