Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14864186
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
145 KB
Subscribers
None
View Options
diff --git a/arcanist/linter/ClangFormatLinter.php b/arcanist/linter/ClangFormatLinter.php
index 38899dcf3..fe3dc5a11 100644
--- a/arcanist/linter/ClangFormatLinter.php
+++ b/arcanist/linter/ClangFormatLinter.php
@@ -1,104 +1,106 @@
<?php
/**
* Uses the clang format to format C/C++/Obj-C code
*/
final class ClangFormatLinter extends ArcanistExternalLinter {
public function getInfoName() {
return 'clang-format';
}
public function getInfoURI() {
return '';
}
public function getInfoDescription() {
return pht('Use clang-format for processing specified files.');
}
public function getLinterName() {
return 'clang-format';
}
public function getLinterConfigurationName() {
return 'clang-format';
}
public function getLinterConfigurationOptions() {
$options = array();
return $options + parent::getLinterConfigurationOptions();
}
public function getDefaultBinary() {
return 'clang-format';
}
public function getVersion() {
list($stdout) = execx('%C -version', $this->getExecutableCommand());
$matches = array();
- $regex = '/^clang-format version (?P<version>\d+\.\d+)\./';
+ $regex = '/clang-format version (?P<version>\d+\.\d+)\./';
if (preg_match($regex, $stdout, $matches)) {
$version = $matches['version'];
} else {
- return false;
+ throw new Exception(pht('Unable to read clang-format version. Please '.
+ 'make sure clang-format version 12.x is '.
+ 'installed and in the PATH.'));
}
/*
* FIXME: This is a hack to only allow for clang-format version 12.x.
* The .arclint `version` field only allow to filter versions using `=`,
* `>`, `<`, `>=` or `<=`. There is no facility to define that the required
* version should be >= 12.0 and < 13.0.
*/
if (substr($version, 0, 2) != '12') {
throw new Exception(pht('Linter %s requires clang-format version 12.x. '.
'You have version %s.',
ClangFormatLinter::class,
$version));
}
return $version;
}
public function getInstallInstructions() {
return pht('Make sure clang-format is in directory specified by $PATH');
}
public function shouldExpectCommandErrors() {
return false;
}
protected function getMandatoryFlags() {
return array();
}
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
$ok = ($err == 0);
if (!$ok) {
return false;
}
$root = $this->getProjectRoot();
$path = Filesystem::resolvePath($path, $root);
$orig = file_get_contents($path);
if ($orig == $stdout) {
return array();
}
$message = id(new ArcanistLintMessage())
->setPath($path)
->setLine(1)
->setChar(1)
->setGranularity(ArcanistLinter::GRANULARITY_FILE)
->setCode('CFMT')
->setSeverity(ArcanistLintSeverity::SEVERITY_AUTOFIX)
->setName('Code style violation')
->setDescription("'$path' has code style errors.")
->setOriginalText($orig)
->setReplacementText($stdout);
return array($message);
}
}
diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp
index da2314f2b..05a81265d 100644
--- a/src/crypto/ripemd160.cpp
+++ b/src/crypto/ripemd160.cpp
@@ -1,330 +1,328 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <crypto/ripemd160.h>
#include <crypto/common.h>
#include <cstring>
// Internal implementation code.
namespace {
/// Internal RIPEMD-160 implementation.
namespace ripemd160 {
- inline uint32_t f1(uint32_t x, uint32_t y, uint32_t z) {
- return x ^ y ^ z;
- }
+ inline uint32_t f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
inline uint32_t f2(uint32_t x, uint32_t y, uint32_t z) {
return (x & y) | (~x & z);
}
inline uint32_t f3(uint32_t x, uint32_t y, uint32_t z) {
return (x | ~y) ^ z;
}
inline uint32_t f4(uint32_t x, uint32_t y, uint32_t z) {
return (x & z) | (y & ~z);
}
inline uint32_t f5(uint32_t x, uint32_t y, uint32_t z) {
return x ^ (y | ~z);
}
/** Initialize RIPEMD-160 state. */
inline void Initialize(uint32_t *s) {
s[0] = 0x67452301ul;
s[1] = 0xEFCDAB89ul;
s[2] = 0x98BADCFEul;
s[3] = 0x10325476ul;
s[4] = 0xC3D2E1F0ul;
}
inline uint32_t rol(uint32_t x, int i) {
return (x << i) | (x >> (32 - i));
}
inline void Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) {
a = rol(a + f + x + k, r) + e;
c = rol(c, 10);
}
inline void R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f1(b, c, d), x, 0, r);
}
inline void R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r);
}
inline void R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r);
}
inline void R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r);
}
inline void R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r);
}
inline void R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r);
}
inline void R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r);
}
inline void R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r);
}
inline void R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r);
}
inline void R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d,
uint32_t e, uint32_t x, int r) {
Round(a, b, c, d, e, f1(b, c, d), x, 0, r);
}
/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
void Transform(uint32_t *s, const uint8_t *chunk) {
uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;
uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4),
w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);
uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20),
w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);
uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36),
w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);
uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52),
w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);
R11(a1, b1, c1, d1, e1, w0, 11);
R12(a2, b2, c2, d2, e2, w5, 8);
R11(e1, a1, b1, c1, d1, w1, 14);
R12(e2, a2, b2, c2, d2, w14, 9);
R11(d1, e1, a1, b1, c1, w2, 15);
R12(d2, e2, a2, b2, c2, w7, 9);
R11(c1, d1, e1, a1, b1, w3, 12);
R12(c2, d2, e2, a2, b2, w0, 11);
R11(b1, c1, d1, e1, a1, w4, 5);
R12(b2, c2, d2, e2, a2, w9, 13);
R11(a1, b1, c1, d1, e1, w5, 8);
R12(a2, b2, c2, d2, e2, w2, 15);
R11(e1, a1, b1, c1, d1, w6, 7);
R12(e2, a2, b2, c2, d2, w11, 15);
R11(d1, e1, a1, b1, c1, w7, 9);
R12(d2, e2, a2, b2, c2, w4, 5);
R11(c1, d1, e1, a1, b1, w8, 11);
R12(c2, d2, e2, a2, b2, w13, 7);
R11(b1, c1, d1, e1, a1, w9, 13);
R12(b2, c2, d2, e2, a2, w6, 7);
R11(a1, b1, c1, d1, e1, w10, 14);
R12(a2, b2, c2, d2, e2, w15, 8);
R11(e1, a1, b1, c1, d1, w11, 15);
R12(e2, a2, b2, c2, d2, w8, 11);
R11(d1, e1, a1, b1, c1, w12, 6);
R12(d2, e2, a2, b2, c2, w1, 14);
R11(c1, d1, e1, a1, b1, w13, 7);
R12(c2, d2, e2, a2, b2, w10, 14);
R11(b1, c1, d1, e1, a1, w14, 9);
R12(b2, c2, d2, e2, a2, w3, 12);
R11(a1, b1, c1, d1, e1, w15, 8);
R12(a2, b2, c2, d2, e2, w12, 6);
R21(e1, a1, b1, c1, d1, w7, 7);
R22(e2, a2, b2, c2, d2, w6, 9);
R21(d1, e1, a1, b1, c1, w4, 6);
R22(d2, e2, a2, b2, c2, w11, 13);
R21(c1, d1, e1, a1, b1, w13, 8);
R22(c2, d2, e2, a2, b2, w3, 15);
R21(b1, c1, d1, e1, a1, w1, 13);
R22(b2, c2, d2, e2, a2, w7, 7);
R21(a1, b1, c1, d1, e1, w10, 11);
R22(a2, b2, c2, d2, e2, w0, 12);
R21(e1, a1, b1, c1, d1, w6, 9);
R22(e2, a2, b2, c2, d2, w13, 8);
R21(d1, e1, a1, b1, c1, w15, 7);
R22(d2, e2, a2, b2, c2, w5, 9);
R21(c1, d1, e1, a1, b1, w3, 15);
R22(c2, d2, e2, a2, b2, w10, 11);
R21(b1, c1, d1, e1, a1, w12, 7);
R22(b2, c2, d2, e2, a2, w14, 7);
R21(a1, b1, c1, d1, e1, w0, 12);
R22(a2, b2, c2, d2, e2, w15, 7);
R21(e1, a1, b1, c1, d1, w9, 15);
R22(e2, a2, b2, c2, d2, w8, 12);
R21(d1, e1, a1, b1, c1, w5, 9);
R22(d2, e2, a2, b2, c2, w12, 7);
R21(c1, d1, e1, a1, b1, w2, 11);
R22(c2, d2, e2, a2, b2, w4, 6);
R21(b1, c1, d1, e1, a1, w14, 7);
R22(b2, c2, d2, e2, a2, w9, 15);
R21(a1, b1, c1, d1, e1, w11, 13);
R22(a2, b2, c2, d2, e2, w1, 13);
R21(e1, a1, b1, c1, d1, w8, 12);
R22(e2, a2, b2, c2, d2, w2, 11);
R31(d1, e1, a1, b1, c1, w3, 11);
R32(d2, e2, a2, b2, c2, w15, 9);
R31(c1, d1, e1, a1, b1, w10, 13);
R32(c2, d2, e2, a2, b2, w5, 7);
R31(b1, c1, d1, e1, a1, w14, 6);
R32(b2, c2, d2, e2, a2, w1, 15);
R31(a1, b1, c1, d1, e1, w4, 7);
R32(a2, b2, c2, d2, e2, w3, 11);
R31(e1, a1, b1, c1, d1, w9, 14);
R32(e2, a2, b2, c2, d2, w7, 8);
R31(d1, e1, a1, b1, c1, w15, 9);
R32(d2, e2, a2, b2, c2, w14, 6);
R31(c1, d1, e1, a1, b1, w8, 13);
R32(c2, d2, e2, a2, b2, w6, 6);
R31(b1, c1, d1, e1, a1, w1, 15);
R32(b2, c2, d2, e2, a2, w9, 14);
R31(a1, b1, c1, d1, e1, w2, 14);
R32(a2, b2, c2, d2, e2, w11, 12);
R31(e1, a1, b1, c1, d1, w7, 8);
R32(e2, a2, b2, c2, d2, w8, 13);
R31(d1, e1, a1, b1, c1, w0, 13);
R32(d2, e2, a2, b2, c2, w12, 5);
R31(c1, d1, e1, a1, b1, w6, 6);
R32(c2, d2, e2, a2, b2, w2, 14);
R31(b1, c1, d1, e1, a1, w13, 5);
R32(b2, c2, d2, e2, a2, w10, 13);
R31(a1, b1, c1, d1, e1, w11, 12);
R32(a2, b2, c2, d2, e2, w0, 13);
R31(e1, a1, b1, c1, d1, w5, 7);
R32(e2, a2, b2, c2, d2, w4, 7);
R31(d1, e1, a1, b1, c1, w12, 5);
R32(d2, e2, a2, b2, c2, w13, 5);
R41(c1, d1, e1, a1, b1, w1, 11);
R42(c2, d2, e2, a2, b2, w8, 15);
R41(b1, c1, d1, e1, a1, w9, 12);
R42(b2, c2, d2, e2, a2, w6, 5);
R41(a1, b1, c1, d1, e1, w11, 14);
R42(a2, b2, c2, d2, e2, w4, 8);
R41(e1, a1, b1, c1, d1, w10, 15);
R42(e2, a2, b2, c2, d2, w1, 11);
R41(d1, e1, a1, b1, c1, w0, 14);
R42(d2, e2, a2, b2, c2, w3, 14);
R41(c1, d1, e1, a1, b1, w8, 15);
R42(c2, d2, e2, a2, b2, w11, 14);
R41(b1, c1, d1, e1, a1, w12, 9);
R42(b2, c2, d2, e2, a2, w15, 6);
R41(a1, b1, c1, d1, e1, w4, 8);
R42(a2, b2, c2, d2, e2, w0, 14);
R41(e1, a1, b1, c1, d1, w13, 9);
R42(e2, a2, b2, c2, d2, w5, 6);
R41(d1, e1, a1, b1, c1, w3, 14);
R42(d2, e2, a2, b2, c2, w12, 9);
R41(c1, d1, e1, a1, b1, w7, 5);
R42(c2, d2, e2, a2, b2, w2, 12);
R41(b1, c1, d1, e1, a1, w15, 6);
R42(b2, c2, d2, e2, a2, w13, 9);
R41(a1, b1, c1, d1, e1, w14, 8);
R42(a2, b2, c2, d2, e2, w9, 12);
R41(e1, a1, b1, c1, d1, w5, 6);
R42(e2, a2, b2, c2, d2, w7, 5);
R41(d1, e1, a1, b1, c1, w6, 5);
R42(d2, e2, a2, b2, c2, w10, 15);
R41(c1, d1, e1, a1, b1, w2, 12);
R42(c2, d2, e2, a2, b2, w14, 8);
R51(b1, c1, d1, e1, a1, w4, 9);
R52(b2, c2, d2, e2, a2, w12, 8);
R51(a1, b1, c1, d1, e1, w0, 15);
R52(a2, b2, c2, d2, e2, w15, 5);
R51(e1, a1, b1, c1, d1, w5, 5);
R52(e2, a2, b2, c2, d2, w10, 12);
R51(d1, e1, a1, b1, c1, w9, 11);
R52(d2, e2, a2, b2, c2, w4, 9);
R51(c1, d1, e1, a1, b1, w7, 6);
R52(c2, d2, e2, a2, b2, w1, 12);
R51(b1, c1, d1, e1, a1, w12, 8);
R52(b2, c2, d2, e2, a2, w5, 5);
R51(a1, b1, c1, d1, e1, w2, 13);
R52(a2, b2, c2, d2, e2, w8, 14);
R51(e1, a1, b1, c1, d1, w10, 12);
R52(e2, a2, b2, c2, d2, w7, 6);
R51(d1, e1, a1, b1, c1, w14, 5);
R52(d2, e2, a2, b2, c2, w6, 8);
R51(c1, d1, e1, a1, b1, w1, 12);
R52(c2, d2, e2, a2, b2, w2, 13);
R51(b1, c1, d1, e1, a1, w3, 13);
R52(b2, c2, d2, e2, a2, w13, 6);
R51(a1, b1, c1, d1, e1, w8, 14);
R52(a2, b2, c2, d2, e2, w14, 5);
R51(e1, a1, b1, c1, d1, w11, 11);
R52(e2, a2, b2, c2, d2, w0, 15);
R51(d1, e1, a1, b1, c1, w6, 8);
R52(d2, e2, a2, b2, c2, w3, 13);
R51(c1, d1, e1, a1, b1, w15, 5);
R52(c2, d2, e2, a2, b2, w9, 11);
R51(b1, c1, d1, e1, a1, w13, 6);
R52(b2, c2, d2, e2, a2, w11, 11);
uint32_t t = s[0];
s[0] = s[1] + c1 + d2;
s[1] = s[2] + d1 + e2;
s[2] = s[3] + e1 + a2;
s[3] = s[4] + a1 + b2;
s[4] = t + b1 + c2;
}
} // namespace ripemd160
} // namespace
////// RIPEMD160
CRIPEMD160::CRIPEMD160() : bytes(0) {
ripemd160::Initialize(s);
}
CRIPEMD160 &CRIPEMD160::Write(const uint8_t *data, size_t len) {
const uint8_t *end = data + len;
size_t bufsize = bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
ripemd160::Transform(s, buf);
bufsize = 0;
}
while (end - data >= 64) {
// Process full chunks directly from the source.
ripemd160::Transform(s, data);
bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CRIPEMD160::Finalize(uint8_t hash[OUTPUT_SIZE]) {
static const uint8_t pad[64] = {0x80};
uint8_t sizedesc[8];
WriteLE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
WriteLE32(hash, s[0]);
WriteLE32(hash + 4, s[1]);
WriteLE32(hash + 8, s[2]);
WriteLE32(hash + 12, s[3]);
WriteLE32(hash + 16, s[4]);
}
CRIPEMD160 &CRIPEMD160::Reset() {
bytes = 0;
ripemd160::Initialize(s);
return *this;
}
diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp
index 371c595fe..be514831f 100644
--- a/src/crypto/sha1.cpp
+++ b/src/crypto/sha1.cpp
@@ -1,200 +1,196 @@
// Copyright (c) 2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <crypto/sha1.h>
#include <crypto/common.h>
#include <cstring>
// Internal implementation code.
namespace {
/// Internal SHA-1 implementation.
namespace sha1 {
/** One round of SHA-1. */
inline void Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d,
uint32_t &e, uint32_t f, uint32_t k, uint32_t w) {
e += ((a << 5) | (a >> 27)) + f + k + w;
b = (b << 30) | (b >> 2);
}
inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d) {
return d ^ (b & (c ^ d));
}
- inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d) {
- return b ^ c ^ d;
- }
+ inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d) {
return (b & c) | (d & (b | c));
}
- inline uint32_t left(uint32_t x) {
- return (x << 1) | (x >> 31);
- }
+ inline uint32_t left(uint32_t x) { return (x << 1) | (x >> 31); }
/** Initialize SHA-1 state. */
inline void Initialize(uint32_t *s) {
s[0] = 0x67452301ul;
s[1] = 0xEFCDAB89ul;
s[2] = 0x98BADCFEul;
s[3] = 0x10325476ul;
s[4] = 0xC3D2E1F0ul;
}
const uint32_t k1 = 0x5A827999ul;
const uint32_t k2 = 0x6ED9EBA1ul;
const uint32_t k3 = 0x8F1BBCDCul;
const uint32_t k4 = 0xCA62C1D6ul;
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
void Transform(uint32_t *s, const uint8_t *chunk) {
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13,
w14, w15;
Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));
Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));
Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));
Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));
Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));
Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));
Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));
Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));
Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));
Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));
Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));
Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));
Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));
Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));
Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));
Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));
Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2));
Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3));
Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4));
Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5));
Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));
Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0));
Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1));
Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2));
Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3));
Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4));
Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5));
Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));
Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0));
Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1));
Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2));
Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3));
Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4));
Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5));
Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6));
Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7));
Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8));
Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9));
Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));
Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0));
Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1));
Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2));
Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3));
Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4));
Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5));
Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6));
Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7));
Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8));
Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9));
Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));
Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0));
Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
}
} // namespace sha1
} // namespace
////// SHA1
CSHA1::CSHA1() : bytes(0) {
sha1::Initialize(s);
}
CSHA1 &CSHA1::Write(const uint8_t *data, size_t len) {
const uint8_t *end = data + len;
size_t bufsize = bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha1::Transform(s, buf);
bufsize = 0;
}
while (end - data >= 64) {
// Process full chunks directly from the source.
sha1::Transform(s, data);
bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CSHA1::Finalize(uint8_t hash[OUTPUT_SIZE]) {
static const uint8_t pad[64] = {0x80};
uint8_t sizedesc[8];
WriteBE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
WriteBE32(hash, s[0]);
WriteBE32(hash + 4, s[1]);
WriteBE32(hash + 8, s[2]);
WriteBE32(hash + 12, s[3]);
WriteBE32(hash + 16, s[4]);
}
CSHA1 &CSHA1::Reset() {
bytes = 0;
sha1::Initialize(s);
return *this;
}
diff --git a/src/crypto/sha256_avx2.cpp b/src/crypto/sha256_avx2.cpp
index b43b93d11..01f990256 100644
--- a/src/crypto/sha256_avx2.cpp
+++ b/src/crypto/sha256_avx2.cpp
@@ -1,471 +1,457 @@
// Copyright (c) 2017-2019 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifdef ENABLE_AVX2
#include <cstdint>
#include <immintrin.h>
#include <crypto/common.h>
namespace sha256d64_avx2 {
namespace {
- __m256i inline K(uint32_t x) {
- return _mm256_set1_epi32(x);
- }
+ __m256i inline K(uint32_t x) { return _mm256_set1_epi32(x); }
- __m256i inline Add(__m256i x, __m256i y) {
- return _mm256_add_epi32(x, y);
- }
+ __m256i inline Add(__m256i x, __m256i y) { return _mm256_add_epi32(x, y); }
__m256i inline Add(__m256i x, __m256i y, __m256i z) {
return Add(Add(x, y), z);
}
__m256i inline Add(__m256i x, __m256i y, __m256i z, __m256i w) {
return Add(Add(x, y), Add(z, w));
}
__m256i inline Add(__m256i x, __m256i y, __m256i z, __m256i w, __m256i v) {
return Add(Add(x, y, z), Add(w, v));
}
__m256i inline Inc(__m256i &x, __m256i y) {
x = Add(x, y);
return x;
}
__m256i inline Inc(__m256i &x, __m256i y, __m256i z) {
x = Add(x, y, z);
return x;
}
__m256i inline Inc(__m256i &x, __m256i y, __m256i z, __m256i w) {
x = Add(x, y, z, w);
return x;
}
- __m256i inline Xor(__m256i x, __m256i y) {
- return _mm256_xor_si256(x, y);
- }
+ __m256i inline Xor(__m256i x, __m256i y) { return _mm256_xor_si256(x, y); }
__m256i inline Xor(__m256i x, __m256i y, __m256i z) {
return Xor(Xor(x, y), z);
}
- __m256i inline Or(__m256i x, __m256i y) {
- return _mm256_or_si256(x, y);
- }
- __m256i inline And(__m256i x, __m256i y) {
- return _mm256_and_si256(x, y);
- }
- __m256i inline ShR(__m256i x, int n) {
- return _mm256_srli_epi32(x, n);
- }
- __m256i inline ShL(__m256i x, int n) {
- return _mm256_slli_epi32(x, n);
- }
+ __m256i inline Or(__m256i x, __m256i y) { return _mm256_or_si256(x, y); }
+ __m256i inline And(__m256i x, __m256i y) { return _mm256_and_si256(x, y); }
+ __m256i inline ShR(__m256i x, int n) { return _mm256_srli_epi32(x, n); }
+ __m256i inline ShL(__m256i x, int n) { return _mm256_slli_epi32(x, n); }
__m256i inline Ch(__m256i x, __m256i y, __m256i z) {
return Xor(z, And(x, Xor(y, z)));
}
__m256i inline Maj(__m256i x, __m256i y, __m256i z) {
return Or(And(x, y), And(z, Or(x, y)));
}
__m256i inline Sigma0(__m256i x) {
return Xor(Or(ShR(x, 2), ShL(x, 30)), Or(ShR(x, 13), ShL(x, 19)),
Or(ShR(x, 22), ShL(x, 10)));
}
__m256i inline Sigma1(__m256i x) {
return Xor(Or(ShR(x, 6), ShL(x, 26)), Or(ShR(x, 11), ShL(x, 21)),
Or(ShR(x, 25), ShL(x, 7)));
}
__m256i inline sigma0(__m256i x) {
return Xor(Or(ShR(x, 7), ShL(x, 25)), Or(ShR(x, 18), ShL(x, 14)),
ShR(x, 3));
}
__m256i inline sigma1(__m256i x) {
return Xor(Or(ShR(x, 17), ShL(x, 15)), Or(ShR(x, 19), ShL(x, 13)),
ShR(x, 10));
}
/** One round of SHA-256. */
inline void __attribute__((always_inline))
Round(__m256i a, __m256i b, __m256i c, __m256i &d, __m256i e, __m256i f,
__m256i g, __m256i &h, __m256i k) {
__m256i t1 = Add(h, Sigma1(e), Ch(e, f, g), k);
__m256i t2 = Add(Sigma0(a), Maj(a, b, c));
d = Add(d, t1);
h = Add(t1, t2);
}
__m256i inline Read8(const uint8_t *chunk, int offset) {
__m256i ret = _mm256_set_epi32(
ReadLE32(chunk + 0 + offset), ReadLE32(chunk + 64 + offset),
ReadLE32(chunk + 128 + offset), ReadLE32(chunk + 192 + offset),
ReadLE32(chunk + 256 + offset), ReadLE32(chunk + 320 + offset),
ReadLE32(chunk + 384 + offset), ReadLE32(chunk + 448 + offset));
return _mm256_shuffle_epi8(
ret, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL,
0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL,
0x04050607UL, 0x00010203UL));
}
inline void Write8(uint8_t *out, int offset, __m256i v) {
v = _mm256_shuffle_epi8(
v, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL,
0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL,
0x04050607UL, 0x00010203UL));
WriteLE32(out + 0 + offset, _mm256_extract_epi32(v, 7));
WriteLE32(out + 32 + offset, _mm256_extract_epi32(v, 6));
WriteLE32(out + 64 + offset, _mm256_extract_epi32(v, 5));
WriteLE32(out + 96 + offset, _mm256_extract_epi32(v, 4));
WriteLE32(out + 128 + offset, _mm256_extract_epi32(v, 3));
WriteLE32(out + 160 + offset, _mm256_extract_epi32(v, 2));
WriteLE32(out + 192 + offset, _mm256_extract_epi32(v, 1));
WriteLE32(out + 224 + offset, _mm256_extract_epi32(v, 0));
}
} // namespace
void Transform_8way(uint8_t *out, const uint8_t *in) {
// Transform 1
__m256i a = K(0x6a09e667ul);
__m256i b = K(0xbb67ae85ul);
__m256i c = K(0x3c6ef372ul);
__m256i d = K(0xa54ff53aul);
__m256i e = K(0x510e527ful);
__m256i f = K(0x9b05688cul);
__m256i g = K(0x1f83d9abul);
__m256i h = K(0x5be0cd19ul);
__m256i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14,
w15;
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0 = Read8(in, 0)));
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1 = Read8(in, 4)));
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2 = Read8(in, 8)));
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3 = Read8(in, 12)));
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4 = Read8(in, 16)));
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5 = Read8(in, 20)));
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6 = Read8(in, 24)));
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7 = Read8(in, 28)));
Round(a, b, c, d, e, f, g, h, Add(K(0xd807aa98ul), w8 = Read8(in, 32)));
Round(h, a, b, c, d, e, f, g, Add(K(0x12835b01ul), w9 = Read8(in, 36)));
Round(g, h, a, b, c, d, e, f, Add(K(0x243185beul), w10 = Read8(in, 40)));
Round(f, g, h, a, b, c, d, e, Add(K(0x550c7dc3ul), w11 = Read8(in, 44)));
Round(e, f, g, h, a, b, c, d, Add(K(0x72be5d74ul), w12 = Read8(in, 48)));
Round(d, e, f, g, h, a, b, c, Add(K(0x80deb1feul), w13 = Read8(in, 52)));
Round(c, d, e, f, g, h, a, b, Add(K(0x9bdc06a7ul), w14 = Read8(in, 56)));
Round(b, c, d, e, f, g, h, a, Add(K(0xc19bf174ul), w15 = Read8(in, 60)));
Round(a, b, c, d, e, f, g, h,
Add(K(0xe49b69c1ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xefbe4786ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x983e5152ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa831c66dul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0xb00327c8ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0xbf597fc7ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0xc6e00bf3ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd5a79147ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x06ca6351ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x14292967ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xbef9a3f7ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0xc67178f2ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
a = Add(a, K(0x6a09e667ul));
b = Add(b, K(0xbb67ae85ul));
c = Add(c, K(0x3c6ef372ul));
d = Add(d, K(0xa54ff53aul));
e = Add(e, K(0x510e527ful));
f = Add(f, K(0x9b05688cul));
g = Add(g, K(0x1f83d9abul));
h = Add(h, K(0x5be0cd19ul));
__m256i t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
// Transform 2
Round(a, b, c, d, e, f, g, h, K(0xc28a2f98ul));
Round(h, a, b, c, d, e, f, g, K(0x71374491ul));
Round(g, h, a, b, c, d, e, f, K(0xb5c0fbcful));
Round(f, g, h, a, b, c, d, e, K(0xe9b5dba5ul));
Round(e, f, g, h, a, b, c, d, K(0x3956c25bul));
Round(d, e, f, g, h, a, b, c, K(0x59f111f1ul));
Round(c, d, e, f, g, h, a, b, K(0x923f82a4ul));
Round(b, c, d, e, f, g, h, a, K(0xab1c5ed5ul));
Round(a, b, c, d, e, f, g, h, K(0xd807aa98ul));
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
Round(b, c, d, e, f, g, h, a, K(0xc19bf374ul));
Round(a, b, c, d, e, f, g, h, K(0x649b69c1ul));
Round(h, a, b, c, d, e, f, g, K(0xf0fe4786ul));
Round(g, h, a, b, c, d, e, f, K(0x0fe1edc6ul));
Round(f, g, h, a, b, c, d, e, K(0x240cf254ul));
Round(e, f, g, h, a, b, c, d, K(0x4fe9346ful));
Round(d, e, f, g, h, a, b, c, K(0x6cc984beul));
Round(c, d, e, f, g, h, a, b, K(0x61b9411eul));
Round(b, c, d, e, f, g, h, a, K(0x16f988faul));
Round(a, b, c, d, e, f, g, h, K(0xf2c65152ul));
Round(h, a, b, c, d, e, f, g, K(0xa88e5a6dul));
Round(g, h, a, b, c, d, e, f, K(0xb019fc65ul));
Round(f, g, h, a, b, c, d, e, K(0xb9d99ec7ul));
Round(e, f, g, h, a, b, c, d, K(0x9a1231c3ul));
Round(d, e, f, g, h, a, b, c, K(0xe70eeaa0ul));
Round(c, d, e, f, g, h, a, b, K(0xfdb1232bul));
Round(b, c, d, e, f, g, h, a, K(0xc7353eb0ul));
Round(a, b, c, d, e, f, g, h, K(0x3069bad5ul));
Round(h, a, b, c, d, e, f, g, K(0xcb976d5ful));
Round(g, h, a, b, c, d, e, f, K(0x5a0f118ful));
Round(f, g, h, a, b, c, d, e, K(0xdc1eeefdul));
Round(e, f, g, h, a, b, c, d, K(0x0a35b689ul));
Round(d, e, f, g, h, a, b, c, K(0xde0b7a04ul));
Round(c, d, e, f, g, h, a, b, K(0x58f4ca9dul));
Round(b, c, d, e, f, g, h, a, K(0xe15d5b16ul));
Round(a, b, c, d, e, f, g, h, K(0x007f3e86ul));
Round(h, a, b, c, d, e, f, g, K(0x37088980ul));
Round(g, h, a, b, c, d, e, f, K(0xa507ea32ul));
Round(f, g, h, a, b, c, d, e, K(0x6fab9537ul));
Round(e, f, g, h, a, b, c, d, K(0x17406110ul));
Round(d, e, f, g, h, a, b, c, K(0x0d8cd6f1ul));
Round(c, d, e, f, g, h, a, b, K(0xcdaa3b6dul));
Round(b, c, d, e, f, g, h, a, K(0xc0bbbe37ul));
Round(a, b, c, d, e, f, g, h, K(0x83613bdaul));
Round(h, a, b, c, d, e, f, g, K(0xdb48a363ul));
Round(g, h, a, b, c, d, e, f, K(0x0b02e931ul));
Round(f, g, h, a, b, c, d, e, K(0x6fd15ca7ul));
Round(e, f, g, h, a, b, c, d, K(0x521afacaul));
Round(d, e, f, g, h, a, b, c, K(0x31338431ul));
Round(c, d, e, f, g, h, a, b, K(0x6ed41a95ul));
Round(b, c, d, e, f, g, h, a, K(0x6d437890ul));
Round(a, b, c, d, e, f, g, h, K(0xc39c91f2ul));
Round(h, a, b, c, d, e, f, g, K(0x9eccabbdul));
Round(g, h, a, b, c, d, e, f, K(0xb5c9a0e6ul));
Round(f, g, h, a, b, c, d, e, K(0x532fb63cul));
Round(e, f, g, h, a, b, c, d, K(0xd2c741c6ul));
Round(d, e, f, g, h, a, b, c, K(0x07237ea3ul));
Round(c, d, e, f, g, h, a, b, K(0xa4954b68ul));
Round(b, c, d, e, f, g, h, a, K(0x4c191d76ul));
w0 = Add(t0, a);
w1 = Add(t1, b);
w2 = Add(t2, c);
w3 = Add(t3, d);
w4 = Add(t4, e);
w5 = Add(t5, f);
w6 = Add(t6, g);
w7 = Add(t7, h);
// Transform 3
a = K(0x6a09e667ul);
b = K(0xbb67ae85ul);
c = K(0x3c6ef372ul);
d = K(0xa54ff53aul);
e = K(0x510e527ful);
f = K(0x9b05688cul);
g = K(0x1f83d9abul);
h = K(0x5be0cd19ul);
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0));
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1));
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2));
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3));
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4));
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5));
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6));
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7));
Round(a, b, c, d, e, f, g, h, K(0x5807aa98ul));
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
Round(b, c, d, e, f, g, h, a, K(0xc19bf274ul));
Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xefbe4786ul), Inc(w1, K(0xa00000ul), sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), K(0x100ul), sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, K(0x11002000ul))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x983e5152ul), w8 = Add(K(0x80000000ul), sigma1(w6), w1)));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa831c66dul), w9 = Add(sigma1(w7), w2)));
Round(g, h, a, b, c, d, e, f,
Add(K(0xb00327c8ul), w10 = Add(sigma1(w8), w3)));
Round(f, g, h, a, b, c, d, e,
Add(K(0xbf597fc7ul), w11 = Add(sigma1(w9), w4)));
Round(e, f, g, h, a, b, c, d,
Add(K(0xc6e00bf3ul), w12 = Add(sigma1(w10), w5)));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd5a79147ul), w13 = Add(sigma1(w11), w6)));
Round(c, d, e, f, g, h, a, b,
Add(K(0x06ca6351ul), w14 = Add(sigma1(w12), w7, K(0x400022ul))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x14292967ul),
w15 = Add(K(0x100ul), sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xbef9a3f7ul), w14, sigma1(w12), w7, sigma0(w15)));
Round(b, c, d, e, f, g, h, a,
Add(K(0xc67178f2ul), w15, sigma1(w13), w8, sigma0(w0)));
// Output
Write8(out, 0, Add(a, K(0x6a09e667ul)));
Write8(out, 4, Add(b, K(0xbb67ae85ul)));
Write8(out, 8, Add(c, K(0x3c6ef372ul)));
Write8(out, 12, Add(d, K(0xa54ff53aul)));
Write8(out, 16, Add(e, K(0x510e527ful)));
Write8(out, 20, Add(f, K(0x9b05688cul)));
Write8(out, 24, Add(g, K(0x1f83d9abul)));
Write8(out, 28, Add(h, K(0x5be0cd19ul)));
}
} // namespace sha256d64_avx2
#endif
diff --git a/src/crypto/sha256_sse41.cpp b/src/crypto/sha256_sse41.cpp
index d3ce6f448..2f5a4dbda 100644
--- a/src/crypto/sha256_sse41.cpp
+++ b/src/crypto/sha256_sse41.cpp
@@ -1,461 +1,447 @@
// Copyright (c) 2017-2019 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifdef ENABLE_SSE41
#include <cstdint>
#include <immintrin.h>
#include <crypto/common.h>
namespace sha256d64_sse41 {
namespace {
- __m128i inline K(uint32_t x) {
- return _mm_set1_epi32(x);
- }
+ __m128i inline K(uint32_t x) { return _mm_set1_epi32(x); }
- __m128i inline Add(__m128i x, __m128i y) {
- return _mm_add_epi32(x, y);
- }
+ __m128i inline Add(__m128i x, __m128i y) { return _mm_add_epi32(x, y); }
__m128i inline Add(__m128i x, __m128i y, __m128i z) {
return Add(Add(x, y), z);
}
__m128i inline Add(__m128i x, __m128i y, __m128i z, __m128i w) {
return Add(Add(x, y), Add(z, w));
}
__m128i inline Add(__m128i x, __m128i y, __m128i z, __m128i w, __m128i v) {
return Add(Add(x, y, z), Add(w, v));
}
__m128i inline Inc(__m128i &x, __m128i y) {
x = Add(x, y);
return x;
}
__m128i inline Inc(__m128i &x, __m128i y, __m128i z) {
x = Add(x, y, z);
return x;
}
__m128i inline Inc(__m128i &x, __m128i y, __m128i z, __m128i w) {
x = Add(x, y, z, w);
return x;
}
- __m128i inline Xor(__m128i x, __m128i y) {
- return _mm_xor_si128(x, y);
- }
+ __m128i inline Xor(__m128i x, __m128i y) { return _mm_xor_si128(x, y); }
__m128i inline Xor(__m128i x, __m128i y, __m128i z) {
return Xor(Xor(x, y), z);
}
- __m128i inline Or(__m128i x, __m128i y) {
- return _mm_or_si128(x, y);
- }
- __m128i inline And(__m128i x, __m128i y) {
- return _mm_and_si128(x, y);
- }
- __m128i inline ShR(__m128i x, int n) {
- return _mm_srli_epi32(x, n);
- }
- __m128i inline ShL(__m128i x, int n) {
- return _mm_slli_epi32(x, n);
- }
+ __m128i inline Or(__m128i x, __m128i y) { return _mm_or_si128(x, y); }
+ __m128i inline And(__m128i x, __m128i y) { return _mm_and_si128(x, y); }
+ __m128i inline ShR(__m128i x, int n) { return _mm_srli_epi32(x, n); }
+ __m128i inline ShL(__m128i x, int n) { return _mm_slli_epi32(x, n); }
__m128i inline Ch(__m128i x, __m128i y, __m128i z) {
return Xor(z, And(x, Xor(y, z)));
}
__m128i inline Maj(__m128i x, __m128i y, __m128i z) {
return Or(And(x, y), And(z, Or(x, y)));
}
__m128i inline Sigma0(__m128i x) {
return Xor(Or(ShR(x, 2), ShL(x, 30)), Or(ShR(x, 13), ShL(x, 19)),
Or(ShR(x, 22), ShL(x, 10)));
}
__m128i inline Sigma1(__m128i x) {
return Xor(Or(ShR(x, 6), ShL(x, 26)), Or(ShR(x, 11), ShL(x, 21)),
Or(ShR(x, 25), ShL(x, 7)));
}
__m128i inline sigma0(__m128i x) {
return Xor(Or(ShR(x, 7), ShL(x, 25)), Or(ShR(x, 18), ShL(x, 14)),
ShR(x, 3));
}
__m128i inline sigma1(__m128i x) {
return Xor(Or(ShR(x, 17), ShL(x, 15)), Or(ShR(x, 19), ShL(x, 13)),
ShR(x, 10));
}
/** One round of SHA-256. */
inline void __attribute__((always_inline))
Round(__m128i a, __m128i b, __m128i c, __m128i &d, __m128i e, __m128i f,
__m128i g, __m128i &h, __m128i k) {
__m128i t1 = Add(h, Sigma1(e), Ch(e, f, g), k);
__m128i t2 = Add(Sigma0(a), Maj(a, b, c));
d = Add(d, t1);
h = Add(t1, t2);
}
__m128i inline Read4(const uint8_t *chunk, int offset) {
__m128i ret = _mm_set_epi32(
ReadLE32(chunk + 0 + offset), ReadLE32(chunk + 64 + offset),
ReadLE32(chunk + 128 + offset), ReadLE32(chunk + 192 + offset));
return _mm_shuffle_epi8(ret, _mm_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL,
0x04050607UL, 0x00010203UL));
}
inline void Write4(uint8_t *out, int offset, __m128i v) {
v = _mm_shuffle_epi8(v, _mm_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL,
0x04050607UL, 0x00010203UL));
WriteLE32(out + 0 + offset, _mm_extract_epi32(v, 3));
WriteLE32(out + 32 + offset, _mm_extract_epi32(v, 2));
WriteLE32(out + 64 + offset, _mm_extract_epi32(v, 1));
WriteLE32(out + 96 + offset, _mm_extract_epi32(v, 0));
}
} // namespace
void Transform_4way(uint8_t *out, const uint8_t *in) {
// Transform 1
__m128i a = K(0x6a09e667ul);
__m128i b = K(0xbb67ae85ul);
__m128i c = K(0x3c6ef372ul);
__m128i d = K(0xa54ff53aul);
__m128i e = K(0x510e527ful);
__m128i f = K(0x9b05688cul);
__m128i g = K(0x1f83d9abul);
__m128i h = K(0x5be0cd19ul);
__m128i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14,
w15;
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0 = Read4(in, 0)));
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1 = Read4(in, 4)));
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2 = Read4(in, 8)));
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3 = Read4(in, 12)));
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4 = Read4(in, 16)));
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5 = Read4(in, 20)));
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6 = Read4(in, 24)));
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7 = Read4(in, 28)));
Round(a, b, c, d, e, f, g, h, Add(K(0xd807aa98ul), w8 = Read4(in, 32)));
Round(h, a, b, c, d, e, f, g, Add(K(0x12835b01ul), w9 = Read4(in, 36)));
Round(g, h, a, b, c, d, e, f, Add(K(0x243185beul), w10 = Read4(in, 40)));
Round(f, g, h, a, b, c, d, e, Add(K(0x550c7dc3ul), w11 = Read4(in, 44)));
Round(e, f, g, h, a, b, c, d, Add(K(0x72be5d74ul), w12 = Read4(in, 48)));
Round(d, e, f, g, h, a, b, c, Add(K(0x80deb1feul), w13 = Read4(in, 52)));
Round(c, d, e, f, g, h, a, b, Add(K(0x9bdc06a7ul), w14 = Read4(in, 56)));
Round(b, c, d, e, f, g, h, a, Add(K(0xc19bf174ul), w15 = Read4(in, 60)));
Round(a, b, c, d, e, f, g, h,
Add(K(0xe49b69c1ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xefbe4786ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x983e5152ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa831c66dul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0xb00327c8ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0xbf597fc7ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0xc6e00bf3ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd5a79147ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x06ca6351ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x14292967ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xbef9a3f7ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0xc67178f2ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
a = Add(a, K(0x6a09e667ul));
b = Add(b, K(0xbb67ae85ul));
c = Add(c, K(0x3c6ef372ul));
d = Add(d, K(0xa54ff53aul));
e = Add(e, K(0x510e527ful));
f = Add(f, K(0x9b05688cul));
g = Add(g, K(0x1f83d9abul));
h = Add(h, K(0x5be0cd19ul));
__m128i t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
// Transform 2
Round(a, b, c, d, e, f, g, h, K(0xc28a2f98ul));
Round(h, a, b, c, d, e, f, g, K(0x71374491ul));
Round(g, h, a, b, c, d, e, f, K(0xb5c0fbcful));
Round(f, g, h, a, b, c, d, e, K(0xe9b5dba5ul));
Round(e, f, g, h, a, b, c, d, K(0x3956c25bul));
Round(d, e, f, g, h, a, b, c, K(0x59f111f1ul));
Round(c, d, e, f, g, h, a, b, K(0x923f82a4ul));
Round(b, c, d, e, f, g, h, a, K(0xab1c5ed5ul));
Round(a, b, c, d, e, f, g, h, K(0xd807aa98ul));
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
Round(b, c, d, e, f, g, h, a, K(0xc19bf374ul));
Round(a, b, c, d, e, f, g, h, K(0x649b69c1ul));
Round(h, a, b, c, d, e, f, g, K(0xf0fe4786ul));
Round(g, h, a, b, c, d, e, f, K(0x0fe1edc6ul));
Round(f, g, h, a, b, c, d, e, K(0x240cf254ul));
Round(e, f, g, h, a, b, c, d, K(0x4fe9346ful));
Round(d, e, f, g, h, a, b, c, K(0x6cc984beul));
Round(c, d, e, f, g, h, a, b, K(0x61b9411eul));
Round(b, c, d, e, f, g, h, a, K(0x16f988faul));
Round(a, b, c, d, e, f, g, h, K(0xf2c65152ul));
Round(h, a, b, c, d, e, f, g, K(0xa88e5a6dul));
Round(g, h, a, b, c, d, e, f, K(0xb019fc65ul));
Round(f, g, h, a, b, c, d, e, K(0xb9d99ec7ul));
Round(e, f, g, h, a, b, c, d, K(0x9a1231c3ul));
Round(d, e, f, g, h, a, b, c, K(0xe70eeaa0ul));
Round(c, d, e, f, g, h, a, b, K(0xfdb1232bul));
Round(b, c, d, e, f, g, h, a, K(0xc7353eb0ul));
Round(a, b, c, d, e, f, g, h, K(0x3069bad5ul));
Round(h, a, b, c, d, e, f, g, K(0xcb976d5ful));
Round(g, h, a, b, c, d, e, f, K(0x5a0f118ful));
Round(f, g, h, a, b, c, d, e, K(0xdc1eeefdul));
Round(e, f, g, h, a, b, c, d, K(0x0a35b689ul));
Round(d, e, f, g, h, a, b, c, K(0xde0b7a04ul));
Round(c, d, e, f, g, h, a, b, K(0x58f4ca9dul));
Round(b, c, d, e, f, g, h, a, K(0xe15d5b16ul));
Round(a, b, c, d, e, f, g, h, K(0x007f3e86ul));
Round(h, a, b, c, d, e, f, g, K(0x37088980ul));
Round(g, h, a, b, c, d, e, f, K(0xa507ea32ul));
Round(f, g, h, a, b, c, d, e, K(0x6fab9537ul));
Round(e, f, g, h, a, b, c, d, K(0x17406110ul));
Round(d, e, f, g, h, a, b, c, K(0x0d8cd6f1ul));
Round(c, d, e, f, g, h, a, b, K(0xcdaa3b6dul));
Round(b, c, d, e, f, g, h, a, K(0xc0bbbe37ul));
Round(a, b, c, d, e, f, g, h, K(0x83613bdaul));
Round(h, a, b, c, d, e, f, g, K(0xdb48a363ul));
Round(g, h, a, b, c, d, e, f, K(0x0b02e931ul));
Round(f, g, h, a, b, c, d, e, K(0x6fd15ca7ul));
Round(e, f, g, h, a, b, c, d, K(0x521afacaul));
Round(d, e, f, g, h, a, b, c, K(0x31338431ul));
Round(c, d, e, f, g, h, a, b, K(0x6ed41a95ul));
Round(b, c, d, e, f, g, h, a, K(0x6d437890ul));
Round(a, b, c, d, e, f, g, h, K(0xc39c91f2ul));
Round(h, a, b, c, d, e, f, g, K(0x9eccabbdul));
Round(g, h, a, b, c, d, e, f, K(0xb5c9a0e6ul));
Round(f, g, h, a, b, c, d, e, K(0x532fb63cul));
Round(e, f, g, h, a, b, c, d, K(0xd2c741c6ul));
Round(d, e, f, g, h, a, b, c, K(0x07237ea3ul));
Round(c, d, e, f, g, h, a, b, K(0xa4954b68ul));
Round(b, c, d, e, f, g, h, a, K(0x4c191d76ul));
w0 = Add(t0, a);
w1 = Add(t1, b);
w2 = Add(t2, c);
w3 = Add(t3, d);
w4 = Add(t4, e);
w5 = Add(t5, f);
w6 = Add(t6, g);
w7 = Add(t7, h);
// Transform 3
a = K(0x6a09e667ul);
b = K(0xbb67ae85ul);
c = K(0x3c6ef372ul);
d = K(0xa54ff53aul);
e = K(0x510e527ful);
f = K(0x9b05688cul);
g = K(0x1f83d9abul);
h = K(0x5be0cd19ul);
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0));
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1));
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2));
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3));
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4));
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5));
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6));
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7));
Round(a, b, c, d, e, f, g, h, K(0x5807aa98ul));
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
Round(b, c, d, e, f, g, h, a, K(0xc19bf274ul));
Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xefbe4786ul), Inc(w1, K(0xa00000ul), sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), K(0x100ul), sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, K(0x11002000ul))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x983e5152ul), w8 = Add(K(0x80000000ul), sigma1(w6), w1)));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa831c66dul), w9 = Add(sigma1(w7), w2)));
Round(g, h, a, b, c, d, e, f,
Add(K(0xb00327c8ul), w10 = Add(sigma1(w8), w3)));
Round(f, g, h, a, b, c, d, e,
Add(K(0xbf597fc7ul), w11 = Add(sigma1(w9), w4)));
Round(e, f, g, h, a, b, c, d,
Add(K(0xc6e00bf3ul), w12 = Add(sigma1(w10), w5)));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd5a79147ul), w13 = Add(sigma1(w11), w6)));
Round(c, d, e, f, g, h, a, b,
Add(K(0x06ca6351ul), w14 = Add(sigma1(w12), w7, K(0x400022ul))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x14292967ul),
w15 = Add(K(0x100ul), sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
Round(d, e, f, g, h, a, b, c,
Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
Round(c, d, e, f, g, h, a, b,
Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
Round(b, c, d, e, f, g, h, a,
Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
Round(a, b, c, d, e, f, g, h,
Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
Round(h, a, b, c, d, e, f, g,
Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
Round(g, h, a, b, c, d, e, f,
Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
Round(f, g, h, a, b, c, d, e,
Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
Round(e, f, g, h, a, b, c, d,
Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
Round(d, e, f, g, h, a, b, c,
Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
Round(c, d, e, f, g, h, a, b,
Add(K(0xbef9a3f7ul), w14, sigma1(w12), w7, sigma0(w15)));
Round(b, c, d, e, f, g, h, a,
Add(K(0xc67178f2ul), w15, sigma1(w13), w8, sigma0(w0)));
// Output
Write4(out, 0, Add(a, K(0x6a09e667ul)));
Write4(out, 4, Add(b, K(0xbb67ae85ul)));
Write4(out, 8, Add(c, K(0x3c6ef372ul)));
Write4(out, 12, Add(d, K(0xa54ff53aul)));
Write4(out, 16, Add(e, K(0x510e527ful)));
Write4(out, 20, Add(f, K(0x9b05688cul)));
Write4(out, 24, Add(g, K(0x1f83d9abul)));
Write4(out, 28, Add(h, K(0x5be0cd19ul)));
}
} // namespace sha256d64_sse41
#endif
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 9d9c3ec50..57d049d0c 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -1,1658 +1,1659 @@
// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <qt/bitcoingui.h>
#include <chain.h>
#include <chainparams.h>
#include <config.h>
#include <interfaces/handler.h>
#include <interfaces/node.h>
#include <node/ui_interface.h>
#include <qt/bitcoinunits.h>
#include <qt/clientmodel.h>
#include <qt/createwalletdialog.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#ifdef Q_OS_MAC
#include <qt/macdockiconhandler.h>
#endif
#include <qt/modaloverlay.h>
#include <qt/networkstyle.h>
#include <qt/notificator.h>
#include <qt/openuridialog.h>
#include <qt/optionsmodel.h>
#include <qt/platformstyle.h>
#include <qt/rpcconsole.h>
#include <qt/utilitydialog.h>
#ifdef ENABLE_WALLET
#include <qt/walletcontroller.h>
#include <qt/walletframe.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
#endif // ENABLE_WALLET
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
#include <functional>
#include <memory>
#include <QAction>
#include <QApplication>
#include <QComboBox>
#include <QDateTime>
#include <QDragEnterEvent>
#include <QListWidget>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QMimeData>
#include <QProgressDialog>
#include <QScreen>
#include <QSettings>
#include <QShortcut>
#include <QStackedWidget>
#include <QStatusBar>
#include <QStyle>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QToolBar>
#include <QUrlQuery>
#include <QVBoxLayout>
#include <QWindow>
const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
#if defined(Q_OS_MAC)
"macosx"
#elif defined(Q_OS_WIN)
"windows"
#else
"other"
#endif
;
BitcoinGUI::BitcoinGUI(interfaces::Node &node, const Config *configIn,
const PlatformStyle *_platformStyle,
const NetworkStyle *networkStyle, QWidget *parent)
: QMainWindow(parent), m_node(node), trayIconMenu{new QMenu()},
config(configIn), platformStyle(_platformStyle),
m_network_style(networkStyle) {
QSettings settings;
if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
// Restore failed (perhaps missing setting), center the window
move(QGuiApplication::primaryScreen()->availableGeometry().center() -
frameGeometry().center());
}
#ifdef ENABLE_WALLET
enableWallet = WalletModel::isWalletEnabled();
#endif // ENABLE_WALLET
QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
setWindowIcon(m_network_style->getTrayAndWindowIcon());
updateWindowTitle();
rpcConsole = new RPCConsole(node, _platformStyle, nullptr);
helpMessageDialog = new HelpMessageDialog(this, false);
#ifdef ENABLE_WALLET
if (enableWallet) {
/** Create wallet frame and make it the central widget */
walletFrame = new WalletFrame(_platformStyle, this);
setCentralWidget(walletFrame);
} else
#endif // ENABLE_WALLET
{
/**
* When compiled without wallet or -disablewallet is provided, the
* central widget is the rpc console.
*/
setCentralWidget(rpcConsole);
Q_EMIT consoleShown(rpcConsole);
}
modalOverlay = new ModalOverlay(enableWallet, this->centralWidget());
// Accept D&D of URIs
setAcceptDrops(true);
// Create actions for the toolbar, menu bar and tray/dock icon
// Needs walletFrame to be initialized
createActions();
// Create application menu bar
createMenuBar();
// Create the toolbars
createToolBars();
// Create system tray icon and notification
if (QSystemTrayIcon::isSystemTrayAvailable()) {
createTrayIcon();
}
notificator =
new Notificator(QApplication::applicationName(), trayIcon, this);
// Create status bar
statusBar();
// Disable size grip because it looks ugly and nobody needs it
statusBar()->setSizeGripEnabled(false);
// Status bar notification icons
QFrame *frameBlocks = new QFrame();
frameBlocks->setContentsMargins(0, 0, 0, 0);
frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
frameBlocksLayout->setContentsMargins(3, 0, 3, 0);
frameBlocksLayout->setSpacing(3);
unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
labelWalletEncryptionIcon = new QLabel();
labelWalletHDStatusIcon = new QLabel();
labelProxyIcon = new GUIUtil::ClickableLabel();
connectionsControl = new GUIUtil::ClickableLabel();
labelBlocksIcon = new GUIUtil::ClickableLabel();
if (enableWallet) {
frameBlocksLayout->addStretch();
frameBlocksLayout->addWidget(unitDisplayControl);
frameBlocksLayout->addStretch();
frameBlocksLayout->addWidget(labelWalletEncryptionIcon);
frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
}
frameBlocksLayout->addWidget(labelProxyIcon);
frameBlocksLayout->addStretch();
frameBlocksLayout->addWidget(connectionsControl);
frameBlocksLayout->addStretch();
frameBlocksLayout->addWidget(labelBlocksIcon);
frameBlocksLayout->addStretch();
// Progress bar and label for blocks download
progressBarLabel = new QLabel();
progressBarLabel->setVisible(false);
progressBar = new GUIUtil::ProgressBar();
progressBar->setAlignment(Qt::AlignCenter);
progressBar->setVisible(false);
// Override style sheet for progress bar for styles that have a segmented
// progress bar, as they make the text unreadable (workaround for issue
// #1071)
// See https://doc.qt.io/qt-5/gallery.html
QString curStyle = QApplication::style()->metaObject()->className();
if (curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle") {
progressBar->setStyleSheet(
"QProgressBar { background-color: #e8e8e8; border: 1px solid grey; "
"border-radius: 7px; padding: 1px; text-align: center; } "
"QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, "
"x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: "
"7px; margin: 0px; }");
}
statusBar()->addWidget(progressBarLabel);
statusBar()->addWidget(progressBar);
statusBar()->addPermanentWidget(frameBlocks);
// Install event filter to be able to catch status tip events
// (QEvent::StatusTip)
this->installEventFilter(this);
// Initially wallet actions should be disabled
setWalletActionsEnabled(false);
// Subscribe to notifications from core
subscribeToCoreSignals();
connect(connectionsControl, &GUIUtil::ClickableLabel::clicked,
[this] { m_node.setNetworkActive(!m_node.getNetworkActive()); });
connect(labelProxyIcon, &GUIUtil::ClickableLabel::clicked,
[this] { openOptionsDialogWithTab(OptionsDialog::TAB_NETWORK); });
connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this,
&BitcoinGUI::showModalOverlay);
connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this,
&BitcoinGUI::showModalOverlay);
#ifdef ENABLE_WALLET
if (enableWallet) {
connect(walletFrame, &WalletFrame::requestedSyncWarningInfo, this,
&BitcoinGUI::showModalOverlay);
}
#endif
#ifdef Q_OS_MAC
m_app_nap_inhibitor = new CAppNapInhibitor;
#endif
GUIUtil::handleCloseWindowShortcut(this);
}
BitcoinGUI::~BitcoinGUI() {
// Unsubscribe from notifications from core
unsubscribeFromCoreSignals();
QSettings settings;
settings.setValue("MainWindowGeometry", saveGeometry());
// Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
if (trayIcon) {
trayIcon->hide();
}
#ifdef Q_OS_MAC
delete m_app_nap_inhibitor;
delete appMenuBar;
MacDockIconHandler::cleanup();
#endif
delete rpcConsole;
}
void BitcoinGUI::createActions() {
QActionGroup *tabGroup = new QActionGroup(this);
connect(modalOverlay, &ModalOverlay::triggered, tabGroup,
&QActionGroup::setEnabled);
overviewAction =
new QAction(platformStyle->SingleColorIcon(":/icons/overview"),
tr("&Overview"), this);
overviewAction->setStatusTip(tr("Show general overview of wallet"));
overviewAction->setToolTip(overviewAction->statusTip());
overviewAction->setCheckable(true);
overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
tabGroup->addAction(overviewAction);
sendCoinsAction = new QAction(
platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
sendCoinsAction->setCheckable(true);
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
sendCoinsMenuAction = new QAction(sendCoinsAction->text(), this);
sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
receiveCoinsAction = new QAction(
platformStyle->SingleColorIcon(":/icons/receiving_addresses"),
tr("&Receive"), this);
receiveCoinsAction->setStatusTip(
tr("Request payments (generates QR codes and %1: URIs)")
.arg(QString::fromStdString(
config->GetChainParams().CashAddrPrefix())));
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
receiveCoinsAction->setCheckable(true);
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
tabGroup->addAction(receiveCoinsAction);
receiveCoinsMenuAction = new QAction(receiveCoinsAction->text(), this);
receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
historyAction =
new QAction(platformStyle->SingleColorIcon(":/icons/history"),
tr("&Transactions"), this);
historyAction->setStatusTip(tr("Browse transaction history"));
historyAction->setToolTip(historyAction->statusTip());
historyAction->setCheckable(true);
historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
tabGroup->addAction(historyAction);
#ifdef ENABLE_WALLET
// These showNormalIfMinimized are needed because Send Coins and Receive
// Coins can be triggered from the tray menu, and need to show the GUI to be
// useful.
connect(overviewAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(overviewAction, &QAction::triggered, this,
&BitcoinGUI::gotoOverviewPage);
connect(sendCoinsAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(sendCoinsAction, &QAction::triggered,
[this] { gotoSendCoinsPage(); });
connect(sendCoinsMenuAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(sendCoinsMenuAction, &QAction::triggered,
[this] { gotoSendCoinsPage(); });
connect(receiveCoinsAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(receiveCoinsAction, &QAction::triggered, this,
&BitcoinGUI::gotoReceiveCoinsPage);
connect(receiveCoinsMenuAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(receiveCoinsMenuAction, &QAction::triggered, this,
&BitcoinGUI::gotoReceiveCoinsPage);
connect(historyAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(historyAction, &QAction::triggered, this,
&BitcoinGUI::gotoHistoryPage);
#endif // ENABLE_WALLET
quitAction = new QAction(tr("E&xit"), this);
quitAction->setStatusTip(tr("Quit application"));
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
quitAction->setMenuRole(QAction::QuitRole);
aboutAction = new QAction(tr("&About %1").arg(PACKAGE_NAME), this);
aboutAction->setStatusTip(
tr("Show information about %1").arg(PACKAGE_NAME));
aboutAction->setMenuRole(QAction::AboutRole);
aboutAction->setEnabled(false);
aboutQtAction = new QAction(tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show information about Qt"));
aboutQtAction->setMenuRole(QAction::AboutQtRole);
optionsAction = new QAction(tr("&Options..."), this);
optionsAction->setStatusTip(
tr("Modify configuration options for %1").arg(PACKAGE_NAME));
optionsAction->setMenuRole(QAction::PreferencesRole);
optionsAction->setEnabled(false);
toggleHideAction = new QAction(tr("&Show / Hide"), this);
toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
encryptWalletAction = new QAction(tr("&Encrypt Wallet..."), this);
encryptWalletAction->setStatusTip(
tr("Encrypt the private keys that belong to your wallet"));
encryptWalletAction->setCheckable(true);
backupWalletAction = new QAction(tr("&Backup Wallet..."), this);
backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
changePassphraseAction = new QAction(tr("&Change Passphrase..."), this);
changePassphraseAction->setStatusTip(
tr("Change the passphrase used for wallet encryption"));
signMessageAction = new QAction(tr("Sign &message..."), this);
signMessageAction->setStatusTip(
tr("Sign messages with your Bitcoin addresses to prove you own them"));
verifyMessageAction = new QAction(tr("&Verify message..."), this);
verifyMessageAction->setStatusTip(
tr("Verify messages to ensure they were signed with specified Bitcoin "
"addresses"));
m_load_psbt_action = new QAction(tr("Load PSBT..."), this);
m_load_psbt_action->setStatusTip(
tr("Load Partially Signed Bitcoin Transaction"));
openRPCConsoleAction = new QAction(tr("&Debug window"), this);
openRPCConsoleAction->setStatusTip(
tr("Open node debugging and diagnostic console"));
// initially disable the debug window menu item
openRPCConsoleAction->setEnabled(false);
openRPCConsoleAction->setObjectName("openRPCConsoleAction");
usedSendingAddressesAction = new QAction(tr("&Sending addresses"), this);
usedSendingAddressesAction->setStatusTip(
tr("Show the list of used sending addresses and labels"));
usedReceivingAddressesAction =
new QAction(tr("&Receiving addresses"), this);
usedReceivingAddressesAction->setStatusTip(
tr("Show the list of used receiving addresses and labels"));
openAction = new QAction(tr("Open &URI..."), this);
openAction->setStatusTip(
tr("Open a %1: URI or payment request")
.arg(QString::fromStdString(
config->GetChainParams().CashAddrPrefix())));
m_open_wallet_action = new QAction(tr("Open Wallet"), this);
m_open_wallet_action->setEnabled(false);
m_open_wallet_action->setStatusTip(tr("Open a wallet"));
m_open_wallet_menu = new QMenu(this);
m_close_wallet_action = new QAction(tr("Close Wallet..."), this);
m_close_wallet_action->setStatusTip(tr("Close wallet"));
m_create_wallet_action = new QAction(tr("Create Wallet..."), this);
m_create_wallet_action->setEnabled(false);
m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
m_close_all_wallets_action = new QAction(tr("Close All Wallets..."), this);
m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
showHelpMessageAction = new QAction(tr("&Command-line options"), this);
showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(
tr("Show the %1 help message to get a list with possible Bitcoin "
"command-line options")
.arg(PACKAGE_NAME));
m_mask_values_action = new QAction(tr("&Mask values"), this);
m_mask_values_action->setShortcut(
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_M));
m_mask_values_action->setStatusTip(
tr("Mask the values in the Overview tab"));
m_mask_values_action->setCheckable(true);
connect(quitAction, &QAction::triggered, qApp, QApplication::quit);
connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked);
connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt);
connect(optionsAction, &QAction::triggered, this,
&BitcoinGUI::optionsClicked);
connect(toggleHideAction, &QAction::triggered, this,
&BitcoinGUI::toggleHidden);
connect(showHelpMessageAction, &QAction::triggered, this,
&BitcoinGUI::showHelpMessageClicked);
connect(openRPCConsoleAction, &QAction::triggered, this,
&BitcoinGUI::showDebugWindow);
// prevents an open debug window from becoming stuck/unusable on client
// shutdown
connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide);
#ifdef ENABLE_WALLET
if (walletFrame) {
connect(encryptWalletAction, &QAction::triggered, walletFrame,
&WalletFrame::encryptWallet);
connect(backupWalletAction, &QAction::triggered, walletFrame,
&WalletFrame::backupWallet);
connect(changePassphraseAction, &QAction::triggered, walletFrame,
&WalletFrame::changePassphrase);
connect(signMessageAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(signMessageAction, &QAction::triggered,
[this] { gotoSignMessageTab(); });
connect(verifyMessageAction, &QAction::triggered,
[this] { showNormalIfMinimized(); });
connect(verifyMessageAction, &QAction::triggered,
[this] { gotoVerifyMessageTab(); });
connect(m_load_psbt_action, &QAction::triggered,
[this] { gotoLoadPSBT(); });
connect(usedSendingAddressesAction, &QAction::triggered, walletFrame,
&WalletFrame::usedSendingAddresses);
connect(usedReceivingAddressesAction, &QAction::triggered, walletFrame,
&WalletFrame::usedReceivingAddresses);
connect(openAction, &QAction::triggered, this,
&BitcoinGUI::openClicked);
connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] {
m_open_wallet_menu->clear();
for (const std::pair<const std::string, bool> &i :
m_wallet_controller->listWalletDir()) {
const std::string &path = i.first;
QString name = path.empty()
? QString("[" + tr("default wallet") + "]")
: QString::fromStdString(path);
// Menu items remove single &. Single & are shown when && is in
// the string, but only the first occurrence. So replace only
// the first & with &&
name.replace(name.indexOf(QChar('&')), 1, QString("&&"));
QAction *action = m_open_wallet_menu->addAction(name);
if (i.second) {
// This wallet is already loaded
action->setEnabled(false);
continue;
}
connect(action, &QAction::triggered, [this, path] {
auto activity =
new OpenWalletActivity(m_wallet_controller, this);
connect(activity, &OpenWalletActivity::opened, this,
&BitcoinGUI::setCurrentWallet);
connect(activity, &OpenWalletActivity::finished, activity,
&QObject::deleteLater);
activity->open(path);
});
}
if (m_open_wallet_menu->isEmpty()) {
QAction *action =
m_open_wallet_menu->addAction(tr("No wallets available"));
action->setEnabled(false);
}
});
connect(m_close_wallet_action, &QAction::triggered, [this] {
m_wallet_controller->closeWallet(walletFrame->currentWalletModel(),
this);
});
connect(m_create_wallet_action, &QAction::triggered, [this] {
auto activity = new CreateWalletActivity(m_wallet_controller, this);
connect(activity, &CreateWalletActivity::created, this,
&BitcoinGUI::setCurrentWallet);
connect(activity, &CreateWalletActivity::finished, activity,
&QObject::deleteLater);
activity->create();
});
connect(m_close_all_wallets_action, &QAction::triggered,
[this] { m_wallet_controller->closeAllWallets(this); });
connect(m_mask_values_action, &QAction::toggled, this,
&BitcoinGUI::setPrivacy);
}
#endif // ENABLE_WALLET
connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this),
&QShortcut::activated, this,
&BitcoinGUI::showDebugWindowActivateConsole);
connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this),
&QShortcut::activated, this, &BitcoinGUI::showDebugWindow);
}
void BitcoinGUI::createMenuBar() {
#ifdef Q_OS_MAC
// Create a decoupled menu bar on Mac which stays even if the window is
// closed
appMenuBar = new QMenuBar();
#else
// Get the main window's menu bar on other platforms
appMenuBar = menuBar();
#endif
// Configure the menus
QMenu *file = appMenuBar->addMenu(tr("&File"));
if (walletFrame) {
file->addAction(m_create_wallet_action);
file->addAction(m_open_wallet_action);
file->addAction(m_close_wallet_action);
file->addAction(m_close_all_wallets_action);
file->addSeparator();
file->addAction(openAction);
file->addAction(backupWalletAction);
file->addAction(signMessageAction);
file->addAction(verifyMessageAction);
file->addAction(m_load_psbt_action);
file->addSeparator();
}
file->addAction(quitAction);
QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
if (walletFrame) {
settings->addAction(encryptWalletAction);
settings->addAction(changePassphraseAction);
settings->addSeparator();
settings->addAction(m_mask_values_action);
settings->addSeparator();
}
settings->addAction(optionsAction);
QMenu *window_menu = appMenuBar->addMenu(tr("&Window"));
QAction *minimize_action = window_menu->addAction(tr("Minimize"));
minimize_action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
connect(minimize_action, &QAction::triggered,
[] { QApplication::activeWindow()->showMinimized(); });
connect(qApp, &QApplication::focusWindowChanged,
[minimize_action](QWindow *window) {
minimize_action->setEnabled(
window != nullptr &&
(window->flags() & Qt::Dialog) != Qt::Dialog &&
window->windowState() != Qt::WindowMinimized);
});
#ifdef Q_OS_MAC
QAction *zoom_action = window_menu->addAction(tr("Zoom"));
connect(zoom_action, &QAction::triggered, [] {
QWindow *window = qApp->focusWindow();
if (window->windowState() != Qt::WindowMaximized) {
window->showMaximized();
} else {
window->showNormal();
}
});
connect(qApp, &QApplication::focusWindowChanged,
[zoom_action](QWindow *window) {
zoom_action->setEnabled(window != nullptr);
});
#endif
if (walletFrame) {
#ifdef Q_OS_MAC
window_menu->addSeparator();
QAction *main_window_action = window_menu->addAction(tr("Main Window"));
connect(main_window_action, &QAction::triggered,
[this] { GUIUtil::bringToFront(this); });
#endif
window_menu->addSeparator();
window_menu->addAction(usedSendingAddressesAction);
window_menu->addAction(usedReceivingAddressesAction);
}
window_menu->addSeparator();
for (RPCConsole::TabTypes tab_type : rpcConsole->tabs()) {
QAction *tab_action =
window_menu->addAction(rpcConsole->tabTitle(tab_type));
tab_action->setShortcut(rpcConsole->tabShortcut(tab_type));
connect(tab_action, &QAction::triggered, [this, tab_type] {
rpcConsole->setTabFocus(tab_type);
showDebugWindow();
});
}
QMenu *help = appMenuBar->addMenu(tr("&Help"));
help->addAction(showHelpMessageAction);
help->addSeparator();
help->addAction(aboutAction);
help->addAction(aboutQtAction);
}
void BitcoinGUI::createToolBars() {
if (walletFrame) {
QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
appToolBar = toolbar;
toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
toolbar->setMovable(false);
toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toolbar->addAction(overviewAction);
toolbar->addAction(sendCoinsAction);
toolbar->addAction(receiveCoinsAction);
toolbar->addAction(historyAction);
overviewAction->setChecked(true);
#ifdef ENABLE_WALLET
QWidget *spacer = new QWidget();
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
toolbar->addWidget(spacer);
m_wallet_selector = new QComboBox();
m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
connect(m_wallet_selector,
static_cast<void (QComboBox::*)(int)>(
&QComboBox::currentIndexChanged),
this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
m_wallet_selector_label = new QLabel();
m_wallet_selector_label->setText(tr("Wallet:") + " ");
m_wallet_selector_label->setBuddy(m_wallet_selector);
m_wallet_selector_label_action =
appToolBar->addWidget(m_wallet_selector_label);
m_wallet_selector_action = appToolBar->addWidget(m_wallet_selector);
m_wallet_selector_label_action->setVisible(false);
m_wallet_selector_action->setVisible(false);
#endif
}
}
void BitcoinGUI::setClientModel(ClientModel *_clientModel,
interfaces::BlockAndHeaderTipInfo *tip_info) {
this->clientModel = _clientModel;
if (_clientModel) {
// Create system tray menu (or setup the dock menu) that late to prevent
// users from calling actions, while the client has not yet fully loaded
createTrayIconMenu();
// Keep up to date with client
updateNetworkState();
connect(_clientModel, &ClientModel::numConnectionsChanged, this,
&BitcoinGUI::setNumConnections);
connect(_clientModel, &ClientModel::networkActiveChanged, this,
&BitcoinGUI::setNetworkActive);
modalOverlay->setKnownBestHeight(
tip_info->header_height,
QDateTime::fromTime_t(tip_info->header_time));
setNumBlocks(tip_info->block_height,
QDateTime::fromTime_t(tip_info->block_time),
tip_info->verification_progress, false,
SynchronizationState::INIT_DOWNLOAD);
connect(_clientModel, &ClientModel::numBlocksChanged, this,
&BitcoinGUI::setNumBlocks);
// Receive and report messages from client model
connect(_clientModel, &ClientModel::message,
[this](const QString &title, const QString &message,
unsigned int style) {
this->message(title, message, style);
});
// Show progress dialog
connect(_clientModel, &ClientModel::showProgress, this,
&BitcoinGUI::showProgress);
rpcConsole->setClientModel(_clientModel, tip_info->block_height,
tip_info->block_time,
tip_info->verification_progress);
updateProxyIcon();
#ifdef ENABLE_WALLET
if (walletFrame) {
walletFrame->setClientModel(_clientModel);
}
#endif // ENABLE_WALLET
unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
OptionsModel *optionsModel = _clientModel->getOptionsModel();
if (optionsModel && trayIcon) {
// be aware of the tray icon disable state change reported by the
// OptionsModel object.
connect(optionsModel, &OptionsModel::hideTrayIconChanged, this,
&BitcoinGUI::setTrayIconVisible);
// initialize the disable state of the tray icon with the current
// value in the model.
setTrayIconVisible(optionsModel->getHideTrayIcon());
}
} else {
// Disable possibility to show main window via action
toggleHideAction->setEnabled(false);
if (trayIconMenu) {
// Disable context menu on tray icon
trayIconMenu->clear();
}
// Propagate cleared model to child objects
rpcConsole->setClientModel(nullptr);
#ifdef ENABLE_WALLET
if (walletFrame) {
walletFrame->setClientModel(nullptr);
}
#endif // ENABLE_WALLET
unitDisplayControl->setOptionsModel(nullptr);
}
}
#ifdef ENABLE_WALLET
void BitcoinGUI::setWalletController(WalletController *wallet_controller) {
assert(!m_wallet_controller);
assert(wallet_controller);
m_wallet_controller = wallet_controller;
m_create_wallet_action->setEnabled(true);
m_open_wallet_action->setEnabled(true);
m_open_wallet_action->setMenu(m_open_wallet_menu);
connect(wallet_controller, &WalletController::walletAdded, this,
&BitcoinGUI::addWallet);
connect(wallet_controller, &WalletController::walletRemoved, this,
&BitcoinGUI::removeWallet);
for (WalletModel *wallet_model : m_wallet_controller->getOpenWallets()) {
addWallet(wallet_model);
}
}
WalletController *BitcoinGUI::getWalletController() {
return m_wallet_controller;
}
void BitcoinGUI::addWallet(WalletModel *walletModel) {
if (!walletFrame) {
return;
}
if (!walletFrame->addWallet(walletModel)) {
return;
}
rpcConsole->addWallet(walletModel);
if (m_wallet_selector->count() == 0) {
setWalletActionsEnabled(true);
} else if (m_wallet_selector->count() == 1) {
m_wallet_selector_label_action->setVisible(true);
m_wallet_selector_action->setVisible(true);
}
const QString display_name = walletModel->getDisplayName();
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
}
void BitcoinGUI::removeWallet(WalletModel *walletModel) {
if (!walletFrame) {
return;
}
labelWalletHDStatusIcon->hide();
labelWalletEncryptionIcon->hide();
int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
m_wallet_selector->removeItem(index);
if (m_wallet_selector->count() == 0) {
setWalletActionsEnabled(false);
overviewAction->setChecked(true);
} else if (m_wallet_selector->count() == 1) {
m_wallet_selector_label_action->setVisible(false);
m_wallet_selector_action->setVisible(false);
}
rpcConsole->removeWallet(walletModel);
walletFrame->removeWallet(walletModel);
updateWindowTitle();
}
void BitcoinGUI::setCurrentWallet(WalletModel *wallet_model) {
if (!walletFrame) {
return;
}
walletFrame->setCurrentWallet(wallet_model);
for (int index = 0; index < m_wallet_selector->count(); ++index) {
if (m_wallet_selector->itemData(index).value<WalletModel *>() ==
wallet_model) {
m_wallet_selector->setCurrentIndex(index);
break;
}
}
updateWindowTitle();
}
void BitcoinGUI::setCurrentWalletBySelectorIndex(int index) {
WalletModel *wallet_model =
m_wallet_selector->itemData(index).value<WalletModel *>();
if (wallet_model) {
setCurrentWallet(wallet_model);
}
}
void BitcoinGUI::removeAllWallets() {
if (!walletFrame) {
return;
}
setWalletActionsEnabled(false);
walletFrame->removeAllWallets();
}
#endif // ENABLE_WALLET
void BitcoinGUI::setWalletActionsEnabled(bool enabled) {
overviewAction->setEnabled(enabled);
sendCoinsAction->setEnabled(enabled);
sendCoinsMenuAction->setEnabled(enabled);
receiveCoinsAction->setEnabled(enabled);
receiveCoinsMenuAction->setEnabled(enabled);
historyAction->setEnabled(enabled);
encryptWalletAction->setEnabled(enabled);
backupWalletAction->setEnabled(enabled);
changePassphraseAction->setEnabled(enabled);
signMessageAction->setEnabled(enabled);
verifyMessageAction->setEnabled(enabled);
usedSendingAddressesAction->setEnabled(enabled);
usedReceivingAddressesAction->setEnabled(enabled);
openAction->setEnabled(enabled);
m_close_wallet_action->setEnabled(enabled);
m_close_all_wallets_action->setEnabled(enabled);
}
void BitcoinGUI::createTrayIcon() {
assert(QSystemTrayIcon::isSystemTrayAvailable());
#ifndef Q_OS_MAC
if (QSystemTrayIcon::isSystemTrayAvailable()) {
trayIcon =
new QSystemTrayIcon(m_network_style->getTrayAndWindowIcon(), this);
QString toolTip = tr("%1 client").arg(PACKAGE_NAME) + " " +
m_network_style->getTitleAddText();
trayIcon->setToolTip(toolTip);
}
#endif
}
void BitcoinGUI::createTrayIconMenu() {
#ifndef Q_OS_MAC
// Return if trayIcon is unset (only on non-macOSes)
if (!trayIcon) {
return;
}
trayIcon->setContextMenu(trayIconMenu.get());
connect(trayIcon, &QSystemTrayIcon::activated, this,
&BitcoinGUI::trayIconActivated);
#else
// Note: On macOS, the Dock icon is used to provide the tray's
// functionality.
MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, this,
&BitcoinGUI::macosDockIconActivated);
trayIconMenu->setAsDockMenu();
#endif
// Configuration of the tray icon (or Dock icon) menu
#ifndef Q_OS_MAC
// Note: On macOS, the Dock icon's menu already has Show / Hide action.
trayIconMenu->addAction(toggleHideAction);
trayIconMenu->addSeparator();
#endif
if (enableWallet) {
trayIconMenu->addAction(sendCoinsMenuAction);
trayIconMenu->addAction(receiveCoinsMenuAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(signMessageAction);
trayIconMenu->addAction(verifyMessageAction);
trayIconMenu->addSeparator();
}
trayIconMenu->addAction(optionsAction);
trayIconMenu->addAction(openRPCConsoleAction);
#ifndef Q_OS_MAC
// This is built-in on macOS
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
#endif
}
#ifndef Q_OS_MAC
void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) {
if (reason == QSystemTrayIcon::Trigger) {
// Click on system tray icon triggers show/hide of the main window
toggleHidden();
}
}
#else
void BitcoinGUI::macosDockIconActivated() {
show();
activateWindow();
}
#endif
void BitcoinGUI::optionsClicked() {
openOptionsDialogWithTab(OptionsDialog::TAB_MAIN);
}
void BitcoinGUI::aboutClicked() {
if (!clientModel) {
return;
}
HelpMessageDialog dlg(this, true);
dlg.exec();
}
void BitcoinGUI::showDebugWindow() {
GUIUtil::bringToFront(rpcConsole);
Q_EMIT consoleShown(rpcConsole);
}
void BitcoinGUI::showDebugWindowActivateConsole() {
rpcConsole->setTabFocus(RPCConsole::TabTypes::CONSOLE);
showDebugWindow();
}
void BitcoinGUI::showHelpMessageClicked() {
helpMessageDialog->show();
}
#ifdef ENABLE_WALLET
void BitcoinGUI::openClicked() {
OpenURIDialog dlg(config->GetChainParams(), this);
if (dlg.exec()) {
Q_EMIT receivedURI(dlg.getURI());
}
}
void BitcoinGUI::gotoOverviewPage() {
overviewAction->setChecked(true);
if (walletFrame) {
walletFrame->gotoOverviewPage();
}
}
void BitcoinGUI::gotoHistoryPage() {
historyAction->setChecked(true);
if (walletFrame) {
walletFrame->gotoHistoryPage();
}
}
void BitcoinGUI::gotoReceiveCoinsPage() {
receiveCoinsAction->setChecked(true);
if (walletFrame) {
walletFrame->gotoReceiveCoinsPage();
}
}
void BitcoinGUI::gotoSendCoinsPage(QString addr) {
sendCoinsAction->setChecked(true);
if (walletFrame) {
walletFrame->gotoSendCoinsPage(addr);
}
}
void BitcoinGUI::gotoSignMessageTab(QString addr) {
if (walletFrame) {
walletFrame->gotoSignMessageTab(addr);
}
}
void BitcoinGUI::gotoVerifyMessageTab(QString addr) {
if (walletFrame) {
walletFrame->gotoVerifyMessageTab(addr);
}
}
void BitcoinGUI::gotoLoadPSBT() {
if (walletFrame) {
walletFrame->gotoLoadPSBT();
}
}
#endif // ENABLE_WALLET
void BitcoinGUI::updateNetworkState() {
int count = clientModel->getNumConnections();
QString icon;
switch (count) {
case 0:
icon = ":/icons/connect_0";
break;
case 1:
case 2:
case 3:
icon = ":/icons/connect_1";
break;
case 4:
case 5:
case 6:
icon = ":/icons/connect_2";
break;
case 7:
case 8:
case 9:
icon = ":/icons/connect_3";
break;
default:
icon = ":/icons/connect_4";
break;
}
QString tooltip;
if (m_node.getNetworkActive()) {
tooltip = tr("%n active connection(s) to Bitcoin network", "", count) +
QString(".<br>") + tr("Click to disable network activity.");
} else {
tooltip = tr("Network activity disabled.") + QString("<br>") +
tr("Click to enable network activity again.");
icon = ":/icons/network_disabled";
}
// Don't word-wrap this (fixed-width) tooltip
tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
connectionsControl->setToolTip(tooltip);
connectionsControl->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(
STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
}
void BitcoinGUI::setNumConnections(int count) {
updateNetworkState();
}
void BitcoinGUI::setNetworkActive(bool networkActive) {
updateNetworkState();
}
void BitcoinGUI::updateHeadersSyncProgressLabel() {
int64_t headersTipTime = clientModel->getHeaderTipTime();
int headersTipHeight = clientModel->getHeaderTipHeight();
int estHeadersLeft =
(GetTime() - headersTipTime) /
config->GetChainParams().GetConsensus().nPowTargetSpacing;
if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC) {
progressBarLabel->setText(
tr("Syncing Headers (%1%)...")
.arg(QString::number(100.0 /
(headersTipHeight + estHeadersLeft) *
headersTipHeight,
'f', 1)));
}
}
void BitcoinGUI::openOptionsDialogWithTab(OptionsDialog::Tab tab) {
if (!clientModel || !clientModel->getOptionsModel()) {
return;
}
OptionsDialog dlg(this, enableWallet);
dlg.setCurrentTab(tab);
dlg.setModel(clientModel->getOptionsModel());
dlg.exec();
}
void BitcoinGUI::setNumBlocks(int count, const QDateTime &blockDate,
double nVerificationProgress, bool header,
SynchronizationState sync_state) {
// Disabling macOS App Nap on initial sync, disk and reindex operations.
#ifdef Q_OS_MAC
if (sync_state == SynchronizationState::POST_INIT) {
m_app_nap_inhibitor->enableAppNap();
} else {
m_app_nap_inhibitor->disableAppNap();
}
#endif
if (modalOverlay) {
if (header) {
modalOverlay->setKnownBestHeight(count, blockDate);
} else {
modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
}
}
if (!clientModel) {
return;
}
// Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait
// until chain-sync starts -> garbled text)
statusBar()->clearMessage();
// Acquire current block source
enum BlockSource blockSource = clientModel->getBlockSource();
switch (blockSource) {
case BlockSource::NETWORK:
if (header) {
updateHeadersSyncProgressLabel();
return;
}
progressBarLabel->setText(tr("Synchronizing with network..."));
updateHeadersSyncProgressLabel();
break;
case BlockSource::DISK:
if (header) {
progressBarLabel->setText(tr("Indexing blocks on disk..."));
} else {
progressBarLabel->setText(tr("Processing blocks on disk..."));
}
break;
case BlockSource::REINDEX:
progressBarLabel->setText(tr("Reindexing blocks on disk..."));
break;
case BlockSource::NONE:
if (header) {
return;
}
progressBarLabel->setText(tr("Connecting to peers..."));
break;
}
QString tooltip;
QDateTime currentDate = QDateTime::currentDateTime();
qint64 secs = blockDate.secsTo(currentDate);
tooltip = tr("Processed %n block(s) of transaction history.", "", count);
// Set icon state: spinning if catching up, tick otherwise
if (secs < MAX_BLOCK_TIME_GAP) {
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
labelBlocksIcon->setPixmap(
platformStyle->SingleColorIcon(":/icons/synced")
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
#ifdef ENABLE_WALLET
if (walletFrame) {
walletFrame->showOutOfSyncWarning(false);
modalOverlay->showHide(true, true);
}
#endif // ENABLE_WALLET
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
} else {
QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
progressBarLabel->setVisible(true);
progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
progressBar->setMaximum(1000000000);
progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
progressBar->setVisible(true);
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
if (count != prevBlocks) {
labelBlocksIcon->setPixmap(
platformStyle
->SingleColorIcon(QString(":/animation/spinner-%1")
.arg(spinnerFrame, 3, 10, QChar('0')))
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
}
prevBlocks = count;
#ifdef ENABLE_WALLET
if (walletFrame) {
walletFrame->showOutOfSyncWarning(true);
modalOverlay->showHide();
}
#endif // ENABLE_WALLET
tooltip += QString("<br>");
tooltip +=
tr("Last received block was generated %1 ago.").arg(timeBehindText);
tooltip += QString("<br>");
tooltip += tr("Transactions after this will not yet be visible.");
}
// Don't word-wrap this (fixed-width) tooltip
tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
labelBlocksIcon->setToolTip(tooltip);
progressBarLabel->setToolTip(tooltip);
progressBar->setToolTip(tooltip);
}
void BitcoinGUI::message(const QString &title, QString message,
unsigned int style, bool *ret,
const QString &detailed_message) {
// Default title. On macOS, the window title is ignored (as required by the
// macOS Guidelines).
QString strTitle{PACKAGE_NAME};
// Default to information icon
int nMBoxIcon = QMessageBox::Information;
int nNotifyIcon = Notificator::Information;
QString msgType;
if (!title.isEmpty()) {
msgType = title;
} else {
switch (style) {
case CClientUIInterface::MSG_ERROR:
msgType = tr("Error");
message = tr("Error: %1").arg(message);
break;
case CClientUIInterface::MSG_WARNING:
msgType = tr("Warning");
message = tr("Warning: %1").arg(message);
break;
case CClientUIInterface::MSG_INFORMATION:
msgType = tr("Information");
// No need to prepend the prefix here.
break;
default:
break;
}
}
if (!msgType.isEmpty()) {
strTitle += " - " + msgType;
}
if (style & CClientUIInterface::ICON_ERROR) {
nMBoxIcon = QMessageBox::Critical;
nNotifyIcon = Notificator::Critical;
} else if (style & CClientUIInterface::ICON_WARNING) {
nMBoxIcon = QMessageBox::Warning;
nNotifyIcon = Notificator::Warning;
}
if (style & CClientUIInterface::MODAL) {
// Check for buttons, use OK as default, if none was supplied
QMessageBox::StandardButton buttons;
- if (!(buttons = (QMessageBox::StandardButton)(
- style & CClientUIInterface::BTN_MASK))) {
+ if (!(buttons =
+ (QMessageBox::StandardButton)(style & CClientUIInterface::
+ BTN_MASK))) {
buttons = QMessageBox::Ok;
}
showNormalIfMinimized();
QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle,
message, buttons, this);
mBox.setTextFormat(Qt::PlainText);
mBox.setDetailedText(detailed_message);
int r = mBox.exec();
if (ret != nullptr) {
*ret = r == QMessageBox::Ok;
}
} else {
notificator->notify(static_cast<Notificator::Class>(nNotifyIcon),
strTitle, message);
}
}
void BitcoinGUI::changeEvent(QEvent *e) {
QMainWindow::changeEvent(e);
#ifndef Q_OS_MAC // Ignored on Mac
if (e->type() == QEvent::WindowStateChange) {
if (clientModel && clientModel->getOptionsModel() &&
clientModel->getOptionsModel()->getMinimizeToTray()) {
QWindowStateChangeEvent *wsevt =
static_cast<QWindowStateChangeEvent *>(e);
if (!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) {
QTimer::singleShot(0, this, &BitcoinGUI::hide);
e->ignore();
} else if ((wsevt->oldState() & Qt::WindowMinimized) &&
!isMinimized()) {
QTimer::singleShot(0, this, &BitcoinGUI::show);
e->ignore();
}
}
}
#endif
}
void BitcoinGUI::closeEvent(QCloseEvent *event) {
#ifndef Q_OS_MAC // Ignored on Mac
if (clientModel && clientModel->getOptionsModel()) {
if (!clientModel->getOptionsModel()->getMinimizeOnClose()) {
// close rpcConsole in case it was open to make some space for the
// shutdown window
rpcConsole->close();
QApplication::quit();
} else {
QMainWindow::showMinimized();
event->ignore();
}
}
#else
QMainWindow::closeEvent(event);
#endif
}
void BitcoinGUI::showEvent(QShowEvent *event) {
// enable the debug window when the main window shows up
openRPCConsoleAction->setEnabled(true);
aboutAction->setEnabled(true);
optionsAction->setEnabled(true);
}
#ifdef ENABLE_WALLET
void BitcoinGUI::incomingTransaction(const QString &date, int unit,
const Amount amount, const QString &type,
const QString &address,
const QString &label,
const QString &walletName) {
// On new transaction, make an info balloon
QString msg = tr("Date: %1\n").arg(date) +
tr("Amount: %1\n")
.arg(BitcoinUnits::formatWithUnit(unit, amount, true));
if (m_node.walletClient().getWallets().size() > 1 &&
!walletName.isEmpty()) {
msg += tr("Wallet: %1\n").arg(walletName);
}
msg += tr("Type: %1\n").arg(type);
if (!label.isEmpty()) {
msg += tr("Label: %1\n").arg(label);
} else if (!address.isEmpty()) {
msg += tr("Address: %1\n").arg(address);
}
message(amount < Amount::zero() ? tr("Sent transaction")
: tr("Incoming transaction"),
msg, CClientUIInterface::MSG_INFORMATION);
}
#endif // ENABLE_WALLET
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) {
// Accept only URIs
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
}
}
void BitcoinGUI::dropEvent(QDropEvent *event) {
if (event->mimeData()->hasUrls()) {
for (const QUrl &uri : event->mimeData()->urls()) {
Q_EMIT receivedURI(uri.toString());
}
}
event->acceptProposedAction();
}
bool BitcoinGUI::eventFilter(QObject *object, QEvent *event) {
// Catch status tip events
if (event->type() == QEvent::StatusTip) {
// Prevent adding text from setStatusTip(), if we currently use the
// status bar for displaying other stuff
if (progressBarLabel->isVisible() || progressBar->isVisible()) {
return true;
}
}
return QMainWindow::eventFilter(object, event);
}
#ifdef ENABLE_WALLET
bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient &recipient) {
// URI has to be valid
if (walletFrame && walletFrame->handlePaymentRequest(recipient)) {
showNormalIfMinimized();
gotoSendCoinsPage();
return true;
}
return false;
}
void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled) {
labelWalletHDStatusIcon->setPixmap(
platformStyle
->SingleColorIcon(privkeyDisabled ? ":/icons/eye"
: hdEnabled ? ":/icons/hd_enabled"
: ":/icons/hd_disabled")
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
labelWalletHDStatusIcon->setToolTip(
privkeyDisabled ? tr("Private key <b>disabled</b>")
: hdEnabled ? tr("HD key generation is <b>enabled</b>")
: tr("HD key generation is <b>disabled</b>"));
labelWalletHDStatusIcon->show();
// eventually disable the QLabel to set its opacity to 50%
labelWalletHDStatusIcon->setEnabled(hdEnabled);
}
void BitcoinGUI::setEncryptionStatus(int status) {
switch (status) {
case WalletModel::Unencrypted:
labelWalletEncryptionIcon->hide();
encryptWalletAction->setChecked(false);
changePassphraseAction->setEnabled(false);
encryptWalletAction->setEnabled(true);
break;
case WalletModel::Unlocked:
labelWalletEncryptionIcon->show();
labelWalletEncryptionIcon->setPixmap(
platformStyle->SingleColorIcon(":/icons/lock_open")
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
labelWalletEncryptionIcon->setToolTip(
tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
encryptWalletAction->setEnabled(false);
break;
case WalletModel::Locked:
labelWalletEncryptionIcon->show();
labelWalletEncryptionIcon->setPixmap(
platformStyle->SingleColorIcon(":/icons/lock_closed")
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
labelWalletEncryptionIcon->setToolTip(
tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
encryptWalletAction->setEnabled(false);
break;
}
}
void BitcoinGUI::updateWalletStatus() {
if (!walletFrame) {
return;
}
WalletView *const walletView = walletFrame->currentWalletView();
if (!walletView) {
return;
}
WalletModel *const walletModel = walletView->getWalletModel();
setEncryptionStatus(walletModel->getEncryptionStatus());
setHDStatus(walletModel->wallet().privateKeysDisabled(),
walletModel->wallet().hdEnabled());
}
#endif // ENABLE_WALLET
void BitcoinGUI::updateProxyIcon() {
std::string ip_port;
bool proxy_enabled = clientModel->getProxyInfo(ip_port);
if (proxy_enabled) {
if (!labelProxyIcon->hasPixmap()) {
QString ip_port_q = QString::fromStdString(ip_port);
labelProxyIcon->setPixmap(
platformStyle->SingleColorIcon(":/icons/proxy")
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
labelProxyIcon->setToolTip(
tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
} else {
labelProxyIcon->show();
}
} else {
labelProxyIcon->hide();
}
}
void BitcoinGUI::updateWindowTitle() {
QString window_title = PACKAGE_NAME;
#ifdef ENABLE_WALLET
if (walletFrame) {
WalletModel *const wallet_model = walletFrame->currentWalletModel();
if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
window_title += " - " + wallet_model->getDisplayName();
}
}
#endif
if (!m_network_style->getTitleAddText().isEmpty()) {
window_title += " - " + m_network_style->getTitleAddText();
}
setWindowTitle(window_title);
}
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) {
if (!clientModel) {
return;
}
if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) &&
fToggleHidden) {
hide();
} else {
GUIUtil::bringToFront(this);
}
}
void BitcoinGUI::toggleHidden() {
showNormalIfMinimized(true);
}
void BitcoinGUI::detectShutdown() {
if (m_node.shutdownRequested()) {
if (rpcConsole) {
rpcConsole->hide();
}
qApp->quit();
}
}
void BitcoinGUI::showProgress(const QString &title, int nProgress) {
if (nProgress == 0) {
progressDialog = new QProgressDialog(title, QString(), 0, 100);
GUIUtil::PolishProgressDialog(progressDialog);
progressDialog->setWindowModality(Qt::ApplicationModal);
progressDialog->setMinimumDuration(0);
progressDialog->setAutoClose(false);
progressDialog->setValue(0);
} else if (nProgress == 100) {
if (progressDialog) {
progressDialog->close();
progressDialog->deleteLater();
progressDialog = nullptr;
}
} else if (progressDialog) {
progressDialog->setValue(nProgress);
}
}
void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon) {
if (trayIcon) {
trayIcon->setVisible(!fHideTrayIcon);
}
}
void BitcoinGUI::showModalOverlay() {
if (modalOverlay &&
(progressBar->isVisible() || modalOverlay->isLayerVisible())) {
modalOverlay->toggleVisibility();
}
}
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const bilingual_str &message,
const std::string &caption,
unsigned int style) {
bool modal = (style & CClientUIInterface::MODAL);
// The SECURE flag has no effect in the Qt GUI.
// bool secure = (style & CClientUIInterface::SECURE);
style &= ~CClientUIInterface::SECURE;
bool ret = false;
// This is original message, in English, for googling and referencing.
QString detailed_message;
if (message.original != message.translated) {
detailed_message = BitcoinGUI::tr("Original message:") + "\n" +
QString::fromStdString(message.original);
}
// In case of modal message, use blocking connection to wait for user to
// click a button
bool invoked = QMetaObject::invokeMethod(
gui, "message",
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(caption)),
Q_ARG(QString, QString::fromStdString(message.translated)),
Q_ARG(unsigned int, style), Q_ARG(bool *, &ret),
Q_ARG(QString, detailed_message));
assert(invoked);
return ret;
}
void BitcoinGUI::subscribeToCoreSignals() {
// Connect signals to client
m_handler_message_box = m_node.handleMessageBox(
std::bind(ThreadSafeMessageBox, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3));
m_handler_question = m_node.handleQuestion(
std::bind(ThreadSafeMessageBox, this, std::placeholders::_1,
std::placeholders::_3, std::placeholders::_4));
}
void BitcoinGUI::unsubscribeFromCoreSignals() {
// Disconnect signals from client
m_handler_message_box->disconnect();
m_handler_question->disconnect();
}
bool BitcoinGUI::isPrivacyModeActivated() const {
assert(m_mask_values_action);
return m_mask_values_action->isChecked();
}
UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(
const PlatformStyle *platformStyle)
: optionsModel(nullptr), menu(nullptr) {
createContextMenu();
setToolTip(tr("Unit to show amounts in. Click to select another unit."));
QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
int max_width = 0;
const QFontMetrics fm(font());
for (const BitcoinUnits::Unit unit : units) {
max_width = qMax(max_width,
GUIUtil::TextWidth(fm, BitcoinUnits::longName(unit)));
}
setMinimumSize(max_width, 0);
setAlignment(Qt::AlignRight | Qt::AlignVCenter);
setStyleSheet(QString("QLabel { color : %1 }")
.arg(platformStyle->SingleColor().name()));
}
/** So that it responds to button clicks */
void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) {
onDisplayUnitsClicked(event->pos());
}
/** Creates context menu, its actions, and wires up all the relevant signals for
* mouse events. */
void UnitDisplayStatusBarControl::createContextMenu() {
menu = new QMenu(this);
for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) {
QAction *menuAction =
new QAction(QString(BitcoinUnits::longName(u)), this);
menuAction->setData(QVariant(u));
menu->addAction(menuAction);
}
connect(menu, &QMenu::triggered, this,
&UnitDisplayStatusBarControl::onMenuSelection);
}
/** Lets the control know about the Options Model (and its signals) */
void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel) {
if (_optionsModel) {
this->optionsModel = _optionsModel;
// be aware of a display unit change reported by the OptionsModel
// object.
connect(_optionsModel, &OptionsModel::displayUnitChanged, this,
&UnitDisplayStatusBarControl::updateDisplayUnit);
// initialize the display units label with the current value in the
// model.
updateDisplayUnit(_optionsModel->getDisplayUnit());
}
}
/** When Display Units are changed on OptionsModel it will refresh the display
* text of the control on the status bar */
void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits) {
setText(BitcoinUnits::longName(newUnits));
}
/** Shows context menu with Display Unit options by the mouse coordinates */
void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint &point) {
QPoint globalPos = mapToGlobal(point);
menu->exec(globalPos);
}
/** Tells underlying optionsModel to update its current display unit. */
void UnitDisplayStatusBarControl::onMenuSelection(QAction *action) {
if (action) {
optionsModel->setDisplayUnit(action->data());
}
}
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 8e6ba0967..41ff74c2e 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -1,422 +1,423 @@
// Copyright (c) 2012-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <checkqueue.h>
#include <sync.h>
#include <util/system.h>
#include <util/time.h>
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <test/util/setup_common.h>
#include <thread>
#include <vector>
#include <boost/test/unit_test.hpp>
#include <memory>
#include <unordered_set>
#include <utility>
/**
* Identical to TestingSetup but excludes lock contention logging if
* `DEBUG_LOCKCONTENTION` is defined, as some of these tests are designed to be
* heavily contested to trigger race conditions or other issues.
*/
struct NoLockLoggingTestingSetup : public TestingSetup {
NoLockLoggingTestingSetup()
#ifdef DEBUG_LOCKCONTENTION
: TestingSetup{CBaseChainParams::MAIN, /*extra_args=*/{
"-debugexclude=lock"
- }} {}
+ }} {
+ }
#else
: TestingSetup{CBaseChainParams::MAIN} {
}
#endif
};
BOOST_FIXTURE_TEST_SUITE(checkqueue_tests, NoLockLoggingTestingSetup)
static const unsigned int QUEUE_BATCH_SIZE = 128;
static const int SCRIPT_CHECK_THREADS = 3;
struct FakeCheck {
bool operator()() const { return true; }
void swap(FakeCheck &x) noexcept {};
};
struct FakeCheckCheckCompletion {
static std::atomic<size_t> n_calls;
bool operator()() {
n_calls.fetch_add(1, std::memory_order_relaxed);
return true;
}
void swap(FakeCheckCheckCompletion &x) noexcept {};
};
struct FailingCheck {
bool fails;
FailingCheck(bool _fails) : fails(_fails){};
FailingCheck() : fails(true){};
bool operator()() const { return !fails; }
void swap(FailingCheck &x) noexcept { std::swap(fails, x.fails); };
};
struct UniqueCheck {
static Mutex m;
static std::unordered_multiset<size_t> results GUARDED_BY(m);
size_t check_id;
UniqueCheck(size_t check_id_in) : check_id(check_id_in){};
UniqueCheck() : check_id(0){};
bool operator()() {
LOCK(m);
results.insert(check_id);
return true;
}
void swap(UniqueCheck &x) noexcept { std::swap(x.check_id, check_id); };
};
struct MemoryCheck {
static std::atomic<size_t> fake_allocated_memory;
bool b{false};
bool operator()() const { return true; }
MemoryCheck(){};
MemoryCheck(const MemoryCheck &x) {
// We have to do this to make sure that destructor calls are paired
//
// Really, copy constructor should be deletable, but CCheckQueue breaks
// if it is deleted because of internal push_back.
fake_allocated_memory.fetch_add(b, std::memory_order_relaxed);
};
MemoryCheck(bool b_) : b(b_) {
fake_allocated_memory.fetch_add(b, std::memory_order_relaxed);
};
~MemoryCheck() {
fake_allocated_memory.fetch_sub(b, std::memory_order_relaxed);
};
void swap(MemoryCheck &x) noexcept { std::swap(b, x.b); };
};
struct FrozenCleanupCheck {
static std::atomic<uint64_t> nFrozen;
static std::condition_variable cv;
static std::mutex m;
// Freezing can't be the default initialized behavior given how the queue
// swaps in default initialized Checks.
bool should_freeze{false};
bool operator()() const { return true; }
FrozenCleanupCheck() {}
~FrozenCleanupCheck() {
if (should_freeze) {
std::unique_lock<std::mutex> l(m);
nFrozen.store(1, std::memory_order_relaxed);
cv.notify_one();
cv.wait(
l, [] { return nFrozen.load(std::memory_order_relaxed) == 0; });
}
}
void swap(FrozenCleanupCheck &x) noexcept {
std::swap(should_freeze, x.should_freeze);
};
};
// Static Allocations
std::mutex FrozenCleanupCheck::m{};
std::atomic<uint64_t> FrozenCleanupCheck::nFrozen{0};
std::condition_variable FrozenCleanupCheck::cv{};
Mutex UniqueCheck::m;
std::unordered_multiset<size_t> UniqueCheck::results;
std::atomic<size_t> FakeCheckCheckCompletion::n_calls{0};
std::atomic<size_t> MemoryCheck::fake_allocated_memory{0};
// Queue Typedefs
typedef CCheckQueue<FakeCheckCheckCompletion> Correct_Queue;
typedef CCheckQueue<FakeCheck> Standard_Queue;
typedef CCheckQueue<FailingCheck> Failing_Queue;
typedef CCheckQueue<UniqueCheck> Unique_Queue;
typedef CCheckQueue<MemoryCheck> Memory_Queue;
typedef CCheckQueue<FrozenCleanupCheck> FrozenCleanup_Queue;
/** This test case checks that the CCheckQueue works properly
* with each specified size_t Checks pushed.
*/
static void Correct_Queue_range(std::vector<size_t> range) {
auto small_queue = std::make_unique<Correct_Queue>(QUEUE_BATCH_SIZE);
small_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
// Make vChecks here to save on malloc (this test can be slow...)
std::vector<FakeCheckCheckCompletion> vChecks;
for (const size_t i : range) {
size_t total = i;
FakeCheckCheckCompletion::n_calls = 0;
CCheckQueueControl<FakeCheckCheckCompletion> control(small_queue.get());
while (total) {
vChecks.resize(std::min(total, (size_t)InsecureRandRange(10)));
total -= vChecks.size();
control.Add(vChecks);
}
BOOST_REQUIRE(control.Wait());
if (FakeCheckCheckCompletion::n_calls != i) {
BOOST_REQUIRE_EQUAL(FakeCheckCheckCompletion::n_calls, i);
}
}
small_queue->StopWorkerThreads();
}
/** Test that 0 checks is correct
*/
BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Zero) {
std::vector<size_t> range;
range.push_back((size_t)0);
Correct_Queue_range(range);
}
/** Test that 1 check is correct
*/
BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_One) {
std::vector<size_t> range;
range.push_back((size_t)1);
Correct_Queue_range(range);
}
/** Test that MAX check is correct
*/
BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Max) {
std::vector<size_t> range;
range.push_back(100000);
Correct_Queue_range(range);
}
/** Test that random numbers of checks are correct
*/
BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Random) {
std::vector<size_t> range;
range.reserve(100000 / 1000);
for (size_t i = 2; i < 100000;
i += std::max((size_t)1, (size_t)InsecureRandRange(std::min(
(size_t)1000, ((size_t)100000) - i)))) {
range.push_back(i);
}
Correct_Queue_range(range);
}
/** Test that failing checks are caught */
BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure) {
auto fail_queue = std::make_unique<Failing_Queue>(QUEUE_BATCH_SIZE);
fail_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
for (size_t i = 0; i < 1001; ++i) {
CCheckQueueControl<FailingCheck> control(fail_queue.get());
size_t remaining = i;
while (remaining) {
size_t r = InsecureRandRange(10);
std::vector<FailingCheck> vChecks;
vChecks.reserve(r);
for (size_t k = 0; k < r && remaining; k++, remaining--) {
vChecks.emplace_back(remaining == 1);
}
control.Add(vChecks);
}
bool success = control.Wait();
if (i > 0) {
BOOST_REQUIRE(!success);
} else if (i == 0) {
BOOST_REQUIRE(success);
}
}
fail_queue->StopWorkerThreads();
}
// Test that a block validation which fails does not interfere with
// future blocks, ie, the bad state is cleared.
BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure) {
auto fail_queue = std::make_unique<Failing_Queue>(QUEUE_BATCH_SIZE);
fail_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
for (auto times = 0; times < 10; ++times) {
for (const bool end_fails : {true, false}) {
CCheckQueueControl<FailingCheck> control(fail_queue.get());
{
std::vector<FailingCheck> vChecks;
vChecks.resize(100, false);
vChecks[99] = end_fails;
control.Add(vChecks);
}
bool r = control.Wait();
BOOST_REQUIRE(r != end_fails);
}
}
fail_queue->StopWorkerThreads();
}
// Test that unique checks are actually all called individually, rather than
// just one check being called repeatedly. Test that checks are not called
// more than once as well
BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck) {
auto queue = std::make_unique<Unique_Queue>(QUEUE_BATCH_SIZE);
queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
size_t COUNT = 100000;
size_t total = COUNT;
{
CCheckQueueControl<UniqueCheck> control(queue.get());
while (total) {
size_t r = InsecureRandRange(10);
std::vector<UniqueCheck> vChecks;
for (size_t k = 0; k < r && total; k++) {
vChecks.emplace_back(--total);
}
control.Add(vChecks);
}
}
{
LOCK(UniqueCheck::m);
bool r = true;
BOOST_REQUIRE_EQUAL(UniqueCheck::results.size(), COUNT);
for (size_t i = 0; i < COUNT; ++i) {
r = r && UniqueCheck::results.count(i) == 1;
}
BOOST_REQUIRE(r);
}
queue->StopWorkerThreads();
}
// Test that blocks which might allocate lots of memory free their memory
// aggressively.
//
// This test attempts to catch a pathological case where by lazily freeing
// checks might mean leaving a check un-swapped out, and decreasing by 1 each
// time could leave the data hanging across a sequence of blocks.
BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) {
auto queue = std::make_unique<Memory_Queue>(QUEUE_BATCH_SIZE);
queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
for (size_t i = 0; i < 1000; ++i) {
size_t total = i;
{
CCheckQueueControl<MemoryCheck> control(queue.get());
while (total) {
size_t r = InsecureRandRange(10);
std::vector<MemoryCheck> vChecks;
for (size_t k = 0; k < r && total; k++) {
total--;
// Each iteration leaves data at the front, back, and middle
// to catch any sort of deallocation failure
vChecks.emplace_back(total == 0 || total == i ||
total == i / 2);
}
control.Add(vChecks);
}
}
BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0U);
}
queue->StopWorkerThreads();
}
// Test that a new verification cannot occur until all checks
// have been destructed
BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup) {
auto queue = std::make_unique<FrozenCleanup_Queue>(QUEUE_BATCH_SIZE);
bool fails = false;
queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
std::thread t0([&]() {
CCheckQueueControl<FrozenCleanupCheck> control(queue.get());
std::vector<FrozenCleanupCheck> vChecks(1);
// Freezing can't be the default initialized behavior given how the
// queue
// swaps in default initialized Checks (otherwise freezing destructor
// would get called twice).
vChecks[0].should_freeze = true;
control.Add(vChecks);
// Hangs here
bool waitResult = control.Wait();
assert(waitResult);
});
{
std::unique_lock<std::mutex> l(FrozenCleanupCheck::m);
// Wait until the queue has finished all jobs and frozen
FrozenCleanupCheck::cv.wait(
l, []() { return FrozenCleanupCheck::nFrozen == 1; });
}
// Try to get control of the queue a bunch of times
for (auto x = 0; x < 100 && !fails; ++x) {
fails = queue->m_control_mutex.try_lock();
}
{
// Unfreeze (we need lock n case of spurious wakeup)
std::unique_lock<std::mutex> l(FrozenCleanupCheck::m);
FrozenCleanupCheck::nFrozen = 0;
}
// Awaken frozen destructor
FrozenCleanupCheck::cv.notify_one();
// Wait for control to finish
t0.join();
BOOST_REQUIRE(!fails);
queue->StopWorkerThreads();
}
/** Test that CCheckQueueControl is threadsafe */
BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) {
auto queue = std::make_unique<Standard_Queue>(QUEUE_BATCH_SIZE);
{
std::vector<std::thread> tg;
std::atomic<int> nThreads{0};
std::atomic<int> fails{0};
for (size_t i = 0; i < 3; ++i) {
tg.emplace_back([&] {
CCheckQueueControl<FakeCheck> control(queue.get());
// While sleeping, no other thread should execute to this point
auto observed = ++nThreads;
UninterruptibleSleep(std::chrono::milliseconds{10});
fails += observed != nThreads;
});
}
for (auto &thread : tg) {
if (thread.joinable()) {
thread.join();
}
}
BOOST_REQUIRE_EQUAL(fails, 0);
}
{
std::vector<std::thread> tg;
std::mutex m;
std::condition_variable cv;
bool has_lock{false};
bool has_tried{false};
bool done{false};
bool done_ack{false};
{
std::unique_lock<std::mutex> l(m);
tg.emplace_back([&] {
CCheckQueueControl<FakeCheck> control(queue.get());
std::unique_lock<std::mutex> ll(m);
has_lock = true;
cv.notify_one();
cv.wait(ll, [&] { return has_tried; });
done = true;
cv.notify_one();
// Wait until the done is acknowledged
//
cv.wait(ll, [&] { return done_ack; });
});
// Wait for thread to get the lock
cv.wait(l, [&]() { return has_lock; });
bool fails = false;
for (auto x = 0; x < 100 && !fails; ++x) {
fails = queue->m_control_mutex.try_lock();
}
has_tried = true;
cv.notify_one();
cv.wait(l, [&]() { return done; });
// Acknowledge the done
done_ack = true;
cv.notify_one();
BOOST_REQUIRE(!fails);
}
for (auto &thread : tg) {
if (thread.joinable()) {
thread.join();
}
}
}
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/util/variant.h b/src/util/variant.h
index b84c1aa7b..f6a6488d0 100644
--- a/src/util/variant.h
+++ b/src/util/variant.h
@@ -1,18 +1,16 @@
// Copyright (c) 2023 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UTIL_VARIANT_H
#define BITCOIN_UTIL_VARIANT_H
namespace variant {
-template <class... Ts> struct overloaded : Ts... {
- using Ts::operator()...;
-};
+template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
// explicit deduction guide (not needed as of C++20)
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
} // namespace variant
#endif // BITCOIN_UTIL_VARIANT_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, May 21, 17:49 (1 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5862073
Default Alt Text
(145 KB)
Attached To
rABC Bitcoin ABC
Event Timeline
Log In to Comment