aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/depends.yml22
-rw-r--r--contrib/depends/packages/freebsd_base.mk4
-rw-r--r--src/wallet/api/wallet.cpp5
-rw-r--r--src/wallet/api/wallet.h1
-rw-r--r--src/wallet/api/wallet2_api.h1
-rw-r--r--src/wallet/wallet2.cpp40
6 files changed, 66 insertions, 7 deletions
diff --git a/.github/workflows/depends.yml b/.github/workflows/depends.yml
index 3e0f048c7..8e4eaf177 100644
--- a/.github/workflows/depends.yml
+++ b/.github/workflows/depends.yml
@@ -45,15 +45,29 @@ jobs:
- uses: actions/checkout@v1
with:
submodules: recursive
+# Most volatile cache
- name: ccache
uses: actions/cache@v2
with:
- path: |
- ~/.ccache
- contrib/depends/built
- contrib/depends/sdk-sources
+ path: ~/.ccache
key: ccache-${{ matrix.toolchain.host }}-${{ github.sha }}
restore-keys: ccache-${{ matrix.toolchain.host }}-
+# Less volatile cache
+ - name: depends cache
+ uses: actions/cache@v2
+ with:
+ path: contrib/depends/built
+ key: depends-${{ matrix.toolchain.host }}-${{ hashFiles('contrib/depends/packages/*') }}
+ restore-keys: |
+ depends-${{ matrix.toolchain.host }}-${{ hashFiles('contrib/depends/packages/*') }}
+ depends-${{ matrix.toolchain.host }}-
+# Static cache
+ - name: OSX SDK cache
+ uses: actions/cache@v2
+ with:
+ path: contrib/depends/sdk-sources
+ key: sdk-${{ matrix.toolchain.host }}-${{ matrix.toolchain.osx_sdk }}
+ restore-keys: sdk-${{ matrix.toolchain.host }}-${{ matrix.toolchain.osx_sdk }}
- name: set apt conf
run: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
diff --git a/contrib/depends/packages/freebsd_base.mk b/contrib/depends/packages/freebsd_base.mk
index c6a209dcd..ad9975f8d 100644
--- a/contrib/depends/packages/freebsd_base.mk
+++ b/contrib/depends/packages/freebsd_base.mk
@@ -12,8 +12,8 @@ endef
define $(package)_build_cmds
mkdir bin &&\
- echo "exec /usr/bin/clang-8 -target x86_64-unknown-freebsd$($(package)_version) --sysroot=$(host_prefix)/native $$$$""@" > bin/clang-8 &&\
- echo "exec /usr/bin/clang++-8 -target x86_64-unknown-freebsd$($(package)_version) --sysroot=$(host_prefix)/native $$$$""@" > bin/clang++-8 &&\
+ echo "#!/bin/sh\n\nexec /usr/bin/clang-8 -target x86_64-unknown-freebsd$($(package)_version) --sysroot=$(host_prefix)/native $$$$""@" > bin/clang-8 &&\
+ echo "#!/bin/sh\n\nexec /usr/bin/clang++-8 -target x86_64-unknown-freebsd$($(package)_version) --sysroot=$(host_prefix)/native $$$$""@" > bin/clang++-8 &&\
chmod 755 bin/*
endef
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 3a2074cc4..0afbda705 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -2365,6 +2365,11 @@ bool WalletImpl::parse_uri(const std::string &uri, std::string &address, std::st
return m_wallet->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error);
}
+std::string WalletImpl::make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const
+{
+ return m_wallet->make_uri(address, payment_id, amount, tx_description, recipient_name, error);
+}
+
std::string WalletImpl::getDefaultDataDir() const
{
return tools::get_default_data_dir();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 011a94ec4..67fc2c08a 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -205,6 +205,7 @@ public:
virtual void startRefresh() override;
virtual void pauseRefresh() override;
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) override;
+ virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const override;
virtual std::string getDefaultDataDir() const override;
virtual bool lightWalletLogin(bool &isNewWallet) const override;
virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index ed8c55d3b..f9c421a93 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1020,6 +1020,7 @@ struct Wallet
virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0;
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) = 0;
+ virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const = 0;
virtual std::string getDefaultDataDir() const = 0;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 217a22027..6e8d585dc 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -144,6 +144,9 @@ using namespace cryptonote;
#define IGNORE_LONG_PAYMENT_ID_FROM_BLOCK_VERSION 12
+#define DEFAULT_UNLOCK_TIME (CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE * DIFFICULTY_TARGET_V2)
+#define RECENT_SPEND_WINDOW (50 * DIFFICULTY_TARGET_V2)
+
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1";
@@ -1019,7 +1022,13 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
num_rct_outputs = *(end - 1);
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
+ THROW_WALLET_EXCEPTION_IF(outputs_to_consider == 0, error::wallet_internal_error, "No rct outputs to consider");
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
+ if (average_output_time == 0) {
+ // TODO: apply this to all cases; do so alongside a hard fork, where all clients will update at the same time, preventing anonymity puddle formation
+ average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider);
+ }
+ THROW_WALLET_EXCEPTION_IF(average_output_time == 0, error::wallet_internal_error, "Average seconds per output cannot be 0.");
};
gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets): gamma_picker(rct_offsets, GAMMA_SHAPE, GAMMA_SCALE) {}
@@ -1028,6 +1037,34 @@ uint64_t gamma_picker::pick()
{
double x = gamma(engine);
x = exp(x);
+
+ if (x > DEFAULT_UNLOCK_TIME)
+ {
+ // We are trying to select an output from the chain that appeared 'x' seconds before the
+ // current chain tip, where 'x' is selected from the gamma distribution recommended in Miller et al.
+ // (https://arxiv.org/pdf/1704.04299/).
+ // Our method is to get the average time delta between outputs in the recent past, estimate the number of
+ // outputs 'n' that would have appeared between 'chain_tip - x' and 'chain_tip', select the real output at
+ // 'current_num_outputs - n', then randomly select an output from the block where that output appears.
+ // Source code to paper: https://github.com/maltemoeser/moneropaper
+ //
+ // Due to the 'default spendable age' mechanic in Monero, 'current_num_outputs' only contains
+ // currently *unlocked* outputs, which means the earliest output that can be selected is not at the chain tip!
+ // Therefore, we must offset 'x' so it matches up with the timing of the outputs being considered. We do
+ // this by saying if 'x` equals the expected age of the first unlocked output (compared to the current
+ // chain tip - i.e. DEFAULT_UNLOCK_TIME), then select the first unlocked output.
+ x -= DEFAULT_UNLOCK_TIME;
+ }
+ else
+ {
+ // If the spent time suggested by the gamma is less than the unlock time, that means the gamma is suggesting an output
+ // that is no longer feasible to be spent (possible since the gamma was constructed when consensus rules did not enforce the
+ // lock time). The assumption made in this code is that an output expected spent quicker than the unlock time would likely
+ // be spent within RECENT_SPEND_WINDOW after allowed. So it returns an output that falls between 0 and the RECENT_SPEND_WINDOW.
+ // The RECENT_SPEND_WINDOW was determined with empirical analysis of observed data.
+ x = crypto::rand_idx(static_cast<uint64_t>(RECENT_SPEND_WINDOW));
+ }
+
uint64_t output_index = x / average_output_time;
if (output_index >= num_rct_outputs)
return std::numeric_limits<uint64_t>::max(); // bad pick
@@ -8659,7 +8696,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (req.outputs[i].index == td.m_global_output_index)
if (daemon_resp.outs[i].key == boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key)
if (daemon_resp.outs[i].mask == mask)
- real_out_found = true;
+ if (daemon_resp.outs[i].unlocked)
+ real_out_found = true;
}
THROW_WALLET_EXCEPTION_IF(!real_out_found, error::wallet_internal_error,
"Daemon response did not include the requested real output");