aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/depends/packages/openssl.mk8
-rw-r--r--contrib/depends/patches/openssl/fix_darwin.patch60
m---------external/randomx0
-rw-r--r--src/crypto/slow-hash.c70
-rw-r--r--src/cryptonote_core/blockchain.cpp21
-rw-r--r--src/cryptonote_core/tx_pool.cpp88
-rw-r--r--src/device/device_ledger.cpp10
-rw-r--r--tests/unit_tests/long_term_block_weight.cpp15
8 files changed, 196 insertions, 76 deletions
diff --git a/contrib/depends/packages/openssl.mk b/contrib/depends/packages/openssl.mk
index 16c232b41..0dddca072 100644
--- a/contrib/depends/packages/openssl.mk
+++ b/contrib/depends/packages/openssl.mk
@@ -1,8 +1,9 @@
package=openssl
-$(package)_version=1.1.1k
+$(package)_version=1.1.1l
$(package)_download_path=https://www.openssl.org/source
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
+$(package)_sha256_hash=0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1
+$(package)_patches=fix_darwin.patch
define $(package)_set_vars
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
@@ -51,7 +52,8 @@ endef
define $(package)_preprocess_cmds
sed -i.old 's|"engines", "apps", "test", "util", "tools", "fuzz"|"engines", "tools"|' Configure && \
- sed -i -e 's|cflags --sysroot.*",|cflags",|' Configurations/15-android.conf
+ sed -i -e 's|cflags --sysroot.*",|cflags",|' Configurations/15-android.conf && \
+ patch -p1 < $($(package)_patch_dir)/fix_darwin.patch
endef
define $(package)_config_cmds
diff --git a/contrib/depends/patches/openssl/fix_darwin.patch b/contrib/depends/patches/openssl/fix_darwin.patch
new file mode 100644
index 000000000..a917daa12
--- /dev/null
+++ b/contrib/depends/patches/openssl/fix_darwin.patch
@@ -0,0 +1,60 @@
+From 96ac8f13f4d0ee96baf5724d9f96c44c34b8606c Mon Sep 17 00:00:00 2001
+From: David Carlier <devnexen@gmail.com>
+Date: Tue, 24 Aug 2021 22:40:14 +0100
+Subject: [PATCH] Darwin platform allows to build on releases before
+ Yosemite/ios 8.
+
+issue #16407 #16408
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/16409)
+---
+ crypto/rand/rand_unix.c | 5 +----
+ include/crypto/rand.h | 10 ++++++++++
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
+index 43f1069d151d..0f4525106af7 100644
+--- a/crypto/rand/rand_unix.c
++++ b/crypto/rand/rand_unix.c
+@@ -34,9 +34,6 @@
+ #if defined(__OpenBSD__)
+ # include <sys/param.h>
+ #endif
+-#if defined(__APPLE__)
+-# include <CommonCrypto/CommonRandom.h>
+-#endif
+
+ #if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
+ # include <sys/types.h>
+@@ -381,7 +378,7 @@ static ssize_t syscall_random(void *buf, size_t buflen)
+ if (errno != ENOSYS)
+ return -1;
+ }
+-# elif defined(__APPLE__)
++# elif defined(OPENSSL_APPLE_CRYPTO_RANDOM)
+ if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess)
+ return (ssize_t)buflen;
+
+diff --git a/include/crypto/rand.h b/include/crypto/rand.h
+index 5350d3a93119..674f840fd13c 100644
+--- a/include/crypto/rand.h
++++ b/include/crypto/rand.h
+@@ -20,6 +20,16 @@
+
+ # include <openssl/rand.h>
+
++# if defined(__APPLE__) && !defined(OPENSSL_NO_APPLE_CRYPTO_RANDOM)
++# include <Availability.h>
++# if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000) || \
++ (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000)
++# define OPENSSL_APPLE_CRYPTO_RANDOM 1
++# include <CommonCrypto/CommonCryptoError.h>
++# include <CommonCrypto/CommonRandom.h>
++# endif
++# endif
++
+ /* forward declaration */
+ typedef struct rand_pool_st RAND_POOL;
+
diff --git a/external/randomx b/external/randomx
-Subproject fe4324e8c0c035fec3affd6e4c49241c2e5b995
+Subproject f9ae3f235183c452962edd2a15384bdc67f7a11
diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c
index 53628ab18..38aeeee54 100644
--- a/src/crypto/slow-hash.c
+++ b/src/crypto/slow-hash.c
@@ -51,6 +51,12 @@
#define INIT_SIZE_BLK 8
#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE)
+#if defined(_MSC_VER)
+#define THREADV __declspec(thread)
+#else
+#define THREADV __thread
+#endif
+
extern void aesb_single_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
@@ -459,12 +465,6 @@ static inline int force_software_aes(void)
_b1 = _b; \
_b = _c; \
-#if defined(_MSC_VER)
-#define THREADV __declspec(thread)
-#else
-#define THREADV __thread
-#endif
-
#pragma pack(push, 1)
union cn_slow_hash_state
{
@@ -1012,6 +1012,44 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
}
#elif !defined NO_AES && (defined(__arm__) || defined(__aarch64__))
+#ifdef __aarch64__
+#include <sys/mman.h>
+THREADV uint8_t *hp_state = NULL;
+THREADV int hp_malloced = 0;
+
+void cn_slow_hash_allocate_state(void)
+{
+ if(hp_state != NULL)
+ return;
+
+#ifndef MAP_HUGETLB
+#define MAP_HUGETLB 0
+#endif
+ hp_state = mmap(0, MEMORY, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON | MAP_HUGETLB, -1, 0);
+
+ if(hp_state == MAP_FAILED)
+ hp_state = NULL;
+ if(hp_state == NULL)
+ {
+ hp_malloced = 1;
+ hp_state = (uint8_t *) malloc(MEMORY);
+ }
+}
+
+void cn_slow_hash_free_state(void)
+{
+ if(hp_state == NULL)
+ return;
+
+ if (hp_malloced)
+ free(hp_state);
+ else
+ munmap(hp_state, MEMORY);
+ hp_state = NULL;
+ hp_malloced = 0;
+}
+#else
void cn_slow_hash_allocate_state(void)
{
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
@@ -1023,6 +1061,7 @@ void cn_slow_hash_free_state(void)
// As above
return;
}
+#endif
#if defined(__GNUC__)
#define RDATA_ALIGN16 __attribute__ ((aligned(16)))
@@ -1272,12 +1311,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
{
RDATA_ALIGN16 uint8_t expandedKey[240];
-#ifndef FORCE_USE_HEAP
- RDATA_ALIGN16 uint8_t local_hp_state[MEMORY];
-#else
- uint8_t *local_hp_state = (uint8_t *)aligned_malloc(MEMORY,16);
-#endif
-
+ uint8_t *local_hp_state;
uint8_t text[INIT_SIZE_BYTE];
RDATA_ALIGN16 uint64_t a[2];
RDATA_ALIGN16 uint64_t b[4];
@@ -1296,6 +1330,14 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
};
+ // this isn't supposed to happen, but guard against it for now.
+ if(hp_state == NULL)
+ cn_slow_hash_allocate_state();
+
+ // locals to avoid constant TLS dereferencing
+ local_hp_state = hp_state;
+
+ // locals to avoid constant TLS dereferencing
/* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */
if (prehashed) {
@@ -1409,10 +1451,6 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
memcpy(state.init, text, INIT_SIZE_BYTE);
hash_permutation(&state.hs);
extra_hashes[state.hs.b[0] & 3](&state, 200, hash);
-
-#ifdef FORCE_USE_HEAP
- aligned_free(local_hp_state);
-#endif
}
#else /* aarch64 && crypto */
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 33407bf95..34031fb7c 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -588,6 +588,7 @@ block Blockchain::pop_block_from_blockchain()
CHECK_AND_ASSERT_THROW_MES(m_db->height() > 1, "Cannot pop the genesis block");
+ const uint8_t previous_hf_version = get_current_hard_fork_version();
try
{
m_db->pop_block(popped_block, popped_txs);
@@ -650,6 +651,13 @@ block Blockchain::pop_block_from_blockchain()
m_tx_pool.on_blockchain_dec(top_block_height, top_block_hash);
invalidate_block_template_cache();
+ const uint8_t new_hf_version = get_current_hard_fork_version();
+ if (new_hf_version != previous_hf_version)
+ {
+ MINFO("Validating txpool for v" << (unsigned)new_hf_version);
+ m_tx_pool.validate(new_hf_version);
+ }
+
return popped_block;
}
//------------------------------------------------------------------
@@ -4392,6 +4400,19 @@ leave:
get_difficulty_for_next_block(); // just to cache it
invalidate_block_template_cache();
+ const uint8_t new_hf_version = get_current_hard_fork_version();
+ if (new_hf_version != hf_version)
+ {
+ // the genesis block is added before everything's setup, and the txpool is empty
+ // when we start from scratch, so we skip this
+ const bool is_genesis_block = new_height == 1;
+ if (!is_genesis_block)
+ {
+ MGINFO("Validating txpool for v" << (unsigned)new_hf_version);
+ m_tx_pool.validate(new_hf_version);
+ }
+ }
+
send_miner_notifications(id, already_generated_coins);
for (const auto& notifier: m_block_notifiers)
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 84605d6f5..5629db3e6 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -1568,61 +1568,59 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
- size_t tx_weight_limit = get_transaction_weight_limit(version);
- std::unordered_set<crypto::hash> remove;
- m_txpool_weight = 0;
- m_blockchain.for_all_txpool_txes([this, &remove, tx_weight_limit](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
- m_txpool_weight += meta.weight;
- if (meta.weight > tx_weight_limit) {
- LOG_PRINT_L1("Transaction " << txid << " is too big (" << meta.weight << " bytes), removing it from pool");
- remove.insert(txid);
- }
- else if (m_blockchain.have_tx(txid)) {
- LOG_PRINT_L1("Transaction " << txid << " is in the blockchain, removing it from pool");
- remove.insert(txid);
- }
+ MINFO("Validating txpool contents for v" << (unsigned)version);
+
+ LockedTXN lock(m_blockchain.get_db());
+
+ struct tx_entry_t
+ {
+ crypto::hash txid;
+ txpool_tx_meta_t meta;
+ };
+
+ // get all txids
+ std::vector<tx_entry_t> txes;
+ m_blockchain.for_all_txpool_txes([this, &txes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
+ if (!meta.pruned) // skip pruned txes
+ txes.push_back({txid, meta});
return true;
}, false, relay_category::all);
- size_t n_removed = 0;
- if (!remove.empty())
+ // take them all out and add them back in, some might fail
+ size_t added = 0;
+ for (auto &e: txes)
{
- LockedTXN lock(m_blockchain.get_db());
- for (const crypto::hash &txid: remove)
+ try
{
- try
- {
- cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid, relay_category::all);
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(txblob, tx)) // remove pruned ones on startup, they're meant to be temporary
- {
- MERROR("Failed to parse tx from txpool");
- continue;
- }
- // remove tx from db first
- m_blockchain.remove_txpool_tx(txid);
- m_txpool_weight -= get_transaction_weight(tx, txblob.size());
- remove_transaction_keyimages(tx, txid);
- auto sorted_it = find_tx_in_sorted_container(txid);
- if (sorted_it == m_txs_by_fee_and_receive_time.end())
- {
- LOG_PRINT_L1("Removing tx " << txid << " from tx pool, but it was not found in the sorted txs container!");
- }
- else
- {
- m_txs_by_fee_and_receive_time.erase(sorted_it);
- }
- ++n_removed;
- }
- catch (const std::exception &e)
+ size_t weight;
+ uint64_t fee;
+ cryptonote::transaction tx;
+ cryptonote::blobdata blob;
+ bool relayed, do_not_relay, double_spend_seen, pruned;
+ if (!take_tx(e.txid, tx, blob, weight, fee, relayed, do_not_relay, double_spend_seen, pruned))
+ MERROR("Failed to get tx " << e.txid << " from txpool for re-validation");
+
+ cryptonote::tx_verification_context tvc{};
+ relay_method tx_relay = e.meta.get_relay_method();
+ if (!add_tx(tx, e.txid, blob, e.meta.weight, tvc, tx_relay, relayed, version))
{
- MERROR("Failed to remove invalid tx from pool");
- // continue
+ MINFO("Failed to re-validate tx " << e.txid << " for v" << (unsigned)version << ", dropped");
+ continue;
}
+ m_blockchain.update_txpool_tx(e.txid, e.meta);
+ ++added;
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to re-validate tx from pool");
+ continue;
}
- lock.commit();
}
+
+ lock.commit();
+
+ const size_t n_removed = txes.size() - added;
if (n_removed > 0)
++m_cookie;
return n_removed;
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index 5caad3a1a..ebad740cd 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -451,13 +451,6 @@ namespace hw {
ASSERT_X(this->length_recv>=3, "Communication error, less than three bytes received. Check your application version.");
- unsigned int device_version = 0;
- device_version = VERSION(this->buffer_recv[0], this->buffer_recv[1], this->buffer_recv[2]);
-
- ASSERT_X (device_version >= MINIMAL_APP_VERSION,
- "Unsupported device application version: " << VERSION_MAJOR(device_version)<<"."<<VERSION_MINOR(device_version)<<"."<<VERSION_MICRO(device_version) <<
- " At least " << MINIMAL_APP_VERSION_MAJOR<<"."<<MINIMAL_APP_VERSION_MINOR<<"."<<MINIMAL_APP_VERSION_MICRO<<" is required.");
-
return true;
}
@@ -470,6 +463,9 @@ namespace hw {
this->length_recv -= 2;
this->sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1];
logRESP();
+ MDEBUG("Device "<< this->id << " exchange: sw: " << this->sw << " expected: " << ok);
+ ASSERT_X(sw != SW_CLIENT_NOT_SUPPORTED, "Monero Ledger App doesn't support current monero version. Try to update the Monero Ledger App, at least " << MINIMAL_APP_VERSION_MAJOR<< "." << MINIMAL_APP_VERSION_MINOR << "." << MINIMAL_APP_VERSION_MICRO << " is required.");
+ ASSERT_X(sw != SW_PROTOCOL_NOT_SUPPORTED, "Make sure no other program is communicating with the Ledger.");
ASSERT_SW(this->sw,ok,msk);
return this->sw;
diff --git a/tests/unit_tests/long_term_block_weight.cpp b/tests/unit_tests/long_term_block_weight.cpp
index f075034bd..c0b057c9a 100644
--- a/tests/unit_tests/long_term_block_weight.cpp
+++ b/tests/unit_tests/long_term_block_weight.cpp
@@ -106,10 +106,16 @@ static uint32_t lcg()
}
+struct BlockchainAndPool
+{
+ cryptonote::tx_memory_pool txpool;
+ cryptonote::Blockchain bc;
+ BlockchainAndPool(): txpool(bc), bc(txpool) {}
+};
+
#define PREFIX_WINDOW(hf_version,window) \
- std::unique_ptr<cryptonote::Blockchain> bc; \
- cryptonote::tx_memory_pool txpool(*bc); \
- bc.reset(new cryptonote::Blockchain(txpool)); \
+ BlockchainAndPool bap; \
+ cryptonote::Blockchain *bc = &bap.bc; \
struct get_test_options { \
const std::pair<uint8_t, uint64_t> hard_forks[3]; \
const cryptonote::test_options test_options = { \
@@ -118,8 +124,7 @@ static uint32_t lcg()
}; \
get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)1), std::make_pair((uint8_t)0, (uint64_t)0)} {} \
} opts; \
- cryptonote::Blockchain *blockchain = bc.get(); \
- bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \
+ bool r = bc->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \
ASSERT_TRUE(r)
#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW)