Merge branch 'dev' into danger
Conflicts: src/net.cpp
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2016-2020 The Hush developers
|
||||
# Copyright (c) 2016-2021 The Hush developers
|
||||
# Released under the GPLv3
|
||||
|
||||
TOPDIR=${TOPDIR:-$(git rev-parse --show-toplevel)}
|
||||
@@ -12,6 +12,15 @@ HUSHTX=${HUSHTX:-$SRCDIR/hush-tx}
|
||||
|
||||
[ ! -x $HUSHD ] && echo "$HUSHD not found or not executable." && exit 1
|
||||
|
||||
# Check if help2man is installed
|
||||
# If not then display error to user and exit
|
||||
if ! command -v help2man &> /dev/null
|
||||
then
|
||||
echo "help2man could not be found"
|
||||
echo "Please install from your Linux package manager and try again"
|
||||
exit
|
||||
fi
|
||||
|
||||
# use this if hushd is not running
|
||||
#HUSHVER="v3.6.2"
|
||||
HUSHVER=$(./src/hushd --version|head -n1|cut -d' ' -f4|cut -d- -f1)
|
||||
|
||||
@@ -215,8 +215,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId)
|
||||
info.fInTried = true;
|
||||
}
|
||||
|
||||
void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||
{
|
||||
void CAddrMan::Good_(const CService& addr, bool test_before_evict, int64_t nTime) {
|
||||
int nId;
|
||||
CAddrInfo* pinfo = Find(addr, &nId);
|
||||
|
||||
@@ -258,12 +257,101 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||
if (nUBucket == -1)
|
||||
return;
|
||||
|
||||
LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
|
||||
// which tried bucket to move the entry to
|
||||
int tried_bucket = info.GetTriedBucket(nKey,m_asmap);
|
||||
int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket);
|
||||
|
||||
// move nId to the tried tables
|
||||
MakeTried(info, nId);
|
||||
// Will moving this address into tried evict another entry?
|
||||
if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
|
||||
LogPrint("addrman", "Collision inserting element into tried table, moving %s to m_tried_collisions=%d\n", addr.ToString(), m_tried_collisions.size());
|
||||
if (m_tried_collisions.size() < ADDRMAN_SET_TRIED_COLLISION_SIZE) {
|
||||
m_tried_collisions.insert(nId);
|
||||
}
|
||||
} else {
|
||||
LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
|
||||
printf("%s: Moving %s to tried\n", __func__, addr.ToString().c_str() );
|
||||
|
||||
// move nId to the tried tables
|
||||
MakeTried(info, nId);
|
||||
}
|
||||
}
|
||||
|
||||
void CAddrMan::ResolveCollisions_() {
|
||||
for (std::set<int>::iterator it = m_tried_collisions.begin(); it != m_tried_collisions.end();) {
|
||||
int id_new = *it;
|
||||
bool erase_collision = false;
|
||||
|
||||
// If id_new not found in mapInfo remove it from m_tried_collisions
|
||||
if (mapInfo.count(id_new) != 1) {
|
||||
erase_collision = true;
|
||||
} else {
|
||||
CAddrInfo& info_new = mapInfo[id_new];
|
||||
|
||||
// Which tried bucket to move the entry to.
|
||||
int tried_bucket = info_new.GetTriedBucket(nKey,m_asmap);
|
||||
int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket);
|
||||
if (!info_new.IsValid()) { // id_new may no longer map to a valid address
|
||||
erase_collision = true;
|
||||
} else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty
|
||||
|
||||
// Get the to-be-evicted address that is being tested
|
||||
int id_old = vvTried[tried_bucket][tried_bucket_pos];
|
||||
CAddrInfo& info_old = mapInfo[id_old];
|
||||
|
||||
// Has successfully connected in last X hours
|
||||
if (GetTime() - info_old.nLastSuccess < ADDRMAN_REPLACEMENT_HOURS*(60*60)) {
|
||||
erase_collision = true;
|
||||
} else if (GetTime() - info_old.nLastTry < ADDRMAN_REPLACEMENT_HOURS*(60*60)) { // attempted to connect and failed in last X hours
|
||||
|
||||
// Give address at least 60 seconds to successfully connect
|
||||
if (GetTime() - info_old.nLastTry > 60) {
|
||||
LogPrint("addrman", "Swapping %s for %s in tried table\n", info_new.ToString(), info_old.ToString());
|
||||
|
||||
// Replaces an existing address already in the tried table with the new address
|
||||
Good_(info_new, false, GetTime());
|
||||
erase_collision = true;
|
||||
}
|
||||
}
|
||||
} else { // Collision is not actually a collision anymore
|
||||
Good_(info_new, false, GetTime());
|
||||
erase_collision = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (erase_collision) {
|
||||
m_tried_collisions.erase(it++);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAddrInfo CAddrMan::SelectTriedCollision_() {
|
||||
if (m_tried_collisions.size() == 0) return CAddrInfo();
|
||||
|
||||
std::set<int>::iterator it = m_tried_collisions.begin();
|
||||
|
||||
// Selects a random element from m_tried_collisions
|
||||
std::advance(it, GetRandInt(m_tried_collisions.size()));
|
||||
int id_new = *it;
|
||||
|
||||
// If id_new not found in mapInfo remove it from m_tried_collisions
|
||||
if (mapInfo.count(id_new) != 1) {
|
||||
m_tried_collisions.erase(it);
|
||||
return CAddrInfo();
|
||||
}
|
||||
|
||||
CAddrInfo& newInfo = mapInfo[id_new];
|
||||
|
||||
// which tried bucket to move the entry to
|
||||
int tried_bucket = newInfo.GetTriedBucket(nKey,m_asmap);
|
||||
int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket);
|
||||
int id_old = vvTried[tried_bucket][tried_bucket_pos];
|
||||
|
||||
return mapInfo[id_old];
|
||||
}
|
||||
|
||||
|
||||
bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
{
|
||||
if (!addr.IsRoutable())
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2012 Pieter Wuille
|
||||
// Copyright (c) 2016-2020 The Hush developers
|
||||
// Copyright (c) 2016-2021 The Hush developers
|
||||
// Distributed under the GPLv3 software license, see the accompanying
|
||||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
@@ -31,7 +30,6 @@
|
||||
#include "clientversion.h"
|
||||
#include "hash.h"
|
||||
#include "netbase.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
@@ -43,7 +41,6 @@
|
||||
class CAddrInfo : public CAddress
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
//! last try whatsoever by us (memory only)
|
||||
int64_t nLastTry;
|
||||
@@ -174,12 +171,18 @@ public:
|
||||
//! after how many failed attempts we give up on a new node
|
||||
#define ADDRMAN_RETRIES 3
|
||||
|
||||
//! the maximum number of tried addr collisions to store
|
||||
#define ADDRMAN_SET_TRIED_COLLISION_SIZE 10
|
||||
|
||||
//! how many successive failures are allowed ...
|
||||
#define ADDRMAN_MAX_FAILURES 10
|
||||
|
||||
//! ... in at least this many days
|
||||
#define ADDRMAN_MIN_FAIL_DAYS 7
|
||||
|
||||
//! how recent a successful connection should be before we allow an address to be evicted from tried
|
||||
#define ADDRMAN_REPLACEMENT_HOURS 4
|
||||
|
||||
//! the maximum percentage of nodes to return in a getaddr call
|
||||
#define ADDRMAN_GETADDR_MAX_PCT 23
|
||||
|
||||
@@ -220,6 +223,12 @@ private:
|
||||
//! list of "new" buckets
|
||||
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
|
||||
|
||||
//! last time Good was called (memory only)
|
||||
int64_t nLastGood;
|
||||
|
||||
//! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discpline used to resolve these collisions.
|
||||
std::set<int> m_tried_collisions;
|
||||
|
||||
protected:
|
||||
//! secret key to randomize bucket select with
|
||||
uint256 nKey;
|
||||
@@ -244,7 +253,14 @@ protected:
|
||||
void ClearNew(int nUBucket, int nUBucketPos);
|
||||
|
||||
//! Mark an entry "good", possibly moving it from "new" to "tried".
|
||||
void Good_(const CService &addr, int64_t nTime);
|
||||
void Good_(const CService &addr, bool test_before_evict, int64_t time);
|
||||
|
||||
|
||||
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
|
||||
void ResolveCollisions_();
|
||||
|
||||
//! Return a random to-be-evicted tried table address.
|
||||
CAddrInfo SelectTriedCollision_();
|
||||
|
||||
//! Add an entry to the "new" table.
|
||||
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
|
||||
@@ -583,12 +599,12 @@ public:
|
||||
}
|
||||
|
||||
//! Mark an entry as accessible.
|
||||
void Good(const CService &addr, int64_t nTime = GetTime())
|
||||
void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetTime())
|
||||
{
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Good_(addr, nTime);
|
||||
Good_(addr, test_before_evict, nTime);
|
||||
Check();
|
||||
}
|
||||
}
|
||||
@@ -604,9 +620,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose an address to connect to.
|
||||
*/
|
||||
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
|
||||
void ResolveCollisions()
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
ResolveCollisions_();
|
||||
Check();
|
||||
}
|
||||
|
||||
//! Randomly select an address in tried that another address is attempting to evict.
|
||||
CAddrInfo SelectTriedCollision()
|
||||
{
|
||||
CAddrInfo ret;
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
ret = SelectTriedCollision_();
|
||||
Check();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Choose an address to connect to.
|
||||
CAddrInfo Select(bool newOnly = false)
|
||||
{
|
||||
CAddrInfo addrRet;
|
||||
|
||||
17
src/net.cpp
17
src/net.cpp
@@ -1442,6 +1442,7 @@ void ThreadOpenConnections()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initiate network connections
|
||||
int64_t nStart = GetTime();
|
||||
|
||||
@@ -1512,10 +1513,18 @@ void ThreadOpenConnections()
|
||||
}
|
||||
}
|
||||
|
||||
int64_t nANow = GetTime();
|
||||
int nTries = 0;
|
||||
int64_t nNow = GetTime();
|
||||
int nTries = 0;
|
||||
|
||||
addrman.ResolveCollisions();
|
||||
|
||||
while (true) {
|
||||
CAddrInfo addr = addrman.Select(fFeeler);
|
||||
CAddrInfo addr = addrman.SelectTriedCollision();
|
||||
|
||||
// SelectTriedCollision returns an invalid address if it is empty.
|
||||
if (!fFeeler || !addr.IsValid()) {
|
||||
addr = addrman.Select(fFeeler);
|
||||
}
|
||||
|
||||
// if we selected an invalid address, restart
|
||||
if (!addr.IsValid() || setConnected.count(addr.GetGroup(addrman.m_asmap)) || IsLocal(addr))
|
||||
@@ -1532,7 +1541,7 @@ void ThreadOpenConnections()
|
||||
continue;
|
||||
|
||||
// only consider very recently tried nodes after 30 failed attempts
|
||||
if (nANow - addr.nLastTry < 600 && nTries < 30)
|
||||
if (nNow - addr.nLastTry < 600 && nTries < 30)
|
||||
continue;
|
||||
|
||||
/* TODO: port this code
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2020 The Hush developers
|
||||
// Copyright (c) 2016-2021 The Hush developers
|
||||
// Distributed under the GPLv3 software license, see the accompanying
|
||||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
/******************************************************************************
|
||||
@@ -1266,7 +1266,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& m
|
||||
if (fMissingInputs) {
|
||||
throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
|
||||
}
|
||||
throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
|
||||
throw JSONRPCError(RPC_TRANSACTION_ERROR, strprintf("Invalid state: %s", state.GetRejectReason()));
|
||||
}
|
||||
}
|
||||
} else if (fHaveChain) {
|
||||
@@ -1274,9 +1274,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& m
|
||||
}
|
||||
LogPrintf("%s: Relaying raw tx to mempool\n", __FUNCTION__);
|
||||
RelayTransaction(tx);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
NSPV_broadcast((char *)params[0].get_str().c_str());
|
||||
}
|
||||
return hashTx.GetHex();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "test/test_bitcoin.h"
|
||||
#include <string>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "hash.h"
|
||||
#include "random.h"
|
||||
|
||||
@@ -49,6 +48,17 @@ public:
|
||||
{
|
||||
CAddrMan::Delete(nId);
|
||||
}
|
||||
|
||||
// Simulates connection failure so that we can test eviction of offline nodes
|
||||
void SimConnFail(CService& addr)
|
||||
{
|
||||
int64_t nLastSuccess = 1;
|
||||
Good_(addr, true, nLastSuccess); // Set last good connection in the deep past.
|
||||
|
||||
bool count_failure = false;
|
||||
int64_t nLastTry = GetAdjustedTime()-61;
|
||||
Attempt(addr, count_failure, nLastTry);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
|
||||
@@ -519,4 +529,155 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
// than 64 buckets.
|
||||
BOOST_CHECK(buckets.size() > 64);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
// Empty addrman should return blank addrman info.
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
|
||||
// Add twenty two addresses.
|
||||
CNetAddr source = ResolveIP("252.2.2.2");
|
||||
for (unsigned int i = 1; i < 23; i++) {
|
||||
CService addr = ResolveService("250.1.1."+std::to_string(i));
|
||||
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||
addrman.Good(addr);
|
||||
|
||||
// No collisions yet.
|
||||
BOOST_CHECK(addrman.size() == i);
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
// Ensure Good handles duplicates well.
|
||||
for (unsigned int i = 1; i < 23; i++) {
|
||||
CService addr = ResolveService("250.1.1."+std::to_string(i));
|
||||
addrman.Good(addr);
|
||||
|
||||
BOOST_CHECK(addrman.size() == 22);
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_noevict)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
// Add twenty two addresses.
|
||||
CNetAddr source = ResolveIP("252.2.2.2");
|
||||
for (unsigned int i = 1; i < 23; i++) {
|
||||
CService addr = ResolveService("250.1.1."+std::to_string(i));
|
||||
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||
addrman.Good(addr);
|
||||
|
||||
// No collision yet.
|
||||
BOOST_CHECK(addrman.size() == i);
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
// Collision between 23 and 19.
|
||||
CService addr23 = ResolveService("250.1.1.23");
|
||||
addrman.Add(CAddress(addr23, NODE_NONE), source);
|
||||
addrman.Good(addr23);
|
||||
|
||||
BOOST_CHECK(addrman.size() == 23);
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.19:0");
|
||||
|
||||
// 23 should be discarded and 19 not evicted.
|
||||
addrman.ResolveCollisions();
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
|
||||
// Lets create two collisions.
|
||||
for (unsigned int i = 24; i < 33; i++) {
|
||||
CService addr = ResolveService("250.1.1."+std::to_string(i));
|
||||
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||
addrman.Good(addr);
|
||||
|
||||
BOOST_CHECK(addrman.size() == i);
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
// Cause a collision.
|
||||
CService addr33 = ResolveService("250.1.1.33");
|
||||
addrman.Add(CAddress(addr33, NODE_NONE), source);
|
||||
addrman.Good(addr33);
|
||||
BOOST_CHECK(addrman.size() == 33);
|
||||
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.27:0");
|
||||
|
||||
// Cause a second collision.
|
||||
addrman.Add(CAddress(addr23, NODE_NONE), source);
|
||||
addrman.Good(addr23);
|
||||
BOOST_CHECK(addrman.size() == 33);
|
||||
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() != "[::]:0");
|
||||
addrman.ResolveCollisions();
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_evictionworks)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
// Empty addrman should return blank addrman info.
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
|
||||
// Add twenty two addresses.
|
||||
CNetAddr source = ResolveIP("252.2.2.2");
|
||||
for (unsigned int i = 1; i < 23; i++) {
|
||||
CService addr = ResolveService("250.1.1."+std::to_string(i));
|
||||
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||
addrman.Good(addr);
|
||||
|
||||
// No collision yet.
|
||||
BOOST_CHECK(addrman.size() == i);
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
// Collision between 23 and 19.
|
||||
CService addr = ResolveService("250.1.1.23");
|
||||
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||
addrman.Good(addr);
|
||||
|
||||
BOOST_CHECK(addrman.size() == 23);
|
||||
CAddrInfo info = addrman.SelectTriedCollision();
|
||||
BOOST_CHECK(info.ToString() == "250.1.1.19:0");
|
||||
|
||||
// Ensure test of address fails, so that it is evicted.
|
||||
addrman.SimConnFail(info);
|
||||
|
||||
// Should swap 23 for 19.
|
||||
addrman.ResolveCollisions();
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
|
||||
// If 23 was swapped for 19, then this should cause no collisions.
|
||||
addrman.Add(CAddress(addr, NODE_NONE), source);
|
||||
addrman.Good(addr);
|
||||
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
|
||||
// If we insert 19 is should collide with 23.
|
||||
CService addr19 = ResolveService("250.1.1.19");
|
||||
addrman.Add(CAddress(addr19, NODE_NONE), source);
|
||||
addrman.Good(addr19);
|
||||
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.23:0");
|
||||
|
||||
addrman.ResolveCollisions();
|
||||
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1473,7 +1473,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
}
|
||||
|
||||
//// debug print
|
||||
LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
|
||||
LogPrintf("AddToWallet %s at height %d %s%s\n", wtxIn.GetHash().ToString(), hush_blockheight(wtxIn.hashBlock), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
|
||||
|
||||
// Write to disk
|
||||
if (fInsertedNew || fUpdated)
|
||||
|
||||
Reference in New Issue
Block a user