Added mapAnchors consensus rules, finished zcrawpour/zcrawreceive.

Some specifics on consensus changes:
* Transactions must be anchored to a real anchor in the chain.
* Anchors are pushed and popped during ConnectBlock/DisconnectBlock as appropriate.
* DisconnectTip triggers evictions, under some circumstances, of transactions in the
  mempool which are anchored to roots that are no longer valid.
* Commitments append to the tree at the current best root during ConnectBlock.
This commit is contained in:
Sean Bowe
2016-01-07 12:09:58 -07:00
parent e934af2404
commit a8ac403db0
13 changed files with 312 additions and 15 deletions

View File

@@ -2344,13 +2344,68 @@ Value listunspent(const Array& params, bool fHelp)
return results;
}
Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
{
/*
zcrawreceive <zcsecretkey> <encrypted_bucket>
*/
RPCTypeCheck(params, boost::assign::list_of(str_type)(str_type));
LOCK(cs_main);
std::vector<unsigned char> a_sk;
std::string sk_enc;
{
CDataStream ssData(ParseHexV(params[0], "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
try {
ssData >> a_sk;
ssData >> sk_enc;
} catch(const std::exception &) {
throw runtime_error(
"zcsecretkey could not be decoded"
);
}
}
libzerocash::PrivateAddress zcsecretkey(a_sk, sk_enc);
libzerocash::Address zcaddress(zcsecretkey);
auto encrypted_bucket_vec = ParseHexV(params[1], "encrypted_bucket");
std::string encrypted_bucket(encrypted_bucket_vec.begin(), encrypted_bucket_vec.end());
libzerocash::Coin decrypted_bucket(encrypted_bucket, zcaddress);
std::vector<unsigned char> commitment_v = decrypted_bucket.getCoinCommitment().getCommitmentValue();
uint256 commitment = uint256(commitment_v);
assert(pwalletMain != NULL);
libsnark::merkle_authentication_path path(INCREMENTAL_MERKLE_TREE_DEPTH); // We don't care during receive... yet! :)
size_t path_index = 0;
uint256 anchor;
auto found_in_chain = pwalletMain->WitnessBucketCommitment(commitment, path, path_index, anchor);
CAmount value_of_bucket = decrypted_bucket.getValue();
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
{
ss << decrypted_bucket.getValue();
ss << decrypted_bucket.getRho();
ss << decrypted_bucket.getR();
}
Object result;
result.push_back(Pair("amount", ValueFromAmount(value_of_bucket)));
result.push_back(Pair("bucket", HexStr(ss.begin(), ss.end())));
result.push_back(Pair("exists", found_in_chain));
return result;
}
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));
LOCK(cs_main);
CTransaction tx;
if (!DecodeHexTx(tx, params[0].get_str()))
@@ -2371,24 +2426,61 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
std::vector<PourInput> vpourin;
std::vector<PourOutput> vpourout;
/*
uint256 anchor;
BOOST_FOREACH(const Pair& s, inputs)
{
// TODO
}
*/
CDataStream ssData(ParseHexV(s.name_, "bucket"), SER_NETWORK, PROTOCOL_VERSION);
uint64_t value;
std::vector<unsigned char> rho;
std::vector<unsigned char> r;
// TODO
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
ssData >> value;
ssData >> rho;
ssData >> r;
std::vector<unsigned char> a_sk;
std::string sk_enc;
{
CDataStream ssData2(ParseHexV(s.value_, "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
try {
ssData2 >> a_sk;
ssData2 >> sk_enc;
} catch(const std::exception &) {
throw runtime_error(
"zcsecretkey could not be decoded"
);
}
}
libzerocash::PrivateAddress zcsecretkey(a_sk, sk_enc);
libzerocash::Address zcaddress(zcsecretkey);
libzerocash::Coin input_coin(zcaddress.getPublicAddress(), value, rho, r);
std::vector<unsigned char> commitment_v = input_coin.getCoinCommitment().getCommitmentValue();
uint256 commitment = uint256(commitment_v);
libsnark::merkle_authentication_path path(INCREMENTAL_MERKLE_TREE_DEPTH);
size_t path_index = 0;
assert(pwalletMain != NULL);
if (!pwalletMain->WitnessBucketCommitment(commitment, path, path_index, anchor)) {
throw std::runtime_error("Couldn't find bucket in the blockchain");
}
vpourin.push_back(PourInput(input_coin, zcaddress, path_index, path));
}
while (vpourin.size() < 2) {
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);
CDataStream ssData(ParseHexV(s.name_, "to_address"), SER_NETWORK, PROTOCOL_VERSION);
std::vector<unsigned char> pubAddressSecret;
std::string encryptionPublicKey;
@@ -2415,7 +2507,6 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
throw runtime_error("unsupported");
}
uint256 anchor; // TODO
CScript scriptPubKey;
CPourTx pourtx(*pzerocashParams,
scriptPubKey,
@@ -2425,6 +2516,8 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
vpub_old,
vpub_new);
assert(pourtx.Verify(*pzerocashParams));
CMutableTransaction mtx(tx);
mtx.nVersion = 2;
mtx.vpour.push_back(pourtx);