From 713175198ace33372cc0ec5df52318c5844c86a5 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Tue, 10 Dec 2019 15:52:56 +0100 Subject: [PATCH 01/45] Added fix for deadlock issue (208) and introduced GUnit test to verify it --- src/wallet/gtest/test_deadlock.cpp | 121 +++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/wallet/gtest/test_deadlock.cpp diff --git a/src/wallet/gtest/test_deadlock.cpp b/src/wallet/gtest/test_deadlock.cpp new file mode 100644 index 0000000000..698542d084 --- /dev/null +++ b/src/wallet/gtest/test_deadlock.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +#include "base58.h" +#include "chainparams.h" +#include "main.h" +#include "primitives/block.h" +#include "random.h" +#include "utiltest.h" +#include "wallet/wallet.h" +#include "zcash/JoinSplit.hpp" +#include "zcash/Note.hpp" +#include "zcash/NoteEncryption.hpp" + +#include + +#include +#include +#include +#include +#include +#include "db_cxx.h" +#include "zcash/Address.hpp" +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +using ::testing::Return; +using namespace libzcash; + +extern ZCJoinSplit *params; + + +CWalletTx GetValidTx(const libzcash::SpendingKey &sk, CAmount value, + bool randomInputs) { + return GetValidReceive(*params, sk, value, randomInputs); +} + +TEST(deadlock_test, setup_datadir_location_run_as_first_test) { + // Get temporary and unique path for file. + boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() + / boost::filesystem::unique_path(); + boost::filesystem::create_directories(pathTemp); + mapArgs["-datadir"] = pathTemp.string(); +} + +void write_db(CWallet &wallet, CBlock &block, SpendingKey &sk, + std::atomic_int &finish) { + + for (int i = 0; i < 1000; i++) { + auto wtx = GetValidTx(sk, 10, true); + + wallet.SyncTransaction(wtx, &block); + } + + finish++; +} + +void write_block(CWallet &walletdb, std::atomic_int &finish) { + + for (int i = 0; i < 100; i++) { + CBlockLocator loc; + walletdb.SetBestChain(loc); + + } + finish++; +} + +TEST(deadlock_test, deadlock) { + + //create wallet + SelectParams(CBaseChainParams::TESTNET); + bool fFirstRun = true; + CWallet pwalletMain("wallet.dat"); + DBErrors nLoadWalletRet = pwalletMain.LoadWallet(fFirstRun); + + auto sk = libzcash::SpendingKey::random(); + pwalletMain.AddSpendingKey(sk); + + //create block + CBlock block; + + //number of concurrent SyncTransaction Thread -1 + int size = 2; + std::atomic_int finished(0); + std::thread myThreads[size]; + + //launch #size -1 thread to process transaction + for (int i = 0; i < size; i++) { + + if (i == 0) { + myThreads[i] = std::thread(write_block, std::ref(pwalletMain), + std::ref(finished)); + + } + //otherwise it process txes + else { + myThreads[i] = std::thread(write_db, std::ref(pwalletMain), + std::ref(block), std::ref(sk), std::ref(finished)); + + } + + } + + //wait all threads to finish + for (int i = 0; i < size; i++) { + myThreads[i].join(); + } + + EXPECT_EQ(finished, size); + +} From d0c572d10843191db8312d6ad62645a24ce35452 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Tue, 10 Dec 2019 15:53:31 +0100 Subject: [PATCH 02/45] leftover from previous commit --- src/Makefile.gtest.include | 3 ++- src/wallet/wallet.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index b271170097..268c8f339f 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -47,7 +47,8 @@ zen_gtest_SOURCES += \ if ENABLE_WALLET zen_gtest_SOURCES += \ - wallet/gtest/test_wallet.cpp + wallet/gtest/test_wallet.cpp \ + wallet/gtest/test_deadlock.cpp endif # zen_gtest_CPPFLAGS = $(AM_CPPFLAGS) -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC -DBITCOIN_TX $(BITCOIN_INCLUDES) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index cbc063d49f..c082ea24f3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -418,6 +418,7 @@ void CWallet::ChainTip(const CBlockIndex *pindex, const CBlock *pblock, void CWallet::SetBestChain(const CBlockLocator& loc) { + LOCK(cs_wallet); CWalletDB walletdb(strWalletFile); SetBestChainINTERNAL(walletdb, loc); } From b798f9f9bf3d6d64def7309712d22b4b74111235 Mon Sep 17 00:00:00 2001 From: abi87 Date: Tue, 10 Dec 2019 17:50:54 +0100 Subject: [PATCH 03/45] cleaned up useless includes --- src/wallet/gtest/test_deadlock.cpp | 34 +++++------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/src/wallet/gtest/test_deadlock.cpp b/src/wallet/gtest/test_deadlock.cpp index 698542d084..072a0a713a 100644 --- a/src/wallet/gtest/test_deadlock.cpp +++ b/src/wallet/gtest/test_deadlock.cpp @@ -2,39 +2,14 @@ #include #include -#include "base58.h" -#include "chainparams.h" -#include "main.h" -#include "primitives/block.h" -#include "random.h" -#include "utiltest.h" -#include "wallet/wallet.h" -#include "zcash/JoinSplit.hpp" -#include "zcash/Note.hpp" -#include "zcash/NoteEncryption.hpp" - #include - -#include #include -#include -#include -#include -#include "db_cxx.h" -#include "zcash/Address.hpp" -#include -#include -#include - -#include -#include -#include -#include - -#include #include -using ::testing::Return; +#include "zcash/JoinSplit.hpp" +#include "wallet/wallet.h" +#include "utiltest.h" + using namespace libzcash; extern ZCJoinSplit *params; @@ -45,6 +20,7 @@ CWalletTx GetValidTx(const libzcash::SpendingKey &sk, CAmount value, return GetValidReceive(*params, sk, value, randomInputs); } + TEST(deadlock_test, setup_datadir_location_run_as_first_test) { // Get temporary and unique path for file. boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() From df07b74ea3ca2f497019a7c6a8be7c8082de58d4 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Wed, 11 Dec 2019 08:53:18 +0100 Subject: [PATCH 04/45] Made lisstransactions filterable by address --- qa/pull-tester/rpc-tests.sh | 1 + qa/rpc-tests/listtransactions.py | 31 ++-- .../listtransactions_addressfilter.py | 137 ++++++++++++++++++ src/wallet/rpcwallet.cpp | 62 +++++--- src/wallet/wallet.cpp | 41 +++++- src/wallet/wallet.h | 3 + 6 files changed, 225 insertions(+), 50 deletions(-) create mode 100755 qa/rpc-tests/listtransactions_addressfilter.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 2cae50cc0f..8a2f6df7b5 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -51,6 +51,7 @@ testScripts=( 'nulldata.py' 'blockdelay.py' 'blockdelay_2.py' + 'listtransactions_addressfilter.py' ); testScriptsExt=( 'getblocktemplate_longpoll.py' diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index a735f41aba..bd8ac5fa3d 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -36,31 +36,25 @@ def run_test(self): # Simple send, 0 to 1: txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) self.sync_all() - check_array_result(self.nodes[0].listtransactions(), - {"txid":txid}, - {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) + check_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) # mine a block, confirmations should change: self.nodes[0].generate(1) self.sync_all() - check_array_result(self.nodes[0].listtransactions(), - {"txid":txid}, - {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1}) + check_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1}) # send-to-self: txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) - check_array_result(self.nodes[0].listtransactions(), - {"txid":txid, "category":"send"}, - {"amount":Decimal("-0.2")}) + check_array_result(self.nodes[0].listtransactions(), {"txid":txid, "category":"receive"}, {"amount":Decimal("0.2")}) - + # sendmany from node1: twice to self, twice to node2: send_to = { self.nodes[0].getnewaddress() : 0.11, self.nodes[1].getnewaddress() : 0.22, @@ -68,30 +62,23 @@ def run_test(self): self.nodes[1].getaccountaddress("") : 0.44 } txid = self.nodes[1].sendmany("", send_to) self.sync_all() - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.11")}, - {"txid":txid} ) + check_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.11")}, {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.22")}, - {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.22")}, {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.33")}, - {"txid":txid} ) + check_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.33")}, {"txid":txid, "account" : ""} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.44")}, - {"txid":txid, "account" : ""} ) + check_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.44")}, {"txid":txid, "account" : ""} ) + if __name__ == '__main__': ListTransactionsTest().main() diff --git a/qa/rpc-tests/listtransactions_addressfilter.py b/qa/rpc-tests/listtransactions_addressfilter.py new file mode 100755 index 0000000000..e3d0f1fa1b --- /dev/null +++ b/qa/rpc-tests/listtransactions_addressfilter.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python2 +# 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. + +# Exercise the listtransactions API + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi + +from decimal import Decimal + +def check_array_result(object_array, to_match, expected): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + """ + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0: + raise AssertionError("No objects matched %s"%(str(to_match))) + +class ListTransactionsTest(BitcoinTestFramework): + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir) + + #connect to a local machine for debugging + #url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18232) + #proxy = AuthServiceProxy(url) + #proxy.url = url # store URL on proxy for info + #self.nodes.append(proxy) + + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + + self.is_network_split=False + self.sync_all() + + def run_test(self): + + self.nodes[0].generate(120) + address=self.nodes[1].getnewaddress() + + + + #simple send 1 to address and verify listtransaction returns this tx with address in input + txid=self.nodes[0].sendtoaddress(address, float(1) ) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + check_array_result(self.nodes[1].listtransactions(address), + {"txid":txid}, + {"amount":Decimal("1.0")}) + + #verify listtransactions returns this tx without any input + check_array_result(self.nodes[1].listtransactions(address), + {"txid":txid}, + {"amount":Decimal("1.0")}) + + #verify listtransactions returns only the tx with a specific address + txid2=self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), float(1) ) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + result=self.nodes[1].listtransactions(address) + if(len(result)!=1): + raise AssertionError("Expected only 1 transaction") + check_array_result(result, + {"txid":txid}, + {"amount":Decimal("1.0"),"address":address}) + + #verify listtransactions returns 2 tx with no inputs + result=self.nodes[1].listtransactions() + if(len(result)!=2): + raise AssertionError("Expected 2 transactions") + + #verify listtransactions returns only last 10 tx with address in input + txes=[] + for i in range(1,11): + txid=self.nodes[0].sendtoaddress(address, float(i) ) + txes.append(txid) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + result=self.nodes[1].listtransactions(address) + if(len(result)!=10): + raise AssertionError("Expected only 10 transactions") + for i in range(11,1): + check_array_result([result[i-1]], + {"txid":txes[i-1]}, + {"amount":float(i),"address":address}) + + + #verify listtransactions returns the 5 most recent transactions of address + result=self.nodes[1].listtransactions(address,5) + if(len(result)!=5): + raise AssertionError("Expected only 10 transactions") + for i in range(11,7): + check_array_result([result[i-1]], + {"txid":txes[i-1]}, + {"amount":float(i),"address":address}) + + + #verify listtransactions returns the transactions n.3-4-5-6-7 of address + result=self.nodes[1].listtransactions(address,5,3) + if(len(result)!=5): + raise AssertionError("Expected only 10 transactions") + for i in range(8,4): + print("I: ",result[i-1]) + check_array_result([result[i-1]], + {"txid":txes[i-1]}, + {"amount":float(i),"address":address}) + + + +if __name__ == '__main__': + ListTransactionsTest().main() + diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 96a03b3d84..d21294ddaf 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1356,7 +1356,8 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) entry.push_back(Pair("address", addr.ToString())); } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) + +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter,string address) { CAmount nFee; string strSentAccount; @@ -1385,6 +1386,9 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); + if(!address.empty()&&address!="*"){ + entry.push_back(Pair("address",address)); + } ret.push_back(entry); } } @@ -1422,12 +1426,16 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); + if(!address.empty()&&address!="*"){ + entry.push_back(Pair("address",address)); + } ret.push_back(entry); } } } } + void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret) { bool fAllAccounts = (strAccount == string("*")); @@ -1455,7 +1463,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) "listtransactions ( \"account\" count from includeWatchonly)\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" "\nArguments:\n" - "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n" + "1. \"address\" (string, optional) The address name.\n" "2. count (numeric, optional, default=10) The number of transactions to return\n" "3. from (numeric, optional, default=0) The number of transactions to skip\n" "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n" @@ -1505,9 +1513,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string strAccount = "*"; - if (params.size() > 0) - strAccount = params[0].get_str(); + + string address="*"; + if (params.size() > 0){ + + address=params[0].get_str(); + CBitcoinAddress baddress = CBitcoinAddress(address); + if (!baddress.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zen address"); + + } + int nCount = 10; if (params.size() > 1) nCount = params[1].get_int(); @@ -1524,29 +1540,25 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if (nFrom < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); + std::multimap txes; + + //getting all TX ordered for nOrderPos and filtered by address + pwalletMain->GetFilteredTransactions(txes,address); UniValue ret(UniValue::VARR); - std::list acentries; - CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); + //for each tx i create the ret object to return + for (std::multimap::reverse_iterator itr = txes.rbegin(); + itr != txes.rend();++itr) { - // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) - { - CWalletTx *const pwtx = (*it).second.first; - if (pwtx != 0) - ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - CAccountingEntry *const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); + ListTransactions(std::ref((*itr).second), "", 0, true, ret, filter,address); - if ((int)ret.size() >= (nCount+nFrom)) break; } - // ret is newest to oldest + //getting all the specifi Txes requested by nCount and nFrom if (nFrom > (int)ret.size()) - nFrom = ret.size(); + nFrom = ret.size(); if ((nFrom + nCount) > (int)ret.size()) - nCount = ret.size() - nFrom; + nCount = ret.size() - nFrom; vector arrTmp = ret.getValues(); @@ -1558,7 +1570,11 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + if(nFrom!=0){ + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + } + ret.clear(); ret.setArray(); @@ -1725,7 +1741,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) CWalletTx tx = (*it).second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(tx, "*", 0, true, transactions, filter); + ListTransactions(tx, "*", 0, true, transactions, filter,""); } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; @@ -1817,7 +1833,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(wtx, "*", 0, false, details, filter); + ListTransactions(wtx, "*", 0, false, details, filter,""); entry.push_back(Pair("details", details)); string strHex = EncodeHexTx(static_cast(wtx)); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index cbc063d49f..bfe745c6d8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -176,7 +176,6 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) { - if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) return false; if (!fFileBacked) @@ -516,7 +515,6 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er } catch (const boost::filesystem::filesystem_error&) { // failure is ok (well, not really, but it's not worse than what we started with) } - // try again if (!bitdb.Open(GetDataDir())) { // if it still fails, it probably means we can't even create the database env @@ -525,14 +523,12 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er return true; } } - if (GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: if (!CWalletDB::Recover(bitdb, walletFile, true)) return false; } - if (boost::filesystem::exists(GetDataDir() / walletFile)) { CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); @@ -546,7 +542,6 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er if (r == CDBEnv::RECOVER_FAIL) errorString += _("wallet.dat corrupt, salvage failed"); } - return true; } @@ -3673,6 +3668,42 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee); } +void CWallet::GetFilteredTransactions(std::multimap& outEntries, std::string address) +{ + LOCK2(cs_main, cs_wallet); + CScript scriptPubKey; + + if(address.compare("*")!=0){ + CBitcoinAddress baddress = CBitcoinAddress(address); + scriptPubKey = GetScriptForDestination(baddress.Get(), false); + + } + + //getting all Txes of address in the wallet + for (auto & p : mapWallet) { + CWalletTx wtx = p.second; + if(address.compare("*")==0){ + outEntries.insert(make_pair(wtx.nOrderPos,wtx)); + } + else{ + for(const CTxOut& txout : wtx.vout){ + auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), + scriptPubKey.end()); + if (res == txout.scriptPubKey.begin()){ + outEntries.insert(make_pair(wtx.nOrderPos,wtx)); + } + + } + + } + + + } + + +} + + /** * Find notes in the wallet filtered by payment address, min depth and ability to spend. * These notes are decrypted and added to the output parameter vector, outEntries. diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a84d633278..03db9d013e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1126,6 +1126,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface int minDepth=1, bool ignoreSpent=true, bool ignoreUnspendable=true); + /*Find all transactions of a specific addres*/ + void GetFilteredTransactions(std::multimap& outEntries, + std::string address); }; From 3bd322fc4515a2c22f45344e7a0cfe6de3d93286 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Wed, 11 Dec 2019 11:08:10 +0100 Subject: [PATCH 05/45] Modified and reintroduced test_foundersreward --- src/chainparams.cpp | 4 +- src/gtest/test_foundersreward.cpp | 82 +++++++++++++++++++------------ 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9605cee5f5..52dbf68a70 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -370,13 +370,15 @@ bool SelectParamsFromCommandLine() // Block height must be >0 and <=last CF reward block height (note that after hfCommunityFundHeight hard fork CF reward is permanent) // Index variable i ranges from 0 - (vCommunityFundAddress.size()-1) std::string CChainParams::GetCommunityFundAddressAtHeight(int nHeight , Fork::CommunityFundType cfType) const { - + assert(nHeight > 0); + assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); return ForkManager::getInstance().getCommunityFundAddress(nHeight,consensus.GetLastCommunityRewardBlockHeight(), cfType); } // The community fund address is expected to be a multisig (P2SH) address CScript CChainParams::GetCommunityFundScriptAtHeight(int nHeight, Fork::CommunityFundType cfType) const { assert(nHeight > 0); + assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); CBitcoinAddress address(GetCommunityFundAddressAtHeight(nHeight, cfType).c_str()); assert(address.IsValid()); diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index bceb4be1a3..4836560c22 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -13,6 +13,8 @@ #include #include #include "util.h" +#include + // To run tests: // ./zcash-gtest --gtest_filter="founders_reward_test.*" @@ -22,9 +24,9 @@ // The output can be copied into chainparams.cpp. // The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd. // -#if 0 + TEST(founders_reward_test, create_testnet_2of3multisig) { - ECC_Start(); + //ECC_Start(); this is called on the main class of gtest SelectParams(CBaseChainParams::TESTNET); boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); boost::filesystem::create_directories(pathTemp); @@ -81,21 +83,24 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { pWallet->Flush(true); - ECC_Stop(); + //ECC_Stop(); this is called on the main class of gtest } -#endif -#if 0 // Disabling all these tests for now until all the latest horizen commits have been integrated then will re-enable and fix + // Utility method to check the number of unique addresses from height 1 to maxHeight void checkNumberOfUniqueAddresses(int nUnique) { - int maxHeight = Params().GetConsensus().GetLastFoundersRewardBlockHeight(); + int maxHeight = Params().GetConsensus().GetLastCommunityRewardBlockHeight(); printf("maxHeight = %d\n",maxHeight); std::set addresses; for (int i = 1; i <= maxHeight; i++) { - addresses.insert(Params().GetFoundersRewardAddressAtHeight(i)); + if(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION).size()>0){ + auto result=addresses.insert(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION)); + + } + } std::set::iterator it; for (it = addresses.begin(); it != addresses.end(); it++) { @@ -107,34 +112,44 @@ void checkNumberOfUniqueAddresses(int nUnique) { TEST(founders_reward_test, general) { + SelectParams(CBaseChainParams::TESTNET); CChainParams params = Params(); - // Fourth testnet reward: - // address = zrBAG3pXCTDq14nivNK9mW8SfwMNcdmMQpb - // script.ToString() = OP_HASH160 9990975a435209031e247dccf9bc3e3ed3c81339 OP_EQUAL - // HexStr(script) = a9149990975a435209031e247dccf9bc3e3ed3c8133987 - - EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(1), ParseHex("a9149990975a435209031e247dccf9bc3e3ed3c8133987")); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "zrH8KT8KUcpKKNBu3fjH4hA84jZBCawErqn"); - EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(53126), ParseHex("a914581dd4277287b64d523f5cd70ccd69f9db384d5387")); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53126), "zrBAG3pXCTDq14nivNK9mW8SfwMNcdmMQpb"); - EXPECT_EQ(params.GetFoundersRewardScriptAtHeight(53127), ParseHex("a914581dd4277287b64d523f5cd70ccd69f9db384d5387")); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53127), "zrBAG3pXCTDq14nivNK9mW8SfwMNcdmMQpb"); + /* + CBitcoinAddress add ("zrRBQ5heytPMN5nY3ssPf3cG4jocXeD8fm1"); + CScriptID scriptID = boost::get(add.Get()); // Get() returns a boost variant + CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; + std::cout<<"Script: "< 0"); + ASSERT_DEATH(params.GetCommunityFundScriptAtHeight(maxHeight+1,Fork::CommunityFundType::FOUNDATION), "nHeight<=consensus.GetLastCommunityRewardBlockHeight()"); + ASSERT_DEATH(params.GetCommunityFundAddressAtHeight(0,Fork::CommunityFundType::FOUNDATION), "nHeight > 0"); + ASSERT_DEATH(params.GetCommunityFundAddressAtHeight(maxHeight+1,Fork::CommunityFundType::FOUNDATION), "nHeight<=consensus.GetLastCommunityRewardBlockHeight()"); } -#define NUM_MAINNET_FOUNDER_ADDRESSES 48 +//#define NUM_MAINNET_FOUNDER_ADDRESSES 48 +#define NUM_MAINNET_FOUNDER_ADDRESSES 7 TEST(founders_reward_test, mainnet) { SelectParams(CBaseChainParams::MAIN); @@ -142,7 +157,8 @@ TEST(founders_reward_test, mainnet) { } -#define NUM_TESTNET_FOUNDER_ADDRESSES 48 +//#define NUM_TESTNET_FOUNDER_ADDRESSES 48 +#define NUM_TESTNET_FOUNDER_ADDRESSES 4 TEST(founders_reward_test, testnet) { SelectParams(CBaseChainParams::TESTNET); @@ -165,7 +181,7 @@ TEST(founders_reward_test, slow_start_subsidy) { SelectParams(CBaseChainParams::MAIN); CChainParams params = Params(); - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); + int maxHeight = params.GetConsensus().GetLastCommunityRewardBlockHeight(); CAmount totalSubsidy = 0; for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; @@ -175,18 +191,20 @@ TEST(founders_reward_test, slow_start_subsidy) { ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); } - +//This test has not more sense because GetNumFoundersRewardAddresses(), GetNumFoundersRewardAddresses2(),vCommunityFundAddress and vCommunityFundAddress2 doesn't exist anymore. +/* // For use with mainnet and testnet which each have 48 addresses. // Verify the number of rewards each individual address receives. void verifyNumberOfRewards() { CChainParams params = Params(); - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); + int maxHeight = params.GetConsensus().GetLastCommunityRewardBlockHeight(); std::multiset ms; for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { - ms.insert(params.GetFoundersRewardAddressAtHeight(nHeight)); + ms.insert(params.GetCommunityFundAddressAtHeight(nHeight,Fork::CommunityFundType::FOUNDATION)); } - EXPECT_EQ(ms.count(params.GetFoundersRewardAddressAtIndex(0)),17500); + EXPECT_EQ(ms.count(params.GetCommunityFundAddressAtHeight(0,Fork::CommunityFundType::FOUNDATION)),17500); + for (int i = 1; i <= params.GetNumFoundersRewardAddresses()-2; i++) { EXPECT_EQ(ms.count(params.GetFoundersRewardAddressAtIndex(i)), 17501); } @@ -210,4 +228,4 @@ TEST(founders_reward_test, per_address_reward_testnet) { SelectParams(CBaseChainParams::TESTNET); verifyNumberOfRewards(); } -#endif +*/ From b104f7e2c92ab466cbb80b640c576678cacdb9fe Mon Sep 17 00:00:00 2001 From: abi87 Date: Wed, 11 Dec 2019 11:49:36 +0100 Subject: [PATCH 06/45] minor gtest cleanup --- src/wallet/gtest/test_deadlock.cpp | 136 +++++++++++++---------------- 1 file changed, 63 insertions(+), 73 deletions(-) diff --git a/src/wallet/gtest/test_deadlock.cpp b/src/wallet/gtest/test_deadlock.cpp index 072a0a713a..c7a63bea8e 100644 --- a/src/wallet/gtest/test_deadlock.cpp +++ b/src/wallet/gtest/test_deadlock.cpp @@ -14,84 +14,74 @@ using namespace libzcash; extern ZCJoinSplit *params; - -CWalletTx GetValidTx(const libzcash::SpendingKey &sk, CAmount value, - bool randomInputs) { - return GetValidReceive(*params, sk, value, randomInputs); -} - - -TEST(deadlock_test, setup_datadir_location_run_as_first_test) { - // Get temporary and unique path for file. - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() - / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); -} - -void write_db(CWallet &wallet, CBlock &block, SpendingKey &sk, - std::atomic_int &finish) { - - for (int i = 0; i < 1000; i++) { - auto wtx = GetValidTx(sk, 10, true); - - wallet.SyncTransaction(wtx, &block); - } - - finish++; +void write_db(CWallet &wallet, CBlock &block, SpendingKey &sk, std::atomic_int &finish) +{ + for (int i = 0; i < 1000; i++) { + auto wtx = GetValidReceive(*params, sk, 10, true); + wallet.SyncTransaction(wtx, &block); + } + + finish++; } void write_block(CWallet &walletdb, std::atomic_int &finish) { + for (int i = 0; i < 100; i++) { + CBlockLocator loc; + walletdb.SetBestChain(loc); + } - for (int i = 0; i < 100; i++) { - CBlockLocator loc; - walletdb.SetBestChain(loc); - - } - finish++; + finish++; } TEST(deadlock_test, deadlock) { - - //create wallet - SelectParams(CBaseChainParams::TESTNET); - bool fFirstRun = true; - CWallet pwalletMain("wallet.dat"); - DBErrors nLoadWalletRet = pwalletMain.LoadWallet(fFirstRun); - - auto sk = libzcash::SpendingKey::random(); - pwalletMain.AddSpendingKey(sk); - - //create block - CBlock block; - - //number of concurrent SyncTransaction Thread -1 - int size = 2; - std::atomic_int finished(0); - std::thread myThreads[size]; - - //launch #size -1 thread to process transaction - for (int i = 0; i < size; i++) { - - if (i == 0) { - myThreads[i] = std::thread(write_block, std::ref(pwalletMain), - std::ref(finished)); - - } - //otherwise it process txes - else { - myThreads[i] = std::thread(write_db, std::ref(pwalletMain), - std::ref(block), std::ref(sk), std::ref(finished)); - - } - - } - - //wait all threads to finish - for (int i = 0; i < size; i++) { - myThreads[i].join(); - } - - EXPECT_EQ(finished, size); - + std::string originalDataDir(""); + if (mapArgs.count("-datadir") != 0) + originalDataDir = mapArgs["-datadir"]; + + //set tmp db folder + boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() + / boost::filesystem::unique_path(); + boost::filesystem::create_directories(pathTemp); + mapArgs["-datadir"] = pathTemp.string(); + + //create wallet + SelectParams(CBaseChainParams::TESTNET); + bool fFirstRun = true; + CWallet walletMain("deadlock_ut_wallet.dat"); + DBErrors nLoadWalletRet = walletMain.LoadWallet(fFirstRun); + + auto sk = libzcash::SpendingKey::random(); + walletMain.AddSpendingKey(sk); + + //create block + CBlock block; + + //number of concurrent SyncTransaction Thread -1 + int size = 2; + std::atomic_int finished(0); + std::thread myThreads[size]; + + //launch #size -1 thread to process transaction + for (int i = 0; i < size; i++) { + if (i == 0) { + myThreads[i] = std::thread(write_block, std::ref(walletMain), + std::ref(finished)); + + } + else { //otherwise it process txes + myThreads[i] = std::thread(write_db, std::ref(walletMain), + std::ref(block), std::ref(sk), std::ref(finished)); + } + + } + + //wait all threads to finish + for (int i = 0; i < size; i++) { + myThreads[i].join(); + } + + EXPECT_EQ(finished, size); + + if (!originalDataDir.empty()) + mapArgs["-datadir"] = originalDataDir; } From 042996eb8b7a7ffdb4b2f24225753ea4e293fb88 Mon Sep 17 00:00:00 2001 From: abi87 Date: Wed, 11 Dec 2019 11:53:58 +0100 Subject: [PATCH 07/45] minor gtest cleanup --- src/wallet/gtest/test_deadlock.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/wallet/gtest/test_deadlock.cpp b/src/wallet/gtest/test_deadlock.cpp index c7a63bea8e..49d391220d 100644 --- a/src/wallet/gtest/test_deadlock.cpp +++ b/src/wallet/gtest/test_deadlock.cpp @@ -34,10 +34,6 @@ void write_block(CWallet &walletdb, std::atomic_int &finish) { } TEST(deadlock_test, deadlock) { - std::string originalDataDir(""); - if (mapArgs.count("-datadir") != 0) - originalDataDir = mapArgs["-datadir"]; - //set tmp db folder boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); @@ -81,7 +77,4 @@ TEST(deadlock_test, deadlock) { } EXPECT_EQ(finished, size); - - if (!originalDataDir.empty()) - mapArgs["-datadir"] = originalDataDir; } From af4bd3ddfe21fe487d3f000118afa6d6cd7d4e11 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Thu, 12 Dec 2019 10:13:54 +0100 Subject: [PATCH 08/45] Made changes suggested by @abi87 --- .../listtransactions_addressfilter.py | 27 +++++++++++- src/wallet/rpcwallet.cpp | 42 ++++++++++--------- src/wallet/wallet.cpp | 33 +++++++-------- src/wallet/wallet.h | 2 +- 4 files changed, 64 insertions(+), 40 deletions(-) diff --git a/qa/rpc-tests/listtransactions_addressfilter.py b/qa/rpc-tests/listtransactions_addressfilter.py index e3d0f1fa1b..b0c35309e3 100755 --- a/qa/rpc-tests/listtransactions_addressfilter.py +++ b/qa/rpc-tests/listtransactions_addressfilter.py @@ -113,7 +113,7 @@ def run_test(self): #verify listtransactions returns the 5 most recent transactions of address result=self.nodes[1].listtransactions(address,5) if(len(result)!=5): - raise AssertionError("Expected only 10 transactions") + raise AssertionError("Expected only 5 transactions") for i in range(11,7): check_array_result([result[i-1]], {"txid":txes[i-1]}, @@ -123,7 +123,7 @@ def run_test(self): #verify listtransactions returns the transactions n.3-4-5-6-7 of address result=self.nodes[1].listtransactions(address,5,3) if(len(result)!=5): - raise AssertionError("Expected only 10 transactions") + raise AssertionError("Expected only transactions: 3-4-5-6-7") for i in range(8,4): print("I: ",result[i-1]) check_array_result([result[i-1]], @@ -131,6 +131,29 @@ def run_test(self): {"amount":float(i),"address":address}) + #verify listtransactions returns only last 10 tx + result=self.nodes[1].listtransactions("*") + if(len(result)!=10): + raise AssertionError("Expected only 10 transactions") + + #verify listtransactions returns the 5 most recent transactions + result=self.nodes[1].listtransactions("*",5) + if(len(result)!=5): + raise AssertionError("Expected only 5 transactions") + for i in range(11,7): + check_array_result([result[i-1]], + {"txid":txes[i-1]}, + {"amount":float(i)}) + + #verify listtransactions returns the transactions n.3-4-5-6-7 + result=self.nodes[1].listtransactions("*",5,3) + if(len(result)!=5): + raise AssertionError("Expected only transactions: 3-4-5-6-7") + for i in range(8,4): + print("I: ",result[i-1]) + check_array_result([result[i-1]], + {"txid":txes[i-1]}, + {"amount":float(i)}) if __name__ == '__main__': ListTransactionsTest().main() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d21294ddaf..c0195349c5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1357,7 +1357,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter,string address) +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter,const string& address) { CAmount nFee; string strSentAccount; @@ -1386,8 +1386,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); - if(!address.empty()&&address!="*"){ - entry.push_back(Pair("address",address)); + if(!address.empty() && address!="*"){ + entry.push_back(Pair("address",address)); } ret.push_back(entry); } @@ -1427,7 +1427,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); if(!address.empty()&&address!="*"){ - entry.push_back(Pair("address",address)); + entry.push_back(Pair("address",address)); } ret.push_back(entry); } @@ -1514,15 +1514,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string address="*"; - if (params.size() > 0){ - - address=params[0].get_str(); - CBitcoinAddress baddress = CBitcoinAddress(address); - if (!baddress.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zen address"); - - } + string address("*"); + if (params.size() > 0) + { + address=params[0].get_str(); + if (address.compare("*")) + { + CBitcoinAddress baddress = CBitcoinAddress(address); + if (!baddress.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zen address"); + } + } int nCount = 10; if (params.size() > 1) @@ -1550,7 +1552,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) for (std::multimap::reverse_iterator itr = txes.rbegin(); itr != txes.rend();++itr) { - ListTransactions(std::ref((*itr).second), "", 0, true, ret, filter,address); + ListTransactions(itr->second, "", 0, true, ret, filter,address); } @@ -2561,7 +2563,7 @@ UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp) uint256 pubKeyHash; uint256 anchor = ZCIncrementalMerkleTree().root(); JSDescription samplejoinsplit(isGroth, - *pzcashParams, + *pzcashParams, pubKeyHash, anchor, {JSInput(), JSInput()}, @@ -2899,7 +2901,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) mtx.nVersion = shieldedTxVersion; mtx.joinSplitPubKey = joinSplitPubKey; JSDescription jsdesc(mtx.nVersion == GROTH_TX_VERSION, - *pzcashParams, + *pzcashParams, joinSplitPubKey, anchor, {vjsin[0], vjsin[1]}, @@ -3609,10 +3611,10 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) CMutableTransaction contextualTx; bool isShielded = !fromTaddr || zaddrRecipients.size() > 0; - contextualTx.nVersion = 1; - if(isShielded) { - contextualTx.nVersion = shieldedTxVersion; - } + contextualTx.nVersion = 1; + if(isShielded) { + contextualTx.nVersion = shieldedTxVersion; + } // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); std::shared_ptr operation( new AsyncRPCOperation_sendmany(contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) ); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bfe745c6d8..1eb89e4a69 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3668,32 +3668,31 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee); } -void CWallet::GetFilteredTransactions(std::multimap& outEntries, std::string address) +void CWallet::GetFilteredTransactions(std::multimap& outEntries, const std::string& address) { - LOCK2(cs_main, cs_wallet); - CScript scriptPubKey; + LOCK2(cs_main, cs_wallet); + CScript scriptPubKey; - if(address.compare("*")!=0){ - CBitcoinAddress baddress = CBitcoinAddress(address); - scriptPubKey = GetScriptForDestination(baddress.Get(), false); + if(address.compare("*")!=0){ + CBitcoinAddress baddress = CBitcoinAddress(address); + scriptPubKey = GetScriptForDestination(baddress.Get(), false); - } + } - //getting all Txes of address in the wallet + //getting all Txes of address in the wallet for (auto & p : mapWallet) { CWalletTx wtx = p.second; if(address.compare("*")==0){ - outEntries.insert(make_pair(wtx.nOrderPos,wtx)); + outEntries.insert(make_pair(wtx.nOrderPos,wtx)); } else{ - for(const CTxOut& txout : wtx.vout){ - auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), - scriptPubKey.end()); - if (res == txout.scriptPubKey.begin()){ - outEntries.insert(make_pair(wtx.nOrderPos,wtx)); - } - - } + for(const CTxOut& txout : wtx.vout){ + auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), scriptPubKey.end()); + if (res == txout.scriptPubKey.begin()){ + outEntries.insert(make_pair(wtx.nOrderPos,wtx)); + } + + } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 03db9d013e..eb24f45d06 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1128,7 +1128,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool ignoreUnspendable=true); /*Find all transactions of a specific addres*/ void GetFilteredTransactions(std::multimap& outEntries, - std::string address); + const std::string& address); }; From c5790e7c41885ea22cf52b75e79097227724245b Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Thu, 12 Dec 2019 15:11:03 +0100 Subject: [PATCH 09/45] Reversed the txes' order returned by listtransactions --- .../listtransactions_addressfilter.py | 60 +++++++++++-------- src/wallet/rpcwallet.cpp | 10 +--- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/qa/rpc-tests/listtransactions_addressfilter.py b/qa/rpc-tests/listtransactions_addressfilter.py index b0c35309e3..95baf539de 100755 --- a/qa/rpc-tests/listtransactions_addressfilter.py +++ b/qa/rpc-tests/listtransactions_addressfilter.py @@ -58,9 +58,8 @@ def run_test(self): self.nodes[0].generate(120) address=self.nodes[1].getnewaddress() - - + #simple send 1 to address and verify listtransaction returns this tx with address in input txid=self.nodes[0].sendtoaddress(address, float(1) ) self.sync_all() @@ -71,7 +70,7 @@ def run_test(self): {"amount":Decimal("1.0")}) #verify listtransactions returns this tx without any input - check_array_result(self.nodes[1].listtransactions(address), + check_array_result(self.nodes[1].listtransactions("*"), {"txid":txid}, {"amount":Decimal("1.0")}) @@ -88,73 +87,84 @@ def run_test(self): {"amount":Decimal("1.0"),"address":address}) #verify listtransactions returns 2 tx with no inputs - result=self.nodes[1].listtransactions() + result=self.nodes[1].listtransactions("*") if(len(result)!=2): raise AssertionError("Expected 2 transactions") + #verify listtransactions returns only last 10 tx with address in input txes=[] - for i in range(1,11): + for i in range(2,12): txid=self.nodes[0].sendtoaddress(address, float(i) ) txes.append(txid) + self.sync_all() self.nodes[2].generate(1) - self.sync_all() + self.sync_all() result=self.nodes[1].listtransactions(address) if(len(result)!=10): raise AssertionError("Expected only 10 transactions") - for i in range(11,1): + + + for i in range(1,11): check_array_result([result[i-1]], {"txid":txes[i-1]}, - {"amount":float(i),"address":address}) - + {"amount":float(i+1),"address":address}) + #verify listtransactions returns the 5 most recent transactions of address result=self.nodes[1].listtransactions(address,5) if(len(result)!=5): raise AssertionError("Expected only 5 transactions") - for i in range(11,7): + + for i in range(1,6): check_array_result([result[i-1]], - {"txid":txes[i-1]}, - {"amount":float(i),"address":address}) + {"txid":txes[4+i]}, + {"amount":float(i+6),"address":address}) + #verify listtransactions returns the transactions n.3-4-5-6-7 of address result=self.nodes[1].listtransactions(address,5,3) if(len(result)!=5): raise AssertionError("Expected only transactions: 3-4-5-6-7") - for i in range(8,4): - print("I: ",result[i-1]) - check_array_result([result[i-1]], - {"txid":txes[i-1]}, - {"amount":float(i),"address":address}) + + for i in range(4,9): + check_array_result([result[i-4]], + {"txid":txes[i-2]}, + {"amount":float(i),"address":address}) + + #verify listtransactions returns only last 10 tx result=self.nodes[1].listtransactions("*") if(len(result)!=10): raise AssertionError("Expected only 10 transactions") + + #verify listtransactions returns the 5 most recent transactions result=self.nodes[1].listtransactions("*",5) + if(len(result)!=5): raise AssertionError("Expected only 5 transactions") - for i in range(11,7): + for i in range(1,6): check_array_result([result[i-1]], - {"txid":txes[i-1]}, - {"amount":float(i)}) + {"txid":txes[4+i]}, + {"amount":float(i+6)}) #verify listtransactions returns the transactions n.3-4-5-6-7 result=self.nodes[1].listtransactions("*",5,3) + if(len(result)!=5): raise AssertionError("Expected only transactions: 3-4-5-6-7") - for i in range(8,4): - print("I: ",result[i-1]) - check_array_result([result[i-1]], - {"txid":txes[i-1]}, + for i in range(4,9): + check_array_result([result[i-4]], + {"txid":txes[i-2]}, {"amount":float(i)}) - + if __name__ == '__main__': ListTransactionsTest().main() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c0195349c5..64c37e076e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1553,7 +1553,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) itr != txes.rend();++itr) { ListTransactions(itr->second, "", 0, true, ret, filter,address); - + if ((int)ret.size() >= (nCount+nFrom)) break; } //getting all the specifi Txes requested by nCount and nFrom @@ -1572,11 +1572,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - if(nFrom!=0){ - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest - - } - + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest ret.clear(); ret.setArray(); @@ -3614,7 +3610,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) contextualTx.nVersion = 1; if(isShielded) { contextualTx.nVersion = shieldedTxVersion; - } + } // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); std::shared_ptr operation( new AsyncRPCOperation_sendmany(contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) ); From d24957d23830b3c236c66a769c98131a93a76046 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Fri, 13 Dec 2019 10:20:13 +0100 Subject: [PATCH 10/45] Changed requested by albi87 --- qa/rpc-tests/listtransactions.py | 2 +- src/wallet/.rpcwallet.cpp.swo | Bin 0 -> 20480 bytes src/wallet/rpcwallet.cpp | 12 ++++++------ src/wallet/wallet.cpp | 6 ------ src/wallet/wallet.h | 4 ++-- 5 files changed, 9 insertions(+), 15 deletions(-) create mode 100644 src/wallet/.rpcwallet.cpp.swo diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index bd8ac5fa3d..d6ad8f4de7 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -54,7 +54,7 @@ def run_test(self): check_array_result(self.nodes[0].listtransactions(), {"txid":txid, "category":"receive"}, {"amount":Decimal("0.2")}) - + # sendmany from node1: twice to self, twice to node2: send_to = { self.nodes[0].getnewaddress() : 0.11, self.nodes[1].getnewaddress() : 0.22, diff --git a/src/wallet/.rpcwallet.cpp.swo b/src/wallet/.rpcwallet.cpp.swo new file mode 100644 index 0000000000000000000000000000000000000000..e2332be1d69968e6642742d0105b8fe7c359d783 GIT binary patch literal 20480 zcmeHNYmgjO6&^t4B?h4o%L2VSSji08otfPb2urfEnVpacyF1J7Y#?Nlsh*xYJ56S~ zJKa6|NC^37S%_L_`Jk};p%xWNkV2tU1o=aOQWd011cM+?MTJnjK}7I7eQ(cn_s%33 zw5YPWtG?Zyd+t5wo^$S_?>V=e*_j#?D~;dtf5${LFI>e zn&qbMG!Ih=0Mkejqo{MH%uy^-)Y-Y)ALHb&YiSns^TrBn&#oz zM>Qe~L>A~~fu>XKTXWL%s)7CtRXHo(!%jVAx?An2JhDJ!fye@p1tJSX7KkhmSs=1N zWP$%f3pi$9Y%laWTIx10{~s0l|DJpL-Rk}O{%1$c7ak@O2C z{o5h>KP7#;q(2g(zb)xr|5i(dJpTWXbnnFTl@R?cNuQDYpAOOAl=Q8VK6H$D@%X|5qh_r=;5<`YVz?De2FK=r2pUXPFsx>|&#m{y>QSqHMoK(m(St@#5L%pro&obUQ?ULDGwoenW`(KxBc) z0+9tG3q%%(ED%}X16e?+#A0;jH|V^3vUn$k2k`y*ePBCqI`AprXy8SBw;llQ18xU? z2z(8g2Na+HtOk036M^UO9lam88Mq1f7BCOY0DZt)_~3mLcm{YHcmUWB+z9Lgz7AXq zTm|d_YQQWo28;rq1WpEC$9dyE;9lUTzydH2Tmlq;Gl2a#)7%Z*1>6Z-4SWf(fI3hB z-p0A0eB1NyElN>fjfYo16Kn@U=TPCcm-$77l3_$0h|Ub z0}kTs`b*#&KoR&n@I21bKLbo)CGaW^+^+z)0=ED^2KEAbfFdvmJcSs-{lKq*`+#eJ zs{sWV0kXj7fTMwj;NNQi^0Q99{%{`Vd*Ug?xrbsJCgVFg`hv&AHm)rF7}==xDB38qQ`5)8oad()9S$ z^u$DAvX~p`WpT*`KCn1zLIKk>EQeR($+lu`VXS8zi^r30Pf$vJ@e$XtIkHF!%9T)@ z0E^u*Sxw5>U>Ob9Y)f=@o3_-%T_I~RWj5_vsjR3w5)+DMCE{~e7@BUIbgs%n<)^fLF|=CFT-8d96}g~C*^w4pGW8_sT& zy_^`%PZqaKAUD-eOjj>qn~s9xH0;EHhJAZkLergd&nY=cYOfbT zoODM!Z}p`+8#Jd@7jdV!KrIul;?)1nZNx1r=vl36s$-*h>)lhF8n+64ruWK7*hanp zN!<KSYI_3}dlX}dSICIFW3Gb1U1M6O z!A2EAD?T|TJbFnzxgk`Qx-IEc%JC~kFW%F|3S+tA#==Nxyg*Cd^f>JZW8A436{Z^w zcHpL7VTp=n(>_*7dTJ3<8W=qaX^>k`;Xe3VjEna8>+z{h>bl!mP~G+>=@P^Ib6BWt+c7>q$GnyW0EwKV)!>Qh`Lc1*QPx|j`O=+H`ZK}>EftOF^=7ci*x)|~0E zk;+L{v=rS|TrtZT_EzkyO`G<7U1@OJR8-FDT6vd>RjC6BWExAE*)6wd* z*HEcXzO7oC>7=0|w@i#tZUvj|Qp;RdYq)T|!wynROKV_^%yB#Iv^^NCBTP~$cPb5* zQTG~#&KEJ_mr{Zyq(((?lwc`Lp0>F)7uG=M&Qi0ZFxa|*bu(C^=~}3cYFNCa8Nq7A zd-a-NnbM$h0hQ4lt7>)5vW1B)`SFVw4jVPcF$dG>`T6-2e5Kn)(^7fLux2p^Rs4oQ zVc0(TBW2di6tNk>0JXGo6YB%Mpeu627|R!#ZB(6k`mmNwda)vLcRQgIO2fn`!gL}Y zS;JhkwAq@2T|3DJGMV%H1~UEUup+je^_oLN6m`IyKf|UJ$H2H|liUQ|L?>({Vssc|2Rs!&n-CXe-qdXG=V|jSm0&Udl+~S_$_cZKyB{?q9?LIWP!*6 zkp&_PL>7oF5LqCyKxBc)0+9tG3;a(k5J-9<3L=v`?EpT?e7Op(A|w11BcunBEJxG5 z$SIXj+_Gu&4G6m6q>e}*q5u?JanIuxM~Vkww`9*cU&P!W@N>xsT(^QbeM5-uO;Mv^ zd&*6Td07UM*6t|%>fD>27Ox}|!BeU$gw_x}sFX~{T02b9E9CPEULbL(-3Rn%r`wMf zaf4yyD+$*ebpA(bJa#Ev)W-RLR66Pgob`KvdvLD50H8encHjhHFMy;3ed~9|P_OegoVL%mNwUDBxGffnNt~1}+9R0iOlV1kM1C0iH!p{88Xm z;LE@sU=6SgxDEO78-VWu*8^V!b^tkG05~0>-1)u0O~99d%YiLG4u}B# z^dw~==!tQ?awQ7AQA+uFOcw;h8%>H}D&|@lcJ6H_XxPx;poN%~Wg|j|d4}ke<#P5I zm-(#7_mJFlnwWA$twAi)m}+qff>Qzpy=6xE3Pimbg8TS|n**Y=tw1{pJLeDs!F-21 zV)FA!z*3~A&kmwHe)kkFLy!>RJ-CBYfw+X9sQ@$!l-V*3ilDluC$ zyP@e^3TO$Ga;7G7<0HfCM{{j4-n5jm281k(QE!DNONFm{3`kj+YF_({kEPImoxGy4 zwf}wb#1#^<6C``Hcpd8pSGSZX!EGY=i|F(m#(%>jBa^wQsZwFGba8GA#ztO8Y6S_@ z%iC9KJWmRS;xE~tr!0po(!99EptyXQix*k;_xp>iXq7(K1CqW1|B1qZ~aJ!OCg5=f*` zuAw)W`a`M6mH3y&&_~8fMrpv@g3>VSe9}}Camrcwaxat!kI%%qwyqsQ4#Ws4Y-Nm^dJp8#7J(FhE461+MOst) z2Qo({F`n!u1?zSLsXQ##$e%b66cmi41}*J2a!b5nhlQiB(x$e1c`W8BLI301mQ=?y z>QKgTAB^_onfM@sb3;!;W+ju%w-+#~kJ*Y{*WpXM6=HFSpSrg^i@cMaTzYx!5UoQb zTHY;52({zZ!}b~4}%i&9hW<+;K3 zO*%^W(%_~2o~BWfZGZss-HL`W$5&vuI(*i!7MW2ExES9Ws3cjs?`{WBzrk6TUSKt# zn||c5nRqIdas|7_Xi3jkF;`?greWgPwxMe1Lq+8KNvLm#e;~6%(G_I974AO2LSEqN zu5xE#GlAP*q}##*F0Kf*+Jlh#jU=jcG1S2*6kl&PMx~C7J2wq{9VHrCMR)Usn-rb( zv;OnX%dm^aipdmfU8(41UlI`PfH%^7vmt0e(W(EqFI^l=m$!s>eLkWh+==tXS25H9 zt>V{=X2E~KDW2Yk{@-nEcXPCRd(6G#MN0bDoS=Q(dT=l;$|RbRi~g8Bqi*dVv=1 R`QZKg@yOjL=fEMI_;0G){doWY literal 0 HcmV?d00001 diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 64c37e076e..492c8c32e4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1386,7 +1386,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); - if(!address.empty() && address!="*"){ + if(address!="*"){ entry.push_back(Pair("address",address)); } ret.push_back(entry); @@ -1426,7 +1426,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); - if(!address.empty()&&address!="*"){ + if(address!="*") + { entry.push_back(Pair("address",address)); } ret.push_back(entry); @@ -1435,7 +1436,6 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe } } - void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret) { bool fAllAccounts = (strAccount == string("*")); @@ -1558,9 +1558,9 @@ UniValue listtransactions(const UniValue& params, bool fHelp) //getting all the specifi Txes requested by nCount and nFrom if (nFrom > (int)ret.size()) - nFrom = ret.size(); + nFrom = ret.size(); if ((nFrom + nCount) > (int)ret.size()) - nCount = ret.size() - nFrom; + nCount = ret.size() - nFrom; vector arrTmp = ret.getValues(); @@ -1739,7 +1739,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) CWalletTx tx = (*it).second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(tx, "*", 0, true, transactions, filter,""); + ListTransactions(tx, "*", 0, true, transactions, filter,"*"); } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1eb89e4a69..a6e6ed46f5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3691,15 +3691,9 @@ void CWallet::GetFilteredTransactions(std::multimap& outEnt if (res == txout.scriptPubKey.begin()){ outEntries.insert(make_pair(wtx.nOrderPos,wtx)); } - } - } - - } - - } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index eb24f45d06..e7dae3b0d2 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1127,8 +1127,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool ignoreSpent=true, bool ignoreUnspendable=true); /*Find all transactions of a specific addres*/ - void GetFilteredTransactions(std::multimap& outEntries, - const std::string& address); + void GetFilteredTransactions(std::multimap& outEntries, + const std::string& address); }; From ee713a1fe8d0092934d381c5c1e02a6eb4796772 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Fri, 13 Dec 2019 11:36:43 +0100 Subject: [PATCH 11/45] Introduced changes requested from albi87 --- src/chainparams.cpp | 6 ++--- src/gtest/test_foundersreward.cpp | 37 +++++++------------------------ 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 52dbf68a70..f61e2a6877 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -370,15 +370,15 @@ bool SelectParamsFromCommandLine() // Block height must be >0 and <=last CF reward block height (note that after hfCommunityFundHeight hard fork CF reward is permanent) // Index variable i ranges from 0 - (vCommunityFundAddress.size()-1) std::string CChainParams::GetCommunityFundAddressAtHeight(int nHeight , Fork::CommunityFundType cfType) const { - assert(nHeight > 0); - assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); + assert(nHeight > 0); + assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); return ForkManager::getInstance().getCommunityFundAddress(nHeight,consensus.GetLastCommunityRewardBlockHeight(), cfType); } // The community fund address is expected to be a multisig (P2SH) address CScript CChainParams::GetCommunityFundScriptAtHeight(int nHeight, Fork::CommunityFundType cfType) const { assert(nHeight > 0); - assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); + assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); CBitcoinAddress address(GetCommunityFundAddressAtHeight(nHeight, cfType).c_str()); assert(address.IsValid()); diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 4836560c22..a56a7d80e9 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -26,12 +26,11 @@ // TEST(founders_reward_test, create_testnet_2of3multisig) { - //ECC_Start(); this is called on the main class of gtest SelectParams(CBaseChainParams::TESTNET); boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); - bool fFirstRun; + bool fFirstRun=true; auto pWallet = std::make_shared("wallet.dat"); ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); pWallet->TopUpKeyPool(); @@ -83,7 +82,6 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { pWallet->Flush(true); - //ECC_Stop(); this is called on the main class of gtest } @@ -96,11 +94,10 @@ void checkNumberOfUniqueAddresses(int nUnique) { printf("maxHeight = %d\n",maxHeight); std::set addresses; for (int i = 1; i <= maxHeight; i++) { - if(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION).size()>0){ - auto result=addresses.insert(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION)); - - } + if(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION).size()>0) { + auto result=addresses.insert(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION)); + } } std::set::iterator it; for (it = addresses.begin(); it != addresses.end(); it++) { @@ -112,22 +109,10 @@ void checkNumberOfUniqueAddresses(int nUnique) { TEST(founders_reward_test, general) { - SelectParams(CBaseChainParams::TESTNET); - CChainParams params = Params(); - - /* - CBitcoinAddress add ("zrRBQ5heytPMN5nY3ssPf3cG4jocXeD8fm1"); - CScriptID scriptID = boost::get(add.Get()); // Get() returns a boost variant - CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; - std::cout<<"Script: "< Date: Fri, 13 Dec 2019 12:28:47 +0100 Subject: [PATCH 12/45] Reintroduced Account for backward compatibility --- .../listtransactions_addressfilter.py | 23 ++++-------- src/wallet/rpcwallet.cpp | 36 ++++++++++--------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/qa/rpc-tests/listtransactions_addressfilter.py b/qa/rpc-tests/listtransactions_addressfilter.py index 95baf539de..2714287838 100755 --- a/qa/rpc-tests/listtransactions_addressfilter.py +++ b/qa/rpc-tests/listtransactions_addressfilter.py @@ -59,16 +59,16 @@ def run_test(self): self.nodes[0].generate(120) address=self.nodes[1].getnewaddress() - + #simple send 1 to address and verify listtransaction returns this tx with address in input txid=self.nodes[0].sendtoaddress(address, float(1) ) self.sync_all() self.nodes[2].generate(1) self.sync_all() - check_array_result(self.nodes[1].listtransactions(address), + check_array_result(self.nodes[1].listtransactions("*",1,0,False,address), {"txid":txid}, {"amount":Decimal("1.0")}) - + #verify listtransactions returns this tx without any input check_array_result(self.nodes[1].listtransactions("*"), {"txid":txid}, @@ -79,7 +79,7 @@ def run_test(self): self.sync_all() self.nodes[2].generate(1) self.sync_all() - result=self.nodes[1].listtransactions(address) + result=self.nodes[1].listtransactions("*",1,0,False,address) if(len(result)!=1): raise AssertionError("Expected only 1 transaction") check_array_result(result, @@ -102,19 +102,8 @@ def run_test(self): self.nodes[2].generate(1) self.sync_all() - result=self.nodes[1].listtransactions(address) - if(len(result)!=10): - raise AssertionError("Expected only 10 transactions") - - - for i in range(1,11): - check_array_result([result[i-1]], - {"txid":txes[i-1]}, - {"amount":float(i+1),"address":address}) - - #verify listtransactions returns the 5 most recent transactions of address - result=self.nodes[1].listtransactions(address,5) + result=self.nodes[1].listtransactions("*",5,0,False,address) if(len(result)!=5): raise AssertionError("Expected only 5 transactions") @@ -126,7 +115,7 @@ def run_test(self): #verify listtransactions returns the transactions n.3-4-5-6-7 of address - result=self.nodes[1].listtransactions(address,5,3) + result=self.nodes[1].listtransactions("*",5,3,False,address) if(len(result)!=5): raise AssertionError("Expected only transactions: 3-4-5-6-7") diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 492c8c32e4..49b9d4beba 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1458,15 +1458,16 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() > 4) + if (fHelp || params.size() > 5) throw runtime_error( "listtransactions ( \"account\" count from includeWatchonly)\n" - "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" + "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for address 'address'.\n" "\nArguments:\n" - "1. \"address\" (string, optional) The address name.\n" + "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n" "2. count (numeric, optional, default=10) The number of transactions to return\n" "3. from (numeric, optional, default=0) The number of transactions to skip\n" "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n" + "5. address (string, optional) Include only transactions involving this address. All previous arguments should specified\n" "\nResult:\n" "[\n" " {\n" @@ -1513,18 +1514,11 @@ UniValue listtransactions(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - - string address("*"); - if (params.size() > 0) - { - address=params[0].get_str(); - if (address.compare("*")) - { - CBitcoinAddress baddress = CBitcoinAddress(address); - if (!baddress.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zen address"); - } - } + string account("*"); + if (params.size() > 0) + { + account=params[0].get_str(); + } int nCount = 10; if (params.size() > 1) @@ -1536,7 +1530,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if(params.size() > 3) if(params[3].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - + string address("*"); + if (params.size()>4) + { + address=params[4].get_str(); + if (address.compare("*")) + { + CBitcoinAddress baddress = CBitcoinAddress(address); + if (!baddress.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zen address"); + } + } if (nCount < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); if (nFrom < 0) From 88d0c8d59893248d3b6db32d811f60abc6991c02 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Fri, 13 Dec 2019 13:13:48 +0100 Subject: [PATCH 13/45] Made changes proposed by @alsala --- src/wallet/gtest/test_deadlock.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/wallet/gtest/test_deadlock.cpp b/src/wallet/gtest/test_deadlock.cpp index 49d391220d..bda12a0fd5 100644 --- a/src/wallet/gtest/test_deadlock.cpp +++ b/src/wallet/gtest/test_deadlock.cpp @@ -14,8 +14,9 @@ using namespace libzcash; extern ZCJoinSplit *params; -void write_db(CWallet &wallet, CBlock &block, SpendingKey &sk, std::atomic_int &finish) +void write_db(CWallet &wallet, SpendingKey &sk, std::atomic_int &finish) { + CBlock block; for (int i = 0; i < 1000; i++) { auto wtx = GetValidReceive(*params, sk, 10, true); wallet.SyncTransaction(wtx, &block); @@ -44,14 +45,11 @@ TEST(deadlock_test, deadlock) { SelectParams(CBaseChainParams::TESTNET); bool fFirstRun = true; CWallet walletMain("deadlock_ut_wallet.dat"); - DBErrors nLoadWalletRet = walletMain.LoadWallet(fFirstRun); + walletMain.LoadWallet(fFirstRun); auto sk = libzcash::SpendingKey::random(); walletMain.AddSpendingKey(sk); - //create block - CBlock block; - //number of concurrent SyncTransaction Thread -1 int size = 2; std::atomic_int finished(0); @@ -66,7 +64,7 @@ TEST(deadlock_test, deadlock) { } else { //otherwise it process txes myThreads[i] = std::thread(write_db, std::ref(walletMain), - std::ref(block), std::ref(sk), std::ref(finished)); + std::ref(sk), std::ref(finished)); } } From 51b3ba8a9c341f1c006eb1daac162bc0134d1c9a Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Mon, 16 Dec 2019 10:33:22 +0100 Subject: [PATCH 14/45] modified help of listtransactions --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 49b9d4beba..f03c20c8fe 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1467,7 +1467,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) "2. count (numeric, optional, default=10) The number of transactions to return\n" "3. from (numeric, optional, default=0) The number of transactions to skip\n" "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n" - "5. address (string, optional) Include only transactions involving this address. All previous arguments should specified\n" + "5. address (string, optional) Include only transactions involving this address\n" "\nResult:\n" "[\n" " {\n" From 64af45d321907aec4931004e9dbaf13f0f6929c6 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Mon, 16 Dec 2019 11:57:51 +0100 Subject: [PATCH 15/45] Refactored wallet.cpp --- src/wallet/wallet.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a6e6ed46f5..b539fc3587 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3676,27 +3676,25 @@ void CWallet::GetFilteredTransactions(std::multimap& outEnt if(address.compare("*")!=0){ CBitcoinAddress baddress = CBitcoinAddress(address); scriptPubKey = GetScriptForDestination(baddress.Get(), false); - } //getting all Txes of address in the wallet for (auto & p : mapWallet) { CWalletTx wtx = p.second; - if(address.compare("*")==0){ + if(address.compare("*")==0) { outEntries.insert(make_pair(wtx.nOrderPos,wtx)); } - else{ - for(const CTxOut& txout : wtx.vout){ + else { + for(const CTxOut& txout : wtx.vout) { auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), scriptPubKey.end()); if (res == txout.scriptPubKey.begin()){ outEntries.insert(make_pair(wtx.nOrderPos,wtx)); } } } - } + } } - /** * Find notes in the wallet filtered by payment address, min depth and ability to spend. * These notes are decrypted and added to the output parameter vector, outEntries. From b87d9fd1f470041f7c914c1de6280fd3a4a894d9 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Mon, 16 Dec 2019 12:36:35 +0100 Subject: [PATCH 16/45] Modified test_foundersreward with albi87's changes --- src/gtest/test_foundersreward.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index a56a7d80e9..0f6a1371ee 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -165,8 +165,7 @@ TEST(founders_reward_test, slow_start_subsidy) { for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; totalSubsidy += nSubsidy; - } - + } ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); } From fd681b8bf5207e7219d59956b27082c2a95a7b55 Mon Sep 17 00:00:00 2001 From: abi87 Date: Mon, 16 Dec 2019 12:56:50 +0100 Subject: [PATCH 17/45] fixed compilation error and cleaned formatting --- src/gtest/test_foundersreward.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 0f6a1371ee..08e402b51b 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -81,12 +81,9 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { std::cout << s << std::endl; pWallet->Flush(true); - } - - // Utility method to check the number of unique addresses from height 1 to maxHeight void checkNumberOfUniqueAddresses(int nUnique) { @@ -106,13 +103,16 @@ void checkNumberOfUniqueAddresses(int nUnique) { EXPECT_EQ(addresses.size(), nUnique); } - - TEST(founders_reward_test, general) { SelectParams(CBaseChainParams::TESTNET); CChainParams params = Params(); - //to get the ParseHex's input, create BitcoinAddress from address, get the CScriptID and then call HexStr on the result + //You can retrieve Hex from a BitCoin address as follows: + //CBitcoinAddress add ("zrRBQ5heytPMN5nY3ssPf3cG4jocXeD8fm1"); + //CScriptID scriptID = boost::get(add.Get()); // Get() returns a boost variant + //CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; + //std::cout< Date: Mon, 16 Dec 2019 15:28:52 +0100 Subject: [PATCH 18/45] Implemented changes requested by alsala --- qa/rpc-tests/listtransactions.py | 33 ++++++++++++++++++++++++++++---- src/wallet/rpcwallet.cpp | 6 +++--- src/wallet/wallet.cpp | 6 +++--- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index d6ad8f4de7..389fdc10b4 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -40,16 +40,29 @@ def run_test(self): check_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) + + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid}, + {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) + # mine a block, confirmations should change: self.nodes[0].generate(1) self.sync_all() - + + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid}, + {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1}) + check_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1}) # send-to-self: txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) + + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid, "category":"send"}, + {"amount":Decimal("-0.2")}) check_array_result(self.nodes[0].listtransactions(), {"txid":txid, "category":"receive"}, @@ -62,19 +75,31 @@ def run_test(self): self.nodes[1].getaccountaddress("") : 0.44 } txid = self.nodes[1].sendmany("", send_to) self.sync_all() - + + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.11")}, + {"txid":txid} ) check_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.11")}, {"txid":txid} ) - + + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.22")}, + {"txid":txid} ) check_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.22")}, {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.33")}, + {"txid":txid} ) check_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.33")}, {"txid":txid, "account" : ""} ) - + + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.44")}, + {"txid":txid, "account" : ""} ) check_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.44")}, {"txid":txid, "account" : ""} ) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f03c20c8fe..ce93690a24 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1428,8 +1428,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); if(address!="*") { - entry.push_back(Pair("address",address)); - } + entry.push_back(Pair("address",address)); + } ret.push_back(entry); } } @@ -1534,7 +1534,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if (params.size()>4) { address=params[4].get_str(); - if (address.compare("*")) + if (address!=("*")) { CBitcoinAddress baddress = CBitcoinAddress(address); if (!baddress.IsValid()) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b539fc3587..450315738a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3672,8 +3672,8 @@ void CWallet::GetFilteredTransactions(std::multimap& outEnt { LOCK2(cs_main, cs_wallet); CScript scriptPubKey; - - if(address.compare("*")!=0){ + bool valid=address==("*"); + if(!valid){ CBitcoinAddress baddress = CBitcoinAddress(address); scriptPubKey = GetScriptForDestination(baddress.Get(), false); } @@ -3681,7 +3681,7 @@ void CWallet::GetFilteredTransactions(std::multimap& outEnt //getting all Txes of address in the wallet for (auto & p : mapWallet) { CWalletTx wtx = p.second; - if(address.compare("*")==0) { + if(valid) { outEntries.insert(make_pair(wtx.nOrderPos,wtx)); } else { From 6a8033854779b2c9c632b661927837d890eef2a2 Mon Sep 17 00:00:00 2001 From: abi87 Date: Mon, 16 Dec 2019 15:38:59 +0100 Subject: [PATCH 19/45] removed commented out test deemed useless --- src/gtest/test_foundersreward.cpp | 40 ------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 08e402b51b..804cee4274 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -164,43 +164,3 @@ TEST(founders_reward_test, slow_start_subsidy) { ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); } -//This test make sense no more because GetNumFoundersRewardAddresses(), GetNumFoundersRewardAddresses2(),vCommunityFundAddress and vCommunityFundAddress2 don't exist anymore. -/* -// For use with mainnet and testnet which each have 48 addresses. -// Verify the number of rewards each individual address receives. -void verifyNumberOfRewards() { - CChainParams params = Params(); - int maxHeight = params.GetConsensus().GetLastCommunityRewardBlockHeight(); - std::multiset ms; - for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { - ms.insert(params.GetCommunityFundAddressAtHeight(nHeight,Fork::CommunityFundType::FOUNDATION)); - } - - EXPECT_EQ(ms.count(params.GetCommunityFundAddressAtHeight(0,Fork::CommunityFundType::FOUNDATION)),17500); - - for (int i = 1; i <= params.GetNumFoundersRewardAddresses()-2; i++) { - EXPECT_EQ(ms.count(params.GetFoundersRewardAddressAtIndex(i)), 17501); - } - EXPECT_EQ(ms.count(params.GetFoundersRewardAddressAtIndex(params.GetNumFoundersRewardAddresses()-1)), 17454); - - EXPECT_EQ(ms.count(params.GetFoundersRewardAddress2AtIndex(0)), 17501); - for (int i = 1; i <= params.GetNumFoundersRewardAddresses2()-2; i++) { - EXPECT_EQ(ms.count(params.GetFoundersRewardAddress2AtIndex(i)), 17501); - } - EXPECT_EQ(ms.count(params.GetFoundersRewardAddress2AtIndex(params.GetNumFoundersRewardAddresses2()-1)), 17501); -} - -// Verify the number of rewards going to each mainnet address -TEST(founders_reward_test, per_address_reward_mainnet) { - SelectParams(CBaseChainParams::MAIN); - verifyNumberOfRewards(); -} - -// Verify the number of rewards going to each testnet address -TEST(founders_reward_test, per_address_reward_testnet) { - SelectParams(CBaseChainParams::TESTNET); - verifyNumberOfRewards(); -} -*/ - - From 382b2808f4943de96f0cbd5aa0673ce34b5428e6 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Fri, 20 Dec 2019 17:08:27 +0100 Subject: [PATCH 20/45] Removed useless asserts --- src/chainparams.cpp | 1 - src/gtest/test_foundersreward.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f61e2a6877..c672cf350f 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -371,7 +371,6 @@ bool SelectParamsFromCommandLine() // Index variable i ranges from 0 - (vCommunityFundAddress.size()-1) std::string CChainParams::GetCommunityFundAddressAtHeight(int nHeight , Fork::CommunityFundType cfType) const { assert(nHeight > 0); - assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); return ForkManager::getInstance().getCommunityFundAddress(nHeight,consensus.GetLastCommunityRewardBlockHeight(), cfType); } diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index 804cee4274..c62ffa2901 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -128,7 +128,6 @@ TEST(founders_reward_test, general) { ASSERT_DEATH(params.GetCommunityFundScriptAtHeight(0,Fork::CommunityFundType::FOUNDATION), "nHeight > 0"); ASSERT_DEATH(params.GetCommunityFundScriptAtHeight(maxHeight+1,Fork::CommunityFundType::FOUNDATION), "nHeight<=consensus.GetLastCommunityRewardBlockHeight()"); ASSERT_DEATH(params.GetCommunityFundAddressAtHeight(0,Fork::CommunityFundType::FOUNDATION), "nHeight > 0"); - ASSERT_DEATH(params.GetCommunityFundAddressAtHeight(maxHeight+1,Fork::CommunityFundType::FOUNDATION), "nHeight<=consensus.GetLastCommunityRewardBlockHeight()"); } TEST(founders_reward_test, mainnet) { From 6d225eeae49e28666afdc5ab2fee6350c49887da Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Tue, 21 Jan 2020 12:04:26 +0100 Subject: [PATCH 21/45] Extended test_checkblock to verify correct send of rewards after the halving --- src/Makefile.gtest.include | 1 - src/chainparams.cpp | 4 +- src/consensus/params.h | 2 +- src/gtest/test_checkblock.cpp | 27 +++++ src/gtest/test_foundersreward.cpp | 165 ------------------------------ 5 files changed, 29 insertions(+), 170 deletions(-) delete mode 100644 src/gtest/test_foundersreward.cpp diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index b271170097..1de02e979b 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -10,7 +10,6 @@ zen_gtest_SOURCES = \ gtest/test_checktransaction.cpp \ gtest/json_test_vectors.cpp \ gtest/json_test_vectors.h \ - gtest/test_foundersreward.cpp \ gtest/test_forkmanager.cpp \ gtest/test_checkblockdelay.cpp # These tests are order-dependent, because they diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c672cf350f..35c17dbda5 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -370,14 +370,12 @@ bool SelectParamsFromCommandLine() // Block height must be >0 and <=last CF reward block height (note that after hfCommunityFundHeight hard fork CF reward is permanent) // Index variable i ranges from 0 - (vCommunityFundAddress.size()-1) std::string CChainParams::GetCommunityFundAddressAtHeight(int nHeight , Fork::CommunityFundType cfType) const { - assert(nHeight > 0); - return ForkManager::getInstance().getCommunityFundAddress(nHeight,consensus.GetLastCommunityRewardBlockHeight(), cfType); + return ForkManager::getInstance().getCommunityFundAddress(nHeight,consensus._deprecatedGetLastCommunityRewardBlockHeight(), cfType); } // The community fund address is expected to be a multisig (P2SH) address CScript CChainParams::GetCommunityFundScriptAtHeight(int nHeight, Fork::CommunityFundType cfType) const { assert(nHeight > 0); - assert(nHeight<=consensus.GetLastCommunityRewardBlockHeight()); CBitcoinAddress address(GetCommunityFundAddressAtHeight(nHeight, cfType).c_str()); assert(address.IsValid()); diff --git a/src/consensus/params.h b/src/consensus/params.h index 3069dfae6d..d7c67da7cd 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -55,7 +55,7 @@ struct Params { */ int SubsidySlowStartShift() const { return nSubsidySlowStartInterval / 2; } int nSubsidyHalvingInterval; - int GetLastCommunityRewardBlockHeight() const { + int _deprecatedGetLastCommunityRewardBlockHeight() const { return nSubsidyHalvingInterval + SubsidySlowStartShift() - 1; } /** Used to check majorities for block version upgrade */ diff --git a/src/gtest/test_checkblock.cpp b/src/gtest/test_checkblock.cpp index 6d3caeda79..c1470a3f35 100644 --- a/src/gtest/test_checkblock.cpp +++ b/src/gtest/test_checkblock.cpp @@ -446,6 +446,33 @@ TEST(ContextualCheckBlock, CoinbaseCommunityReward) { block.vtx[0] = CTransaction(mtx);; EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); + //Exceed the LastCommunityRewardBlockHeight + CChainParams params = Params(); + int exceedHeight=params.GetConsensus()._deprecatedGetLastCommunityRewardBlockHeight()+1; + + address_foundation.SetString(Params().GetCommunityFundAddressAtHeight(exceedHeight, Fork::CommunityFundType::FOUNDATION).c_str()); + address_sec_node.SetString(Params().GetCommunityFundAddressAtHeight(exceedHeight, Fork::CommunityFundType::SECURENODE).c_str()); + address_sup_node.SetString(Params().GetCommunityFundAddressAtHeight(exceedHeight, Fork::CommunityFundType::SUPERNODE).c_str()); + + scriptID_found = boost::get(address_foundation.Get()); + scriptID_sec_node = boost::get(address_sec_node.Get()); + scriptID_sup_node = boost::get(address_sup_node.Get()); + + mtx.vin[0].scriptSig = CScript() << exceedHeight << OP_0; + + mtx.vout.resize(3); + mtx.vout[0].scriptPubKey = CScript() << OP_HASH160 << ToByteVector(scriptID_found) << OP_EQUAL; + mtx.vout[0].nValue = 1.25 * COIN; + + mtx.vout[1].scriptPubKey = CScript() << OP_HASH160 << ToByteVector(scriptID_sec_node) << OP_EQUAL; + mtx.vout[1].nValue = 0.625 * COIN; + + mtx.vout[2].scriptPubKey = CScript() << OP_HASH160 << ToByteVector(scriptID_sup_node) << OP_EQUAL; + mtx.vout[2].nValue = 0.625 * COIN; + + indexPrev.nHeight = exceedHeight -1; + block.vtx[0] = CTransaction(mtx);; + EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); } TEST(ContextualCheckBlock, CoinbaseCommunityRewardAmount) { diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp deleted file mode 100644 index c62ffa2901..0000000000 --- a/src/gtest/test_foundersreward.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include - -#include "main.h" -#include "utilmoneystr.h" -#include "chainparams.h" -#include "utilstrencodings.h" -#include "zcash/Address.hpp" -#include "wallet/wallet.h" -#include "amount.h" -#include -#include -#include -#include -#include -#include "util.h" -#include - - -// To run tests: -// ./zcash-gtest --gtest_filter="founders_reward_test.*" - -// -// Enable this test to generate and print 48 testnet 2-of-3 multisig addresses. -// The output can be copied into chainparams.cpp. -// The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd. -// - -TEST(founders_reward_test, create_testnet_2of3multisig) { - SelectParams(CBaseChainParams::TESTNET); - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); - bool fFirstRun=true; - auto pWallet = std::make_shared("wallet.dat"); - ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); - pWallet->TopUpKeyPool(); - std::cout << "Test wallet and logs saved in folder: " << pathTemp.native() << std::endl; - - int numKeys = 48; - std::vector pubkeys; - pubkeys.resize(3); - CPubKey newKey; - std::vector addresses; - for (int i = 0; i < numKeys; i++) { - ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); - pubkeys[0] = newKey; - pWallet->SetAddressBook(newKey.GetID(), "", "receive"); - - ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); - pubkeys[1] = newKey; - pWallet->SetAddressBook(newKey.GetID(), "", "receive"); - - ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); - pubkeys[2] = newKey; - pWallet->SetAddressBook(newKey.GetID(), "", "receive"); - - CScript result = GetScriptForMultisig(2, pubkeys); - ASSERT_FALSE(result.size() > MAX_SCRIPT_ELEMENT_SIZE); - CScriptID innerID(result); - pWallet->AddCScript(result); - pWallet->SetAddressBook(innerID, "", "receive"); - - std::string address = CBitcoinAddress(innerID).ToString(); - addresses.push_back(address); - } - - // Print out the addresses, 4 on each line. - std::string s = "vFoundersRewardAddress = {\n"; - int i=0; - int colsPerRow = 4; - ASSERT_TRUE(numKeys % colsPerRow == 0); - int numRows = numKeys/colsPerRow; - for (int row=0; rowFlush(true); -} - - -// Utility method to check the number of unique addresses from height 1 to maxHeight -void checkNumberOfUniqueAddresses(int nUnique) { - - int maxHeight = Params().GetConsensus().GetLastCommunityRewardBlockHeight(); - printf("maxHeight = %d\n",maxHeight); - std::set addresses; - for (int i = 1; i <= maxHeight; i++) { - if(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION).size()>0) { - auto result=addresses.insert(Params().GetCommunityFundAddressAtHeight(i, Fork::CommunityFundType::FOUNDATION)); - - } - } - std::set::iterator it; - for (it = addresses.begin(); it != addresses.end(); it++) { - printf("Found address %s\n",(*it).c_str()); - } - EXPECT_EQ(addresses.size(), nUnique); -} - -TEST(founders_reward_test, general) { - SelectParams(CBaseChainParams::TESTNET); - CChainParams params = Params(); - - //You can retrieve Hex from a BitCoin address as follows: - //CBitcoinAddress add ("zrRBQ5heytPMN5nY3ssPf3cG4jocXeD8fm1"); - //CScriptID scriptID = boost::get(add.Get()); // Get() returns a boost variant - //CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; - //std::cout< 0"); - ASSERT_DEATH(params.GetCommunityFundScriptAtHeight(maxHeight+1,Fork::CommunityFundType::FOUNDATION), "nHeight<=consensus.GetLastCommunityRewardBlockHeight()"); - ASSERT_DEATH(params.GetCommunityFundAddressAtHeight(0,Fork::CommunityFundType::FOUNDATION), "nHeight > 0"); -} - -TEST(founders_reward_test, mainnet) { - int NUM_MAINNET_FOUNDER_ADDRESSES = 7; - SelectParams(CBaseChainParams::MAIN); - checkNumberOfUniqueAddresses(NUM_MAINNET_FOUNDER_ADDRESSES); -} - -TEST(founders_reward_test, testnet) { - int NUM_TESTNET_FOUNDER_ADDRESSES = 4; - SelectParams(CBaseChainParams::TESTNET); - checkNumberOfUniqueAddresses(NUM_TESTNET_FOUNDER_ADDRESSES); -} - -TEST(founders_reward_test, regtest) { - int NUM_REGTEST_FOUNDER_ADDRESSES = 1; - SelectParams(CBaseChainParams::REGTEST); - checkNumberOfUniqueAddresses(NUM_REGTEST_FOUNDER_ADDRESSES); -} - -// Test that 10% founders reward is fully rewarded after the first halving and slow start shift. -// On Mainnet, this would be 2,100,000 ZEC after 850,000 blocks (840,000 + 10,000). -TEST(founders_reward_test, slow_start_subsidy) { - SelectParams(CBaseChainParams::MAIN); - CChainParams params = Params(); - - int maxHeight = params.GetConsensus().GetLastCommunityRewardBlockHeight(); - CAmount totalSubsidy = 0; - for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { - CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; - totalSubsidy += nSubsidy; - } - ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); -} - From 4f96ee8e9ae2869290c122b42dd4012af8fffafa Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Tue, 21 Jan 2020 15:57:34 +0100 Subject: [PATCH 22/45] Removed GetFilteredTransaction and modified OrderedTxItems --- src/wallet/.rpcwallet.cpp.swo | Bin 20480 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/wallet/.rpcwallet.cpp.swo diff --git a/src/wallet/.rpcwallet.cpp.swo b/src/wallet/.rpcwallet.cpp.swo deleted file mode 100644 index e2332be1d69968e6642742d0105b8fe7c359d783..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 zcmeHNYmgjO6&^t4B?h4o%L2VSSji08otfPb2urfEnVpacyF1J7Y#?Nlsh*xYJ56S~ zJKa6|NC^37S%_L_`Jk};p%xWNkV2tU1o=aOQWd011cM+?MTJnjK}7I7eQ(cn_s%33 zw5YPWtG?Zyd+t5wo^$S_?>V=e*_j#?D~;dtf5${LFI>e zn&qbMG!Ih=0Mkejqo{MH%uy^-)Y-Y)ALHb&YiSns^TrBn&#oz zM>Qe~L>A~~fu>XKTXWL%s)7CtRXHo(!%jVAx?An2JhDJ!fye@p1tJSX7KkhmSs=1N zWP$%f3pi$9Y%laWTIx10{~s0l|DJpL-Rk}O{%1$c7ak@O2C z{o5h>KP7#;q(2g(zb)xr|5i(dJpTWXbnnFTl@R?cNuQDYpAOOAl=Q8VK6H$D@%X|5qh_r=;5<`YVz?De2FK=r2pUXPFsx>|&#m{y>QSqHMoK(m(St@#5L%pro&obUQ?ULDGwoenW`(KxBc) z0+9tG3q%%(ED%}X16e?+#A0;jH|V^3vUn$k2k`y*ePBCqI`AprXy8SBw;llQ18xU? z2z(8g2Na+HtOk036M^UO9lam88Mq1f7BCOY0DZt)_~3mLcm{YHcmUWB+z9Lgz7AXq zTm|d_YQQWo28;rq1WpEC$9dyE;9lUTzydH2Tmlq;Gl2a#)7%Z*1>6Z-4SWf(fI3hB z-p0A0eB1NyElN>fjfYo16Kn@U=TPCcm-$77l3_$0h|Ub z0}kTs`b*#&KoR&n@I21bKLbo)CGaW^+^+z)0=ED^2KEAbfFdvmJcSs-{lKq*`+#eJ zs{sWV0kXj7fTMwj;NNQi^0Q99{%{`Vd*Ug?xrbsJCgVFg`hv&AHm)rF7}==xDB38qQ`5)8oad()9S$ z^u$DAvX~p`WpT*`KCn1zLIKk>EQeR($+lu`VXS8zi^r30Pf$vJ@e$XtIkHF!%9T)@ z0E^u*Sxw5>U>Ob9Y)f=@o3_-%T_I~RWj5_vsjR3w5)+DMCE{~e7@BUIbgs%n<)^fLF|=CFT-8d96}g~C*^w4pGW8_sT& zy_^`%PZqaKAUD-eOjj>qn~s9xH0;EHhJAZkLergd&nY=cYOfbT zoODM!Z}p`+8#Jd@7jdV!KrIul;?)1nZNx1r=vl36s$-*h>)lhF8n+64ruWK7*hanp zN!<KSYI_3}dlX}dSICIFW3Gb1U1M6O z!A2EAD?T|TJbFnzxgk`Qx-IEc%JC~kFW%F|3S+tA#==Nxyg*Cd^f>JZW8A436{Z^w zcHpL7VTp=n(>_*7dTJ3<8W=qaX^>k`;Xe3VjEna8>+z{h>bl!mP~G+>=@P^Ib6BWt+c7>q$GnyW0EwKV)!>Qh`Lc1*QPx|j`O=+H`ZK}>EftOF^=7ci*x)|~0E zk;+L{v=rS|TrtZT_EzkyO`G<7U1@OJR8-FDT6vd>RjC6BWExAE*)6wd* z*HEcXzO7oC>7=0|w@i#tZUvj|Qp;RdYq)T|!wynROKV_^%yB#Iv^^NCBTP~$cPb5* zQTG~#&KEJ_mr{Zyq(((?lwc`Lp0>F)7uG=M&Qi0ZFxa|*bu(C^=~}3cYFNCa8Nq7A zd-a-NnbM$h0hQ4lt7>)5vW1B)`SFVw4jVPcF$dG>`T6-2e5Kn)(^7fLux2p^Rs4oQ zVc0(TBW2di6tNk>0JXGo6YB%Mpeu627|R!#ZB(6k`mmNwda)vLcRQgIO2fn`!gL}Y zS;JhkwAq@2T|3DJGMV%H1~UEUup+je^_oLN6m`IyKf|UJ$H2H|liUQ|L?>({Vssc|2Rs!&n-CXe-qdXG=V|jSm0&Udl+~S_$_cZKyB{?q9?LIWP!*6 zkp&_PL>7oF5LqCyKxBc)0+9tG3;a(k5J-9<3L=v`?EpT?e7Op(A|w11BcunBEJxG5 z$SIXj+_Gu&4G6m6q>e}*q5u?JanIuxM~Vkww`9*cU&P!W@N>xsT(^QbeM5-uO;Mv^ zd&*6Td07UM*6t|%>fD>27Ox}|!BeU$gw_x}sFX~{T02b9E9CPEULbL(-3Rn%r`wMf zaf4yyD+$*ebpA(bJa#Ev)W-RLR66Pgob`KvdvLD50H8encHjhHFMy;3ed~9|P_OegoVL%mNwUDBxGffnNt~1}+9R0iOlV1kM1C0iH!p{88Xm z;LE@sU=6SgxDEO78-VWu*8^V!b^tkG05~0>-1)u0O~99d%YiLG4u}B# z^dw~==!tQ?awQ7AQA+uFOcw;h8%>H}D&|@lcJ6H_XxPx;poN%~Wg|j|d4}ke<#P5I zm-(#7_mJFlnwWA$twAi)m}+qff>Qzpy=6xE3Pimbg8TS|n**Y=tw1{pJLeDs!F-21 zV)FA!z*3~A&kmwHe)kkFLy!>RJ-CBYfw+X9sQ@$!l-V*3ilDluC$ zyP@e^3TO$Ga;7G7<0HfCM{{j4-n5jm281k(QE!DNONFm{3`kj+YF_({kEPImoxGy4 zwf}wb#1#^<6C``Hcpd8pSGSZX!EGY=i|F(m#(%>jBa^wQsZwFGba8GA#ztO8Y6S_@ z%iC9KJWmRS;xE~tr!0po(!99EptyXQix*k;_xp>iXq7(K1CqW1|B1qZ~aJ!OCg5=f*` zuAw)W`a`M6mH3y&&_~8fMrpv@g3>VSe9}}Camrcwaxat!kI%%qwyqsQ4#Ws4Y-Nm^dJp8#7J(FhE461+MOst) z2Qo({F`n!u1?zSLsXQ##$e%b66cmi41}*J2a!b5nhlQiB(x$e1c`W8BLI301mQ=?y z>QKgTAB^_onfM@sb3;!;W+ju%w-+#~kJ*Y{*WpXM6=HFSpSrg^i@cMaTzYx!5UoQb zTHY;52({zZ!}b~4}%i&9hW<+;K3 zO*%^W(%_~2o~BWfZGZss-HL`W$5&vuI(*i!7MW2ExES9Ws3cjs?`{WBzrk6TUSKt# zn||c5nRqIdas|7_Xi3jkF;`?greWgPwxMe1Lq+8KNvLm#e;~6%(G_I974AO2LSEqN zu5xE#GlAP*q}##*F0Kf*+Jlh#jU=jcG1S2*6kl&PMx~C7J2wq{9VHrCMR)Usn-rb( zv;OnX%dm^aipdmfU8(41UlI`PfH%^7vmt0e(W(EqFI^l=m$!s>eLkWh+==tXS25H9 zt>V{=X2E~KDW2Yk{@-nEcXPCRd(6G#MN0bDoS=Q(dT=l;$|RbRi~g8Bqi*dVv=1 R`QZKg@yOjL=fEMI_;0G){doWY From 4fb7dfa9c739f8a7ed8b03d5f1586c464cc5450b Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Wed, 22 Jan 2020 12:28:54 +0100 Subject: [PATCH 23/45] Removed GetFilteredTransaction and modified orederedTxItems to match previous serialization --- qa/rpc-tests/listtransactions.py | 46 +++++++++++------------------- src/wallet/rpcwallet.cpp | 42 ++++++++++++--------------- src/wallet/wallet.cpp | 49 +++++++++++++------------------- src/wallet/wallet.h | 5 +--- 4 files changed, 56 insertions(+), 86 deletions(-) diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 389fdc10b4..a735f41aba 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -36,34 +36,27 @@ def run_test(self): # Simple send, 0 to 1: txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) self.sync_all() - + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid}, + {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) check_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) - - check_array_result(self.nodes[0].listtransactions(), - {"txid":txid}, - {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) - # mine a block, confirmations should change: self.nodes[0].generate(1) self.sync_all() - - check_array_result(self.nodes[0].listtransactions(), - {"txid":txid}, + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid}, {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1}) - check_array_result(self.nodes[1].listtransactions(), {"txid":txid}, {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1}) # send-to-self: txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) - - check_array_result(self.nodes[0].listtransactions(), - {"txid":txid, "category":"send"}, + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid, "category":"send"}, {"amount":Decimal("-0.2")}) - check_array_result(self.nodes[0].listtransactions(), {"txid":txid, "category":"receive"}, {"amount":Decimal("0.2")}) @@ -75,35 +68,30 @@ def run_test(self): self.nodes[1].getaccountaddress("") : 0.44 } txid = self.nodes[1].sendmany("", send_to) self.sync_all() - - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.11")}, - {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.11")}, + {"txid":txid} ) check_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.11")}, {"txid":txid} ) - - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.22")}, - {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.22")}, + {"txid":txid} ) check_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.22")}, {"txid":txid} ) - - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.33")}, + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.33")}, {"txid":txid} ) check_array_result(self.nodes[0].listtransactions(), {"category":"receive","amount":Decimal("0.33")}, {"txid":txid, "account" : ""} ) - - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.44")}, + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.44")}, {"txid":txid, "account" : ""} ) check_array_result(self.nodes[1].listtransactions(), {"category":"receive","amount":Decimal("0.44")}, {"txid":txid, "account" : ""} ) - if __name__ == '__main__': ListTransactionsTest().main() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ce93690a24..f5f36a2aea 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1357,7 +1357,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter,const string& address) +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; string strSentAccount; @@ -1386,9 +1386,6 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); - if(address!="*"){ - entry.push_back(Pair("address",address)); - } ret.push_back(entry); } } @@ -1426,10 +1423,6 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if (fLong) WalletTxToJSON(wtx, entry); entry.push_back(Pair("size", static_cast(wtx).GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION))); - if(address!="*") - { - entry.push_back(Pair("address",address)); - } ret.push_back(entry); } } @@ -1514,10 +1507,10 @@ UniValue listtransactions(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - string account("*"); + string strAccount("*"); if (params.size() > 0) { - account=params[0].get_str(); + strAccount=params[0].get_str(); } int nCount = 10; @@ -1546,28 +1539,30 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if (nFrom < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); - std::multimap txes; - - //getting all TX ordered for nOrderPos and filtered by address - pwalletMain->GetFilteredTransactions(txes,address); UniValue ret(UniValue::VARR); + std::list acentries; + CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount,address); - //for each tx i create the ret object to return - for (std::multimap::reverse_iterator itr = txes.rbegin(); - itr != txes.rend();++itr) { + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); - ListTransactions(itr->second, "", 0, true, ret, filter,address); - if ((int)ret.size() >= (nCount+nFrom)) break; + if ((int)ret.size() >= (nCount+nFrom)) break; } - //getting all the specifi Txes requested by nCount and nFrom + //getting all the specific Txes requested by nCount and nFrom if (nFrom > (int)ret.size()) nFrom = ret.size(); if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; vector arrTmp = ret.getValues(); - vector::iterator first = arrTmp.begin(); std::advance(first, nFrom); vector::iterator last = arrTmp.begin(); @@ -1581,7 +1576,6 @@ UniValue listtransactions(const UniValue& params, bool fHelp) ret.clear(); ret.setArray(); ret.push_backV(arrTmp); - return ret; } @@ -1743,7 +1737,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) CWalletTx tx = (*it).second; if (depth == -1 || tx.GetDepthInMainChain() < depth) - ListTransactions(tx, "*", 0, true, transactions, filter,"*"); + ListTransactions(tx, "*", 0, true, transactions, filter); } CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; @@ -1835,7 +1829,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); - ListTransactions(wtx, "*", 0, false, details, filter,""); + ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); string strHex = EncodeHexTx(static_cast(wtx)); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 450315738a..4ac0ea3585 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -945,11 +945,19 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) return nRet; } -CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, std::string strAccount) +CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, std::string strAccount,std::string address) { AssertLockHeld(cs_wallet); // mapWallet CWalletDB walletdb(strWalletFile); + CScript scriptPubKey; + bool noFilter=address==("*"); + if(!noFilter){ + CBitcoinAddress baddress = CBitcoinAddress(address); + scriptPubKey = GetScriptForDestination(baddress.Get(), false); + } + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap. TxItems txOrdered; @@ -958,7 +966,17 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { CWalletTx* wtx = &((*it).second); - txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + if(noFilter){ + txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + } + else{ + for(const CTxOut& txout : wtx->vout) { + auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), scriptPubKey.end()); + if (res == txout.scriptPubKey.begin()) { + txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + } + } + } } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); @@ -3668,33 +3686,6 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee); } -void CWallet::GetFilteredTransactions(std::multimap& outEntries, const std::string& address) -{ - LOCK2(cs_main, cs_wallet); - CScript scriptPubKey; - bool valid=address==("*"); - if(!valid){ - CBitcoinAddress baddress = CBitcoinAddress(address); - scriptPubKey = GetScriptForDestination(baddress.Get(), false); - } - - //getting all Txes of address in the wallet - for (auto & p : mapWallet) { - CWalletTx wtx = p.second; - if(valid) { - outEntries.insert(make_pair(wtx.nOrderPos,wtx)); - } - else { - for(const CTxOut& txout : wtx.vout) { - auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), scriptPubKey.end()); - if (res == txout.scriptPubKey.begin()){ - outEntries.insert(make_pair(wtx.nOrderPos,wtx)); - } - } - } - } -} - /** * Find notes in the wallet filtered by payment address, min depth and ability to spend. * These notes are decrypted and added to the output parameter vector, outEntries. diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index e7dae3b0d2..4e7f492ffa 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -974,7 +974,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface * @return multimap of ordered transactions and accounting entries * @warning Returned pointers are *only* valid within the scope of passed acentries */ - TxItems OrderedTxItems(std::list& acentries, std::string strAccount = ""); + TxItems OrderedTxItems(std::list& acentries, std::string strAccount = "",std::string address="*"); void MarkDirty(); bool UpdateNullifierNoteMap(); @@ -1126,9 +1126,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface int minDepth=1, bool ignoreSpent=true, bool ignoreUnspendable=true); - /*Find all transactions of a specific addres*/ - void GetFilteredTransactions(std::multimap& outEntries, - const std::string& address); }; From ee6e9e4fd4c250ee182183a11f94e2597b1fc75f Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Thu, 23 Jan 2020 13:28:58 +0100 Subject: [PATCH 24/45] Merged listtransactions' test --- .../listtransactions_addressfilter.py | 159 ------------------ 1 file changed, 159 deletions(-) delete mode 100755 qa/rpc-tests/listtransactions_addressfilter.py diff --git a/qa/rpc-tests/listtransactions_addressfilter.py b/qa/rpc-tests/listtransactions_addressfilter.py deleted file mode 100755 index 2714287838..0000000000 --- a/qa/rpc-tests/listtransactions_addressfilter.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python2 -# 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. - -# Exercise the listtransactions API - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException -from test_framework.util import assert_equal, initialize_chain_clean, \ - start_nodes, connect_nodes_bi - -from decimal import Decimal - -def check_array_result(object_array, to_match, expected): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - """ - num_matched = 0 - for item in object_array: - all_match = True - for key,value in to_match.items(): - if item[key] != value: - all_match = False - if not all_match: - continue - for key,value in expected.items(): - if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 - if num_matched == 0: - raise AssertionError("No objects matched %s"%(str(to_match))) - -class ListTransactionsTest(BitcoinTestFramework): - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) - - def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) - - #connect to a local machine for debugging - #url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18232) - #proxy = AuthServiceProxy(url) - #proxy.url = url # store URL on proxy for info - #self.nodes.append(proxy) - - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) - - self.is_network_split=False - self.sync_all() - - def run_test(self): - - self.nodes[0].generate(120) - address=self.nodes[1].getnewaddress() - - - #simple send 1 to address and verify listtransaction returns this tx with address in input - txid=self.nodes[0].sendtoaddress(address, float(1) ) - self.sync_all() - self.nodes[2].generate(1) - self.sync_all() - check_array_result(self.nodes[1].listtransactions("*",1,0,False,address), - {"txid":txid}, - {"amount":Decimal("1.0")}) - - #verify listtransactions returns this tx without any input - check_array_result(self.nodes[1].listtransactions("*"), - {"txid":txid}, - {"amount":Decimal("1.0")}) - - #verify listtransactions returns only the tx with a specific address - txid2=self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), float(1) ) - self.sync_all() - self.nodes[2].generate(1) - self.sync_all() - result=self.nodes[1].listtransactions("*",1,0,False,address) - if(len(result)!=1): - raise AssertionError("Expected only 1 transaction") - check_array_result(result, - {"txid":txid}, - {"amount":Decimal("1.0"),"address":address}) - - #verify listtransactions returns 2 tx with no inputs - result=self.nodes[1].listtransactions("*") - if(len(result)!=2): - raise AssertionError("Expected 2 transactions") - - - #verify listtransactions returns only last 10 tx with address in input - txes=[] - for i in range(2,12): - txid=self.nodes[0].sendtoaddress(address, float(i) ) - txes.append(txid) - - self.sync_all() - self.nodes[2].generate(1) - self.sync_all() - - #verify listtransactions returns the 5 most recent transactions of address - result=self.nodes[1].listtransactions("*",5,0,False,address) - if(len(result)!=5): - raise AssertionError("Expected only 5 transactions") - - for i in range(1,6): - check_array_result([result[i-1]], - {"txid":txes[4+i]}, - {"amount":float(i+6),"address":address}) - - - - #verify listtransactions returns the transactions n.3-4-5-6-7 of address - result=self.nodes[1].listtransactions("*",5,3,False,address) - if(len(result)!=5): - raise AssertionError("Expected only transactions: 3-4-5-6-7") - - - for i in range(4,9): - - check_array_result([result[i-4]], - {"txid":txes[i-2]}, - {"amount":float(i),"address":address}) - - - #verify listtransactions returns only last 10 tx - result=self.nodes[1].listtransactions("*") - if(len(result)!=10): - raise AssertionError("Expected only 10 transactions") - - - - #verify listtransactions returns the 5 most recent transactions - result=self.nodes[1].listtransactions("*",5) - - if(len(result)!=5): - raise AssertionError("Expected only 5 transactions") - for i in range(1,6): - check_array_result([result[i-1]], - {"txid":txes[4+i]}, - {"amount":float(i+6)}) - - #verify listtransactions returns the transactions n.3-4-5-6-7 - result=self.nodes[1].listtransactions("*",5,3) - - if(len(result)!=5): - raise AssertionError("Expected only transactions: 3-4-5-6-7") - for i in range(4,9): - check_array_result([result[i-4]], - {"txid":txes[i-2]}, - {"amount":float(i)}) - -if __name__ == '__main__': - ListTransactionsTest().main() - From 7b22adb41f9de3cd3923b3d7cdfec287afa0603f Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Thu, 23 Jan 2020 14:25:59 +0100 Subject: [PATCH 25/45] Some refactor on listtransactions test --- qa/pull-tester/rpc-tests.sh | 1 - qa/rpc-tests/listtransactions.py | 211 ++++++++++++++++++++++++------- src/wallet/rpcwallet.cpp | 22 ++-- src/wallet/wallet.cpp | 14 +- 4 files changed, 178 insertions(+), 70 deletions(-) diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 8a2f6df7b5..2cae50cc0f 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -51,7 +51,6 @@ testScripts=( 'nulldata.py' 'blockdelay.py' 'blockdelay_2.py' - 'listtransactions_addressfilter.py' ); testScriptsExt=( 'getblocktemplate_longpoll.py' diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index a735f41aba..1306953677 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -9,6 +9,7 @@ from decimal import Decimal + def check_array_result(object_array, to_match, expected): """ Pass in array of JSON objects, a dictionary with key/value pairs @@ -18,81 +19,195 @@ def check_array_result(object_array, to_match, expected): num_matched = 0 for item in object_array: all_match = True - for key,value in to_match.items(): + for key, value in to_match.items(): if item[key] != value: all_match = False if not all_match: continue - for key,value in expected.items(): + for key, value in expected.items(): if item[key] != value: - raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) - num_matched = num_matched+1 + raise AssertionError("%s : expected %s=%s" % (str(item), str(key), str(value))) + num_matched = num_matched + 1 if num_matched == 0: - raise AssertionError("No objects matched %s"%(str(to_match))) + raise AssertionError("No objects matched %s" % (str(to_match))) + class ListTransactionsTest(BitcoinTestFramework): def run_test(self): # Simple send, 0 to 1: - txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) + txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 0.1) self.sync_all() check_array_result(self.nodes[0].listtransactions(), - {"txid":txid}, - {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0}) - check_array_result(self.nodes[1].listtransactions(), - {"txid":txid}, - {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0}) + {"txid": txid}, + {"category": "send", "account": "", "amount": Decimal("-0.1"), "confirmations": 0}) + check_array_result(self.nodes[2].listtransactions(), + {"txid": txid}, + {"category": "receive", "account": "", "amount": Decimal("0.1"), "confirmations": 0}) # mine a block, confirmations should change: self.nodes[0].generate(1) self.sync_all() check_array_result(self.nodes[0].listtransactions(), - {"txid":txid}, - {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1}) - check_array_result(self.nodes[1].listtransactions(), - {"txid":txid}, - {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1}) + {"txid": txid}, + {"category": "send", "account": "", "amount": Decimal("-0.1"), "confirmations": 1}) + check_array_result(self.nodes[2].listtransactions(), + {"txid": txid}, + {"category": "receive", "account": "", "amount": Decimal("0.1"), "confirmations": 1}) # send-to-self: txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) check_array_result(self.nodes[0].listtransactions(), - {"txid":txid, "category":"send"}, - {"amount":Decimal("-0.2")}) + {"txid": txid, "category": "send"}, + {"amount": Decimal("-0.2")}) check_array_result(self.nodes[0].listtransactions(), - {"txid":txid, "category":"receive"}, - {"amount":Decimal("0.2")}) + {"txid": txid, "category": "receive"}, + {"amount": Decimal("0.2")}) # sendmany from node1: twice to self, twice to node2: - send_to = { self.nodes[0].getnewaddress() : 0.11, - self.nodes[1].getnewaddress() : 0.22, - self.nodes[0].getaccountaddress("") : 0.33, - self.nodes[1].getaccountaddress("") : 0.44 } - txid = self.nodes[1].sendmany("", send_to) + send_to = {self.nodes[0].getnewaddress(): 0.11, + self.nodes[2].getnewaddress(): 0.22, + self.nodes[0].getaccountaddress(""): 0.33, + self.nodes[2].getaccountaddress(""): 0.44} + txid = self.nodes[2].sendmany("", send_to) self.sync_all() - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.11")}, - {"txid":txid} ) + check_array_result(self.nodes[2].listtransactions(), + {"category": "send", "amount": Decimal("-0.11")}, + {"txid": txid}) check_array_result(self.nodes[0].listtransactions(), - {"category":"receive","amount":Decimal("0.11")}, - {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.22")}, - {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"receive","amount":Decimal("0.22")}, - {"txid":txid} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.33")}, - {"txid":txid} ) + {"category": "receive", "amount": Decimal("0.11")}, + {"txid": txid}) + check_array_result(self.nodes[2].listtransactions(), + {"category": "send", "amount": Decimal("-0.22")}, + {"txid": txid}) + check_array_result(self.nodes[2].listtransactions(), + {"category": "receive", "amount": Decimal("0.22")}, + {"txid": txid}) + check_array_result(self.nodes[2].listtransactions(), + {"category": "send", "amount": Decimal("-0.33")}, + {"txid": txid}) check_array_result(self.nodes[0].listtransactions(), - {"category":"receive","amount":Decimal("0.33")}, - {"txid":txid, "account" : ""} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"send","amount":Decimal("-0.44")}, - {"txid":txid, "account" : ""} ) - check_array_result(self.nodes[1].listtransactions(), - {"category":"receive","amount":Decimal("0.44")}, - {"txid":txid, "account" : ""} ) + {"category": "receive", "amount": Decimal("0.33")}, + {"txid": txid, "account": ""}) + check_array_result(self.nodes[2].listtransactions(), + {"category": "send", "amount": Decimal("-0.44")}, + {"txid": txid, "account": ""}) + check_array_result(self.nodes[2].listtransactions(), + {"category": "receive", "amount": Decimal("0.44")}, + {"txid": txid, "account": ""}) + + # Below tests about filtering by address + self.nodes[0].generate(10) + address = self.nodes[1].getnewaddress() + + # simple send 1 to address and verify listtransaction returns this tx with address in input + txid = self.nodes[0].sendtoaddress(address, Decimal("1.0")) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + check_array_result(self.nodes[1].listtransactions("*", 1, 0, False, address), + {"category": "receive", "amount": Decimal("1.0"), "address": address}, + {"txid": txid}) + check_array_result(self.nodes[0].listtransactions("*", 1, 0, False, address), + {"category": "send", "amount": Decimal("-1.0"), "address": address}, + {"txid": txid}) + + # verify listtransactions returns this tx without any input + check_array_result(self.nodes[1].listtransactions("*"), + {"txid": txid}, + {"category": "receive", "amount": Decimal("1.0"), "address": address}) + check_array_result(self.nodes[0].listtransactions("*"), + {"txid": txid}, + {"category": "send", "amount": Decimal("-1.0"), "address": address}) + + # verify listtransactions returns only the tx with a specific address + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), Decimal("1.0")) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + result_node1 = self.nodes[1].listtransactions("*", 1, 0, False, address) + result_node0 = self.nodes[0].listtransactions("*", 1, 0, False, address) + if (len(result_node1) != 1): + raise AssertionError("Expected only 1 transaction") + check_array_result(result_node1, + {"txid": txid}, + {"category": "receive", "amount": Decimal("1.0"), "address": address}) + check_array_result(result_node0, + {"txid": txid}, + {"category": "send", "amount": Decimal("-1.0"), "address": address}) + + # verify listtransactions returns 10 tx with no inputs + result_node1 = self.nodes[1].listtransactions("*") + + if (len(result_node1) != 10): + raise AssertionError("Expected 10 transactions") + + # verify listtransactions returns only last 10 tx with address in input + txes = [] + for i in range(2, 12): + txid = self.nodes[0].sendtoaddress(address, Decimal(str(i))) + txes.append(txid) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # verify listtransactions returns the 5 most recent transactions of address + result_node1 = self.nodes[1].listtransactions("*", 5, 0, False, address) + result_node0 = self.nodes[0].listtransactions("*", 5, 0, False, address) + if (len(result_node1) != 5): + raise AssertionError("Expected only 5 transactions") + + for i in range(1, 6): + check_array_result([result_node1[i - 1]], + {"txid": txes[4 + i]}, + {"category": "receive", "amount": Decimal(str(i + 6)), "address": address}) + check_array_result([result_node0[i - 1]], + {"txid": txes[4 + i]}, + {"category": "send", "amount": Decimal("-"+str(i + 6)), "address": address}) + + # verify listtransactions returns the transactions n.3-4-5-6-7 of address + result_node1 = self.nodes[1].listtransactions("*", 5, 3, False, address) + result_node0 = self.nodes[0].listtransactions("*", 5, 3, False, address) + if (len(result_node1) != 5): + raise AssertionError("Expected only transactions: 3-4-5-6-7") + + for i in range(4, 9): + check_array_result([result_node1[i - 4]], + {"txid": txes[i - 2]}, + {"category": "receive", "amount": Decimal(str(i)), "address": address}) + check_array_result([result_node0[i - 4]], + {"txid": txes[i - 2]}, + {"category": "send", "amount": Decimal("-"+str(i)), "address": address}) + + # verify listtransactions returns the 5 most recent transactions + result_node1 = self.nodes[1].listtransactions("*", 5) + result_node0 = self.nodes[0].listtransactions("*", 5) + + if (len(result_node1) != 5): + raise AssertionError("Expected only 5 transactions") + for i in range(1, 6): + check_array_result([result_node1[i - 1]], + {"txid": txes[4 + i]}, + {"category": "receive", "amount": Decimal(str(i + 6))}) + check_array_result([result_node0[i - 1]], + {"txid": txes[4 + i]}, + {"category": "send", "amount": Decimal("-"+str(i + 6))}) + + # verify listtransactions returns the transactions n.3-4-5-6-7 + result_node1 = self.nodes[1].listtransactions("*", 5, 3) + result_node0 = self.nodes[0].listtransactions("*", 5, 3) + + if (len(result_node1) != 5): + raise AssertionError("Expected only transactions: 3-4-5-6-7") + for i in range(4, 9): + check_array_result([result_node1[i - 4]], + {"txid": txes[i - 2]}, + {"amount": Decimal(str(i))}) + check_array_result([result_node0[i - 4]], + {"txid": txes[i - 2]}, + {"amount": Decimal("-"+str(i))}) + if __name__ == '__main__': ListTransactionsTest().main() - diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f5f36a2aea..b523f24373 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1509,35 +1509,33 @@ UniValue listtransactions(const UniValue& params, bool fHelp) string strAccount("*"); if (params.size() > 0) - { strAccount=params[0].get_str(); - } int nCount = 10; if (params.size() > 1) nCount = params[1].get_int(); + if (nCount < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); + int nFrom = 0; if (params.size() > 2) nFrom = params[2].get_int(); + if (nFrom < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); + isminefilter filter = ISMINE_SPENDABLE; if(params.size() > 3) if(params[3].get_bool()) filter = filter | ISMINE_WATCH_ONLY; string address("*"); - if (params.size()>4) - { + if (params.size()>4) { address=params[4].get_str(); - if (address!=("*")) - { + if (address!=("*")) { CBitcoinAddress baddress = CBitcoinAddress(address); if (!baddress.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zen address"); } } - if (nCount < 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); - if (nFrom < 0) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); UniValue ret(UniValue::VARR); std::list acentries; @@ -1547,10 +1545,10 @@ UniValue listtransactions(const UniValue& params, bool fHelp) for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; - if (pwtx != 0) + if (pwtx != nullptr) ListTransactions(*pwtx, strAccount, 0, true, ret, filter); CAccountingEntry *const pacentry = (*it).second.second; - if (pacentry != 0) + if (pacentry != nullptr) AcentryToJSON(*pacentry, strAccount, ret); if ((int)ret.size() >= (nCount+nFrom)) break; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4ac0ea3585..2b74bc8662 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -952,24 +952,21 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, CScript scriptPubKey; bool noFilter=address==("*"); - if(!noFilter){ + if(!noFilter) { CBitcoinAddress baddress = CBitcoinAddress(address); scriptPubKey = GetScriptForDestination(baddress.Get(), false); } - // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap. TxItems txOrdered; // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry // would make this much faster for applications that do this a lot. - for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) - { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { CWalletTx* wtx = &((*it).second); - if(noFilter){ + if(noFilter) txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - } - else{ + else { for(const CTxOut& txout : wtx->vout) { auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), scriptPubKey.end()); if (res == txout.scriptPubKey.begin()) { @@ -980,8 +977,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); - BOOST_FOREACH(CAccountingEntry& entry, acentries) - { + BOOST_FOREACH(CAccountingEntry& entry, acentries) { txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry))); } From 29a8a14f3cbd626fd771bd7ee884fcae9ff81e54 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Thu, 23 Jan 2020 14:44:15 +0100 Subject: [PATCH 26/45] Some changed comments --- qa/rpc-tests/listtransactions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 1306953677..1d1d2dd9cf 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -35,7 +35,7 @@ def check_array_result(object_array, to_match, expected): class ListTransactionsTest(BitcoinTestFramework): def run_test(self): - # Simple send, 0 to 1: + # Simple send, 0 to 2: txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 0.1) self.sync_all() check_array_result(self.nodes[0].listtransactions(), @@ -63,7 +63,7 @@ def run_test(self): {"txid": txid, "category": "receive"}, {"amount": Decimal("0.2")}) - # sendmany from node1: twice to self, twice to node2: + # sendmany from node2: twice to self, twice to node0: send_to = {self.nodes[0].getnewaddress(): 0.11, self.nodes[2].getnewaddress(): 0.22, self.nodes[0].getaccountaddress(""): 0.33, From 8b37d3d287b93e4113bda4311b2935277b159bc2 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Thu, 23 Jan 2020 14:45:52 +0100 Subject: [PATCH 27/45] Removed unused variable --- src/gtest/test_checkblock.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gtest/test_checkblock.cpp b/src/gtest/test_checkblock.cpp index c1470a3f35..f85cb26e58 100644 --- a/src/gtest/test_checkblock.cpp +++ b/src/gtest/test_checkblock.cpp @@ -447,8 +447,7 @@ TEST(ContextualCheckBlock, CoinbaseCommunityReward) { EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); //Exceed the LastCommunityRewardBlockHeight - CChainParams params = Params(); - int exceedHeight=params.GetConsensus()._deprecatedGetLastCommunityRewardBlockHeight()+1; + int exceedHeight=Params().GetConsensus()._deprecatedGetLastCommunityRewardBlockHeight()+1; address_foundation.SetString(Params().GetCommunityFundAddressAtHeight(exceedHeight, Fork::CommunityFundType::FOUNDATION).c_str()); address_sec_node.SetString(Params().GetCommunityFundAddressAtHeight(exceedHeight, Fork::CommunityFundType::SECURENODE).c_str()); From 4a7c5265521fcafbbf7900c68cfafa5e2b4ab2f0 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Fri, 24 Jan 2020 12:40:14 +0100 Subject: [PATCH 28/45] changed passing-parameter in OrderderTxItems --- src/wallet/wallet.cpp | 6 +++--- src/wallet/wallet.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2b74bc8662..4647368c00 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -945,14 +945,14 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) return nRet; } -CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, std::string strAccount,std::string address) +CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, const std::string& strAccount,const std::string& address) { AssertLockHeld(cs_wallet); // mapWallet CWalletDB walletdb(strWalletFile); CScript scriptPubKey; - bool noFilter=address==("*"); - if(!noFilter) { + bool noFilter=address==std::string("*"); + if(!noFilter) { CBitcoinAddress baddress = CBitcoinAddress(address); scriptPubKey = GetScriptForDestination(baddress.Get(), false); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 4e7f492ffa..73fdd1d27f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -974,7 +974,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface * @return multimap of ordered transactions and accounting entries * @warning Returned pointers are *only* valid within the scope of passed acentries */ - TxItems OrderedTxItems(std::list& acentries, std::string strAccount = "",std::string address="*"); + TxItems OrderedTxItems(std::list& acentries, const std::string& strAccount = "",const std::string& address="*"); void MarkDirty(); bool UpdateNullifierNoteMap(); From 809d0503ed117a2fac824928893a5164c55c2dc8 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Fri, 24 Jan 2020 14:49:36 +0100 Subject: [PATCH 29/45] Fixed test wallet_shieldcoinbase --- qa/rpc-tests/wallet_shieldcoinbase.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/wallet_shieldcoinbase.py b/qa/rpc-tests/wallet_shieldcoinbase.py index 184d690e50..0b6fc8e765 100755 --- a/qa/rpc-tests/wallet_shieldcoinbase.py +++ b/qa/rpc-tests/wallet_shieldcoinbase.py @@ -210,10 +210,11 @@ def run_test (self): self.sync_all() mytaddr = self.nodes[0].getnewaddress() result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001')) - print(result) assert_equal(result["shieldingUTXOs"], Decimal('50')) assert_equal(result["remainingUTXOs"], Decimal('50')) self.wait_and_assert_operationid_status(0, result['opid']) + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) # Verify maximum number of utxos which node 0 can shield can be set by the limit parameter result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 33) From 0155d81dc7deb34630fecabe0e98c20506d30585 Mon Sep 17 00:00:00 2001 From: MarcoOl94 Date: Tue, 28 Jan 2020 15:50:26 +0100 Subject: [PATCH 30/45] Introduced break in orderedTxItems --- src/wallet/wallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4647368c00..5d645432f0 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -971,6 +971,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, auto res = std::search(txout.scriptPubKey.begin(), txout.scriptPubKey.end(), scriptPubKey.begin(), scriptPubKey.end()); if (res == txout.scriptPubKey.begin()) { txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + break; } } } From dc7ae21eba083967824e9e2a74d9a492c89b44af Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 11 Nov 2019 09:47:38 +0000 Subject: [PATCH 31/45] Cast uint8* in InterruptibleRecv to char* for recv Fixes a Windows-specific compile bug introduced in #4212. Closes #4214. --- src/netbase.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index afa3d9575e..3112d335eb 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -256,7 +256,13 @@ bool static InterruptibleRecv(uint8_t* data, size_t len, int timeout, SOCKET& hS // to break off in case of an interruption. const int64_t maxWait = 1000; while (len > 0 && curTime < endTime) { - ssize_t ret = recv(hSocket, data, len, 0); // Optimistically try the recv first + // Optimistically try the recv first. + // + // POSIX recv() does not require a cast, as it takes a void *buf: + // ssize_t recv(int sockfd, void *buf, size_t len, int flags); + // However Windows explicitly requires a char *buf: + // int recv(SOCKET s, char *buf, int len, int flags); + ssize_t ret = recv(hSocket, reinterpret_cast(data), len, 0); if (ret > 0) { len -= ret; data += ret; From c55c9437d0845fed0c903d0caeb9ba5159d7bcc2 Mon Sep 17 00:00:00 2001 From: cronicc Date: Wed, 5 Feb 2020 15:23:46 +0000 Subject: [PATCH 32/45] Fix socket.settimeout python error on MacOS --- qa/rpc-tests/test_framework/authproxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index b3628e45b6..c3b3e7eb30 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -49,7 +49,7 @@ USER_AGENT = "AuthServiceProxy/0.1" -HTTP_TIMEOUT = 6000000 +HTTP_TIMEOUT = 600 log = logging.getLogger("BitcoinRPC") From 34dd3e13a6ef2efb098d695c1340ed017b473215 Mon Sep 17 00:00:00 2001 From: cronicc Date: Wed, 5 Feb 2020 15:28:15 +0000 Subject: [PATCH 33/45] Workaround for 'Connection reset by peer' rpc test failures * Fixes AuthServiceProxy connections timing out on long running tests with no rpc commands in -rpcservertimeout (default 60s) interval --- qa/rpc-tests/test_framework/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index fbe0cfdad8..c094412780 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -121,7 +121,7 @@ def initialize_chain(test_dir): # Create cache directories, run bitcoinds: for i in range(4): datadir=initialize_datadir("cache", i) - args = [ os.getenv("BITCOIND", "zend"), "-keypool=1", "-datadir="+datadir, "-discover=0" ] + args = [ os.getenv("BITCOIND", "zend"), "-keypool=1", "-datadir="+datadir, "-discover=0", "-rpcservertimeout=600" ] if i > 0: args.append("-connect=127.0.0.1:"+str(p2p_port(0))) bitcoind_processes[i] = subprocess.Popen(args) @@ -206,7 +206,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= datadir = os.path.join(dirname, "node"+str(i)) if binary is None: binary = os.getenv("BITCOIND", "zend") - args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] + args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest", "-rpcservertimeout=600" ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) devnull = open("/dev/null", "w+") From 552bcadc3c9579399271e33d758cd973773664c5 Mon Sep 17 00:00:00 2001 From: cronicc Date: Wed, 5 Feb 2020 15:46:37 +0000 Subject: [PATCH 34/45] fetch-params.sh bugfix * Fix aria2 downloader with spaces in PARAMS_DIR path * Reduce number of parallel aria2 connections from 16 to 4 --- zcutil/fetch-params.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zcutil/fetch-params.sh b/zcutil/fetch-params.sh index eebfdc1bf0..a600979cfa 100755 --- a/zcutil/fetch-params.sh +++ b/zcutil/fetch-params.sh @@ -36,7 +36,7 @@ function fetch_aria2 { fi local filename="$1" - local dlname="$(basename $2)" + local dlname="$(basename "$2")" cat < Date: Wed, 5 Feb 2020 15:49:35 +0000 Subject: [PATCH 35/45] Add test for fetch-params.sh using all supported DL methods --- qa/zen/test-fetch-params.sh | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 qa/zen/test-fetch-params.sh diff --git a/qa/zen/test-fetch-params.sh b/qa/zen/test-fetch-params.sh new file mode 100755 index 0000000000..d5799a25ba --- /dev/null +++ b/qa/zen/test-fetch-params.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -euo pipefail + +if [[ "$OSTYPE" == "darwin"* ]]; then + PARAMS_DIR="$HOME/Library/Application Support/ZcashParams" +else + PARAMS_DIR="$HOME/.zcash-params" +fi + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +# download using aria2c +if [ -d "${PARAMS_DIR}" ]; then + rm -f "${PARAMS_DIR}"/* +fi +ZC_DISABLE_ARIA2="" ZC_DISABLE_CURL=1 ZC_DISABLE_IPFS=1 ZC_DISABLE_WGET=1 "${SCRIPT_DIR}"/../../zcutil/fetch-params.sh + +# download using curl +if [ -d "${PARAMS_DIR}" ]; then + rm -f "${PARAMS_DIR}"/* +fi +ZC_DISABLE_ARIA2=1 ZC_DISABLE_CURL="" ZC_DISABLE_IPFS=1 ZC_DISABLE_WGET=1 "${SCRIPT_DIR}"/../../zcutil/fetch-params.sh + +# download using wget +if [ -d "${PARAMS_DIR}" ]; then + rm -f "${PARAMS_DIR}"/* +fi +ZC_DISABLE_ARIA2=1 ZC_DISABLE_CURL=1 ZC_DISABLE_IPFS=1 ZC_DISABLE_WGET="" "${SCRIPT_DIR}"/../../zcutil/fetch-params.sh + +# disabled because of 'ipfs resolve -r /ipfs/QmZKKx7Xup7LiAtFRhYsE1M7waXcv9ir9eCECyXAFGxhEo/sapling-spend.params: no link named "sapling-spend.params" under QmZKKx7Xup7LiAtFRhYsE1M7waXcv9ir9eCECyXAFGxhEo' +# download using ipfs +#ipfs init +#ipfs daemon & +#sleep 30 +#if [ -d "${PARAMS_DIR}" ]; then +# rm -f "${PARAMS_DIR}"/* +#fi +#ZC_DISABLE_ARIA2=1 ZC_DISABLE_CURL=1 ZC_DISABLE_IPFS="" ZC_DISABLE_WGET=1 "${SCRIPT_DIR}"/../../zcutil/fetch-params.sh From 30e591ebd790ec2efbebff6abf9aa3539c93d5d3 Mon Sep 17 00:00:00 2001 From: cronicc Date: Wed, 5 Feb 2020 15:51:17 +0000 Subject: [PATCH 36/45] Refactor rpc-tests.sh * Fix style and indentation * Add -exclude and -split options --- qa/pull-tester/rpc-tests.sh | 312 ++++++++++++++++++++---------------- qa/rpc-tests/README.md | 6 + 2 files changed, 180 insertions(+), 138 deletions(-) diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 2cae50cc0f..da9707d8e4 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -5,83 +5,105 @@ CURDIR=$(cd $(dirname "$0"); pwd) # Get BUILDDIR and REAL_BITCOIND . "${CURDIR}/tests-config.sh" -export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli -export BITCOIND=${REAL_BITCOIND} +export BITCOINCLI="${BUILDDIR}/qa/pull-tester/run-bitcoin-cli" +export BITCOIND="${REAL_BITCOIND}" + +# parse args +for i in "$@"; do + case "${i}" in + -extended) + EXTENDED="true" + shift + ;; + -exclude=*) + EXCLUDE="${i#*=}" + shift + ;; + -split=*) + SPLIT="${i#*=}" + shift + ;; + *) + # unknown option/passOn + passOn+="${i} " + ;; + esac +done #Run the tests testScripts=( - 'paymentdisclosure.py' - 'prioritisetransaction.py' - 'wallet_treestate.py' - 'wallet_protectcoinbase.py' - 'wallet_shieldcoinbase.py' - 'wallet.py' - 'wallet_nullifiers.py' - 'wallet_1941.py' - 'wallet_grothtx.py' - 'listtransactions.py' - 'mempool_resurrect_test.py' - 'txn_doublespend.py' - 'txn_doublespend.py --mineblock' - 'getchaintips.py' - 'rawtransactions.py' - 'rest.py' - 'mempool_spendcoinbase.py' - 'mempool_coinbase_spends.py' - 'mempool_tx_input_limit.py' - 'httpbasics.py' - 'zapwallettxes.py' - 'proxy_test.py' - 'merkle_blocks.py' - 'fundrawtransaction.py' - 'signrawtransactions.py' - 'walletbackup.py' - 'key_import_export.py' - 'nodehandling.py' - 'reindex.py' - 'decodescript.py' - 'disablewallet.py' - 'zcjoinsplit.py' - 'zcjoinsplitdoublespend.py' - 'zkey_import_export.py' - 'getblocktemplate.py' - 'bip65-cltv-p2p.py' - 'bipdersig-p2p.py' - 'nulldata.py' - 'blockdelay.py' - 'blockdelay_2.py' + 'paymentdisclosure.py' + 'prioritisetransaction.py' + 'wallet_treestate.py' + 'wallet_protectcoinbase.py' + 'wallet_shieldcoinbase.py' + 'wallet.py' + 'wallet_nullifiers.py' + 'wallet_1941.py' + 'wallet_grothtx.py' + 'listtransactions.py' + 'mempool_resurrect_test.py' + 'txn_doublespend.py' + 'txn_doublespend.py --mineblock' + 'getchaintips.py' + 'rawtransactions.py' + 'rest.py' + 'mempool_spendcoinbase.py' + 'mempool_coinbase_spends.py' + 'mempool_tx_input_limit.py' + 'httpbasics.py' + 'zapwallettxes.py' + 'proxy_test.py' + 'merkle_blocks.py' + 'fundrawtransaction.py' + 'signrawtransactions.py' + 'walletbackup.py' + 'key_import_export.py' + 'nodehandling.py' + 'reindex.py' + 'decodescript.py' + 'disablewallet.py' + 'zcjoinsplit.py' + 'zcjoinsplitdoublespend.py' + 'zkey_import_export.py' + 'getblocktemplate.py' + 'bip65-cltv-p2p.py' + 'bipdersig-p2p.py' + 'nulldata.py' + 'blockdelay.py' + 'blockdelay_2.py' ); testScriptsExt=( - 'getblocktemplate_longpoll.py' - 'getblocktemplate_proposals.py' - 'getblocktemplate_blockmaxcomplexity.py' - 'getblocktemplate_priority.py' -# 'pruning.py' # disabled for Zen. Failed because of the issue #1302 in zcash - 'forknotify.py' -# 'hardforkdetection.py' # disabled for Zen. Failed because of the issue #1302 in zcash -# 'invalidateblock.py' # disabled for Zen. Failed because of the issue #1302 in zcash - 'keypool.py' - 'receivedby.py' - 'rpcbind_test.py' -# 'script_test.py' # requires create_block functionality that is not implemented for zcash blocks yet - 'smartfees.py' - 'maxblocksinflight.py' -# 'invalidblockrequest.py' # requires create_block functionality that is not implemented for zcash blocks yet -# 'forknotify.py' -# 'p2p-acceptblock.py' # requires create_block functionality that is not implemented for zcash blocks yet - 'replay_protection.py' - 'headers_01.py' - 'headers_02.py' - 'headers_03.py' - 'headers_04.py' - 'headers_05.py' - 'headers_06.py' - 'headers_07.py' - 'headers_08.py' - 'headers_09.py' - 'headers_10.py' - 'checkblockatheight.py' + 'getblocktemplate_longpoll.py' + 'getblocktemplate_proposals.py' + 'getblocktemplate_blockmaxcomplexity.py' + 'getblocktemplate_priority.py' +# 'pruning.py' # disabled for Zen. Failed because of the issue #1302 in zcash + 'forknotify.py' +# 'hardforkdetection.py' # disabled for Zen. Failed because of the issue #1302 in zcash +# 'invalidateblock.py' # disabled for Zen. Failed because of the issue #1302 in zcash + 'keypool.py' + 'receivedby.py' + 'rpcbind_test.py' +# 'script_test.py' # requires create_block functionality that is not implemented for zcash blocks yet + 'smartfees.py' + 'maxblocksinflight.py' +# 'invalidblockrequest.py' # requires create_block functionality that is not implemented for zcash blocks yet +# 'forknotify.py' +# 'p2p-acceptblock.py' # requires create_block functionality that is not implemented for zcash blocks yet + 'replay_protection.py' + 'headers_01.py' + 'headers_02.py' + 'headers_03.py' + 'headers_04.py' + 'headers_05.py' + 'headers_06.py' + 'headers_07.py' + 'headers_08.py' + 'headers_09.py' + 'headers_10.py' + 'checkblockatheight.py' ); if [ "x$ENABLE_ZMQ" = "x1" ]; then @@ -92,89 +114,103 @@ if [ "x$ENABLE_PROTON" = "x1" ]; then testScripts+=('proton_test.py') fi -extArg="-extended" -passOn=${@#$extArg} +# include extended tests +if [ ! -z "$EXTENDED" ] && [ "${EXTENDED}" = "true" ]; then + testScripts+=( "${testScriptsExt[@]}" ) +fi + +# remove tests provided by --exclude= from testScripts +if [ ! -z "$EXCLUDE" ]; then + for target in ${EXCLUDE//,/ }; do + for i in "${!testScripts[@]}"; do + if [ "${testScripts[i]}" = "$target" ] || [ "${testScripts[i]}" = "$target.py" ]; then + unset "testScripts[i]" + fi + done + done +fi + +# split array into m parts and only run tests of part n where SPLIT=m:n +if [ ! -z "$SPLIT" ]; then + chunks="${SPLIT%*:*}" + chunk="${SPLIT#*:}" + chunkSize="$((${#testScripts[@]}/${chunks}))" + start=0 + for (( i = 1; i <= $chunks; i++ )); do + if [ $i -eq $chunk ]; then + break + fi + start=$(($start+$chunkSize)) + done + if [ $chunks -eq $chunk ]; then + testScripts=( "${testScripts[@]:$start}" ) + else + testScripts=( "${testScripts[@]:$start:$chunkSize}" ) + fi +fi successCount=0 declare -a failures function checkFileExists { - # take only file name, strip off any options/param - local TestScriptFile="$(echo $1 | cut -d' ' -f1)" - local TestScriptFileAndPath=${BUILDDIR}/qa/rpc-tests/${TestScriptFile} - - if [ ! -f ${TestScriptFileAndPath} ] - then - echo -e "\nWARNING: file not found [ ${TestScriptFileAndPath} ]" - failures[${#failures[@]}]="(#-NotFound-$1-#)" - fi + # take only file name, strip off any options/param + local TestScriptFile="$(echo $1 | cut -d' ' -f1)" + local TestScriptFileAndPath="${BUILDDIR}/qa/rpc-tests/${TestScriptFile}" + + if [ ! -f "${TestScriptFileAndPath}" ]; then + echo -e "\nWARNING: file not found [ ${TestScriptFileAndPath} ]" + failures[${#failures[@]}]="(#-NotFound-$1-#)" + fi } function runTestScript { - local testName="$1" - shift - - echo -e "=== Running testscript ${testName} ===" - - if eval "$@" - then - successCount=$(expr $successCount + 1) - echo "--- Success: ${testName} ---" - else - failures[${#failures[@]}]="$testName" - echo "!!! FAIL: ${testName} !!!" - fi + local testName="$1" + shift - echo -} - -if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then - for (( i = 0; i < ${#testScripts[@]}; i++ )) - do - checkFileExists "${testScripts[$i]}" - - if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ] - then - runTestScript \ - "${testScripts[$i]}" \ - "${BUILDDIR}/qa/rpc-tests/${testScripts[$i]}" \ - --srcdir "${BUILDDIR}/src" ${passOn} - fi - done - for (( i = 0; i < ${#testScriptsExt[@]}; i++ )) - do - checkFileExists "${testScriptsExt[$i]}" - - if [ "$1" == $extArg ] || [ "$1" == "${testScriptsExt[$i]}" ] || [ "$1.py" == "${testScriptsExt[$i]}" ] - then - runTestScript \ - "${testScriptsExt[$i]}" \ - "${BUILDDIR}/qa/rpc-tests/${testScriptsExt[$i]}" \ - --srcdir "${BUILDDIR}/src" ${passOn} - fi - done + echo -e "=== Running testscript ${testName} ===" - total=$(($successCount + ${#failures[@]})) - echo -e "\n\nTests completed: $total" - echo "successes $successCount; failures: ${#failures[@]}" + if eval "$@"; then + successCount=$(expr $successCount + 1) + echo "--- Success: ${testName} ---" + else + failures[${#failures[@]}]="$testName" + echo "!!! FAIL: ${testName} !!!" + fi - if [ $total == 0 ] - then - echo -e "\nCould not exec any test: File name [$1]" - checkFileExists $1 - exit 1 - fi + echo +} - if [ ${#failures[@]} -gt 0 ] - then - echo -e "\nFailing tests: ${failures[*]}" - exit 1 - else - exit 0 +if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then + for (( i = 0; i < ${#testScripts[@]}; i++ )); do + checkFileExists "${testScripts[$i]}" + + if [ -z "$1" ] || [ "${1:0:1}" = "-" ] || [ "$1" = "${testScripts[$i]}" ] || [ "$1.py" = "${testScripts[$i]}" ]; then + runTestScript \ + "${testScripts[$i]}" \ + "${BUILDDIR}/qa/rpc-tests/${testScripts[$i]}" \ + --srcdir "${BUILDDIR}/src" ${passOn} fi + done + + total=$(($successCount + ${#failures[@]})) + echo -e "\n\nTests completed: $total" + echo "successes $successCount; failures: ${#failures[@]}" + + if [ $total -eq 0 ]; then + echo -e "\nCould not exec any test: File name [$1]" + checkFileExists $1 + exit 1 + fi + + if [ ${#failures[@]} -gt 0 ]; then + echo -e "\nFailing tests: ${failures[*]}" + exit 1 + else + exit 0 + fi else echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" fi diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index cfda8fe91f..1269f31c92 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -19,6 +19,12 @@ You can run a single test by calling `qa/pull-tester/rpc-tests.sh `. Run all possible tests with `qa/pull-tester/rpc-tests.sh -extended`. +Run a subset of the tests with `qa/pull-tester/rpc-tests.sh -split=m:n`, this splits the list of tests into m parts and runs part n. +E.g. given 30 enabled total tests `qa/pull-tester/rpc-tests.sh -split=3:2` would run tests 11-20. + +Exclude individual tests by calling `qa/pull-tester/rpc-tests.sh -exclude=,`, +e.g. `-exclude=prioritizetransaction.py,paymentdisclosure`. + Possible options: ``` From e366b8e455ae3b547abb5d9e31285c3ae756c825 Mon Sep 17 00:00:00 2001 From: cronicc Date: Wed, 5 Feb 2020 15:52:16 +0000 Subject: [PATCH 37/45] Add --rpc-exclude --rpc-split options for refactored rpc-tests.sh --- qa/zcash/full_test_suite.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/qa/zcash/full_test_suite.py b/qa/zcash/full_test_suite.py index cab924d670..203cb460c2 100755 --- a/qa/zcash/full_test_suite.py +++ b/qa/zcash/full_test_suite.py @@ -156,15 +156,16 @@ def util_test(): # Test driver # -def run_stage(stage, option=None): +def run_stage(stage, options=None): print('Running stage %s' % stage) print('=' * (len(stage) + 14)) print cmd = STAGE_COMMANDS[stage] if type(cmd) == type([]): - if option: - cmd.append(option) + if options: + for option in options: + cmd.append(option) ret = subprocess.call(cmd) == 0 else: ret = cmd() @@ -183,6 +184,10 @@ def main(): help='One of %s'%STAGES) parser.add_argument('--rpc-extended', dest='extended', action='store_true', help='run extended rpc tests') + parser.add_argument('--rpc-exclude', dest='exclude', + action='store', help='comma separated string of rpc tests to exclude, see qa/rpc-tests/README.md for more') + parser.add_argument('--rpc-split', dest='split', + action='store', help='string in format m:n, see qa/rpc-tests/README.md for more') args = parser.parse_args() # Check for list @@ -200,9 +205,16 @@ def main(): # Run the stages passed = True for s in args.stage: - # Check for extended rpc tests - if args.extended and s == 'rpc': - passed &= run_stage(s, '-extended') + # Check for rpc test args + if s == 'rpc': + options=[] + if args.extended: + options.append('-extended') + if args.exclude: + options.append('-exclude=' + args.exclude) + if args.split: + options.append('-split=' + args.split) + passed &= run_stage(s, options) else: passed &= run_stage(s) From 1410ddfe83579288c64997399d6afb5f7a66ff5f Mon Sep 17 00:00:00 2001 From: cronicc Date: Wed, 5 Feb 2020 15:54:06 +0000 Subject: [PATCH 38/45] Add travis-ci CI/CD pipeline part1 --- .gitignore | 1 + .travis.yml | 314 +++++++++++++----- .../amd64/linux/ubuntu_bionic/Dockerfile | 53 +++ .../amd64/linux/ubuntu_bionic/entrypoint.sh | 39 +++ .../amd64/linux/ubuntu_xenial/Dockerfile | 53 +++ .../amd64/linux/ubuntu_xenial/entrypoint.sh | 39 +++ .../amd64/windows/ubuntu_bionic/Dockerfile | 48 +++ .../amd64/windows/ubuntu_bionic/entrypoint.sh | 39 +++ .../arm64/linux/ubuntu_bionic/Dockerfile | 53 +++ .../arm64/linux/ubuntu_bionic/entrypoint.sh | 39 +++ .../arm64/linux/ubuntu_xenial/Dockerfile | 53 +++ .../arm64/linux/ubuntu_xenial/entrypoint.sh | 39 +++ .../build/build_amd64_linux_ubuntu_bionic.sh | 8 + .../build/build_amd64_linux_ubuntu_xenial.sh | 8 + .../scripts/build/build_amd64_osx_xcode9.4.sh | 14 + .../build_amd64_windows_ubuntu_bionic.sh | 8 + .../common/b2_compress_checksum_upload.sh | 11 + .../common/b2_download_verify_decompress.sh | 27 ++ .../ci-horizen/scripts/common/get_archive.sh | 14 + contrib/ci-horizen/scripts/common/install.sh | 32 ++ .../ci-horizen/scripts/common/push_archive.sh | 13 + .../scripts/common/setup_environment.sh | 140 ++++++++ .../scripts/common/travis_stay_alive.sh | 3 + .../scripts/prepare/build_zencash-apple.sh | 8 + .../scripts/prepare/docker_image_build.sh | 22 ++ .../scripts/prepare/docker_image_deploy.sh | 25 ++ contrib/ci-horizen/scripts/test/run_test.sh | 21 ++ 27 files changed, 1048 insertions(+), 76 deletions(-) create mode 100644 contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/Dockerfile create mode 100755 contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/entrypoint.sh create mode 100644 contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/Dockerfile create mode 100755 contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/entrypoint.sh create mode 100644 contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/Dockerfile create mode 100755 contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/entrypoint.sh create mode 100644 contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/Dockerfile create mode 100755 contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/entrypoint.sh create mode 100644 contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/Dockerfile create mode 100755 contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/entrypoint.sh create mode 100755 contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_bionic.sh create mode 100755 contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_xenial.sh create mode 100755 contrib/ci-horizen/scripts/build/build_amd64_osx_xcode9.4.sh create mode 100755 contrib/ci-horizen/scripts/build/build_amd64_windows_ubuntu_bionic.sh create mode 100755 contrib/ci-horizen/scripts/common/b2_compress_checksum_upload.sh create mode 100755 contrib/ci-horizen/scripts/common/b2_download_verify_decompress.sh create mode 100755 contrib/ci-horizen/scripts/common/get_archive.sh create mode 100755 contrib/ci-horizen/scripts/common/install.sh create mode 100755 contrib/ci-horizen/scripts/common/push_archive.sh create mode 100755 contrib/ci-horizen/scripts/common/setup_environment.sh create mode 100755 contrib/ci-horizen/scripts/common/travis_stay_alive.sh create mode 100755 contrib/ci-horizen/scripts/prepare/build_zencash-apple.sh create mode 100755 contrib/ci-horizen/scripts/prepare/docker_image_build.sh create mode 100755 contrib/ci-horizen/scripts/prepare/docker_image_deploy.sh create mode 100755 contrib/ci-horizen/scripts/test/run_test.sh diff --git a/.gitignore b/.gitignore index 2313e9a975..1504992092 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,7 @@ qrc_*.cpp # Mac specific .DS_Store build +!contrib/ci-horizen/scripts/build #lcov *.gcno diff --git a/.travis.yml b/.travis.yml index ecb31ef0f0..80996b7d11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,79 +1,241 @@ -# errata: -# - A travis bug causes caches to trample eachother when using the same -# compiler key (which we don't use anyway). This is worked around for now by -# replacing the "compilers" with a build name prefixed by the no-op ":" -# command. See: https://github.com/travis-ci/travis-ci/issues/4393 -# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback] -# IPv6 support - -sudo: required -dist: precise -group: legacy +language: shell os: linux -language: cpp -compiler: gcc -env: - global: - - MAKEJOBS=-j3 - - RUN_TESTS=false - - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID - - CCACHE_SIZE=100M - - CCACHE_TEMPDIR=/tmp/.ccache-temp - - CCACHE_COMPRESS=1 - - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoincore.org/depends-sources/sdks - - PYTHON_DEBUG=1 - - WINEDEBUG=fixme-all -cache: - apt: true - directories: - - depends/built - - depends/sdk-sources - - $HOME/.ccache -matrix: - fast_finish: true - include: - - compiler: ": ARM" - env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - - compiler: ": Win32" - env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-reduce-exports" MAKEJOBS="-j2" - - compiler: ": 32-bit + dash" - env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" PPA="ppa:chris-lea/zeromq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-reduce-exports" MAKEJOBS="-j2" - - compiler: ": bitcoind" - env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" PPA="ppa:chris-lea/zeromq" DEP_OPTS="DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - - compiler: ": No wallet" - env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - - compiler: ": Cross-Mac" - env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" - exclude: - - compiler: gcc + +.com.github.zencashofficial.zen_ci_testing.env-definitions: + - &docker_amd64_linux_ubuntu_xenial + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_xenial + - DOCKER_IS_DEB=true + - &docker_amd64_linux_ubuntu_bionic + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_bionic + - DOCKER_IS_DEB=true + - &docker_amd64_windows_ubuntu_bionic + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=windows + - DOCKER_FROM=ubuntu_bionic + - DOCKER_IS_DEB=true + - &docker_amd64_linux_ubuntu_xenial_unit-tests + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_xenial + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="btest gtest sec-hard no-dot-so util-test secp256k1 libsnark univalue" + - &docker_amd64_linux_ubuntu_xenial_rpc-tests_1 + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_xenial + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-split=3:1" + - &docker_amd64_linux_ubuntu_xenial_rpc-tests_2 + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_xenial + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-split=3:2" + - &docker_amd64_linux_ubuntu_xenial_rpc-tests_3 + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_xenial + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-split=3:3" + - &docker_amd64_linux_ubuntu_xenial_test-fetch-params + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_xenial + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zen/test-fetch-params.sh" + - &docker_amd64_linux_ubuntu_bionic_unit-tests + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_bionic + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="btest gtest sec-hard no-dot-so util-test secp256k1 libsnark univalue" + - &docker_amd64_linux_ubuntu_bionic_rpc-tests_1 + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_bionic + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-split=3:1" + - &docker_amd64_linux_ubuntu_bionic_rpc-tests_2 + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_bionic + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-split=3:2" + - &docker_amd64_linux_ubuntu_bionic_rpc-tests_3 + env: + - DOCKER_ARCH=amd64 + - DOCKER_TARGET_OS=linux + - DOCKER_FROM=ubuntu_bionic + - DOCKER_IS_DEB=true + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-split=3:3" + - &amd64_osx_xcode9_4_unit-tests + env: + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="btest gtest util-test secp256k1 libsnark univalue" + - &amd64_osx_xcode9_4_rpc-tests_1 + env: + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-exclude=rpcbind_test.py --rpc-split=3:1" + - &amd64_osx_xcode9_4_rpc-tests_2 + env: + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-exclude=rpcbind_test.py --rpc-split=3:2" + - &amd64_osx_xcode9_4_rpc-tests_3 + env: + - TEST_CMD="./qa/zcash/full_test_suite.py" + - TEST_ARGS="rpc --rpc-extended --rpc-exclude=rpcbind_test.py --rpc-split=3:3" + +.com.github.zencashofficial.zen_ci_testing.job-definitions: + - &prepare_docker_amd64 + os: linux + dist: bionic + cache: false + script: + - bash "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/prepare/docker_image_build.sh" + - bash "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/prepare/docker_image_deploy.sh" + - &build_docker_amd64 + os: linux + dist: bionic + cache: + directories: + - "$HOME/.ccache" + script: + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/build/build_${TRAVIS_CPU_ARCH}_${DOCKER_TARGET_OS}_${DOCKER_FROM}.sh" + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/push_archive.sh ${B2_UL_COMPRESS_FOLDER} ${B2_UL_FILENAME}" + - &test_docker_amd64 + if: env(SKIP_TESTS) != true + os: linux + dist: bionic + cache: + directories: + - "$HOME/.zcash-params" + script: + - bash -c "RENAME_FOLDER='true' RENAME_SUFFIX='_clean' ${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/get_archive.sh ${B2_DL_DECOMPRESS_FOLDER} ${B2_DL_FILENAME}" + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/travis_stay_alive.sh" + - bash -c '${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/test/run_test.sh "${TEST_CMD}" "${TEST_ARGS}"' + - &test_osx_xcode9_4 + if: (env(SKIP_TESTS) != true) OR (env(SKIP_OSX) != true) + os: osx + osx_image: xcode9.4 + cache: + directories: + - "$HOME/Library/Application Support/ZcashParams" + script: + - bash -c "RENAME_FOLDER='true' RENAME_SUFFIX='_clean' ${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/get_archive.sh ${B2_DL_DECOMPRESS_FOLDER} ${B2_DL_FILENAME}" + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/travis_stay_alive.sh" + - bash -c '${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/test/run_test.sh "${TEST_CMD}" "${TEST_ARGS}"' + +before_install: + - source "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/setup_environment.sh" + install: - - if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi - - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi -before_script: - - unset CC; unset CXX - - mkdir -p depends/SDKs depends/sdk-sources - - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS -script: - - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST - - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" - - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE - - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi - - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - - make distdir PACKAGE=bitcoin VERSION=$HOST - - cd bitcoin-$HOST - - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) - - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - - if [ "$RUN_TESTS" = "true" ]; then make check; fi - - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.sh; fi -after_script: - - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/install.sh" + +jobs: + include: + # build and push docker build/test dependency images + - stage: Prepare + <<: *prepare_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial + - stage: Prepare + <<: *prepare_docker_amd64 + <<: *docker_amd64_linux_ubuntu_bionic + - stage: Prepare + <<: *prepare_docker_amd64 + <<: *docker_amd64_windows_ubuntu_bionic + # build zencash-apple toolchain + - stage: Prepare + if: env(SKIP_OSX) != true + os: osx + osx_image: xcode9.4 + cache: false + script: + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/prepare/build_zencash-apple.sh" + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/push_archive.sh ${B2_UL_COMPRESS_FOLDER} ${B2_UL_FILENAME}" + # Docker based builds + - stage: Build + <<: *build_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial + - stage: Build + <<: *build_docker_amd64 + <<: *docker_amd64_linux_ubuntu_bionic + - stage: Build + <<: *build_docker_amd64 + <<: *docker_amd64_windows_ubuntu_bionic + # osx build + - stage: Build + if: env(SKIP_OSX) != true + os: osx + osx_image: xcode9.4 + cache: + directories: + - "$HOME/.ccache" + script: + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/get_archive.sh ${B2_DL_DECOMPRESS_FOLDER} ${B2_DL_FILENAME}" + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/build/build_${TRAVIS_CPU_ARCH}_${TRAVIS_OS_NAME}_${TRAVIS_OSX_IMAGE}.sh" + - bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/push_archive.sh ${B2_UL_COMPRESS_FOLDER} ${B2_UL_FILENAME}" + # Docker based tests + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial_unit-tests + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial_rpc-tests_1 + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial_rpc-tests_2 + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial_rpc-tests_3 + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_xenial_test-fetch-params + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_bionic_unit-tests + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_bionic_rpc-tests_1 + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_bionic_rpc-tests_2 + - stage: Test + <<: *test_docker_amd64 + <<: *docker_amd64_linux_ubuntu_bionic_rpc-tests_3 + # osx based tests + - stage: Test + <<: *test_osx_xcode9_4 + <<: *amd64_osx_xcode9_4_unit-tests + - stage: Test + <<: *test_osx_xcode9_4 + <<: *amd64_osx_xcode9_4_rpc-tests_1 + - stage: Test + <<: *test_osx_xcode9_4 + <<: *amd64_osx_xcode9_4_rpc-tests_2 + - stage: Test + <<: *test_osx_xcode9_4 + <<: *amd64_osx_xcode9_4_rpc-tests_3 diff --git a/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/Dockerfile b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/Dockerfile new file mode 100644 index 0000000000..ef9e1a1c95 --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/Dockerfile @@ -0,0 +1,53 @@ +FROM ubuntu:bionic + +MAINTAINER cronic@zensystem.io + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh + +SHELL ["/bin/bash", "-c"] + +RUN set -euxo pipefail \ + && DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get -y --no-install-recommends install apt-utils \ + && apt-get -y --no-install-recommends dist-upgrade \ + && apt-get -y --no-install-recommends install aria2 autoconf automake bsdmainutils build-essential \ + ca-certificates cmake curl dirmngr fakeroot git g++-multilib gnupg2 help2man libc6-dev libgomp1 \ + libtool lintian m4 ncurses-dev pigz pkg-config pv python python-dev python-pip python-setuptools \ + python-wheel python-wheel-common python-zmq unzip wget zlib1g-dev \ + && pip install b2 pyblake2 \ + && BASEURL="https://github.com/tianon/gosu/releases/download/" \ + && GOSU_VERSION="1.11" \ + && DPKG_ARCH="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ + && curl -o /usr/local/bin/gosu -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}" \ + && curl -o /usr/local/bin/gosu.asc -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg2 --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver hkp://ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.mit.edu --recv-key B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver keyserver.pgp.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.key-server.io --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg2 --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true \ + && BASEURL=$(curl -s https://api.github.com/repos/ipfs/go-ipfs/releases | grep browser_download_url | awk 'FNR <= 1' | cut -d '"' -f 4 | sed 's:/[^/]*$::') \ + && IPFS_VERSION=$(echo -n $BASEURL | sed 's:.*/::') \ + && TMP="$(mktemp -d)" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" \ + && cd $TMP && sha512sum -c "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" && tar -xf "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && cd go-ipfs && ./install.sh && cd && rm -rf $TMP \ + && apt-get -y autoremove --purge \ + && apt-get -y autoclean \ + && apt-get clean \ + && rm -rf /var/cache/apt/archives/*.deb /var/lib/apt/lists/* /root/.cache /tmp/* \ + && chmod +x /usr/local/bin/entrypoint.sh + +VOLUME ["/mnt/.ccache"] + +VOLUME ["/mnt/.zcash-params"] + +VOLUME ["/mnt/build"] + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/entrypoint.sh b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/entrypoint.sh new file mode 100755 index 0000000000..27db4f28eb --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_bionic/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +# Add local zenbuilder user +# Either use LOCAL_USER_ID:LOCAL_GRP_ID if set via environment +# or fallback to 9001:9001 + +USER_ID=${LOCAL_USER_ID:-9001} +GRP_ID=${LOCAL_GRP_ID:-9001} + +getent group zenbuilder > /dev/null 2>&1 || groupadd -g $GRP_ID zenbuilder +id -u zenbuilder > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m zenbuilder + +LOCAL_UID=$(id -u zenbuilder) +LOCAL_GID=$(getent group zenbuilder | cut -d ":" -f 3) + +if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then + echo "Warning: User zenbuilder with differing UID $LOCAL_UID/GID $LOCAL_GID already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID." +fi + +echo "Starting with UID/GID: $LOCAL_UID:$LOCAL_GID" + +export HOME=/home/zenbuilder + +# Mount host directories +for dir in .ccache .zcash-params build; do + if [ -d "/mnt/${dir}" ]; then + if [ ! -L "/home/zenbuilder/${dir}" ]; then + ln -sf "/mnt/${dir}" "/home/zenbuilder/${dir}" + fi + else + mkdir -p "/home/zenbuilder/${dir}" + fi +done + +# Fix ownership recursively +chown -RH zenbuilder:zenbuilder /home/zenbuilder + +exec /usr/local/bin/gosu zenbuilder "$@" diff --git a/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/Dockerfile b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/Dockerfile new file mode 100644 index 0000000000..ed90aaa69a --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/Dockerfile @@ -0,0 +1,53 @@ +FROM ubuntu:xenial + +MAINTAINER cronic@zensystem.io + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh + +SHELL ["/bin/bash", "-c"] + +RUN set -euxo pipefail \ + && DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get -y --no-install-recommends install apt-utils \ + && apt-get -y --no-install-recommends dist-upgrade \ + && apt-get -y --no-install-recommends install aria2 autoconf automake bsdmainutils build-essential \ + ca-certificates cmake curl dirmngr fakeroot git g++-multilib gnupg2 help2man libc6-dev libgomp1 \ + libtool lintian m4 ncurses-dev pigz pkg-config pv python python-dev python-pip python-setuptools \ + python-wheel python-wheel-common python-zmq unzip wget zlib1g-dev \ + && pip install b2 pyblake2 \ + && BASEURL="https://github.com/tianon/gosu/releases/download/" \ + && GOSU_VERSION="1.11" \ + && DPKG_ARCH="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ + && curl -o /usr/local/bin/gosu -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}" \ + && curl -o /usr/local/bin/gosu.asc -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg2 --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver hkp://ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.mit.edu --recv-key B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver keyserver.pgp.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.key-server.io --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg2 --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true \ + && BASEURL=$(curl -s https://api.github.com/repos/ipfs/go-ipfs/releases | grep browser_download_url | awk 'FNR <= 1' | cut -d '"' -f 4 | sed 's:/[^/]*$::') \ + && IPFS_VERSION=$(echo -n $BASEURL | sed 's:.*/::') \ + && TMP="$(mktemp -d)" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" \ + && cd $TMP && sha512sum -c "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" && tar -xf "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && cd go-ipfs && ./install.sh && cd && rm -rf $TMP \ + && apt-get -y autoremove --purge \ + && apt-get -y autoclean \ + && apt-get clean \ + && rm -rf /var/cache/apt/archives/*.deb /var/lib/apt/lists/* /root/.cache /tmp/* \ + && chmod +x /usr/local/bin/entrypoint.sh + +VOLUME ["/mnt/.ccache"] + +VOLUME ["/mnt/.zcash-params"] + +VOLUME ["/mnt/build"] + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/entrypoint.sh b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/entrypoint.sh new file mode 100755 index 0000000000..27db4f28eb --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/amd64/linux/ubuntu_xenial/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +# Add local zenbuilder user +# Either use LOCAL_USER_ID:LOCAL_GRP_ID if set via environment +# or fallback to 9001:9001 + +USER_ID=${LOCAL_USER_ID:-9001} +GRP_ID=${LOCAL_GRP_ID:-9001} + +getent group zenbuilder > /dev/null 2>&1 || groupadd -g $GRP_ID zenbuilder +id -u zenbuilder > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m zenbuilder + +LOCAL_UID=$(id -u zenbuilder) +LOCAL_GID=$(getent group zenbuilder | cut -d ":" -f 3) + +if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then + echo "Warning: User zenbuilder with differing UID $LOCAL_UID/GID $LOCAL_GID already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID." +fi + +echo "Starting with UID/GID: $LOCAL_UID:$LOCAL_GID" + +export HOME=/home/zenbuilder + +# Mount host directories +for dir in .ccache .zcash-params build; do + if [ -d "/mnt/${dir}" ]; then + if [ ! -L "/home/zenbuilder/${dir}" ]; then + ln -sf "/mnt/${dir}" "/home/zenbuilder/${dir}" + fi + else + mkdir -p "/home/zenbuilder/${dir}" + fi +done + +# Fix ownership recursively +chown -RH zenbuilder:zenbuilder /home/zenbuilder + +exec /usr/local/bin/gosu zenbuilder "$@" diff --git a/contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/Dockerfile b/contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/Dockerfile new file mode 100644 index 0000000000..48bb91360f --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/Dockerfile @@ -0,0 +1,48 @@ +FROM ubuntu:bionic + +MAINTAINER cronic@zensystem.io + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh + +SHELL ["/bin/bash", "-c"] + +RUN set -euxo pipefail \ + && DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get -y --no-install-recommends install apt-utils \ + && apt-get -y --no-install-recommends dist-upgrade \ + && apt-get -y --no-install-recommends install aria2 autoconf automake bsdmainutils build-essential \ + ca-certificates cmake curl dirmngr git g++-multilib gnupg2 help2man libc6-dev libgomp1 libtool \ + m4 mingw-w64 ncurses-dev pigz pkg-config pv python python-pip python-setuptools python-wheel \ + python-wheel-common unzip wget zlib1g-dev \ + && pip install b2 \ + && BASEURL="https://github.com/tianon/gosu/releases/download/" \ + && GOSU_VERSION="1.11" \ + && DPKG_ARCH="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ + && curl -o /usr/local/bin/gosu -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}" \ + && curl -o /usr/local/bin/gosu.asc -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg2 --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver hkp://ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.mit.edu --recv-key B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver keyserver.pgp.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.key-server.io --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg2 --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true \ + && update-alternatives --install /usr/bin/x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix 100 \ + && update-alternatives --install /usr/bin/x86_64-w64-mingw32-g++ x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix 100 \ + && apt-get -y autoremove --purge \ + && apt-get -y autoclean \ + && apt-get clean \ + && rm -rf /var/cache/apt/archives/*.deb /var/lib/apt/lists/* /root/.cache /tmp/* \ + && chmod +x /usr/local/bin/entrypoint.sh + +VOLUME ["/mnt/.ccache"] + +VOLUME ["/mnt/.zcash-params"] + +VOLUME ["/mnt/build"] + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/entrypoint.sh b/contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/entrypoint.sh new file mode 100755 index 0000000000..27db4f28eb --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/amd64/windows/ubuntu_bionic/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +# Add local zenbuilder user +# Either use LOCAL_USER_ID:LOCAL_GRP_ID if set via environment +# or fallback to 9001:9001 + +USER_ID=${LOCAL_USER_ID:-9001} +GRP_ID=${LOCAL_GRP_ID:-9001} + +getent group zenbuilder > /dev/null 2>&1 || groupadd -g $GRP_ID zenbuilder +id -u zenbuilder > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m zenbuilder + +LOCAL_UID=$(id -u zenbuilder) +LOCAL_GID=$(getent group zenbuilder | cut -d ":" -f 3) + +if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then + echo "Warning: User zenbuilder with differing UID $LOCAL_UID/GID $LOCAL_GID already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID." +fi + +echo "Starting with UID/GID: $LOCAL_UID:$LOCAL_GID" + +export HOME=/home/zenbuilder + +# Mount host directories +for dir in .ccache .zcash-params build; do + if [ -d "/mnt/${dir}" ]; then + if [ ! -L "/home/zenbuilder/${dir}" ]; then + ln -sf "/mnt/${dir}" "/home/zenbuilder/${dir}" + fi + else + mkdir -p "/home/zenbuilder/${dir}" + fi +done + +# Fix ownership recursively +chown -RH zenbuilder:zenbuilder /home/zenbuilder + +exec /usr/local/bin/gosu zenbuilder "$@" diff --git a/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/Dockerfile b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/Dockerfile new file mode 100644 index 0000000000..ef9e1a1c95 --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/Dockerfile @@ -0,0 +1,53 @@ +FROM ubuntu:bionic + +MAINTAINER cronic@zensystem.io + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh + +SHELL ["/bin/bash", "-c"] + +RUN set -euxo pipefail \ + && DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get -y --no-install-recommends install apt-utils \ + && apt-get -y --no-install-recommends dist-upgrade \ + && apt-get -y --no-install-recommends install aria2 autoconf automake bsdmainutils build-essential \ + ca-certificates cmake curl dirmngr fakeroot git g++-multilib gnupg2 help2man libc6-dev libgomp1 \ + libtool lintian m4 ncurses-dev pigz pkg-config pv python python-dev python-pip python-setuptools \ + python-wheel python-wheel-common python-zmq unzip wget zlib1g-dev \ + && pip install b2 pyblake2 \ + && BASEURL="https://github.com/tianon/gosu/releases/download/" \ + && GOSU_VERSION="1.11" \ + && DPKG_ARCH="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ + && curl -o /usr/local/bin/gosu -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}" \ + && curl -o /usr/local/bin/gosu.asc -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg2 --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver hkp://ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.mit.edu --recv-key B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver keyserver.pgp.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.key-server.io --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg2 --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true \ + && BASEURL=$(curl -s https://api.github.com/repos/ipfs/go-ipfs/releases | grep browser_download_url | awk 'FNR <= 1' | cut -d '"' -f 4 | sed 's:/[^/]*$::') \ + && IPFS_VERSION=$(echo -n $BASEURL | sed 's:.*/::') \ + && TMP="$(mktemp -d)" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" \ + && cd $TMP && sha512sum -c "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" && tar -xf "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && cd go-ipfs && ./install.sh && cd && rm -rf $TMP \ + && apt-get -y autoremove --purge \ + && apt-get -y autoclean \ + && apt-get clean \ + && rm -rf /var/cache/apt/archives/*.deb /var/lib/apt/lists/* /root/.cache /tmp/* \ + && chmod +x /usr/local/bin/entrypoint.sh + +VOLUME ["/mnt/.ccache"] + +VOLUME ["/mnt/.zcash-params"] + +VOLUME ["/mnt/build"] + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/entrypoint.sh b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/entrypoint.sh new file mode 100755 index 0000000000..27db4f28eb --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_bionic/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +# Add local zenbuilder user +# Either use LOCAL_USER_ID:LOCAL_GRP_ID if set via environment +# or fallback to 9001:9001 + +USER_ID=${LOCAL_USER_ID:-9001} +GRP_ID=${LOCAL_GRP_ID:-9001} + +getent group zenbuilder > /dev/null 2>&1 || groupadd -g $GRP_ID zenbuilder +id -u zenbuilder > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m zenbuilder + +LOCAL_UID=$(id -u zenbuilder) +LOCAL_GID=$(getent group zenbuilder | cut -d ":" -f 3) + +if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then + echo "Warning: User zenbuilder with differing UID $LOCAL_UID/GID $LOCAL_GID already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID." +fi + +echo "Starting with UID/GID: $LOCAL_UID:$LOCAL_GID" + +export HOME=/home/zenbuilder + +# Mount host directories +for dir in .ccache .zcash-params build; do + if [ -d "/mnt/${dir}" ]; then + if [ ! -L "/home/zenbuilder/${dir}" ]; then + ln -sf "/mnt/${dir}" "/home/zenbuilder/${dir}" + fi + else + mkdir -p "/home/zenbuilder/${dir}" + fi +done + +# Fix ownership recursively +chown -RH zenbuilder:zenbuilder /home/zenbuilder + +exec /usr/local/bin/gosu zenbuilder "$@" diff --git a/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/Dockerfile b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/Dockerfile new file mode 100644 index 0000000000..ed90aaa69a --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/Dockerfile @@ -0,0 +1,53 @@ +FROM ubuntu:xenial + +MAINTAINER cronic@zensystem.io + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh + +SHELL ["/bin/bash", "-c"] + +RUN set -euxo pipefail \ + && DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get -y --no-install-recommends install apt-utils \ + && apt-get -y --no-install-recommends dist-upgrade \ + && apt-get -y --no-install-recommends install aria2 autoconf automake bsdmainutils build-essential \ + ca-certificates cmake curl dirmngr fakeroot git g++-multilib gnupg2 help2man libc6-dev libgomp1 \ + libtool lintian m4 ncurses-dev pigz pkg-config pv python python-dev python-pip python-setuptools \ + python-wheel python-wheel-common python-zmq unzip wget zlib1g-dev \ + && pip install b2 pyblake2 \ + && BASEURL="https://github.com/tianon/gosu/releases/download/" \ + && GOSU_VERSION="1.11" \ + && DPKG_ARCH="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ + && curl -o /usr/local/bin/gosu -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}" \ + && curl -o /usr/local/bin/gosu.asc -SL "${BASEURL}/${GOSU_VERSION}/gosu-${DPKG_ARCH}.asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg2 --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver hkp://ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.mit.edu --recv-key B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver keyserver.pgp.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \ + gpg2 --batch --keyserver pgp.key-server.io --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg2 --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true \ + && BASEURL=$(curl -s https://api.github.com/repos/ipfs/go-ipfs/releases | grep browser_download_url | awk 'FNR <= 1' | cut -d '"' -f 4 | sed 's:/[^/]*$::') \ + && IPFS_VERSION=$(echo -n $BASEURL | sed 's:.*/::') \ + && TMP="$(mktemp -d)" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && curl -SLo "$TMP/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" "${BASEURL}/go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" \ + && cd $TMP && sha512sum -c "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz.sha512" && tar -xf "go-ipfs_${IPFS_VERSION}_linux-${DPKG_ARCH}.tar.gz" \ + && cd go-ipfs && ./install.sh && cd && rm -rf $TMP \ + && apt-get -y autoremove --purge \ + && apt-get -y autoclean \ + && apt-get clean \ + && rm -rf /var/cache/apt/archives/*.deb /var/lib/apt/lists/* /root/.cache /tmp/* \ + && chmod +x /usr/local/bin/entrypoint.sh + +VOLUME ["/mnt/.ccache"] + +VOLUME ["/mnt/.zcash-params"] + +VOLUME ["/mnt/build"] + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/entrypoint.sh b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/entrypoint.sh new file mode 100755 index 0000000000..27db4f28eb --- /dev/null +++ b/contrib/ci-horizen/dockerfiles/arm64/linux/ubuntu_xenial/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +# Add local zenbuilder user +# Either use LOCAL_USER_ID:LOCAL_GRP_ID if set via environment +# or fallback to 9001:9001 + +USER_ID=${LOCAL_USER_ID:-9001} +GRP_ID=${LOCAL_GRP_ID:-9001} + +getent group zenbuilder > /dev/null 2>&1 || groupadd -g $GRP_ID zenbuilder +id -u zenbuilder > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m zenbuilder + +LOCAL_UID=$(id -u zenbuilder) +LOCAL_GID=$(getent group zenbuilder | cut -d ":" -f 3) + +if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then + echo "Warning: User zenbuilder with differing UID $LOCAL_UID/GID $LOCAL_GID already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID." +fi + +echo "Starting with UID/GID: $LOCAL_UID:$LOCAL_GID" + +export HOME=/home/zenbuilder + +# Mount host directories +for dir in .ccache .zcash-params build; do + if [ -d "/mnt/${dir}" ]; then + if [ ! -L "/home/zenbuilder/${dir}" ]; then + ln -sf "/mnt/${dir}" "/home/zenbuilder/${dir}" + fi + else + mkdir -p "/home/zenbuilder/${dir}" + fi +done + +# Fix ownership recursively +chown -RH zenbuilder:zenbuilder /home/zenbuilder + +exec /usr/local/bin/gosu zenbuilder "$@" diff --git a/contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_bionic.sh b/contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_bionic.sh new file mode 100755 index 0000000000..f55ec5ae70 --- /dev/null +++ b/contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_bionic.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euo pipefail + +docker run --rm -v "${TRAVIS_BUILD_DIR}:/mnt/build" -v "$HOME/.ccache:/mnt/.ccache" -e LOCAL_USER_ID="$(id -u)" \ + -e LOCAL_GRP_ID="$(id -g)" --env-file <(env | grep 'DOCKER_') "${IMAGE_NAME}:${IMAGE_TAG}" \ + bash -c 'set -xeuo pipefail && export HOST="$(gcc -dumpmachine)" && export MAKEFLAGS="-j $(($(nproc)+1))" \ + && cd "${DOCKER_HOME}" && time ./zcutil/build.sh $MAKEFLAGS' diff --git a/contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_xenial.sh b/contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_xenial.sh new file mode 100755 index 0000000000..f55ec5ae70 --- /dev/null +++ b/contrib/ci-horizen/scripts/build/build_amd64_linux_ubuntu_xenial.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euo pipefail + +docker run --rm -v "${TRAVIS_BUILD_DIR}:/mnt/build" -v "$HOME/.ccache:/mnt/.ccache" -e LOCAL_USER_ID="$(id -u)" \ + -e LOCAL_GRP_ID="$(id -g)" --env-file <(env | grep 'DOCKER_') "${IMAGE_NAME}:${IMAGE_TAG}" \ + bash -c 'set -xeuo pipefail && export HOST="$(gcc -dumpmachine)" && export MAKEFLAGS="-j $(($(nproc)+1))" \ + && cd "${DOCKER_HOME}" && time ./zcutil/build.sh $MAKEFLAGS' diff --git a/contrib/ci-horizen/scripts/build/build_amd64_osx_xcode9.4.sh b/contrib/ci-horizen/scripts/build/build_amd64_osx_xcode9.4.sh new file mode 100755 index 0000000000..8d9e8566cf --- /dev/null +++ b/contrib/ci-horizen/scripts/build/build_amd64_osx_xcode9.4.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -euo pipefail + +cd "${B2_DL_DECOMPRESS_FOLDER}" +source environment + +cd "${TRAVIS_BUILD_DIR}" +export MAKEFLAGS="-j $(($(nproc)+1))" +export LIBTOOLIZE=glibtoolize +# travis-ci has a 4MB log size limitation after which any job is terminated +# due to stdout verbosity we only display stderr +# stdout and stderr are saved in build.log, the last 100 lines are displayed on error +time ./zcutil/build-mac-clang.sh --disable-libs $MAKEFLAGS > >(tee -a "${TRAVIS_BUILD_DIR}/build.log" > /dev/null) 2> >(tee -a "${TRAVIS_BUILD_DIR}/build.log" >&2) || (tail -n 100 "${TRAVIS_BUILD_DIR}/build.log"; false) diff --git a/contrib/ci-horizen/scripts/build/build_amd64_windows_ubuntu_bionic.sh b/contrib/ci-horizen/scripts/build/build_amd64_windows_ubuntu_bionic.sh new file mode 100755 index 0000000000..d7bff2dc99 --- /dev/null +++ b/contrib/ci-horizen/scripts/build/build_amd64_windows_ubuntu_bionic.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euo pipefail + +docker run --rm -v "${TRAVIS_BUILD_DIR}:/mnt/build" -v "$HOME/.ccache:/mnt/.ccache" -e LOCAL_USER_ID="$(id -u)" \ + -e LOCAL_GRP_ID="$(id -g)" --env-file <(env | grep 'DOCKER_') "${IMAGE_NAME}:${IMAGE_TAG}" \ + bash -c 'set -xeuo pipefail && export HOST=x86_64-w64-mingw32 && export MAKEFLAGS="-j $(($(nproc)+1))" \ + && cd "${DOCKER_HOME}" && time ./zcutil/build.sh $MAKEFLAGS' diff --git a/contrib/ci-horizen/scripts/common/b2_compress_checksum_upload.sh b/contrib/ci-horizen/scripts/common/b2_compress_checksum_upload.sh new file mode 100755 index 0000000000..04dc658345 --- /dev/null +++ b/contrib/ci-horizen/scripts/common/b2_compress_checksum_upload.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euo pipefail + +FOLDERNAME="$1" +FILENAME="$2" + +tar -hcf - -C "${FOLDERNAME}" . | pigz -c | tee >(sha256sum | cut -d " " -f1 | xargs -I {} echo {}" ${FILENAME}" > ~/"${FILENAME}.sha256") > ~/"${FILENAME}" +b2 authorize-account +b2 upload-file "${B2_BUCKET_NAME}" ~/"${FILENAME}.sha256" "${FILENAME}.sha256" +b2 upload-file --threads 20 "${B2_BUCKET_NAME}" ~/"${FILENAME}" "${FILENAME}" diff --git a/contrib/ci-horizen/scripts/common/b2_download_verify_decompress.sh b/contrib/ci-horizen/scripts/common/b2_download_verify_decompress.sh new file mode 100755 index 0000000000..ed0a19eb32 --- /dev/null +++ b/contrib/ci-horizen/scripts/common/b2_download_verify_decompress.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set +u -eo pipefail + +FOLDERNAME="$1" +FILENAME="$2" + +if [ "${RENAME_FOLDER}" = "true" ] && [ ! -z "${RENAME_SUFFIX}" ]; then + mv "${FOLDERNAME}" "${FOLDERNAME}${RENAME_SUFFIX}" +fi +aria2c --file-allocation=none --max-tries=3 --continue=true "${B2_DOWNLOAD_URL}${FILENAME}.sha256" -d "${HOME}" || FAILURE="true" +aria2c --file-allocation=none -s4 -x4 --max-tries=3 --continue=true "${B2_DOWNLOAD_URL}${FILENAME}" -d "${HOME}" || FAILURE="true" +if [ "${FAILURE}" = "true" ]; then + if [ "${ALLOW_FAILURE}" = "true" ]; then + exit 0 + else + exit 1 + fi +else + cd "${HOME}" + sha256sum -c "${FILENAME}.sha256" + mkdir -p "${FOLDERNAME}" + pigz -cd "${FILENAME}" | tar -xf - -C "${FOLDERNAME}" + if [ "${DELETE_DL_FILE}" = "true" ]; then + rm -f "${HOME}/${FILENAME}" "${HOME}/${FILENAME}.sha256" + fi +fi diff --git a/contrib/ci-horizen/scripts/common/get_archive.sh b/contrib/ci-horizen/scripts/common/get_archive.sh new file mode 100755 index 0000000000..eb21304060 --- /dev/null +++ b/contrib/ci-horizen/scripts/common/get_archive.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -eo pipefail + +FOLDERNAME="$1" +FILENAME="$2" + +if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/b2_download_verify_decompress.sh ${FOLDERNAME} ${FILENAME}" +else + docker run --rm -v "${TRAVIS_BUILD_DIR}/../:/mnt/build" -e LOCAL_USER_ID="$(id -u)" -e LOCAL_GRP_ID="$(id -g)" \ + -e RENAME_FOLDER="${RENAME_FOLDER}" -e RENAME_SUFFIX="${RENAME_SUFFIX}" --env-file <(env | grep 'DOCKER_\|B2_\|TRAVIS_') "${IMAGE_NAME}:${IMAGE_TAG}" \ + bash -c "${DOCKER_HOME}/$(basename ${TRAVIS_BUILD_DIR})/contrib/ci-horizen/scripts/common/b2_download_verify_decompress.sh ${FOLDERNAME} ${FILENAME}" +fi diff --git a/contrib/ci-horizen/scripts/common/install.sh b/contrib/ci-horizen/scripts/common/install.sh new file mode 100755 index 0000000000..570e8204a6 --- /dev/null +++ b/contrib/ci-horizen/scripts/common/install.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -euo pipefail + +if [ "${TRAVIS_OS_NAME}" = "linux" ]; then + if [ ! -z "${DOCKER_UPDATE_PACKAGES}" ]; then + sudo add-apt-repository "deb [arch=${TRAVIS_CPU_ARCH}] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + UPDATE_PACKAGES="${UPDATE_PACKAGES} ${DOCKER_UPDATE_PACKAGES}" + fi + if [ ! -z "${PIP_UPDATE_PACKAGES}" ] && [ ! -z "${PIP_INSTALL}" ]; then + UPDATE_PACKAGES="${UPDATE_PACKAGES} ${PIP_UPDATE_PACKAGES}" + fi + sudo apt-get update + sudo apt-get -y --no-install-recommends install ${UPDATE_PACKAGES} + if [ ! -z "${DOCKER_UPDATE_PACKAGES}" ]; then + ls /proc/sys/fs/binfmt_misc/ + if [ "${TRAVIS_CPU_ARCH}" = "amd64" ]; then + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + docker image rm multiarch/qemu-user-static:latest + fi + fi + if [ ! -z "${PIP_INSTALL}" ]; then + sudo pip install --upgrade ${PIP_INSTALL} + fi +fi + +if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + brew install ${UPDATE_PACKAGES} + if [ ! -z "${PIP_INSTALL}" ]; then + sudo pip install --upgrade ${PIP_INSTALL} + fi +fi diff --git a/contrib/ci-horizen/scripts/common/push_archive.sh b/contrib/ci-horizen/scripts/common/push_archive.sh new file mode 100755 index 0000000000..0cf988cbbd --- /dev/null +++ b/contrib/ci-horizen/scripts/common/push_archive.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -euo pipefail + +FOLDERNAME="$1" +FILENAME="$2" + +if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + bash -c "${TRAVIS_BUILD_DIR}/contrib/ci-horizen/scripts/common/b2_compress_checksum_upload.sh $FOLDERNAME $FILENAME" +else + docker run --rm -v "${TRAVIS_BUILD_DIR}:/mnt/build" -e LOCAL_USER_ID="$(id -u)" -e LOCAL_GRP_ID="$(id -g)" --env-file <(env | grep 'DOCKER_\|B2_\|TRAVIS_') "${IMAGE_NAME}:${IMAGE_TAG}" \ + bash -c "${DOCKER_HOME}/contrib/ci-horizen/scripts/common/b2_compress_checksum_upload.sh $FOLDERNAME $FILENAME" +fi diff --git a/contrib/ci-horizen/scripts/common/setup_environment.sh b/contrib/ci-horizen/scripts/common/setup_environment.sh new file mode 100755 index 0000000000..5c9b72b434 --- /dev/null +++ b/contrib/ci-horizen/scripts/common/setup_environment.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +set -euo pipefail + +NEED_DOCKER_CREDS="false" +NEED_B2_CREDS="false" +NEED_GH_CREDS="false" +NEED_MAC_SIGN_CREDS="false" +NEED_WIN_SIGN_CREDS="false" +NEED_PGP_SIGN_CREDS="false" + +export B2_DOWNLOAD_URL="https://downloads.horizen.global/file/${B2_BUCKET_NAME}/" + +if [ "${TRAVIS_OS_NAME}" = "linux" ]; then + export DOCKER_UPDATE_PACKAGES="binfmt-support containerd.io docker-ce docker-ce-cli qemu-user-static" + export UPDATE_PACKAGES="ca-certificates curl jq openssl" + export PIP_UPDATE_PACKAGES="python-pip python-setuptools python-wheel python-wheel-common" + export PIP_INSTALL="" + export IMAGE_NAME=zencash/zen-builder + export IMAGE_BASE_TAG="${DOCKER_ARCH}-${DOCKER_TARGET_OS}-${DOCKER_FROM}" + export IMAGE_LATEST_TAG="${IMAGE_BASE_TAG}-latest" + export DOCKER_HOME="/home/zenbuilder/build" + if [ -z "${TRAVIS_TAG}" ]; then + export IMAGE_TAG="${IMAGE_LATEST_TAG}" + else + export IMAGE_TAG="${IMAGE_BASE_TAG}-$(echo -n ${TRAVIS_TAG} | sed 's/[^-._a-zA-Z0-9]/-/g')" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Prepare" ]; then + export DATE=$(date '+%Y-%m-%d') + export IMAGE_PATH="${TRAVIS_BUILD_DIR}/contrib/ci-horizen/dockerfiles/${DOCKER_ARCH}/${DOCKER_TARGET_OS}/${DOCKER_FROM}" + NEED_DOCKER_CREDS="true" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Build" ]; then + export B2_UL_COMPRESS_FOLDER="${DOCKER_HOME}" + export B2_UL_FILENAME="${DOCKER_ARCH}-${DOCKER_TARGET_OS}-${DOCKER_FROM}-${TRAVIS_BUILD_ID}-${TRAVIS_COMMIT}.tar.gz" + NEED_B2_CREDS="true" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Test" ]; then + export B2_DL_DECOMPRESS_FOLDER="${DOCKER_HOME}/$(basename ${TRAVIS_BUILD_DIR})" + export B2_DL_FILENAME="${DOCKER_ARCH}-${DOCKER_TARGET_OS}-${DOCKER_FROM}-${TRAVIS_BUILD_ID}-${TRAVIS_COMMIT}.tar.gz" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Package" ]; then + NEED_B2_CREDS="true" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Sign" ]; then + NEED_B2_CREDS="true" + NEED_GH_CREDS="true" + NEED_PGP_SIGN_CREDS="true" + if [ "${DOCKER_TARGET_OS}" = "windows" ]; then + NEED_WIN_SIGN_CREDS="true" + fi + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Deploy" ]; then + export DOCKER_UPDATE_PACKAGES="" + NEED_GH_CREDS="true" + NEED_PGP_SIGN_CREDS="true" + fi +fi + +if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + export UPDATE_PACKAGES="aria2 pigz" + export PIP_INSTALL="" + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Prepare" ]; then + export PIP_INSTALL="${PIP_INSTALL} b2" + export CLONE_REPO="https://github.com/ZencashOfficial/zencash-apple.git" + export CLONE_TARGET="${HOME}/zencash-apple" + export B2_UL_COMPRESS_FOLDER="${CLONE_TARGET}" + export B2_UL_FILENAME="${TRAVIS_CPU_ARCH}-${TRAVIS_OS_NAME}-${TRAVIS_OSX_IMAGE}-${TRAVIS_BUILD_ID}-${TRAVIS_COMMIT}-zencash-apple.tar.gz" + NEED_B2_CREDS="true" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Build" ]; then + export PIP_INSTALL="${PIP_INSTALL} b2" + export B2_DL_DECOMPRESS_FOLDER="${HOME}/zencash-apple" + export B2_DL_FILENAME="${TRAVIS_CPU_ARCH}-${TRAVIS_OS_NAME}-${TRAVIS_OSX_IMAGE}-${TRAVIS_BUILD_ID}-${TRAVIS_COMMIT}-zencash-apple.tar.gz" + export B2_UL_COMPRESS_FOLDER="${TRAVIS_BUILD_DIR}" + export B2_UL_FILENAME="${TRAVIS_CPU_ARCH}-${TRAVIS_OS_NAME}-${TRAVIS_OSX_IMAGE}-${TRAVIS_BUILD_ID}-${TRAVIS_COMMIT}.tar.gz" + NEED_B2_CREDS="true" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Test" ]; then + export PIP_INSTALL="${PIP_INSTALL} pyblake2 pyzmq" + export B2_DL_DECOMPRESS_FOLDER="${TRAVIS_BUILD_DIR}" + export B2_DL_FILENAME="${TRAVIS_CPU_ARCH}-${TRAVIS_OS_NAME}-${TRAVIS_OSX_IMAGE}-${TRAVIS_BUILD_ID}-${TRAVIS_COMMIT}.tar.gz" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Package" ]; then + NEED_B2_CREDS="true" + fi + if [ "${TRAVIS_BUILD_STAGE_NAME}" = "Sign" ]; then + NEED_B2_CREDS="true" + NEED_GH_CREDS="true" + NEED_PGP_SIGN_CREDS="true" + NEED_MAC_SIGN_CREDS="true" + fi +fi + +# clear credentials when not needed +if [ "${NEED_DOCKER_CREDS}" = "false" ]; then + export DOCKER_USERNAME="" + export DOCKER_PASSWORD="" + unset DOCKER_USERNAME + unset DOCKER_PASSWORD +fi + +if [ "${NEED_B2_CREDS}" = "false" ]; then + export B2_APPLICATION_KEY_ID="" + export B2_APPLICATION_KEY="" + unset B2_APPLICATION_KEY_ID + unset B2_APPLICATION_KEY +fi + +if [ "${NEED_GH_CREDS}" = "false" ]; then + export GH_USER="" + export GH_AUTH="" + unset GH_USER + unset GH_AUTH +fi + +if [ "${NEED_MAC_SIGN_CREDS}" = "false" ]; then + export CERT_ARCHIVE_URL="" + export CERT_ARCHIVE_PASSWORD="" + export MAC_CERT_PASSWORD="" + unset CERT_ARCHIVE_URL + unset CERT_ARCHIVE_PASSWORD + unset MAC_CERT_PASSWORD +fi + +if [ "${NEED_WIN_SIGN_CREDS}" = "false" ]; then + export CERT_ARCHIVE_URL="" + export CERT_ARCHIVE_PASSWORD="" + export WIN_CERT_PASSWORD="" + unset CERT_ARCHIVE_URL + unset CERT_ARCHIVE_PASSWORD + unset WIN_CERT_PASSWORD +fi + +if [ "${NEED_PGP_SIGN_CREDS}" = "false" ]; then + export PGP_KEY_PASSWORD="" + unset PGP_KEY_PASSWORD +fi + +set +u diff --git a/contrib/ci-horizen/scripts/common/travis_stay_alive.sh b/contrib/ci-horizen/scripts/common/travis_stay_alive.sh new file mode 100755 index 0000000000..0d3c8964d1 --- /dev/null +++ b/contrib/ci-horizen/scripts/common/travis_stay_alive.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +bash -c 'while true; do sleep 300; echo "______ travis keep alive ______"; done &' diff --git a/contrib/ci-horizen/scripts/prepare/build_zencash-apple.sh b/contrib/ci-horizen/scripts/prepare/build_zencash-apple.sh new file mode 100755 index 0000000000..1f5b2d8b04 --- /dev/null +++ b/contrib/ci-horizen/scripts/prepare/build_zencash-apple.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euo pipefail + +git clone "${CLONE_REPO}" "${CLONE_TARGET}" +cd "${CLONE_TARGET}" +source environment +make diff --git a/contrib/ci-horizen/scripts/prepare/docker_image_build.sh b/contrib/ci-horizen/scripts/prepare/docker_image_build.sh new file mode 100755 index 0000000000..cbdd89eb09 --- /dev/null +++ b/contrib/ci-horizen/scripts/prepare/docker_image_build.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -euo pipefail + +HASH_PACKAGE_LIST_REGISTRY="" +HASH_PACKAGE_LIST_LOCAL="differs from registry" + +if [ -z "${TRAVIS_TAG}" ]; then + docker build --force-rm --pull --no-cache -t "${IMAGE_NAME}:${IMAGE_BASE_TAG}-${DATE}" "${IMAGE_PATH}" + if [ "${DOCKER_IS_DEB}" = "true" ]; then + HASH_PACKAGE_LIST_LOCAL=$(docker run --rm --entrypoint='' "${IMAGE_NAME}:${IMAGE_BASE_TAG}-${DATE}" bash -c 'dpkg -l | sha256sum | cut -d " " -f 1') + HASH_PACKAGE_LIST_REGISTRY=$(docker run --rm --entrypoint='' "${IMAGE_NAME}:${IMAGE_LATEST_TAG}" bash -c 'dpkg -l | sha256sum | cut -d " " -f 1') + echo "$HASH_PACKAGE_LIST_REGISTRY $HASH_PACKAGE_LIST_LOCAL" + docker image rm "${IMAGE_NAME}:${IMAGE_LATEST_TAG}" + fi + if [ "${HASH_PACKAGE_LIST_REGISTRY}" = "${HASH_PACKAGE_LIST_LOCAL}" ] && [ "$DOCKER_FORCE_DEPLOY" != "true" ]; then + echo "Deleting locally built image, no changes detected between ${IMAGE_NAME}:${IMAGE_BASE_TAG}-${DATE} and ${IMAGE_NAME}:${IMAGE_LATEST_TAG}" + docker image rm "${IMAGE_NAME}:${IMAGE_BASE_TAG}-${DATE}" + else + docker tag "${IMAGE_NAME}:${IMAGE_BASE_TAG}-${DATE}" "${IMAGE_NAME}:${IMAGE_LATEST_TAG}" + fi +fi diff --git a/contrib/ci-horizen/scripts/prepare/docker_image_deploy.sh b/contrib/ci-horizen/scripts/prepare/docker_image_deploy.sh new file mode 100755 index 0000000000..0f87a35e94 --- /dev/null +++ b/contrib/ci-horizen/scripts/prepare/docker_image_deploy.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -euo pipefail + +if [ -z "${TRAVIS_TAG}" ]; then + echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + for image in $(docker image ls --filter=reference="${IMAGE_NAME}" --format "{{.Repository}}:{{.Tag}}"); do + echo "Pushing $image to registry" + docker push "$image" + done +else + AUTH_URL="https://auth.docker.io/token" + AUTH_SERVICE="registry.docker.io" + AUTH_SCOPE="repository:${IMAGE_NAME}:pull,push" + AUTH_OFFLINE_TOKEN="1" + AUTH_CLIENT_ID="shell" + REGISTRY="https://registry.hub.docker.com/v2" + CONTENT_TYPE="application/vnd.docker.distribution.manifest.v2+json" + TOKEN=$(curl -s -H "Content-Type: application/json" -u "${DOCKER_USERNAME}:${DOCKER_PASSWORD}" "${AUTH_URL}?service=${AUTH_SERVICE}&scope=${AUTH_SCOPE}&offline_token=${AUTH_OFFLINE_TOKEN}&client_id=${AUTH_CLIENT_ID}" | jq -r .token) + TAG_OLD="${IMAGE_LATEST_TAG}" + TAG_NEW="${IMAGE_TAG}" + echo "Tagging image ${IMAGE_NAME}:${TAG_OLD} as ${IMAGE_NAME}:${TAG_NEW}" + MANIFEST=$(curl -s -H "Accept: ${CONTENT_TYPE}" -H "Authorization: Bearer ${TOKEN}" "${REGISTRY}/${IMAGE_NAME}/manifests/${TAG_OLD}") + curl -s -X PUT -H "Content-Type: ${CONTENT_TYPE}" -H "Authorization: Bearer ${TOKEN}" -d "${MANIFEST}" "${REGISTRY}/${IMAGE_NAME}/manifests/${TAG_NEW}" +fi diff --git a/contrib/ci-horizen/scripts/test/run_test.sh b/contrib/ci-horizen/scripts/test/run_test.sh new file mode 100755 index 0000000000..0f0bdc2ade --- /dev/null +++ b/contrib/ci-horizen/scripts/test/run_test.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -euo pipefail + +export CMD="$1" +export ARGS="$2" + +if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + # workaround until https://github.com/zcash/zcash/pull/3538 is pulled in from upstream + # or the work porting the test suite to python3 is pulled in + find "${TRAVIS_BUILD_DIR}/qa" -type f -name *.py | LC_ALL=C xargs sed -i '' 's/env python2/env python/' + bash -c 'set -xeuo pipefail && export HOST=$(gcc -dumpmachine) && export MAKEFLAGS="-j $(($(nproc)+1))" \ + && cd "${TRAVIS_BUILD_DIR}" && ./zcutil/fetch-params.sh && time "${CMD}" ${ARGS}' +else + docker network create --ipv6 --subnet=fd00::/48 dockerbridge + docker run --rm -v "${TRAVIS_BUILD_DIR}:/mnt/build" -v "$HOME/.zcash-params:/mnt/.zcash-params" --tmpfs /tmp \ + -e LOCAL_USER_ID="$(id -u)" -e LOCAL_GRP_ID="$(id -g)" -e CMD -e ARGS \ + --env-file <(env | grep 'DOCKER_\|B2_\|TEST_\|TRAVIS_') --network=dockerbridge "${IMAGE_NAME}:${IMAGE_TAG}" \ + bash -c 'set -xeuo pipefail && export HOST=$(gcc -dumpmachine) \ + && export MAKEFLAGS="-j $(($(nproc)+1))" && cd "${DOCKER_HOME}" && ./zcutil/fetch-params.sh && time "${CMD}" ${ARGS}' +fi From 1d433d6e19d40f10daaf444740a8ba1350822198 Mon Sep 17 00:00:00 2001 From: Miles Manley Date: Mon, 13 Jan 2020 13:23:16 +0900 Subject: [PATCH 39/45] Update libsodium download-path Fixes error 404 when building for macOS Maybe update to 1.0.16? --- depends/packages/libsodium.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/libsodium.mk b/depends/packages/libsodium.mk index a494f125a6..173a4f0d0e 100644 --- a/depends/packages/libsodium.mk +++ b/depends/packages/libsodium.mk @@ -1,6 +1,6 @@ package=libsodium $(package)_version=1.0.15 -$(package)_download_path=https://download.libsodium.org/libsodium/releases/old/ +$(package)_download_path=https://download.libsodium.org/libsodium/releases/old/unsupported/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 $(package)_dependencies= From 78cb17552b837f7d77eee379a5258b40eb5bc2c6 Mon Sep 17 00:00:00 2001 From: cronicc Date: Mon, 10 Feb 2020 08:07:31 +0000 Subject: [PATCH 40/45] Set mainnet/testnet checkpoint blocks --- src/chainparams.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 35c17dbda5..21085ad949 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -147,11 +147,12 @@ class CMainParams : public CChainParams { ( 429014, uint256S("0x000000000dc4f58375d9fa6dc4cb1bfc4b0afefbf4f7e1ee2cc755d6ca3b40b0")) ( 491000, uint256S("0x0000000018d0b189de58bcd8ff5048d2e4d1c652b98912ff002c8f07c6f81b8c")) ( 543000, uint256S("0x00000000111469e247ecb152e57c371147775b56173260950075dcb471614fed")) - ( 596000, uint256S("0x000000000656846513b2d3faf3a70f59dc22fffcb8e14401ec5a17eec8994410")), - 1569977374, // * UNIX timestamp of last checkpoint block - 10471870, // * total number of transactions between genesis and last checkpoint + ( 596000, uint256S("0x000000000656846513b2d3faf3a70f59dc22fffcb8e14401ec5a17eec8994410")) + ( 671000, uint256S("0x00000000097174dacaf850075917d1a24145fce88a800881ece709bb8f8746cf")), + 1581303190, // * UNIX timestamp of last checkpoint block + 12878591, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) - 10120 // * estimated number of transactions per day after checkpoint + 11064 // * estimated number of transactions per day after checkpoint // total number of tx / (checkpoint block height / (24 * 24)) }; @@ -241,11 +242,12 @@ class CTestNetParams : public CMainParams { (362210, uint256S("0x00023d5c074a7c2ccf130dac34b2b6f77e3c4466cfed0b72c3f3715157c92949")) (423000, uint256S("0x000d04b28067fe99445961f795ee7436f1dbbffc3a045f6890868e605209d170")) (467550, uint256S("0x0007f73f339ea99e920e83da38d7537ce7d0028d48e709c88b1b89adf521b4f9")) - (520000, uint256S("0x00052e65426a0ffbb90893208a6c89a82816abbed328fa2be5a647828609e61a")), - 1569935276, // * UNIX timestamp of last checkpoint block - 1090788, // * total number of transactions between genesis and last checkpoint + (520000, uint256S("0x00052e65426a0ffbb90893208a6c89a82816abbed328fa2be5a647828609e61a")) + (595000, uint256S("0x0000da85ddc79fdd297e996d6b6b887fc5b345619b7a6726c496941dcf830966")), + 1581235560, // * UNIX timestamp of last checkpoint block + 1213107, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) - 1208 // total number of tx / (checkpoint block height / (24 * 24)) + 1175 // total number of tx / (checkpoint block height / (24 * 24)) }; // commented out - seems to make no sense but kept around for reference just in case From fa5ac79b60c3f835a22c59edf561283fea1d08d3 Mon Sep 17 00:00:00 2001 From: cronicc Date: Mon, 10 Feb 2020 08:21:26 +0000 Subject: [PATCH 41/45] Set deprecation block 736000 --- src/deprecation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deprecation.h b/src/deprecation.h index a610b902ce..28e56f5643 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -5,7 +5,7 @@ #ifndef ZCASH_DEPRECATION_H #define ZCASH_DEPRECATION_H -static const int APPROX_RELEASE_HEIGHT = 615488; +static const int APPROX_RELEASE_HEIGHT = 671488; static const int WEEKS_UNTIL_DEPRECATION = 16; static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 24); From cbdae14c9b919bb5fbbf40e16034bb66acab23c4 Mon Sep 17 00:00:00 2001 From: cronicc Date: Mon, 10 Feb 2020 09:13:01 +0000 Subject: [PATCH 42/45] Add test instructions to README.md * closes #217 --- README.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8f373df58..a2993b650f 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,8 @@ https://github.com/ZencashOfficial/zencash-apple * Install for Windows (Cross-Compiled, building on Windows is not supported yet) ``` -./zcutil/build-win.sh -j$(nproc) +export HOST=x86_64-w64-mingw32 +./zcutil/build.sh -j$(nproc) ``` * Install for aarch64(ARM64) @@ -102,8 +103,35 @@ ln -s /usr/bin/ranlib aarch64-unknown-linux-gnu-ranlib ln -s /usr/bin/strip aarch64-unknown-linux-gnu-strip PATH=$PATH:~/bin cd ~/zen/ -./zcutil/build-arm.sh -j$(nproc) +export HOST=aarch64-unknown-linux +./zcutil/build.sh -j$(nproc) ``` +Running Regression Tests +---------------- +1. Get dependencies: + 1. Debian + ```{r, engine='bash'} + sudo apt-get install \ + python python-dev python-pip python-setuptools \ + python-wheel python-wheel-common python-zmq + sudo pip install --upgrade pyblake2 + ``` + 2. MacOS + ```{r, engine='bash'} + brew install python@2 + sudo pip install --upgrade pyblake2 pyzmq + ``` +2. Start test suite + ```{r, engine='bash'} + if [[ "$OSTYPE" == "darwin"* ]]; then + TEST_ARGS="btest gtest sec-hard no-dot-so util-test secp256k1 libsnark univalue rpc --rpc-extended --rpc-exclude=rpcbind_test.py" + else + TEST_ARGS="--rpc-extended" + fi + export HOST=$(gcc -dumpmachine) + ./zcutil/fetch-params.sh + ./qa/zcash/full_test_suite.py ${TEST_ARGS} + ``` Instructions to redeem pre-block 110,000 ZCL ------------- 1. Linux: From 2a980348a58aef040110274c587d212768eb4bbd Mon Sep 17 00:00:00 2001 From: cronicc Date: Mon, 10 Feb 2020 09:14:58 +0000 Subject: [PATCH 43/45] Set version to 2.0.20 --- README.md | 2 +- configure.ac | 4 ++-- src/clientversion.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a2993b650f..70b3f892ed 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Zen 2.0.19-1 +Zen 2.0.20 ============== What is Horizen? diff --git a/configure.ac b/configure.ac index 5f5f0643b7..18e44a453b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 2) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_REVISION, 19) -define(_CLIENT_VERSION_BUILD, 51) +define(_CLIENT_VERSION_REVISION, 20) +define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) define(_CLIENT_VERSION_IS_RELEASE, true) diff --git a/src/clientversion.h b/src/clientversion.h index 0a8b5fda58..2518f54510 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -34,8 +34,8 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 19 -#define CLIENT_VERSION_BUILD 51 +#define CLIENT_VERSION_REVISION 20 +#define CLIENT_VERSION_BUILD 50 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true From 5ac5c63277beb26c85033a40b02f18f836e33951 Mon Sep 17 00:00:00 2001 From: cronicc Date: Mon, 10 Feb 2020 09:17:28 +0000 Subject: [PATCH 44/45] Generate manpages --- doc/man/zen-cli.1 | 6 +++--- doc/man/zen-tx.1 | 6 +++--- doc/man/zend.1 | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/man/zen-cli.1 b/doc/man/zen-cli.1 index 468145b338..684ee70f10 100644 --- a/doc/man/zen-cli.1 +++ b/doc/man/zen-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZEN-CLI "1" "November 2019" "zen-cli v2.0.19-1" "User Commands" +.TH ZEN-CLI "1" "February 2020" "zen-cli v2.0.20" "User Commands" .SH NAME -zen-cli \- manual page for zen-cli v2.0.19-1 +zen-cli \- manual page for zen-cli v2.0.20 .SH DESCRIPTION -Horizen RPC client version v2.0.19-1 +Horizen RPC client version v2.0.20 .SS "Usage:" .TP zen\-cli [options] [params] diff --git a/doc/man/zen-tx.1 b/doc/man/zen-tx.1 index 228d970e00..daad61aae2 100644 --- a/doc/man/zen-tx.1 +++ b/doc/man/zen-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZEN-TX "1" "November 2019" "zen-tx v2.0.19-1" "User Commands" +.TH ZEN-TX "1" "February 2020" "zen-tx v2.0.20" "User Commands" .SH NAME -zen-tx \- manual page for zen-tx v2.0.19-1 +zen-tx \- manual page for zen-tx v2.0.20 .SH DESCRIPTION -Zencash zen\-tx utility version v2.0.19-1 +Zencash zen\-tx utility version v2.0.20 .SS "Usage:" .TP zen\-tx [options] [commands] diff --git a/doc/man/zend.1 b/doc/man/zend.1 index 6a968c4165..5dbc96b2ca 100644 --- a/doc/man/zend.1 +++ b/doc/man/zend.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZEND "1" "November 2019" "zend v2.0.19-1" "User Commands" +.TH ZEND "1" "February 2020" "zend v2.0.20" "User Commands" .SH NAME -zend \- manual page for zend v2.0.19-1 +zend \- manual page for zend v2.0.20 .SH DESCRIPTION -Zen Daemon version v2.0.19-1 +Zen Daemon version v2.0.20 .SS "Usage:" .TP zend [options] @@ -51,7 +51,7 @@ Specify data directory \fB\-disabledeprecation=\fR .IP Disable block\-height node deprecation and automatic shutdown (example: -\fB\-disabledeprecation\fR=\fI\,2\/\fR.0.19-1) +\fB\-disabledeprecation\fR=\fI\,2\/\fR.0.20) .HP \fB\-exportdir=\fR .IP From 9a96535495a2092eab639073d434aa297d122e29 Mon Sep 17 00:00:00 2001 From: cronicc Date: Mon, 10 Feb 2020 09:38:55 +0000 Subject: [PATCH 45/45] Update release notes --- doc/authors.md | 259 +++++++++++---------- doc/release-notes/release-notes-v2.0.20.md | 61 +++++ 2 files changed, 193 insertions(+), 127 deletions(-) create mode 100644 doc/release-notes/release-notes-v2.0.20.md diff --git a/doc/authors.md b/doc/authors.md index 144165dd61..534f887c6c 100644 --- a/doc/authors.md +++ b/doc/authors.md @@ -1,140 +1,145 @@ Zcash Contributors ================== -Jack Grigg (976) -FranckDG (438) -Simon Liu (390) -cronicc (285) -Sean Bowe (213) -Daira Hopwood (184) -Wladimir J. van der Laan (173) -Nathan Wilcox (156) -Alberto Sala (140) -Taylor Hornby (113) -Jonas Schnelli (99) -Jay Graber (97) -pierstab (67) -Cory Fields (62) -syd (43) -joshuayabut (40) -Kevin Gallagher (38) -Jake Tarren (37) +Jack Grigg (1006) +Simon Liu (287) +Sean Bowe (241) +FranckDG (219) +Daira Hopwood (199) +Wladimir J. van der Laan (141) +cronicc (114) +Jay Graber (110) +Nathan Wilcox (106) +Jonas Schnelli (98) +Kevin Gallagher (76) +Taylor Hornby (73) +Cory Fields (56) +MarcoOl94 (50) Pieter Wuille (32) -hellcatz (29) -nomnombtc (27) -PeaStew (21) -tarrenj (18) -Luke Dashjr (18) -zebambam (17) -Paige Peterson (17) +pierstab (29) +Alberto Sala (29) +syd (28) +joshuayabut (20) +nomnombtc (18) +Paige Peterson (18) fanquake (16) -Code Particle (16) -MarcoFalke (15) -Ariel Gabizon (15) -kozyilmaz (12) -Reza Barazesh (12) -Peter Todd (12) -Matt Corallo (12) -Karl-Johan Alm (12) -Gregory Maxwell (11) -g666 (10) -Philip Kaufmann (10) -Pavel Janík (9) -Jonathan "Duke" Leto (8) -str4d (6) -pstab (6) -kpcyrd (6) -Smrtz (6) -Per Grön (6) +MarcoFalke (14) +Luke Dashjr (12) +Jake Tarren (11) +hellcatz (10) +abi87 (10) +Johnathan Corgan (10) +Gregory Maxwell (10) +Ariel Gabizon (10) +tarrenj (8) +kozyilmaz (8) +Peter Todd (8) +Matt Corallo (8) +Karl-Johan Alm (8) +Jeff Garzik (8) +David Mercer (8) +Daniel Cousens (8) +Code Particle (8) +Philip Kaufmann (7) +PeaStew (7) +lpescher (6) +Pavel Janík (6) Patrick Strateman (6) -Larry Ruane (6) -Jason Davies (6) -Jack Gavigan (6) -Gavin Andresen (6) -Daniel Cousens (6) -Boris P (6) -Bjorn Hjortsberg (6) -Amgad Abdelhafez (6) -nickolay (5) -fgius (5) -ca333 (5) -Stefano (5) -Oleksandr Iozhytsia (5) -João Barbosa (5) -Johnathan Corgan (5) -Homu (5) +João Barbosa (6) +Alfie John (5) +str4d (4) paveljanik (4) -codeparticle (4) -Kent (4) -Joshua Yabut (4) -Jeff Garzik (4) -David Mercer (4) -zathras-crypto (3) -unsystemizer (3) -practicalswift (3) -mruddy (3) -lpescher (3) -instagibbs (3) -emilrus (3) -dexX7 (3) -daniel (3) -calebogden (3) -Stephen (3) -Ross Nicoll (3) -René Nyffenegger (3) -Pavel Vasin (3) -Paul Georgiou (3) -Nathaniel Mahieu (3) -Murilo Santana (3) -Matt Quinn (3) -Leo Arias (3) -Kevin Pan (3) -Jorge Timón (3) -Ian Kelling (3) -Forrest Voight (3) -Florian Schmaus (3) -Duke Leto (3) -Daniel Kraft (3) -Casey Rodarmor (3) -Bruno Arueira (3) -Boris Hajduk (3) -Bob McElrath (3) -Ariel (3) -Anthony Towns (3) -Allan Niemerg (3) -Alfie John (3) -Alex van der Peet (3) -Alberto Garoffolo (3) -Adam Weiss (3) -Adam Brown (3) -pier (2) -koljenovic (2) +kpcyrd (4) +Scott (4) +Reza Barazesh (4) +Per Grön (4) +Joe Turgeon (4) +Jason Davies (4) +Jack Gavigan (4) +ITH4Coinomia (4) +Gavin Andresen (4) +Bjorn Hjortsberg (4) +Amgad Abdelhafez (4) +zebambam (3) +Smrtz (3) +Robert C. Seacord (3) +Jonathan "Duke" Leto (3) +zathras-crypto (2) +unsystemizer (2) +pstab (2) +practicalswift (2) +mruddy (2) +mrbandrews (2) +kazcw (2) +isle2983 (2) +instagibbs (2) +g666 (2) +emilrus (2) +dexX7 (2) +daniel (2) +codeparticle (2) +calebogden (2) +ayleph (2) aniemerg (2) -Scott (2) -Robert C. Seacord (2) -Marius Kjærstad (2) -Joe Turgeon (2) -JOSEPH NICHOLAS R. ALCANTARA (2) -Igor Mikheiko (2) -ITH4Coinomia (2) -Franck De Girolami (2) -mrbandrews (1) -kazcw (1) -isle2983 (1) -ayleph (1) +Stephen (2) +S. Matthew English (2) +Ross Nicoll (2) +René Nyffenegger (2) +Pavel Vasin (2) +Paul Georgiou (2) +Paragon Initiative Enterprises, LLC (2) +Nathaniel Mahieu (2) +Murilo Santana (2) +Miles Manley (2) +Matt Quinn (2) +Louis Nyffenegger (2) +Leo Arias (2) +Kevin Pan (2) +Joshua Yabut (2) +Jorge Timón (2) +Jeffrey Walton (2) +Ian Kelling (2) +Forrest Voight (2) +Florian Schmaus (2) +Eran Tromer (2) +Duke Leto (2) +Daniel Kraft (2) +Christian von Roques (2) +Chirag Davé (2) +Casey Rodarmor (2) +Cameron Boehmer (2) +Bryan Stitt (2) +Bruno Arueira (2) +Boris Hajduk (2) +Bob McElrath (2) +Bitcoin Error Log (2) +Ariel (2) +Anthony Towns (2) +Allan Niemerg (2) +Alex van der Peet (2) +Adam Weiss (2) +Adam Brown (2) +4ZEC (2) + (2) +pier (1) +nickolay (1) +koljenovic (1) +fgius (1) +ca333 (1) +Zcash Company (1) Tom Ritter (1) -S. Matthew English (1) -Paragon Initiative Enterprises, LLC (1) -Louis Nyffenegger (1) +Stefano (1) +Oleksandr Iozhytsia (1) +Marius Kjærstad (1) Lars-Magnus Skog (1) -Jeffrey Walton (1) +Larry Ruane (1) +Kent (1) +JOSEPH NICHOLAS R. ALCANTARA (1) +Igor Mikheiko (1) +Homu (1) Gaurav Rana (1) +Franck De Girolami (1) Ethan Heilman (1) -Eran Tromer (1) -Christian von Roques (1) -Chirag Davé (1) -Cameron Boehmer (1) -Bryan Stitt (1) -Bitcoin Error Log (1) +Boris P (1) Alex (1) -4ZEC (1) +Alberto Garoffolo (1) diff --git a/doc/release-notes/release-notes-v2.0.20.md b/doc/release-notes/release-notes-v2.0.20.md new file mode 100644 index 0000000000..089c2a6515 --- /dev/null +++ b/doc/release-notes/release-notes-v2.0.20.md @@ -0,0 +1,61 @@ +Changelog +========= + +Jack Grigg (1): + Cast uint8* in InterruptibleRecv to char* for recv + +MarcoOl94 (25): + Added fix for deadlock issue (208) and introduced GUnit test to verify it + leftover from previous commit + Made lisstransactions filterable by address + Modified and reintroduced test_foundersreward + Made changes suggested by @abi87 + Reversed the txes' order returned by listtransactions + Changed requested by albi87 + Introduced changes requested from albi87 + Reintroduced Account for backward compatibility + Made changes proposed by @alsala + modified help of listtransactions + Refactored wallet.cpp + Modified test_foundersreward with albi87's changes + Implemented changes requested by alsala + Removed useless asserts + Extended test_checkblock to verify correct send of rewards after the halving + Removed GetFilteredTransaction and modified OrderedTxItems + Removed GetFilteredTransaction and modified orederedTxItems to match previous serialization + Merged listtransactions' test + Some refactor on listtransactions test + Some changed comments + Removed unused variable + changed passing-parameter in OrderderTxItems + Fixed test wallet_shieldcoinbase + Introduced break in orderedTxItems + +Miles Manley (1): + Update libsodium download-path + +Sean Bowe (1): + Fix of CVE-2017-18350 + +abi87 (5): + cleaned up useless includes + minor gtest cleanup + minor gtest cleanup + fixed compilation error and cleaned formatting + removed commented out test deemed useless + +cronicc (13): + Bump version to 2.0.19-1 + Fix socket.settimeout python error on MacOS + Workaround for 'Connection reset by peer' rpc test failures + fetch-params.sh bugfix + Add test for fetch-params.sh using all supported DL methods + Refactor rpc-tests.sh + Add --rpc-exclude --rpc-split options for refactored rpc-tests.sh + Add travis-ci CI/CD pipeline part1 + Set mainnet/testnet checkpoint blocks + Set deprecation block 736000 + Add test instructions to README.md + Set version to 2.0.20 + Generate manpages +