Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/bitcoin/bitcoin into btc_…
Browse files Browse the repository at this point in the history
…200922
  • Loading branch information
decryp2kanon committed Sep 22, 2020
2 parents 86bee64 + 7737603 commit 60a8898
Show file tree
Hide file tree
Showing 29 changed files with 650 additions and 182 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ BITCOIN_CORE_H = \
script/signingprovider.h \
script/standard.h \
shutdown.h \
signet.h \
streams.h \
support/allocators/secure.h \
support/allocators/zeroafterfree.h \
Expand Down Expand Up @@ -322,6 +323,7 @@ libbitcoin_server_a_SOURCES = \
rpc/server.cpp \
script/sigcache.cpp \
shutdown.cpp \
signet.cpp \
timedata.cpp \
torcontrol.cpp \
txdb.cpp \
Expand Down
7 changes: 7 additions & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ FUZZ_TARGETS = \
test/fuzz/secp256k1_ecdsa_signature_parse_der_lax \
test/fuzz/service_deserialize \
test/fuzz/signature_checker \
test/fuzz/signet \
test/fuzz/snapshotmetadata_deserialize \
test/fuzz/span \
test/fuzz/spanparsing \
Expand Down Expand Up @@ -1129,6 +1130,12 @@ test_fuzz_signature_checker_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_signature_checker_LDFLAGS = $(FUZZ_SUITE_LDFLAGS_COMMON)
test_fuzz_signature_checker_SOURCES = test/fuzz/signature_checker.cpp

test_fuzz_signet_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
test_fuzz_signet_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_signet_LDADD = $(FUZZ_SUITE_LD_COMMON)
test_fuzz_signet_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_signet_SOURCES = test/fuzz/signet.cpp

test_fuzz_snapshotmetadata_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSNAPSHOTMETADATA_DESERIALIZE=1
test_fuzz_snapshotmetadata_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_snapshotmetadata_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
Expand Down
105 changes: 102 additions & 3 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <chainparamsseeds.h>
#include <consensus/merkle.h>
#include <hash.h> // for signet block challenge hash
#include <tinyformat.h>
#include <util/system.h>
#include <util/strencodings.h>
Expand Down Expand Up @@ -63,6 +64,8 @@ class CMainParams : public CChainParams {
public:
CMainParams() {
strNetworkID = CBaseChainParams::MAIN;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22");
consensus.BIP34Height = 227931;
Expand Down Expand Up @@ -172,6 +175,8 @@ class CTestNetParams : public CChainParams {
public:
CTestNetParams() {
strNetworkID = CBaseChainParams::TESTNET;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105");
consensus.BIP34Height = 21111;
Expand Down Expand Up @@ -250,13 +255,104 @@ class CTestNetParams : public CChainParams {
}
};

/**
* Signet
*/
class SigNetParams : public CChainParams {
public:
explicit SigNetParams(const ArgsManager& args) {
std::vector<uint8_t> bin;
vSeeds.clear();

if (!args.IsArgSet("-signetchallenge")) {
LogPrintf("Using default signet network\n");
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
vSeeds.emplace_back("178.128.221.177");
vSeeds.emplace_back("2a01:7c8:d005:390::5");
vSeeds.emplace_back("ntv3mtqw5wt63red.onion:38333");
} else {
const auto signet_challenge = args.GetArgs("-signetchallenge");
if (signet_challenge.size() != 1) {
throw std::runtime_error(strprintf("%s: -signetchallenge cannot be multiple values.", __func__));
}
bin = ParseHex(signet_challenge[0]);

LogPrintf("Signet with challenge %s\n", signet_challenge[0]);
}

if (args.IsArgSet("-signetseednode")) {
vSeeds = args.GetArgs("-signetseednode");
}

strNetworkID = CBaseChainParams::SIGNET;
consensus.signet_blocks = true;
consensus.signet_challenge.assign(bin.begin(), bin.end());
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP34Height = 1;
consensus.BIP65Height = 1;
consensus.BIP66Height = 1;
consensus.CSVHeight = 1;
consensus.SegwitHeight = 1;
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1916;
consensus.nMinerConfirmationWindow = 2016;
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008

// message start is defined as the first 4 bytes of the sha256d of the block script
CHashWriter h(SER_DISK, 0);
h << consensus.signet_challenge;
uint256 hash = h.GetHash();
memcpy(pchMessageStart, hash.begin(), 4);
LogPrintf("Signet derived magic (message start): %s\n", HexStr({pchMessageStart, pchMessageStart + 4}));

nDefaultPort = 38333;
nPruneAfterHeight = 1000;
m_assumed_blockchain_size = 0;
m_assumed_chain_state_size = 0;

genesis = CreateGenesisBlock(1598918400, 52613770, 0x1e0377ae, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));

vFixedSeeds.clear();

base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};

bech32_hrp = "tb";

fDefaultConsistencyChecks = false;
fRequireStandard = true;
m_is_test_chain = true;
m_is_mockable_chain = false;

chainTxData = ChainTxData{
0,
0,
0
};
}
};

/**
* Regression test
*/
class CRegTestParams : public CChainParams {
public:
explicit CRegTestParams(const ArgsManager& args) {
strNetworkID = CBaseChainParams::REGTEST;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
consensus.nSubsidyHalvingInterval = 150;
consensus.BIP16Exception = uint256();
consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
Expand Down Expand Up @@ -391,12 +487,15 @@ const CChainParams &Params() {

std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
if (chain == CBaseChainParams::MAIN) {
return std::unique_ptr<CChainParams>(new CMainParams());
else if (chain == CBaseChainParams::TESTNET)
} else if (chain == CBaseChainParams::TESTNET) {
return std::unique_ptr<CChainParams>(new CTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
} else if (chain == CBaseChainParams::SIGNET) {
return std::unique_ptr<CChainParams>(new SigNetParams(gArgs));
} else if (chain == CBaseChainParams::REGTEST) {
return std::unique_ptr<CChainParams>(new CRegTestParams(gArgs));
}
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}

Expand Down
16 changes: 11 additions & 5 deletions src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

const std::string CBaseChainParams::MAIN = "main";
const std::string CBaseChainParams::TESTNET = "test";
const std::string CBaseChainParams::SIGNET = "signet";
const std::string CBaseChainParams::REGTEST = "regtest";

void SetupChainParamsBaseOptions(ArgsManager& argsman)
Expand All @@ -23,6 +24,9 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signet", "Use the signet chain. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-signetseednode", "Specify a seed node for the signet network, in the hostname[:port] format, e.g. sig.net:1234 (may be used multiple times to specify multiple seed nodes; defaults to the global default signet test network seed node(s))", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
}

static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
Expand All @@ -35,14 +39,16 @@ const CBaseChainParams& BaseParams()

std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
if (chain == CBaseChainParams::MAIN) {
return MakeUnique<CBaseChainParams>("", 8332);
else if (chain == CBaseChainParams::TESTNET)
} else if (chain == CBaseChainParams::TESTNET) {
return MakeUnique<CBaseChainParams>("testnet3", 18332);
else if (chain == CBaseChainParams::REGTEST)
} else if (chain == CBaseChainParams::SIGNET) {
return MakeUnique<CBaseChainParams>("signet", 38332);
} else if (chain == CBaseChainParams::REGTEST) {
return MakeUnique<CBaseChainParams>("regtest", 18443);
else
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}

void SelectBaseParams(const std::string& chain)
Expand Down
1 change: 1 addition & 0 deletions src/chainparamsbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class CBaseChainParams
/** Chain name strings */
static const std::string MAIN;
static const std::string TESTNET;
static const std::string SIGNET;
static const std::string REGTEST;
///@}

Expand Down
7 changes: 7 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ struct Params {
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
uint256 nMinimumChainWork;
uint256 defaultAssumeValid;

/**
* If true, witness commitments contain a payload equal to a Bitcoin Script solution
* to the signet challenge. See BIP325.
*/
bool signet_blocks{false};
std::vector<uint8_t> signet_challenge;
};
} // namespace Consensus

Expand Down
27 changes: 27 additions & 0 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
#include <primitives/transaction.h>
#include <primitives/block.h>

/** Index marker for when no witness commitment is present in a coinbase transaction. */
static constexpr int NO_WITNESS_COMMITMENT{-1};

/** Minimum size of a witness commitment structure. Defined in BIP 141. **/
static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38};

/** A "reason" why a transaction was invalid, suitable for determining whether the
* provider of the transaction should be banned/ignored/disconnected/etc.
*/
Expand Down Expand Up @@ -151,4 +157,25 @@ static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
}

/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */
inline int GetWitnessCommitmentIndex(const CBlock& block)
{
int commitpos = NO_WITNESS_COMMITMENT;
if (!block.vtx.empty()) {
for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
const CTxOut& vout = block.vtx[0]->vout[o];
if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT &&
vout.scriptPubKey[0] == OP_RETURN &&
vout.scriptPubKey[1] == 0x24 &&
vout.scriptPubKey[2] == 0xaa &&
vout.scriptPubKey[3] == 0x21 &&
vout.scriptPubKey[4] == 0xa9 &&
vout.scriptPubKey[5] == 0xed) {
commitpos = o;
}
}
}
return commitpos;
}

#endif // BITCOIN_CONSENSUS_VALIDATION_H
73 changes: 40 additions & 33 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";

static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
static const uint64_t RANDOMIZER_ID_ADDRCACHE = 0x1cf2e4ddd306dda9ULL; // SHA256("addrcache")[0:8]
//
// Global state variables
//
Expand Down Expand Up @@ -621,32 +622,6 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
return true;
}

void CNode::SetSendVersion(int nVersionIn)
{
// Send version may only be changed in the version message, and
// only one version message is allowed per session. We can therefore
// treat this value as const and even atomic as long as it's only used
// once a version message has been successfully processed. Any attempt to
// set this twice is an error.
if (nSendVersion != 0) {
error("Send version already set for node: %i. Refusing to change from %i to %i", id, nSendVersion, nVersionIn);
} else {
nSendVersion = nVersionIn;
}
}

int CNode::GetSendVersion() const
{
// The send version should always be explicitly set to
// INIT_PROTO_VERSION rather than using this value until SetSendVersion
// has been called.
if (nSendVersion == 0) {
error("Requesting unset send version for node: %i. Using %i", id, INIT_PROTO_VERSION);
return INIT_PROTO_VERSION;
}
return nSendVersion;
}

int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
{
// copy data to temporary parsing buffer
Expand Down Expand Up @@ -1193,7 +1168,7 @@ void CConnman::InactivityCheck(CNode *pnode)
LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
pnode->fDisconnect = true;
}
else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
else if (nTime - pnode->nLastRecv > (pnode->GetCommonVersion() > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
{
LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
pnode->fDisconnect = true;
Expand Down Expand Up @@ -2560,15 +2535,47 @@ std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pc
return addresses;
}

std::vector<CAddress> CConnman::GetAddresses(Network requestor_network, size_t max_addresses, size_t max_pct)
std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addresses, size_t max_pct)
{
SOCKET socket;
WITH_LOCK(requestor.cs_hSocket, socket = requestor.hSocket);
auto local_socket_bytes = GetBindAddress(socket).GetAddrBytes();
uint64_t cache_id = GetDeterministicRandomizer(RANDOMIZER_ID_ADDRCACHE)
.Write(requestor.addr.GetNetwork())
.Write(local_socket_bytes.data(), local_socket_bytes.size())
.Finalize();
const auto current_time = GetTime<std::chrono::microseconds>();
if (m_addr_response_caches.find(requestor_network) == m_addr_response_caches.end() ||
m_addr_response_caches[requestor_network].m_update_addr_response < current_time) {
m_addr_response_caches[requestor_network].m_addrs_response_cache = GetAddresses(max_addresses, max_pct);
m_addr_response_caches[requestor_network].m_update_addr_response = current_time + std::chrono::hours(21) + GetRandMillis(std::chrono::hours(6));
auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
CachedAddrResponse& cache_entry = r.first->second;
if (cache_entry.m_cache_entry_expiration < current_time) { // If emplace() added new one it has expiration 0.
cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct);
// Choosing a proper cache lifetime is a trade-off between the privacy leak minimization
// and the usefulness of ADDR responses to honest users.
//
// Longer cache lifetime makes it more difficult for an attacker to scrape
// enough AddrMan data to maliciously infer something useful.
// By the time an attacker scraped enough AddrMan records, most of
// the records should be old enough to not leak topology info by
// e.g. analyzing real-time changes in timestamps.
//
// It takes only several hundred requests to scrape everything from an AddrMan containing 100,000 nodes,
// so ~24 hours of cache lifetime indeed makes the data less inferable by the time
// most of it could be scraped (considering that timestamps are updated via
// ADDR self-announcements and when nodes communicate).
// We also should be robust to those attacks which may not require scraping *full* victim's AddrMan
// (because even several timestamps of the same handful of nodes may leak privacy).
//
// On the other hand, longer cache lifetime makes ADDR responses
// outdated and less useful for an honest requestor, e.g. if most nodes
// in the ADDR response are no longer active.
//
// However, the churn in the network is known to be rather low. Since we consider
// nodes to be "terrible" (see IsTerrible()) if the timestamps are older than 30 days,
// max. 24 hours of "penalty" due to cache shouldn't make any meaningful difference
// in terms of the freshness of the response.
cache_entry.m_cache_entry_expiration = current_time + std::chrono::hours(21) + GetRandMillis(std::chrono::hours(6));
}
return m_addr_response_caches[requestor_network].m_addrs_response_cache;
return cache_entry.m_addrs_response_cache;
}

bool CConnman::AddNode(const std::string& strNode)
Expand Down
Loading

0 comments on commit 60a8898

Please sign in to comment.