Auto merge of #3521 - bitcartel:sapling_json_data, r=str4d
Add Sapling fields to JSON RPC output using TxToJSON. Related to #3063 to add Sapling support to wallet RPCs.
This commit is contained in:
commit
e95bdeabbf
|
@ -89,7 +89,7 @@ class WalletSaplingTest(BitcoinTestFramework):
|
|||
recipients.append({"address": saplingAddr0, "amount": Decimal('5')})
|
||||
recipients.append({"address": taddr1, "amount": Decimal('5')})
|
||||
myopid = self.nodes[1].z_sendmany(saplingAddr1, recipients, 1, 0)
|
||||
wait_and_assert_operationid_status(self.nodes[1], myopid)
|
||||
mytxid = wait_and_assert_operationid_status(self.nodes[1], myopid)
|
||||
|
||||
self.sync_all()
|
||||
self.nodes[2].generate(1)
|
||||
|
@ -100,5 +100,26 @@ class WalletSaplingTest(BitcoinTestFramework):
|
|||
assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal('5'))
|
||||
assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('5'))
|
||||
|
||||
# Verify existence of Sapling related JSON fields
|
||||
resp = self.nodes[0].getrawtransaction(mytxid, 1)
|
||||
assert_equal(resp['valueBalance'], Decimal('5'))
|
||||
assert(len(resp['vShieldedSpend']) == 1)
|
||||
assert(len(resp['vShieldedOutput']) == 2)
|
||||
assert('bindingSig' in resp)
|
||||
shieldedSpend = resp['vShieldedSpend'][0]
|
||||
assert('cv' in shieldedSpend)
|
||||
assert('anchor' in shieldedSpend)
|
||||
assert('nullifier' in shieldedSpend)
|
||||
assert('rk' in shieldedSpend)
|
||||
assert('proof' in shieldedSpend)
|
||||
assert('spendAuthSig' in shieldedSpend)
|
||||
shieldedOutput = resp['vShieldedOutput'][0]
|
||||
assert('cv' in shieldedOutput)
|
||||
assert('cmu' in shieldedOutput)
|
||||
assert('ephemeralKey' in shieldedOutput)
|
||||
assert('encCiphertext' in shieldedOutput)
|
||||
assert('outCiphertext' in shieldedOutput)
|
||||
assert('proof' in shieldedOutput)
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletSaplingTest().main()
|
||||
|
|
|
@ -114,6 +114,36 @@ UniValue TxJoinSplitToJSON(const CTransaction& tx) {
|
|||
return vjoinsplit;
|
||||
}
|
||||
|
||||
UniValue TxShieldedSpendsToJSON(const CTransaction& tx) {
|
||||
UniValue vdesc(UniValue::VARR);
|
||||
for (const SpendDescription& spendDesc : tx.vShieldedSpend) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("cv", spendDesc.cv.GetHex()));
|
||||
obj.push_back(Pair("anchor", spendDesc.anchor.GetHex()));
|
||||
obj.push_back(Pair("nullifier", spendDesc.nullifier.GetHex()));
|
||||
obj.push_back(Pair("rk", spendDesc.rk.GetHex()));
|
||||
obj.push_back(Pair("proof", HexStr(spendDesc.zkproof.begin(), spendDesc.zkproof.end())));
|
||||
obj.push_back(Pair("spendAuthSig", HexStr(spendDesc.spendAuthSig.begin(), spendDesc.spendAuthSig.end())));
|
||||
vdesc.push_back(obj);
|
||||
}
|
||||
return vdesc;
|
||||
}
|
||||
|
||||
UniValue TxShieldedOutputsToJSON(const CTransaction& tx) {
|
||||
UniValue vdesc(UniValue::VARR);
|
||||
for (const OutputDescription& outputDesc : tx.vShieldedOutput) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("cv", outputDesc.cv.GetHex()));
|
||||
obj.push_back(Pair("cmu", outputDesc.cm.GetHex()));
|
||||
obj.push_back(Pair("ephemeralKey", outputDesc.ephemeralKey.GetHex()));
|
||||
obj.push_back(Pair("encCiphertext", HexStr(outputDesc.encCiphertext.begin(), outputDesc.encCiphertext.end())));
|
||||
obj.push_back(Pair("outCiphertext", HexStr(outputDesc.outCiphertext.begin(), outputDesc.outCiphertext.end())));
|
||||
obj.push_back(Pair("proof", HexStr(outputDesc.zkproof.begin(), outputDesc.zkproof.end())));
|
||||
vdesc.push_back(obj);
|
||||
}
|
||||
return vdesc;
|
||||
}
|
||||
|
||||
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
||||
{
|
||||
entry.push_back(Pair("txid", tx.GetHash().GetHex()));
|
||||
|
@ -160,6 +190,17 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
|||
UniValue vjoinsplit = TxJoinSplitToJSON(tx);
|
||||
entry.push_back(Pair("vjoinsplit", vjoinsplit));
|
||||
|
||||
if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
|
||||
entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance)));
|
||||
UniValue vspenddesc = TxShieldedSpendsToJSON(tx);
|
||||
entry.push_back(Pair("vShieldedSpend", vspenddesc));
|
||||
UniValue voutputdesc = TxShieldedOutputsToJSON(tx);
|
||||
entry.push_back(Pair("vShieldedOutput", voutputdesc));
|
||||
if (!(vspenddesc.empty() && voutputdesc.empty())) {
|
||||
entry.push_back(Pair("bindingSig", HexStr(tx.bindingSig.begin(), tx.bindingSig.end())));
|
||||
}
|
||||
}
|
||||
|
||||
if (!hashBlock.IsNull()) {
|
||||
entry.push_back(Pair("blockhash", hashBlock.GetHex()));
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
|
||||
|
|
Loading…
Reference in New Issue