Implementation of Overwinter transaction format ZIP 202.

This commit is contained in:
Simon
2018-02-15 22:19:36 -08:00
parent d527116d46
commit 072099d788
25 changed files with 1125 additions and 66 deletions

View File

@@ -50,14 +50,16 @@ int find_output(UniValue obj, int n) {
}
AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
CMutableTransaction contextualTx,
std::string fromAddress,
std::vector<SendManyRecipient> tOutputs,
std::vector<SendManyRecipient> zOutputs,
int minDepth,
CAmount fee,
UniValue contextInfo) :
fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo)
tx_(contextualTx), fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo)
{
assert(contextualTx.nVersion >= 2); // transaction format version must support vjoinsplit
assert(fee_ >= 0);
if (minDepth < 0) {
@@ -370,7 +372,6 @@ bool AsyncRPCOperation_sendmany::main_impl() {
// Prepare raw transaction to handle JoinSplits
CMutableTransaction mtx(tx_);
mtx.nVersion = 2;
crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_);
mtx.joinSplitPubKey = joinSplitPubKey_;
tx_ = CTransaction(mtx);

View File

@@ -51,7 +51,7 @@ struct WitnessAnchorData {
class AsyncRPCOperation_sendmany : public AsyncRPCOperation {
public:
AsyncRPCOperation_sendmany(std::string fromAddress, std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue);
AsyncRPCOperation_sendmany(CMutableTransaction contextualTx, std::string fromAddress, std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue);
virtual ~AsyncRPCOperation_sendmany();
// We don't want to be copied or moved around

View File

@@ -52,12 +52,15 @@ static int find_output(UniValue obj, int n) {
}
AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
CMutableTransaction contextualTx,
std::vector<ShieldCoinbaseUTXO> inputs,
std::string toAddress,
CAmount fee,
UniValue contextInfo) :
inputs_(inputs), fee_(fee), contextinfo_(contextInfo)
tx_(contextualTx), inputs_(inputs), fee_(fee), contextinfo_(contextInfo)
{
assert(contextualTx.nVersion >= 2); // transaction format version must support vjoinsplit
if (fee < 0 || fee > MAX_MONEY) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range");
}
@@ -213,7 +216,6 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
// Prepare raw transaction to handle JoinSplits
CMutableTransaction mtx(tx_);
mtx.nVersion = 2;
crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_);
mtx.joinSplitPubKey = joinSplitPubKey_;
tx_ = CTransaction(mtx);

View File

@@ -42,7 +42,7 @@ struct ShieldCoinbaseJSInfo
class AsyncRPCOperation_shieldcoinbase : public AsyncRPCOperation {
public:
AsyncRPCOperation_shieldcoinbase(std::vector<ShieldCoinbaseUTXO> inputs, std::string toAddress, CAmount fee = SHIELD_COINBASE_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue);
AsyncRPCOperation_shieldcoinbase(CMutableTransaction contextualTx, std::vector<ShieldCoinbaseUTXO> inputs, std::string toAddress, CAmount fee = SHIELD_COINBASE_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue);
virtual ~AsyncRPCOperation_shieldcoinbase();
// We don't want to be copied or moved around

View File

@@ -3525,9 +3525,16 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
o.push_back(Pair("fee", std::stod(FormatMoney(nFee))));
UniValue contextInfo = o;
// Contextual transaction we will build on
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
Params().GetConsensus(), chainActive.Height() + 1);
if (contextualTx.nVersion == 1) {
contextualTx.nVersion = 2; // Tx format should support vjoinsplits
}
// Create operation and add to global queue
std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) );
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) );
q->addOperation(operation);
AsyncRPCOperationId operationId = operation->getId();
return operationId;
@@ -3709,9 +3716,17 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
contextInfo.push_back(Pair("toaddress", params[1]));
contextInfo.push_back(Pair("fee", ValueFromAmount(nFee)));
// Contextual transaction we will build on
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
Params().GetConsensus(),
chainActive.Height() + 1);
if (contextualTx.nVersion == 1) {
contextualTx.nVersion = 2; // Tx format should support vjoinsplits
}
// Create operation and add to global queue
std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_shieldcoinbase(inputs, destaddress, nFee, contextInfo) );
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_shieldcoinbase(contextualTx, inputs, destaddress, nFee, contextInfo) );
q->addOperation(operation);
AsyncRPCOperationId operationId = operation->getId();

View File

@@ -2572,7 +2572,8 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
wtxNew.fTimeReceivedIsTxTime = true;
wtxNew.BindWallet(this);
CMutableTransaction txNew;
CMutableTransaction txNew = CreateNewContextualCMutableTransaction(
Params().GetConsensus(), chainActive.Height() + 1);
// Discourage fee sniping.
//