Compare commits

..

No commits in common. "flo-master" and "coin-control" have entirely different histories.

27 changed files with 161 additions and 491 deletions

5
.gitignore vendored
View File

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

126
README.md
View File

@ -1,3 +1,78 @@
FLO Core integration/staging tree
=====================================
[![Build Status](https://travis-ci.org/floblockchain/flo.svg?branch=master)](https://travis-ci.org/floblockchain/flo)
https://flo.cash
What is FLO?
----------------
FLO is an experimental digital currency that enables instant payments to
anyone, anywhere in the world. FLO uses peer-to-peer technology to operate
with no central authority: managing transactions and issuing money are carried
out collectively by the network. FLO Core is the name of open source
software which enables the use of this currency.
For more information, as well as an immediately useable, binary version of
the FLO Core software, see [https://flo.cash](https://flo.cash).
License
-------
FLO Core is released under the terms of the MIT license. See [COPYING](COPYING) for more
information or see https://opensource.org/licenses/MIT.
Development Process
-------------------
The `master` branch is regularly built and tested, but is not guaranteed to be
completely stable. [Tags](https://github.com/floblockchain/flo/tags) are created
regularly to indicate new official, stable release versions of FLO Core.
The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md).
Testing
-------
Testing and code review is the bottleneck for development; we get more pull
requests than we can review and test on short notice. Please be patient and help out by testing
other people's pull requests, and remember this is a security-critical project where any mistake might cost people
lots of money.
### Automated Testing
Developers are strongly encouraged to write [unit tests](src/test/README.md) for new code, and to
submit new unit tests for old code. Unit tests can be compiled and run
(assuming they weren't disabled in configure) with: `make check`. Further details on running
and extending unit tests can be found in [/src/test/README.md](/src/test/README.md).
There are also [regression and integration tests](/test), written
in Python, that are run automatically on the build server.
These tests can be run (if the [test dependencies](/test) are installed) with: `test/functional/test_runner.py`
The Travis CI system makes sure that every pull request is built for Windows, Linux, and OS X, and that unit/sanity tests are run automatically.
### Manual Quality Assurance (QA) Testing
Changes should be tested by somebody other than the developer who wrote the
code. This is especially important for large or high-risk changes. It is useful
to add a test plan to the pull request description if testing the changes is
not straightforward.
Translations
------------
We only accept translation fixes that are submitted through [Bitcoin Core's Transifex page](https://www.transifex.com/projects/p/bitcoin/).
Translations are converted to FLO periodically.
Translations are periodically pulled from Transifex and merged into the git repository. See the
[translation process](doc/translation_process.md) for details on how this works.
**Important**: We do not accept translation changes as GitHub pull requests because the next
pull from Transifex would automatically overwrite them again.
Usage Usage
-------- --------
@ -21,56 +96,12 @@ flo-tx - FLO transactions
4. For more details view the readme file in the extracted directory 4. For more details view the readme file in the extracted directory
### Compiling on Linux OS Server ### For creating Pre-compiled executable binary files from source code :
Go to **flo** directory, and execute
cd depends/
make HOST=x86_64-linux-gnu
cd ..
./autogen.sh
./configure --prefix=`pwd`/depends/x86_64-linux-gnu
make
For PCs on Linux, and execute
cd depends/
make HOST=x86_64-pc-linux-gnu
cd ..
./autogen.sh
./configure --prefix=`pwd`/depends/x86_64-pc-linux-gnu
make
To make with debuging in GDB
cd depends/
make clean HOST=x86_64-pc-linux-gnu
cd ..
./autogen.sh
./configure CXXFLAGS="-O0 -ggdb3" --prefix=`pwd`/depends/x86_64-pc-linux-gnu
make -j $(nproc)
### Details: For creating Pre-compiled executable binary files from source code :
The dependencies for creating pre-compiled binaries are present in **depends/** directory. The dependencies for creating pre-compiled binaries are present in **depends/** directory.
cd depends/ cd depends/
To build dependencies for the current arch/OS (usually this gives error if architecture/OS is not specified in some versions. Better to specify arch/OS prefix explicitly): To build dependencies for the current arch/OS:
make make
@ -111,8 +142,7 @@ To enable it, add **SendChangeToBack=1** in flo.conf (or) pass **-SendChangeToBa
### Added Multi-Wallet support for Linux : ### Added Multi-Wallet support for Linux :
Multi-wallet support allows the user to run more than 1 wallet simultaneously. Multi-wallet support allows the user to run more than 1 wallet simultaneously.
The Multi-wallet executable file is located in **tmp/** The Multi-wallet executable file is located in **bin/Linux**
Copy the executable(binary) file to the flo binary files
To access multi-wallet run : To access multi-wallet run :
./multiWallet -create [walletName] ./multiWallet -create [walletName]

BIN
bin/linux.tar.xz Normal file

Binary file not shown.

BIN
bin/win_32-bit.zip Normal file

Binary file not shown.

BIN
bin/win_64-bits.zip Normal file

Binary file not shown.

View File

@ -2,10 +2,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60]) AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 15) define(_CLIENT_VERSION_MINOR, 15)
define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 1) define(_CLIENT_VERSION_BUILD, 1)
define(_CLIENT_VERSION_IS_RELEASE, true) define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2019) define(_COPYRIGHT_YEAR, 2017)
define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[FLO Core]]) 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/]) 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.2.1" name: "flo-linux-0.15"
enable_cache: true enable_cache: true
suites: suites:
- "trusty" - "trusty"

View File

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

View File

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

View File

@ -1,59 +0,0 @@
# How I started mining FLO coins using my GPU
To get started with GPU mining, Create an account with Suprnova.
After registration, navigate to My Account and then click on Edit Account.
Scroll down and update the payment address by entering your Flo Core wallet address and make sure you click on the update button.
(Use the payment address that you got when you registered for FLO Core Wallet.
You can find your Payment address by navigating to the receive section and clicking on the request payment option).
Once youve updated the payment option, Go to my Account and click on My Workers.
Add a new worker and update the credentials accordingly.
Again make sure you click on the update button once youve added a new worker.
Make sure that the monitor option is enabled.
Now once youve got all the Supernova stuff figured out, its time to get the miner running.
Ive given the links to all the resources below. From there, Download GC Miner. Youll need an application to extract the RAR file.
I used Peazip, you. can use your preferred application. Once youve got it downloaded, extract the file and make sure you have it
stored properly and safely in a specific new folder.
After its done, open the extracted file and navigate to the config file.
Delete the config file. Once youre done deleting it, click on the empty space present in the address
bar and type cmd. This will open the command prompt. Now to start running the mining software executethe command:-
```
cgminer — scrypt -o stratum+tcp://flo.suprnova.cc:3210 -u [workername] -p [worker_pass]
```
Here “workername” and “worker_pass” refer to the credentials of the workers which we created in Supernova.
Note that the workername should be typed in the format [your username].[worker name] and replace it accordingly.
for example
```
-u bharat01.mall01 -p duckgostack123
```
Once youve executed the program by replacing the appropriate usernames and passwords, the process of mining will be started. and this is what itll look like.
To quit the program press q. We cant always type in a long command so lets create a shortcut. Create a new text file in the folder and rename it as start.bat
edit this document in the text file and type in the same executable that we used to start the mining process.
```
cgminer — scrypt -o stratum+tcp://flo.suprnova.cc:3210 -u [workername] -p [worker_pass]
```
After saving the bat file, copy and paste the start.bat file to the desktop for easy access.
Happy mining!!
All the resources used:-
#### GC Miner:-
(https://drive.google.com/file/d/1nNutlChYfkXFoDIE_bFVtH9YhVGWPdU9/view?usp=drive_link)
#### Peazip download:-
(https://peazip.github.io/index.html)
#### Suprnova:-
(https://flo.suprnova.cc/index.php)
### Written by Bhardwaj Hariharan on Medium
For attached screenshots, read this Medium post
(https://medium.com/@bhardhwaj01/how-i-started-mining-flo-coins-using-my-gpu-01ea0ac436eb)

View File

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

View File

@ -63,7 +63,6 @@ public:
const Consensus::Params& GetConsensus() const { return consensus; } const Consensus::Params& GetConsensus() const { return consensus; }
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
int GetDefaultPort() const { return nDefaultPort; } int GetDefaultPort() const { return nDefaultPort; }
int NoLargeReorgLimit() const { return nNlrLimit; }
const CBlock& GenesisBlock() const { return genesis; } const CBlock& GenesisBlock() const { return genesis; }
/** Default value for -checkmempool and -checkblockindex argument */ /** Default value for -checkmempool and -checkblockindex argument */
@ -88,7 +87,6 @@ protected:
CMessageHeader::MessageStartChars pchMessageStart; CMessageHeader::MessageStartChars pchMessageStart;
int nDefaultPort; int nDefaultPort;
uint64_t nPruneAfterHeight; uint64_t nPruneAfterHeight;
int nNlrLimit;
std::vector<CDNSSeedData> vSeeds; std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES]; std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
std::string strNetworkID; std::string strNetworkID;

View File

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

View File

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

View File

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

View File

@ -401,7 +401,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER)); 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("-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("-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("-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("-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)); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG));

View File

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

View File

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

View File

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

View File

@ -28,7 +28,13 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed()) if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed())
return false; return false;
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); 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);
if (!key.Sign(hash, vchSig)) if (!key.Sign(hash, vchSig))
return false; return false;
vchSig.push_back((unsigned char)nHashType); vchSig.push_back((unsigned char)nHashType);

View File

@ -2313,42 +2313,12 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block. * Try to make some progress towards making pindexMostWork the active block.
* pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork. * 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, bool reconsider) static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
const CBlockIndex *pindexOldTip = chainActive.Tip(); const CBlockIndex *pindexOldTip = chainActive.Tip();
const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); 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. // Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false; bool fBlocksDisconnected = false;
DisconnectedBlockTransactions disconnectpool; DisconnectedBlockTransactions disconnectpool;
@ -2450,7 +2420,7 @@ static void NotifyHeaderTip() {
* or an activated best chain. pblock is either nullptr or a pointer to a block * 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). * 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 reconsider) { bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
// Note that while we're often called here from ProcessNewBlock, this is // 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 // 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 // us in the middle of ProcessNewBlock - do not assume pblock is set
@ -2481,7 +2451,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
bool fInvalidFound = false; bool fInvalidFound = false;
std::shared_ptr<const CBlock> nullBlockPtr; std::shared_ptr<const CBlock> nullBlockPtr;
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace, reconsider)) if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
return false; return false;
if (fInvalidFound) { if (fInvalidFound) {
@ -2854,7 +2824,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
// Check transactions // Check transactions
for (const auto& tx : block.vtx) for (const auto& tx : block.vtx)
if (!CheckTransaction(*tx, state)) if (!CheckTransaction(*tx, state, false))
return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(),
strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage())); strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage()));

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) //! -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; static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB;
/** Default for -limitancestorcount, max number of in-mempool ancestors */ /** Default for -limitancestorcount, max number of in-mempool ancestors */
static const unsigned int DEFAULT_ANCESTOR_LIMIT = 1250; static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25;
/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 1750; static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101;
/** Default for -limitdescendantcount, max number of in-mempool descendants */ /** Default for -limitdescendantcount, max number of in-mempool descendants */
static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1250; static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25;
/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */ /** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 1750; static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101;
/** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */
static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 336; static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 336;
/** Maximum kilobytes for transactions to store for processing during reorg */ /** 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) */ /** 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); 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 */ /** 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 reconsider=false); bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>());
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */

View File

@ -1,105 +0,0 @@
#!/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,12 +310,6 @@ class BitcoinTestFramework(object):
connect_nodes_bi(self.nodes, 1, 2) connect_nodes_bi(self.nodes, 1, 2)
self.sync_all() 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): def sync_all(self, node_groups=None):
if not node_groups: if not node_groups:
node_groups = [self.nodes] node_groups = [self.nodes]

View File

@ -1,23 +0,0 @@
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 -?

Binary file not shown.

View File

@ -1,81 +0,0 @@
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()