Compare commits

...

20 Commits

Author SHA1 Message Date
Sai Raj
6ec6ee4b96
Merge pull request #2 from ranchimall/dev
Max-Reorg-Depth
2021-06-20 15:14:51 +05:30
sairajzero
f9b49f3a67 remove old binaries 2021-06-20 15:10:37 +05:30
sairajzero
1ff115d7de Max-Reorg-Depth 2021-06-19 15:22:26 +05:30
Sai Raj
d34c2ce7f7
Merge branch 'floblockchain:flo-master' into flo-master 2021-06-18 19:34:52 +05:30
Chris Chrysostom
8708d4bc17
Regtest ports (#18)
* Ignore IntelliJ files

* Regtest RPC Port to 17413
2020-02-04 17:37:00 -07:00
Jeremiah Buddenhagen
72120bff0d 0.15.2.1 2019-11-15 21:25:50 -08:00
Wladimir J. van der Laan
cba88b4c54 net: Improve and document SOCKS code
Make the SOCKS code more consistent, and document the constants used.
2019-11-15 21:25:09 -08:00
Jeremiah Buddenhagen
cbaf28e4dd sign floData for all transactions 2019-11-15 21:24:28 -08:00
Sky Young
ffa312c126 Remove prepended text: from floData sent from UI 2019-11-15 21:23:32 -08:00
bitspill
6af88ae751
Merge pull request #11 from bitspill/versionBump
bump version and copyright year
2019-04-04 13:17:28 -07:00
bitspill
0786249978
Merge pull request #8 from OstlerDev/increase-max-tx-chain
Increase Maximum utxo chain to 1250 (50x increase)
2019-04-04 13:17:05 -07:00
Sky Young
818b91b454
Set Ancestor/Descendant Size limit to 1.75MB
Rational for 1.75MB limit: https://github.com/floblockchain/flo/pull/8#issuecomment-458666055
Comment documenting testing of values: https://github.com/floblockchain/flo/pull/8#issuecomment-460356226
2019-02-04 11:24:11 -07:00
Jeremiah Buddenhagen
3da8e84238 bump version and copyright year 2019-01-29 11:24:31 -08:00
Sky Young
0b8b8f16c6
Increase Maximum utxo chain to 1250 2019-01-29 10:10:35 -07:00
Sky Young
df02b9c155
Merge pull request #1 from floblockchain/flo-master
Pull in changes from master
2019-01-29 09:06:56 -08:00
Jeremiah Buddenhagen
a33e124e82 version bump 2018-10-08 12:56:17 -07:00
Jeremiah Buddenhagen
2fe045194c nlr 2018-10-03 16:47:54 -07:00
Jeremiah Buddenhagen
998ac47e9a version bump 2018-10-01 15:59:32 -07:00
Jeremiah Buddenhagen
1ee6c75b74 checkpoint block 3,000,000 2018-10-01 15:57:35 -07:00
Jeremiah Buddenhagen
4d3b091eb2 CVE-2018-17144 fix
https://bitcoincore.org/en/2018/09/20/notice/
2018-10-01 15:28:46 -07:00
28 changed files with 409 additions and 86 deletions

5
.gitignore vendored
View File

@ -109,3 +109,8 @@ test/cache/*
libbitcoinconsensus.pc
contrib/devtools/split-debug.sh
#IntelliJ
*.iml
.idea/

View File

@ -142,7 +142,8 @@ To enable it, add **SendChangeToBack=1** in flo.conf (or) pass **-SendChangeToBa
### Added Multi-Wallet support for Linux :
Multi-wallet support allows the user to run more than 1 wallet simultaneously.
The Multi-wallet executable file is located in **bin/Linux**
The Multi-wallet executable file is located in **tmp/**
Copy the executable(binary) file to the flo binary files
To access multi-wallet run :
./multiWallet -create [walletName]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,10 +2,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 15)
define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_REVISION, 2)
define(_CLIENT_VERSION_BUILD, 1)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2017)
define(_COPYRIGHT_YEAR, 2019)
define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[FLO Core]])
AC_INIT([FLO Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/floblockchain/flo/issues],[flo],[https://flo.cash/])

View File

@ -1,5 +1,5 @@
---
name: "flo-linux-0.15"
name: "flo-linux-0.15.2.1"
enable_cache: true
suites:
- "trusty"

View File

@ -1,5 +1,5 @@
---
name: "flo-osx-0.15"
name: "flo-osx-0.15.2.1"
enable_cache: true
suites:
- "trusty"

View File

@ -1,5 +1,5 @@
---
name: "flo-win-0.15"
name: "flo-win-0.15.2.1"
enable_cache: true
suites:
- "trusty"

View File

@ -102,10 +102,10 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1554098766; // April 1st, 2019
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000011f1db4843f05806");
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000050b6f9f1c2494ad8"); // 3,000,000
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x4a8cb5ca397b7c92c270ccfa9139ffb93f7c5b9515e52486c635c7a1dee9d221"); // 2000000
consensus.defaultAssumeValid = uint256S("0x5ad3a302e3b1c681f0177411384ea03ee595a80a530c23a61f22839fae948e7f"); // 3,000,000
// Difficulty adjustments
consensus.nPowTargetSpacing = 40; // 40s block time
@ -139,6 +139,7 @@ public:
pchMessageStart[3] = 0xf1;
nDefaultPort = 7312;
nPruneAfterHeight = 100000;
nNlrLimit = 100; // 100 * ~40s = ~66 minutes
genesis = CreateGenesisBlock(1371488396, 1000112548, 0x1e0ffff0, 1, 100 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
@ -191,17 +192,20 @@ public:
{1796633, uint256S("0xc2da8b936a7f2c0de02aa0c6c45f3d971ebad78655255a945b0e60b62f27d445")},
{2094558, uint256S("0x946616c88286f32bfac15868456d87a86f8611e1f9b56594b81e46831ce43f81")},
{2532181, uint256S("0xcacd5149aaed1088ae1db997a741210b0525e941356104120f182f3159931c79")},
{3000000, uint256S("0x5ad3a302e3b1c681f0177411384ea03ee595a80a530c23a61f22839fae948e7f")},
}
};
chainTxData = ChainTxData{
// Data as of block cacd5149aaed1088ae1db997a741210b0525e941356104120f182f3159931c79 (height 2532181).
1515282818, // * UNIX timestamp of last known number of transactions
3223208, // * total number of transactions between genesis and that timestamp
// Data as of block 5ad3a302e3b1c681f0177411384ea03ee595a80a530c23a61f22839fae948e7f (height 3,000,000).
1538389345, // * UNIX timestamp of last known number of transactions
4563023, // * total number of transactions between genesis and that timestamp
// (the tx=... number in the SetBestChain debug.log lines)
0.04 // * estimated number of transactions per second after that timestamp
0.03 // * estimated number of transactions per second after that timestamp
};
// Max-Reorg (51% attack prevention)
nMaxReorganizationDepth = 55; // 55 at 1 minute block timespan is +/- 55 minutes.
nMinReorganizationPeers = 3;
}
};
@ -237,10 +241,10 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1530446401; // July 1, 2018 FLO future date
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000083540886d");
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000003dd47d3172"); // 230,000
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x4be79531ee8b0f410f0d8c8d785083acb4e14e5d54b0820502bc60f98a629b19"); //flo testnet block 20,000
consensus.defaultAssumeValid = uint256S("0xc2e6451240a580c3bfa5ddbfad1b001f8655e7c51d5c32c123e16f69c2d2b539"); // 230,000
// Difficulty adjustments
consensus.nPowTargetSpacing = 40; // 40s block time
@ -274,6 +278,7 @@ public:
pchMessageStart[3] = 0xf2;
nDefaultPort = 17312;
nPruneAfterHeight = 100000;
nNlrLimit = 50; // 50 * ~40s = ~33 minutes
genesis = CreateGenesisBlock(1371387277, 1000580675, 0x1e0ffff0, 1, 100 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
@ -303,14 +308,15 @@ public:
checkpointData = (CCheckpointData) {
{
{2056, uint256S("0xd3334db071731beaa651f10624c2fea1a5e8c6f9e50f0e602f86262938374148")},
{230000, uint256S("0xc2e6451240a580c3bfa5ddbfad1b001f8655e7c51d5c32c123e16f69c2d2b539")},
}
};
chainTxData = ChainTxData{
// flo: Data as of block 4be79531ee8b0f410f0d8c8d785083acb4e14e5d54b0820502bc60f98a629b19 (height 20000)
1515699893, // * UNIX timestamp of last known number of transactions
34572, // * total number of transactions between genesis and that timestamp
0.001454897737891917 // * estimated number of transactions per second after that timestamp
// flo: Data as of block c2e6451240a580c3bfa5ddbfad1b001f8655e7c51d5c32c123e16f69c2d2b539 (height 230,000)
1538135261, // * UNIX timestamp of last known number of transactions
265211, // * total number of transactions between genesis and that timestamp
0.01 // * estimated number of transactions per second after that timestamp
};
}
@ -387,6 +393,7 @@ public:
pchMessageStart[3] = 0xda;
nDefaultPort = 17412;
nPruneAfterHeight = 1000;
nNlrLimit = 10;
genesis = CreateGenesisBlock(1371387277, 0, 0x207fffff, 1, 100 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
@ -406,7 +413,7 @@ public:
fDefaultConsistencyChecks = true;
fRequireStandard = false;
fMineBlocksOnDemand = true;
fMineBlocksOnDemand = true;
// checkpointData = (CCheckpointData) {
// {

View File

@ -63,6 +63,7 @@ public:
const Consensus::Params& GetConsensus() const { return consensus; }
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
int GetDefaultPort() const { return nDefaultPort; }
int NoLargeReorgLimit() const { return nNlrLimit; }
const CBlock& GenesisBlock() const { return genesis; }
/** Default value for -checkmempool and -checkblockindex argument */
@ -80,6 +81,9 @@ public:
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
// Max-Reorg (51% attack prevention)
int MaxReorganizationDepth() const { return nMaxReorganizationDepth; }
int MinReorganizationPeers() const { return nMinReorganizationPeers; }
protected:
CChainParams() {}
@ -87,6 +91,7 @@ protected:
CMessageHeader::MessageStartChars pchMessageStart;
int nDefaultPort;
uint64_t nPruneAfterHeight;
int nNlrLimit;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
std::string strNetworkID;
@ -97,6 +102,9 @@ protected:
bool fMineBlocksOnDemand;
CCheckpointData checkpointData;
ChainTxData chainTxData;
// Max-Reorg (51% attack prevention)
int nMaxReorganizationDepth;
int nMinReorganizationPeers;
};
/**

View File

@ -58,7 +58,7 @@ class CBaseRegTestParams : public CBaseChainParams
public:
CBaseRegTestParams()
{
nRPCPort = 17313;
nRPCPort = 17413;
strDataDir = "regtest";
}
};

View File

@ -157,7 +157,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
return nSigOps;
}
bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs)
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
{
// Basic checks that don't depend on any context
if (tx.vin.empty())
@ -181,14 +181,12 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge");
}
// Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
if (fCheckDuplicateInputs) {
std::set<COutPoint> vInOutPoints;
for (const auto& txin : tx.vin)
{
if (!vInOutPoints.insert(txin.prevout).second)
return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate");
}
// Check for duplicate inputs - note that this check is slow (no longer skipped due to CVE-2018-17144)
std::set<COutPoint> vInOutPoints;
for (const auto& txin : tx.vin)
{
if (!vInOutPoints.insert(txin.prevout).second)
return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate");
}
if (tx.IsCoinBase())

View File

@ -17,7 +17,7 @@ class CValidationState;
/** Transaction validation functions */
/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, CValidationState& state, bool fCheckDuplicateInputs=true);
bool CheckTransaction(const CTransaction& tx, CValidationState& state);
namespace Consensus {
/**

View File

@ -22,6 +22,8 @@ static const unsigned char REJECT_NONSTANDARD = 0x40;
// static const unsigned char REJECT_DUST = 0x41; // part of BIP 61
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
static const unsigned char REJECT_CHECKPOINT = 0x43;
// Max-Reorg (51% attack prevention)
static const unsigned char REJECT_MAXREORGDEPTH = 0x44;
/** Capture information about block/transaction validation */
class CValidationState {

View File

@ -364,6 +364,8 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
strUsage += HelpMessageOpt("-maxreorg=<n>", strprintf(_("Set the Maximum reorg depth (default: %u)"), defaultChainParams->MaxReorganizationDepth())); //#51-Attk-prevention
strUsage += HelpMessageOpt("-minreorgpeers=<n>", strprintf(_("Set the Minimum amount of peers required to not allow reorgs. Peers must be greater than. (default: %u)"), defaultChainParams->MinReorganizationPeers())); //#51-Attk-prevention
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
@ -401,6 +403,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER));
strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXSENDBUFFER));
strUsage += HelpMessageOpt("-maxtimeadjustment", strprintf(_("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)"), DEFAULT_MAX_TIME_ADJUSTMENT));
strUsage += HelpMessageOpt("-nlrlimit=<n>", strprintf(_("Set the limit to be considered a large reorg, -nlrlimit=0 to disable NLR mode (default: %u)"), defaultChainParams->NoLargeReorgLimit()));
strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG));

View File

@ -1009,6 +1009,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// best equivalent proof of work) than the best header chain we know about.
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) &&
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
(chainActive.Height() - mi->second->nHeight < Params().MaxReorganizationDepth()) && //(51% attk prevention)
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth);
if (!send) {
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());

View File

@ -185,6 +185,48 @@ struct timeval MillisToTimeval(int64_t nTimeout)
return timeout;
}
/** SOCKS version */
enum SOCKSVersion: uint8_t {
SOCKS4 = 0x04,
SOCKS5 = 0x05
};
/** Values defined for METHOD in RFC1928 */
enum SOCKS5Method: uint8_t {
NOAUTH = 0x00, //! No authentication required
GSSAPI = 0x01, //! GSSAPI
USER_PASS = 0x02, //! Username/password
NO_ACCEPTABLE = 0xff, //! No acceptable methods
};
/** Values defined for CMD in RFC1928 */
enum SOCKS5Command: uint8_t {
CONNECT = 0x01,
BIND = 0x02,
UDP_ASSOCIATE = 0x03
};
/** Values defined for REP in RFC1928 */
enum SOCKS5Reply: uint8_t {
SUCCEEDED = 0x00, //! Succeeded
GENFAILURE = 0x01, //! General failure
NOTALLOWED = 0x02, //! Connection not allowed by ruleset
NETUNREACHABLE = 0x03, //! Network unreachable
HOSTUNREACHABLE = 0x04, //! Network unreachable
CONNREFUSED = 0x05, //! Connection refused
TTLEXPIRED = 0x06, //! TTL expired
CMDUNSUPPORTED = 0x07, //! Command not supported
ATYPEUNSUPPORTED = 0x08, //! Address type not supported
};
/** Values defined for ATYPE in RFC1928 */
enum SOCKS5Atyp: uint8_t {
IPV4 = 0x01,
DOMAINNAME = 0x03,
IPV6 = 0x04,
};
/** Status codes that can be returned by InterruptibleRecv */
enum class IntrRecvError {
OK,
Timeout,
@ -204,7 +246,7 @@ enum class IntrRecvError {
*
* @note This function requires that hSocket is in non-blocking mode.
*/
static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, const SOCKET& hSocket)
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const SOCKET& hSocket)
{
int64_t curTime = GetTimeMillis();
int64_t endTime = curTime + timeout;
@ -212,7 +254,7 @@ static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, cons
// 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
ssize_t ret = recv(hSocket, (char*)data, len, 0); // Optimistically try the recv first
if (ret > 0) {
len -= ret;
data += ret;
@ -243,24 +285,35 @@ static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, cons
return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
}
/** Credentials for proxy authentication */
struct ProxyCredentials
{
std::string username;
std::string password;
};
std::string Socks5ErrorString(int err)
/** Convert SOCKS5 reply to a an error message */
std::string Socks5ErrorString(uint8_t err)
{
switch(err) {
case 0x01: return "general failure";
case 0x02: return "connection not allowed";
case 0x03: return "network unreachable";
case 0x04: return "host unreachable";
case 0x05: return "connection refused";
case 0x06: return "TTL expired";
case 0x07: return "protocol error";
case 0x08: return "address type not supported";
default: return "unknown";
case SOCKS5Reply::GENFAILURE:
return "general failure";
case SOCKS5Reply::NOTALLOWED:
return "connection not allowed";
case SOCKS5Reply::NETUNREACHABLE:
return "network unreachable";
case SOCKS5Reply::HOSTUNREACHABLE:
return "host unreachable";
case SOCKS5Reply::CONNREFUSED:
return "connection refused";
case SOCKS5Reply::TTLEXPIRED:
return "TTL expired";
case SOCKS5Reply::CMDUNSUPPORTED:
return "protocol error";
case SOCKS5Reply::ATYPEUNSUPPORTED:
return "address type not supported";
default:
return "unknown";
}
}
@ -275,34 +328,34 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
}
// Accepted authentication methods
std::vector<uint8_t> vSocks5Init;
vSocks5Init.push_back(0x05);
vSocks5Init.push_back(SOCKSVersion::SOCKS5);
if (auth) {
vSocks5Init.push_back(0x02); // # METHODS
vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
vSocks5Init.push_back(0x02); // X'02' USERNAME/PASSWORD (RFC1929)
vSocks5Init.push_back(0x02); // Number of methods
vSocks5Init.push_back(SOCKS5Method::NOAUTH);
vSocks5Init.push_back(SOCKS5Method::USER_PASS);
} else {
vSocks5Init.push_back(0x01); // # METHODS
vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
vSocks5Init.push_back(0x01); // Number of methods
vSocks5Init.push_back(SOCKS5Method::NOAUTH);
}
ssize_t ret = send(hSocket, (const char*)vSocks5Init.data(), vSocks5Init.size(), MSG_NOSIGNAL);
if (ret != (ssize_t)vSocks5Init.size()) {
CloseSocket(hSocket);
return error("Error sending to proxy");
}
char pchRet1[2];
uint8_t pchRet1[2];
if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
CloseSocket(hSocket);
LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
return false;
}
if (pchRet1[0] != 0x05) {
if (pchRet1[0] != SOCKSVersion::SOCKS5) {
CloseSocket(hSocket);
return error("Proxy failed to initialize");
}
if (pchRet1[1] == 0x02 && auth) {
if (pchRet1[1] == SOCKS5Method::USER_PASS && auth) {
// Perform username/password authentication (as described in RFC1929)
std::vector<uint8_t> vAuth;
vAuth.push_back(0x01);
vAuth.push_back(0x01); // Current (and only) version of user/pass subnegotiation
if (auth->username.size() > 255 || auth->password.size() > 255)
return error("Proxy username or password too long");
vAuth.push_back(auth->username.size());
@ -315,7 +368,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
return error("Error sending authentication to proxy");
}
LogPrint(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
char pchRetA[2];
uint8_t pchRetA[2];
if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
CloseSocket(hSocket);
return error("Error reading proxy authentication response");
@ -324,17 +377,17 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
CloseSocket(hSocket);
return error("Proxy authentication unsuccessful");
}
} else if (pchRet1[1] == 0x00) {
} else if (pchRet1[1] == SOCKS5Method::NOAUTH) {
// Perform no authentication
} else {
CloseSocket(hSocket);
return error("Proxy requested wrong authentication method %02x", pchRet1[1]);
}
std::vector<uint8_t> vSocks5;
vSocks5.push_back(0x05); // VER protocol version
vSocks5.push_back(0x01); // CMD CONNECT
vSocks5.push_back(0x00); // RSV Reserved
vSocks5.push_back(0x03); // ATYP DOMAINNAME
vSocks5.push_back(SOCKSVersion::SOCKS5); // VER protocol version
vSocks5.push_back(SOCKS5Command::CONNECT); // CMD CONNECT
vSocks5.push_back(0x00); // RSV Reserved must be 0
vSocks5.push_back(SOCKS5Atyp::DOMAINNAME); // ATYP DOMAINNAME
vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function
vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
vSocks5.push_back((port >> 8) & 0xFF);
@ -344,7 +397,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
CloseSocket(hSocket);
return error("Error sending to proxy");
}
char pchRet2[4];
uint8_t pchRet2[4];
if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
CloseSocket(hSocket);
if (recvr == IntrRecvError::Timeout) {
@ -356,26 +409,26 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
return error("Error while reading proxy response");
}
}
if (pchRet2[0] != 0x05) {
if (pchRet2[0] != SOCKSVersion::SOCKS5) {
CloseSocket(hSocket);
return error("Proxy failed to accept request");
}
if (pchRet2[1] != 0x00) {
if (pchRet2[1] != SOCKS5Reply::SUCCEEDED) {
// Failures to connect to a peer that are not proxy errors
CloseSocket(hSocket);
LogPrintf("Socks5() connect to %s:%d failed: %s\n", strDest, port, Socks5ErrorString(pchRet2[1]));
return false;
}
if (pchRet2[2] != 0x00) {
if (pchRet2[2] != 0x00) { // Reserved field must be 0
CloseSocket(hSocket);
return error("Error: malformed proxy response");
}
char pchRet3[256];
uint8_t pchRet3[256];
switch (pchRet2[3])
{
case 0x01: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
case 0x04: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
case 0x03:
case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
case SOCKS5Atyp::DOMAINNAME:
{
recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
if (recvr != IntrRecvError::OK) {

View File

@ -266,8 +266,6 @@ void SendCoinsDialog::on_sendButton_clicked()
// prepare transaction for getting txFee earlier
std::string floData = ui->floData->text().toStdString();
if (!floData.empty())
floData = "text:" + floData;
WalletModelTransaction currentTransaction(recipients, floData);
WalletModel::SendCoinsReturn prepareStatus;

View File

@ -1457,7 +1457,7 @@ UniValue reconsiderblock(const JSONRPCRequest& request)
}
CValidationState state;
ActivateBestChain(state, Params());
ActivateBestChain(state, Params(), std::shared_ptr<const CBlock>(), true);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());

View File

@ -28,13 +28,7 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed())
return false;
int tempHashType = nHashType;
if (sigversion != SIGVERSION_WITNESS_V0) {
// Compatibility with v0.10.4 requires not signing the flo data
// Once v0.10.4 is sufficiently fazed out this should be removed
tempHashType |= SIGHASH_OMIT_FLO_DATA;
}
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, tempHashType, amount, sigversion);
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
if (!key.Sign(hash, vchSig))
return false;
vchSig.push_back((unsigned char)nHashType);

View File

@ -42,6 +42,7 @@
#include "validationinterface.h"
#include "versionbits.h"
#include "warnings.h"
#include "net.h"
#include <atomic>
#include <sstream>
@ -2313,12 +2314,42 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block.
* pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork.
*/
static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace, bool reconsider)
{
AssertLockHeld(cs_main);
const CBlockIndex *pindexOldTip = chainActive.Tip();
const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
int nNlrLimit = gArgs.GetArg("-nlrlimit", Params().NoLargeReorgLimit());
if (nNlrLimit != 0 && !reconsider && !IsInitialBlockDownload() && pindexFork != nullptr
&& chainActive.Tip()->nHeight - pindexFork->nHeight >= nNlrLimit) {
LogPrintf("%s: NLR triggered! current height=%d current hash=%s | fork height=%d fork hash=%s\n", __func__,
pindexOldTip->nHeight, pindexOldTip->GetBlockHash().ToString(), pindexMostWork->nHeight,
pindexMostWork->GetBlockHash().ToString());
CBlockIndex *pindexWalk = pindexMostWork;
// mark invalid_child from tip of fork to second block of fork
while (pindexWalk->nHeight != pindexFork->nHeight+2) {
pindexWalk = pindexWalk->pprev;
pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
setDirtyBlockIndex.insert(pindexWalk);
setBlockIndexCandidates.erase(pindexWalk);
}
// mark invalid first block of fork
pindexWalk = pindexWalk->pprev;
pindexWalk->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindexWalk);
setBlockIndexCandidates.erase(pindexWalk);
// sanity check
assert(pindexWalk->pprev == pindexFork);
fInvalidFound = true;
InvalidChainFound(pindexMostWork);
return true;
}
// Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false;
DisconnectedBlockTransactions disconnectpool;
@ -2420,7 +2451,7 @@ static void NotifyHeaderTip() {
* or an activated best chain. pblock is either nullptr or a pointer to a block
* that is already loaded (to avoid loading it again from disk).
*/
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock, bool reconsider) {
// Note that while we're often called here from ProcessNewBlock, this is
// far from a guarantee. Things in the P2P/RPC will often end up calling
// us in the middle of ProcessNewBlock - do not assume pblock is set
@ -2451,7 +2482,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
bool fInvalidFound = false;
std::shared_ptr<const CBlock> nullBlockPtr;
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace, reconsider))
return false;
if (fInvalidFound) {
@ -2824,7 +2855,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
// Check transactions
for (const auto& tx : block.vtx)
if (!CheckTransaction(*tx, state, false))
if (!CheckTransaction(*tx, state))
return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(),
strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage()));
@ -2912,6 +2943,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
assert(pindexPrev != nullptr);
const int nHeight = pindexPrev->nHeight + 1;
//If this is a reorg, check that it is not too deep (51% attack prevention)
int nMaxReorgDepth = gArgs.GetArg("-maxreorg", Params().MaxReorganizationDepth());
int nMinReorgPeers = gArgs.GetArg("-minreorgpeers", Params().MinReorganizationPeers());
bool fGreaterThanMaxReorg = chainActive.Height() - nHeight >= nMaxReorgDepth;
if (fGreaterThanMaxReorg && g_connman && (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) > nMinReorgPeers && !IsInitialBlockDownload())
return state.DoS(1, error("%s: forked chain older than max reorganization depth (height %d), with connections (count %d), and (initial download %s)", __func__, nHeight, g_connman ? g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) : -1, IsInitialBlockDownload() ? "true" : "false"), REJECT_MAXREORGDEPTH, "bad-fork-prior-to-maxreorgdepth");
// Check proof of work
const Consensus::Params& consensusParams = params.GetConsensus();
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))

View File

@ -59,13 +59,13 @@ static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN;
//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB;
/** Default for -limitancestorcount, max number of in-mempool ancestors */
static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25;
static const unsigned int DEFAULT_ANCESTOR_LIMIT = 1250;
/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101;
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 1750;
/** Default for -limitdescendantcount, max number of in-mempool descendants */
static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25;
static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1250;
/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101;
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 1750;
/** Default for -mempoolexpiry, expiration time for mempool transactions in hours */
static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 336;
/** Maximum kilobytes for transactions to store for processing during reorg */
@ -273,7 +273,7 @@ bool IsInitialBlockDownload();
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
bool GetTransaction(const uint256 &hash, CTransactionRef &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false);
/** Find the best known block, and make it the tip of the block chain */
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>());
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>(), bool reconsider=false);
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */

105
test/functional/nlr.py Normal file
View File

@ -0,0 +1,105 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Copyright (c) Flo Developers 2013-2018
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the getchaintips RPC.
- introduce a network split
- work on chains of different lengths
- join the network together again
- verify that getchaintips now returns two chain tips.
"""
import time
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
class GetChainTipsTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.extra_args = [['-nlrlimit=0'], ['-nlrlimit=10'], ['-nlrlimit=10'], ['-nlrlimit=10']]
self.setup_clean_chain = False
def run_test (self):
tips = self.nodes[0].getchaintips ()
assert_equal (len (tips), 1)
assert_equal (tips[0]['branchlen'], 0)
assert_equal (tips[0]['height'], 200)
assert_equal (tips[0]['status'], 'active')
# Split the network and build two chains of different lengths.
self.split_network()
self.nodes[0].generate(10)
self.nodes[2].generate(20)
self.sync_all([self.nodes[:2], self.nodes[2:]])
tips = self.nodes[1].getchaintips ()
assert_equal (len (tips), 1)
shortTip = tips[0]
assert_equal(shortTip['branchlen'], 0)
assert_equal(shortTip['height'], 210)
assert_equal(tips[0]['status'], 'active')
tips = self.nodes[3].getchaintips ()
assert_equal (len (tips), 1)
longTip = tips[0]
assert_equal (longTip['branchlen'], 0)
assert_equal (longTip['height'], 220)
assert_equal (tips[0]['status'], 'active')
# Join the network halves and check that we now have two tips
# (at least at the nodes that previously had the short chain).
print("pre join")
self.join_network_no_sync ()
time.sleep(10)
print("post join")
print("node 0")
print(self.nodes[0].getchaintips())
print("node 1")
print(self.nodes[1].getchaintips())
print("node 2")
print(self.nodes[2].getchaintips())
print("reconsider")
self.nodes[1].reconsiderblock(self.nodes[2].getbestblockhash())
self.sync_all()
print("node 0")
print(self.nodes[0].getchaintips ())
print("node 1")
print(self.nodes[1].getchaintips ())
print("node 2")
print(self.nodes[2].getchaintips ())
self.nodes[2].generate(20)
self.sync_all()
self.nodes[1].generate(20)
self.sync_all()
print("node 0")
print(self.nodes[0].getchaintips ())
print("node 1")
print(self.nodes[1].getchaintips ())
print("node 2")
print(self.nodes[2].getchaintips ())
# tips = self.nodes[1].getchaintips ()
# assert_equal (len (tips), 2)
# assert_equal (tips[0], longTip)
#
# assert_equal (tips[1]['branchlen'], 10)
# assert_equal (tips[1]['status'], 'valid-fork')
# tips[1]['branchlen'] = 0
# tips[1]['status'] = 'active'
# assert_equal (tips[1], shortTip)
assert_equal(1, 3)
if __name__ == '__main__':
GetChainTipsTest().main()

View File

@ -310,6 +310,12 @@ class BitcoinTestFramework(object):
connect_nodes_bi(self.nodes, 1, 2)
self.sync_all()
def join_network_no_sync(self):
"""
Join the (previously split) network halves together. Do not wait sync.
"""
connect_nodes_bi(self.nodes, 1, 2)
def sync_all(self, node_groups=None):
if not node_groups:
node_groups = [self.nodes]

23
tmp/README.md Normal file
View File

@ -0,0 +1,23 @@
FLO Core MultiWallet
This executable file is used to run more than 1 wallet at a same time
Usage:
./multiWallet -create [walletName]
creates a wallet under 'walletName' if specified
else creates wallet with name 'floxxxxxx'
./multiWallet <walletName> <command> [option]
executes the command in wallet 'walletName'
commands:
flo-qt - open FLO Core Wallet
flo-cli - run cli commands
flod - run FLO daemon
for more info on each commands use option -help (or) -?
./flo-qt -?
./flo-cli -?
./flod -?

BIN
tmp/multiWallet Normal file

Binary file not shown.

81
tmp/multiWallet.py Normal file
View File

@ -0,0 +1,81 @@
import subprocess
import random
import sys
import os
import socket
def _start():
if(len(sys.argv)<2):
_help()
print('Error : too few parameters')
elif(sys.argv[1] in ['-help','-?']):
_help()
elif(sys.argv[1]=='-create'):
try:
foldername = sys.argv[2]
except:
rand = random.randint(1,999999)
foldername = 'flo'+str(rand)
print('Creating a new Wallet...')
try:
subprocess.call(['mkdir','-p',foldername])
except Exception as e:
print('Wallet Creation Failed : '+str(e))
exit(0)
print('Created wallet '+foldername)
print('To use wallet : '+sys.argv[0]+' '+foldername)
elif(len(sys.argv)<3):
_help()
print('Error : too few parameters (command missing)')
elif(sys.argv[2] in ['flo-qt','flo-cli','flod']):
#use this for find ip n available port using socket instead of random port
localip=socket.gethostbyname(socket.gethostname())
'''
for p in range(0, 65535):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
if(!sock.connect_ex(('localhost', p)))
port = p
break;
'''
#localip = '0.0.0.0'
port = str(random.randint(2000,10000))
path=os.getcwd()
cmd = ['./'+sys.argv[2]] + ['-conf='+path+'/'+sys.argv[1]+'/flo.conf','-datadir='+sys.argv[1],'-bind='+localip+':'+port] + sys.argv[3:]
#print(cmd)
subprocess.run(cmd)
else:
_help()
print('Error : command '+sys.argv[2]+' not recognised')
def _help():
help_data=f"""
FLO Core MultiWallet
Usage:
{sys.argv[0]} -create [walletName]
creates a wallet under 'walletName' if specified
else creates wallet with name 'floxxxxxx'
{sys.argv[0]} <walletName> <command> [option]
executes the command in wallet 'walletName'
commands:
flo-qt - open FLO Core Wallet
flo-cli - run cli commands
flod - run FLO daemon
for more info on each commands use option -help (or) -?
"""
print(help_data)
_start()