aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--ci/test/00_setup_env_arm.sh5
-rwxr-xr-xci/test/06_script_b.sh20
-rw-r--r--doc/benchmarking.md2
-rw-r--r--src/compat/stdin.cpp2
-rw-r--r--src/psbt.h29
-rw-r--r--src/qt/transactionrecord.cpp10
-rw-r--r--src/qt/transactiontablemodel.cpp1
-rw-r--r--test/functional/data/rpc_psbt.json10
9 files changed, 63 insertions, 20 deletions
diff --git a/.travis.yml b/.travis.yml
index 0810e7ef3c..f59c7fc7e8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -111,12 +111,12 @@ jobs:
- set -o errexit; source ./ci/lint/06_script.sh
- stage: test
- name: 'ARM [GOAL: install] [no unit or functional tests]'
+ name: 'ARM [GOAL: install] [unit tests, no functional tests]'
env: >-
FILE_ENV="./ci/test/00_setup_env_arm.sh"
- stage: test
- name: 'Win64 [GOAL: deploy] [no gui or functional tests]'
+ name: 'Win64 [GOAL: deploy] [unit tests, no gui, no functional tests]'
env: >-
FILE_ENV="./ci/test/00_setup_env_win64.sh"
diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh
index db640015b1..9335f0b337 100644
--- a/ci/test/00_setup_env_arm.sh
+++ b/ci/test/00_setup_env_arm.sh
@@ -7,9 +7,10 @@
export LC_ALL=C.UTF-8
export HOST=arm-linux-gnueabihf
-export PACKAGES="python3 g++-arm-linux-gnueabihf busybox"
+export QEMU_USER_CMD="qemu-arm -L /usr/arm-linux-gnueabihf/"
+export PACKAGES="python3 g++-arm-linux-gnueabihf busybox qemu-user"
export USE_BUSY_BOX=true
-export RUN_UNIT_TESTS=false
+export RUN_UNIT_TESTS=true
export RUN_FUNCTIONAL_TESTS=false
export GOAL="install"
# -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1"
diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh
index ea7beae85f..1a5217277a 100755
--- a/ci/test/06_script_b.sh
+++ b/ci/test/06_script_b.sh
@@ -8,8 +8,28 @@ export LC_ALL=C.UTF-8
cd "build/bitcoin-$HOST" || (echo "could not enter distdir build/bitcoin-$HOST"; exit 1)
+if [ -n "$QEMU_USER_CMD" ]; then
+ BEGIN_FOLD wrap-qemu
+ echo "Prepare to run functional tests for HOST=$HOST"
+ # Generate all binaries, so that they can be wrapped
+ DOCKER_EXEC make $MAKEJOBS -C src/secp256k1 VERBOSE=1
+ DOCKER_EXEC make $MAKEJOBS -C src/univalue VERBOSE=1
+ for b_name in {"${BASE_OUTDIR}/bin"/*,src/secp256k1/*tests,src/univalue/{no_nul,test_json,unitester,object}}; do
+ # shellcheck disable=SC2044
+ for b in $(find "${BASE_ROOT_DIR}" -executable -type f -name $(basename $b_name)); do
+ echo "Wrap $b ..."
+ DOCKER_EXEC mv "$b" "${b}_orig"
+ DOCKER_EXEC echo "\#\!/usr/bin/env bash" \> "$b"
+ DOCKER_EXEC echo "$QEMU_USER_CMD \\\"${b}_orig\\\" \\\"\\\$@\\\"" \>\> "$b"
+ DOCKER_EXEC chmod +x "$b"
+ done
+ done
+ END_FOLD
+fi
+
if [ "$RUN_UNIT_TESTS" = "true" ]; then
BEGIN_FOLD unit-tests
+ bash -c "while sleep 500; do echo .; done" & # Print dots in case the unit tests take a long time to run
DOCKER_EXEC LD_LIBRARY_PATH=$BASE_BUILD_DIR/depends/$HOST/lib make $MAKEJOBS check VERBOSE=1
END_FOLD
fi
diff --git a/doc/benchmarking.md b/doc/benchmarking.md
index 8e3d88ab7a..b1a06009b5 100644
--- a/doc/benchmarking.md
+++ b/doc/benchmarking.md
@@ -11,7 +11,7 @@ Running
For benchmarks purposes you only need to compile `bitcoin_bench`. Beware of configuring without `--enable-debug` as this would impact
benchmarking by unlatching log printers and lock analysis.
- make -C src bench_bitcoin
+ make -C src bitcoin_bench
After compiling bitcoin-core, the benchmarks can be run with:
diff --git a/src/compat/stdin.cpp b/src/compat/stdin.cpp
index 4f2ba1e9c4..98d406cca8 100644
--- a/src/compat/stdin.cpp
+++ b/src/compat/stdin.cpp
@@ -14,7 +14,7 @@
#else
#include <termios.h> // for SetStdinEcho()
#include <unistd.h> // for SetStdinEcho(), isatty()
-#include <sys/poll.h> // for StdinReady()
+#include <poll.h> // for StdinReady()
#endif
#include <compat/stdin.h>
diff --git a/src/psbt.h b/src/psbt.h
index 6d77db0c6f..802a7c5ba7 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -126,6 +126,9 @@ struct PSBTInput
template <typename Stream>
inline void Unserialize(Stream& s) {
+ // Used for duplicate key detection
+ std::set<std::vector<unsigned char>> key_lookup;
+
// Read loop
bool found_sep = false;
while(!s.empty()) {
@@ -147,7 +150,7 @@ struct PSBTInput
switch(type) {
case PSBT_IN_NON_WITNESS_UTXO:
{
- if (non_witness_utxo) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Non-witness utxo key is more than one byte type");
@@ -158,7 +161,7 @@ struct PSBTInput
break;
}
case PSBT_IN_WITNESS_UTXO:
- if (!witness_utxo.IsNull()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input witness utxo already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Witness utxo key is more than one byte type");
@@ -189,7 +192,7 @@ struct PSBTInput
break;
}
case PSBT_IN_SIGHASH:
- if (sighash_type > 0) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input sighash type already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Sighash type key is more than one byte type");
@@ -198,7 +201,7 @@ struct PSBTInput
break;
case PSBT_IN_REDEEMSCRIPT:
{
- if (!redeem_script.empty()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input redeemScript already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Input redeemScript key is more than one byte type");
@@ -208,7 +211,7 @@ struct PSBTInput
}
case PSBT_IN_WITNESSSCRIPT:
{
- if (!witness_script.empty()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input witnessScript already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Input witnessScript key is more than one byte type");
@@ -223,7 +226,7 @@ struct PSBTInput
}
case PSBT_IN_SCRIPTSIG:
{
- if (!final_script_sig.empty()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Final scriptSig key is more than one byte type");
@@ -233,7 +236,7 @@ struct PSBTInput
}
case PSBT_IN_SCRIPTWITNESS:
{
- if (!final_script_witness.IsNull()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, input final scriptWitness already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Final scriptWitness key is more than one byte type");
@@ -309,6 +312,9 @@ struct PSBTOutput
template <typename Stream>
inline void Unserialize(Stream& s) {
+ // Used for duplicate key detection
+ std::set<std::vector<unsigned char>> key_lookup;
+
// Read loop
bool found_sep = false;
while(!s.empty()) {
@@ -330,7 +336,7 @@ struct PSBTOutput
switch(type) {
case PSBT_OUT_REDEEMSCRIPT:
{
- if (!redeem_script.empty()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, output redeemScript already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Output redeemScript key is more than one byte type");
@@ -340,7 +346,7 @@ struct PSBTOutput
}
case PSBT_OUT_WITNESSSCRIPT:
{
- if (!witness_script.empty()) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, output witnessScript already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Output witnessScript key is more than one byte type");
@@ -448,6 +454,9 @@ struct PartiallySignedTransaction
throw std::ios_base::failure("Invalid PSBT magic bytes");
}
+ // Used for duplicate key detection
+ std::set<std::vector<unsigned char>> key_lookup;
+
// Read global data
bool found_sep = false;
while(!s.empty()) {
@@ -469,7 +478,7 @@ struct PartiallySignedTransaction
switch(type) {
case PSBT_GLOBAL_UNSIGNED_TX:
{
- if (tx) {
+ if (!key_lookup.emplace(key).second) {
throw std::ios_base::failure("Duplicate Key, unsigned tx already provided");
} else if (key.size() != 1) {
throw std::ios_base::failure("Global unsigned tx key is more than one byte type");
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 9de90759fa..08ba030d65 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -93,10 +93,14 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const interface
if (fAllFromMe && fAllToMe)
{
// Payment to self
- CAmount nChange = wtx.change;
+ std::string address;
+ for (auto it = wtx.txout_address.begin(); it != wtx.txout_address.end(); ++it) {
+ if (it != wtx.txout_address.begin()) address += ", ";
+ address += EncodeDestination(*it);
+ }
- parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
- -(nDebit - nChange), nCredit - nChange));
+ CAmount nChange = wtx.change;
+ parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, address, -(nDebit - nChange), nCredit - nChange));
parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
}
else if (fAllFromMe)
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 8d0cb54151..fed55577ca 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -394,6 +394,7 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b
case TransactionRecord::SendToOther:
return QString::fromStdString(wtx->address) + watchAddress;
case TransactionRecord::SendToSelf:
+ return lookupAddress(wtx->address, tooltip) + watchAddress;
default:
return tr("(n/a)") + watchAddress;
}
diff --git a/test/functional/data/rpc_psbt.json b/test/functional/data/rpc_psbt.json
index 57f2608ee9..0f6cd97fd8 100644
--- a/test/functional/data/rpc_psbt.json
+++ b/test/functional/data/rpc_psbt.json
@@ -18,7 +18,15 @@
"cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wCAwABAAAAAAEAFgAUYunpgv/zTdgjlhAxawkM0qO3R8sAAQAiACCHa62DLx0WgBXtQSMqnqZaGBXZ7xPA74dZ9ktbKyeKZQEBJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A",
"cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wAAgAAFgAUYunpgv/zTdgjlhAxawkM0qO3R8sAAQAiACCHa62DLx0WgBXtQSMqnqZaGBXZ7xPA74dZ9ktbKyeKZQEBJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A",
"cHNidP8BAHMCAAAAATAa6YblFqHsisW0vGVz0y+DtGXiOtdhZ9aLOOcwtNvbAAAAAAD/////AnR7AQAAAAAAF6kUA6oXrogrXQ1Usl1jEE5P/s57nqKHYEOZOwAAAAAXqRS5IbG6b3IuS/qDtlV6MTmYakLsg4cAAAAAAAEBHwDKmjsAAAAAFgAU0tlLZK4IWH7vyO6xh8YB6Tn5A3wAAQAWABRi6emC//NN2COWEDFrCQzSo7dHywABACIAIIdrrYMvHRaAFe1BIyqeploYFdnvE8Dvh1n2S1srJ4plIQEAJVEhA7fOI6AcW0vwCmQlN836uzFbZoMyhnR471EwnSvVf4qHUa4A",
- "cHNidP8BAHMCAAAAAbiWoY6pOQepFsEGhUPXaulX9rvye2NH+NrdlAHg+WgpAQAAAAD/////AkBLTAAAAAAAF6kUqWwXCcLM5BN2zoNqMNT5qMlIi7+HQEtMAAAAAAAXqRSVF/in2XNxAlN1OSxkyp0z+Wtg2YcAAAAAAAEBIBNssgAAAAAAF6kUamsvautR8hRlMRY6OKNTx03DK96HAQcXFgAUo8u1LWpHprjt/uENAwBpGZD0UH0BCGsCRzBEAiAONfH3DYiw67ZbylrsxCF/XXpVwyWBRgofyRbPslzvwgIgIKCsWw5sHSIPh1icNvcVLZLHWj6NA7Dk+4Os2pOnMbQBIQPGStfYHPtyhpV7zIWtn0Q4GXv5gK1zy/tnJ+cBXu4iiwABABYAFMwmJQEz+HDpBEEabxJ5PogPsqZRAAEAFgAUyCrGc3h3FYCmiIspbv2pSTKZ5jU"
+ "cHNidP8BAHMCAAAAAbiWoY6pOQepFsEGhUPXaulX9rvye2NH+NrdlAHg+WgpAQAAAAD/////AkBLTAAAAAAAF6kUqWwXCcLM5BN2zoNqMNT5qMlIi7+HQEtMAAAAAAAXqRSVF/in2XNxAlN1OSxkyp0z+Wtg2YcAAAAAAAEBIBNssgAAAAAAF6kUamsvautR8hRlMRY6OKNTx03DK96HAQcXFgAUo8u1LWpHprjt/uENAwBpGZD0UH0BCGsCRzBEAiAONfH3DYiw67ZbylrsxCF/XXpVwyWBRgofyRbPslzvwgIgIKCsWw5sHSIPh1icNvcVLZLHWj6NA7Dk+4Os2pOnMbQBIQPGStfYHPtyhpV7zIWtn0Q4GXv5gK1zy/tnJ+cBXu4iiwABABYAFMwmJQEz+HDpBEEabxJ5PogPsqZRAAEAFgAUyCrGc3h3FYCmiIspbv2pSTKZ5jU",
+ "cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAQEAAQEBagA=",
+ "cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAQAAAQABagA=",
+ "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQEJ//////////8AAQEJAADK/gAAAAAAAA==",
+ "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQMErd7f7gEDBAEAAAAA",
+ "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQQAAQQBagA=",
+ "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQEJAOH1BQAAAAAAAQUAAQUBUQA=",
+ "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQcAAQcBUQA=",
+ "cHNidP8BADMBAAAAAREREREREREREREREREREREREfrK3hERERERERERERERfwAAAAD/////AAAAAAAAAQEJAOH1BQAAAAAAAQgBAAEIAwEBUQA="
],
"valid" : [
"cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAAAA",