Merge branch 'sietch_dynamic' into danger

This commit is contained in:
Duke Leto
2020-07-26 08:29:45 -04:00
4 changed files with 55 additions and 19 deletions

View File

@@ -16,6 +16,27 @@
#ifndef SIETCH_H #ifndef SIETCH_H
#define SIETCH_H #define SIETCH_H
string newSietchZaddr() {
bool addToWallet = false;
auto zaddr = EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey(addToWallet));
return zaddr;
}
SendManyRecipient newSietchRecipient(string zaddr) {
int nAmount = 0;
// Sietch zouts have random data in their memos so they are indistinguishable from
// encrypted data being stored in the memo field
char hex[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
// memo field is 512 bytes or 1024 hex chars
char str[1024];
for(int i=0;i<1024;i++) {
str[i] = hex[GetRandInt(16)];
}
str[1024] = 0;
return SendManyRecipient( zaddr, nAmount, string(str) );
}
// The network essentially DoS's these addresses and reduces their privacy slightly // The network essentially DoS's these addresses and reduces their privacy slightly
// by making them public, but in return, the rest of the shielded pool benefits // by making them public, but in return, the rest of the shielded pool benefits
// and so it's a large benefit for a small cost. // and so it's a large benefit for a small cost.

View File

@@ -72,6 +72,7 @@ using namespace libzcash;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; extern std::string ASSETCHAINS_OVERRIDE_PUBKEY;
const std::string ADDR_TYPE_SAPLING = "sapling"; const std::string ADDR_TYPE_SAPLING = "sapling";
const std::string ADDR_TYPE_DONOTREMEMBER = "donotremember";
extern UniValue TxJoinSplitToJSON(const CTransaction& tx); extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
extern int32_t KOMODO_INSYNC; extern int32_t KOMODO_INSYNC;
uint32_t komodo_segid32(char *coinaddr); uint32_t komodo_segid32(char *coinaddr);
@@ -81,6 +82,9 @@ CBlockIndex *komodo_getblockindex(uint256 hash);
extern string randomSietchZaddr(); extern string randomSietchZaddr();
extern CAmount fConsolidationTxFee; extern CAmount fConsolidationTxFee;
extern bool fZindex; extern bool fZindex;
extern string randomSietchZaddr();
extern SendManyRecipient newSietchRecipient(string zaddr);
extern string newSietchZaddr();
int64_t nWalletUnlockTime; int64_t nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime;
@@ -2812,6 +2816,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
const CHDChain& hdChain = pwalletMain->GetHDChain();
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
@@ -2820,6 +2825,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp, const CPubKey& mypk)
obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("saplingAccountCounter", (int)hdChain.saplingAccountCounter));
if (pwalletMain->IsCrypted()) if (pwalletMain->IsCrypted())
obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
@@ -3890,14 +3896,15 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk
"z_getnewaddress ( type )\n" "z_getnewaddress ( type )\n"
"\nReturns a new shielded address for receiving payments.\n" "\nReturns a new shielded address for receiving payments.\n"
"\nWith no arguments, returns a Sapling address.\n" "\nWith no arguments, returns a Sapling address.\n"
"\nBe very careful with 'donotremember' address type, the extended spending key (xsk) of that address is not stored in wallet.dat!\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. One of [\"" "1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. Either "+ ADDR_TYPE_SAPLING + " or " + ADDR_TYPE_DONOTREMEMBER + " .\n"
+ ADDR_TYPE_SAPLING + "\"].\n"
"\nResult:\n" "\nResult:\n"
"\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The new shielded address.\n" "\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The new shielded address.\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("z_getnewaddress", "") + HelpExampleCli("z_getnewaddress", "")
+ HelpExampleCli("z_getnewaddress", ADDR_TYPE_SAPLING) + HelpExampleCli("z_getnewaddress", ADDR_TYPE_SAPLING)
+ HelpExampleCli("z_getnewaddress", ADDR_TYPE_DONOTREMEMBER)
); );
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -3908,11 +3915,17 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk
if (params.size() > 0) { if (params.size() > 0) {
addrType = params[0].get_str(); addrType = params[0].get_str();
} }
if (addrType == ADDR_TYPE_SAPLING) { if (addrType == ADDR_TYPE_SAPLING) {
return EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey()); return EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey());
} else if (addrType == ADDR_TYPE_DONOTREMEMBER) {
bool addToWallet = false;
auto zaddr = EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey(addToWallet));
if(fZdebug) {
fprintf(stderr,"%s: Sietch zaddr=%s created, xsk not stored in wallet.dat!\n", __FUNCTION__, zaddr.c_str() );
}
return zaddr;
} else { } else {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid address type!"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid address type! Try " + ADDR_TYPE_SAPLING + " or " + ADDR_TYPE_DONOTREMEMBER);
} }
} }
@@ -4264,6 +4277,7 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& my
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n" " \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n"
" \"private\": xxxxx, (numeric) the total balance of shielded funds\n"
" \"private\": xxxxx, (numeric) the total balance of private funds\n" " \"private\": xxxxx, (numeric) the total balance of private funds\n"
" \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n" " \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n"
"}\n" "}\n"
@@ -4725,44 +4739,44 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
// SIETCH: Sprinkle our cave with some magic privacy zdust // SIETCH: Sprinkle our cave with some magic privacy zdust
// End goal is to have this be as large as possible without slowing xtns down too much // End goal is to have this be as large as possible without slowing xtns down too much
// A value of 7 will provide much stronger linkability privacy versus pre-Sietch operations // A value of 7 will provide much stronger linkability privacy versus pre-Sietch operations
unsigned int DEFAULT_MIN_ZOUTS=7; unsigned int DEFAULT_MIN_ZOUTS=7;
unsigned int MAX_ZOUTS=25; unsigned int MAX_ZOUTS=25;
unsigned int MIN_ZOUTS=GetArg("--sietch-min-zouts", DEFAULT_MIN_ZOUTS); unsigned int MIN_ZOUTS=GetArg("--sietch-min-zouts", DEFAULT_MIN_ZOUTS);
if((MIN_ZOUTS<2) || (MIN_ZOUTS>MAX_ZOUTS)) { if((MIN_ZOUTS<3) || (MIN_ZOUTS>MAX_ZOUTS)) {
fprintf(stderr,"%s: Sietch min zouts must be >=2 and <= 25, setting to default value of %d\n", __FUNCTION__, DEFAULT_MIN_ZOUTS ); fprintf(stderr,"%s: Sietch min zouts must be >=3 and <= 25, setting to default value of %d\n", __FUNCTION__, DEFAULT_MIN_ZOUTS );
MIN_ZOUTS=DEFAULT_MIN_ZOUTS; MIN_ZOUTS=DEFAULT_MIN_ZOUTS;
} }
int nAmount = 0;
// Dynamic Sietch zaddrs default to OFF
bool fSietchDynamic = GetArg("--sietch-dynamic",0);
while (zaddrRecipients.size() < MIN_ZOUTS) { while (zaddrRecipients.size() < MIN_ZOUTS) {
// OK, we identify this xtn as needing privacy zdust, we must decide how much, non-deterministically // OK, we identify this xtn as needing privacy zdust, we must decide how much, non-deterministically
int nAmount = 0;
int decider = 1 + GetRandInt(100); // random int between 1 and 100 int decider = 1 + GetRandInt(100); // random int between 1 and 100
string memo = "f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
string zdust1, zdust2; string zdust1, zdust2;
// Which zaddr we send to is non-deterministically chosen from two zpools... // Which zaddr we send to is non-deterministically chosen from two zpools...
zdust1 = randomSietchZaddr(); zdust1 = fSietchDynamic ? newSietchZaddr() : randomSietchZaddr();
// And their ordering when given to internals is also non-deterministic, which // And their ordering when given to internals is also non-deterministic, which
// helps breaks assumptions blockchain analysts may use from z_sendmany internals // helps breaks assumptions blockchain analysts may use from z_sendmany internals
if (decider % 2) { if (decider % 2) {
zaddrRecipients.insert(std::begin(zaddrRecipients), SendManyRecipient(zdust1, nAmount, memo) ); zaddrRecipients.insert(std::begin(zaddrRecipients), newSietchRecipient(zdust1) );
} else { } else {
zaddrRecipients.push_back( SendManyRecipient(zdust1, nAmount, memo) ); zaddrRecipients.push_back( newSietchRecipient(zdust1) );
} }
if(fZdebug) if(fZdebug)
fprintf(stderr,"%s: adding %s as zdust receiver\n", __FUNCTION__, zdust1.c_str()); fprintf(stderr,"%s: adding %s as zdust receiver\n", __FUNCTION__, zdust1.c_str());
//50% chance of adding another zout //50% chance of adding another zout
if (decider % 2) { if (decider % 2) {
zdust2 = randomSietchZaddr(); zdust2 = fSietchDynamic ? newSietchZaddr() : randomSietchZaddr();
// 50% chance of adding it to the front or back since all odd numbers are 1 or 3 mod 4
if(decider % 4 == 3) { if(decider % 4 == 3) {
zaddrRecipients.push_back( SendManyRecipient(zdust2, nAmount, memo) ); zaddrRecipients.push_back( newSietchRecipient(zdust2) );
} else { } else {
zaddrRecipients.insert(std::begin(zaddrRecipients), SendManyRecipient(zdust2, nAmount, memo) ); zaddrRecipients.insert(std::begin(zaddrRecipients), newSietchRecipient(zdust2) );
} }
if(fZdebug) if(fZdebug)
fprintf(stderr,"%s: adding %s as zdust receiver\n", __FUNCTION__, zdust2.c_str()); fprintf(stderr,"%s: adding %s as zdust receiver\n", __FUNCTION__, zdust2.c_str());

View File

@@ -118,7 +118,7 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
// Generate a new Sapling spending key and return its public payment address // Generate a new Sapling spending key and return its public payment address
SaplingPaymentAddress CWallet::GenerateNewSaplingZKey() SaplingPaymentAddress CWallet::GenerateNewSaplingZKey(bool addToWallet)
{ {
AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
@@ -159,7 +159,7 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
mapSaplingZKeyMetadata[ivk] = metadata; mapSaplingZKeyMetadata[ivk] = metadata;
auto addr = xsk.DefaultAddress(); auto addr = xsk.DefaultAddress();
if (!AddSaplingZKey(xsk, addr)) { if (addToWallet && !AddSaplingZKey(xsk, addr)) {
throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed"); throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed");
} }
// return default sapling payment address. // return default sapling payment address.

View File

@@ -1071,7 +1071,8 @@ public:
* Sapling ZKeys * Sapling ZKeys
*/ */
//! Generates new Sapling key //! Generates new Sapling key
libzcash::SaplingPaymentAddress GenerateNewSaplingZKey(); // Sietch uses addToWallet=false
libzcash::SaplingPaymentAddress GenerateNewSaplingZKey(bool addToWallet=true);
//! Adds Sapling spending key to the store, and saves it to disk //! Adds Sapling spending key to the store, and saves it to disk
bool AddSaplingZKey( bool AddSaplingZKey(
const libzcash::SaplingExtendedSpendingKey &key, const libzcash::SaplingExtendedSpendingKey &key,