mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
Conflicts: src/Peer.cpp
This commit is contained in:
37
deploy/cointoss.nsi
Normal file
37
deploy/cointoss.nsi
Normal file
@@ -0,0 +1,37 @@
|
||||
Name "CoinToss"
|
||||
|
||||
; The file to write
|
||||
OutFile "toss install.exe"
|
||||
|
||||
; The default installation directory
|
||||
InstallDir "$PROGRAMFILES\CoinToss"
|
||||
|
||||
; Request application privileges for Windows Vista
|
||||
RequestExecutionLevel user
|
||||
|
||||
;--------------------------------
|
||||
|
||||
; Pages
|
||||
|
||||
Page directory
|
||||
Page instfiles
|
||||
|
||||
;--------------------------------
|
||||
|
||||
; The stuff to install
|
||||
Section "" ;No components page, name is not important
|
||||
|
||||
; Set output path to the installation directory.
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
; Put file there
|
||||
File ..\Release\newcoin.exe
|
||||
File ..\*.dll
|
||||
File "start CoinToss.bat"
|
||||
File newcoind.cfg
|
||||
File validators.txt
|
||||
File /r /x .git ..\..\nc-client\*.*
|
||||
|
||||
|
||||
|
||||
SectionEnd ; end the section
|
||||
147
deploy/newcoind.cfg
Normal file
147
deploy/newcoind.cfg
Normal file
@@ -0,0 +1,147 @@
|
||||
#
|
||||
# Sample newcoind.cfg
|
||||
#
|
||||
# This file should be named newcoind.cfg. This file is UTF-8 with Dos, UNIX,
|
||||
# or Mac style end of lines. Blank lines and lines beginning with '#' are
|
||||
# ignored. Undefined sections are reserved. No escapes are currently defined.
|
||||
#
|
||||
# When you launch newcoind, it will attempt to find this file.
|
||||
#
|
||||
# --conf=<path>:
|
||||
# You may specify the location of this file with --conf=<path>. The config
|
||||
# directory is the directory containing this file. The data directory is a
|
||||
# the subdirectory named "dbs".
|
||||
#
|
||||
# Windows and no --conf:
|
||||
# The config directory is the same directory as the newcoind program. The
|
||||
# data directory is a the subdirectory named "dbs".
|
||||
#
|
||||
# Other OSes and no --conf:
|
||||
# This file will be looked for in these places in the following order:
|
||||
# ./newcoind.cfg
|
||||
# $XDG_CONFIG_HOME/newcoin/newcoind.cfg
|
||||
#
|
||||
# If newcoind.cfg, is found in the current working directory, the directory
|
||||
# will be used as the config directory. The data directory is a the
|
||||
# subdirectory named "dbs".
|
||||
#
|
||||
# Otherwise, the data directory data is:
|
||||
# $XDG_DATA_HOME/newcoin/
|
||||
#
|
||||
# Note: $XDG_CONFIG_HOME defaults to $HOME/.config
|
||||
# $XDG_DATA_HOME defaults to $HOME/.local/share
|
||||
#
|
||||
# [debug_logfile]
|
||||
# Specifies were a debug logfile is kept. By default, no debug log is kept
|
||||
#
|
||||
# Example: debug.log
|
||||
#
|
||||
# [validators_site]:
|
||||
# Specifies where to find validators.txt for UNL boostrapping and RPC command unl_network.
|
||||
# During alpha testing, this defaults to: redstem.com
|
||||
#
|
||||
# Example: newcoin.org
|
||||
#
|
||||
# [unl_default]:
|
||||
# XXX This should be called: [validators_file]
|
||||
# Specifies how to bootstrap the UNL list. The UNL list is based on a
|
||||
# validators.txt file and is maintained in the databases. When newcoind
|
||||
# starts up, if the databases are missing or are obsolete due to an upgrade
|
||||
# of newcoind, newcoind will reconstruct the UNL list as specified here.
|
||||
#
|
||||
# If this entry is not present or empty, newcoind will look for a validators.txt in the
|
||||
# config directory. If not found there, it will attempt to retrieve the file
|
||||
# from the newcoin foundation's web site.
|
||||
#
|
||||
# This entry is also used by the RPC command unl_load.
|
||||
#
|
||||
# Specify the file by specifying its full path.
|
||||
#
|
||||
# Examples:
|
||||
# C:/home/johndoe/newcoin/validators.txt
|
||||
# /home/johndoe/newcoin/validators.txt
|
||||
#
|
||||
# [validators]:
|
||||
# Only valid in "newcoind.cfg", "newcoin.txt", and the referered [validators_url].
|
||||
# List of nodes to accept as validators speficied by public key or domain.
|
||||
#
|
||||
# For domains, newcoind will probe for https web servers at the specied
|
||||
# domain in the following order: newcoin.DOMAIN, www.DOMAIN, DOMAIN
|
||||
#
|
||||
# Examples:
|
||||
# redstem.com
|
||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
||||
#
|
||||
# [ips]:
|
||||
# Only valid in "newcoind.cfg", "newcoin.txt", and the referered [ips_url].
|
||||
# List of ips where the Newcoin protocol is avialable.
|
||||
# One ipv4 or ipv6 address per line.
|
||||
# A port may optionally be specified after adding a space to the address.
|
||||
# By convention, if known, IPs are listed in from most to least trusted.
|
||||
#
|
||||
# Examples:
|
||||
# 192.168.0.1
|
||||
# 192.168.0.1 3939
|
||||
# 2001:0db8:0100:f101:0210:a4ff:fee3:9566
|
||||
#
|
||||
# [peer_ip]:
|
||||
# IP address or domain to bind to allow external connections from peers.
|
||||
# Defaults to not allow external connections from peers.
|
||||
#
|
||||
# Examples: 0.0.0.0 - Bind on all interfaces.
|
||||
#
|
||||
# [peer_port]:
|
||||
# Port to bind to allow external connections from peers.
|
||||
#
|
||||
# [rpc_ip]:
|
||||
# IP address or domain to bind to allow insecure RPC connections.
|
||||
# Defaults to not allow RPC connections.
|
||||
#
|
||||
# [rpc_port]:
|
||||
# Port to bind to if allowing insecure RPC connections.
|
||||
#
|
||||
# [rpc_allow_remote]:
|
||||
# 0 or 1. 0 only allows RPC connections from 127.0.0.1. [default 0]
|
||||
#
|
||||
# [websocket_ip]:
|
||||
# IP address or domain to bind to allow client connections.
|
||||
#
|
||||
# Examples: 0.0.0.0 - Bind on all interfaces.
|
||||
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
|
||||
#
|
||||
# [websocket_port]:
|
||||
# Port to bind to allow client connections.
|
||||
#
|
||||
# [validation_seed]:
|
||||
# To perform validation, this section should contain either a validation seed or key.
|
||||
# The validation seed is used to generate the validation public/private key pair.
|
||||
# To obtain a validation seed, use the validation_create command.
|
||||
#
|
||||
# Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE
|
||||
# shfArahZT9Q9ckTf3s1psJ7C7qzVN
|
||||
#
|
||||
|
||||
[peer_ip]
|
||||
0.0.0.0
|
||||
|
||||
[peer_port]
|
||||
51235
|
||||
|
||||
[rpc_ip]
|
||||
127.0.0.1
|
||||
|
||||
[rpc_port]
|
||||
5005
|
||||
|
||||
[rpc_allow_remote]
|
||||
1
|
||||
|
||||
[debug_logfile]
|
||||
debug.log
|
||||
|
||||
[validation_seed]
|
||||
shh1D4oj5czH3PUEjYES8c7Bay3tE
|
||||
|
||||
[unl_default]
|
||||
validators.txt
|
||||
3
deploy/start CoinToss.bat
Normal file
3
deploy/start CoinToss.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
start newcoin
|
||||
sleep 4
|
||||
start index.html
|
||||
25
deploy/validators.txt
Normal file
25
deploy/validators.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Default validators.txt
|
||||
#
|
||||
# A list of domains to bootstrap a nodes UNLs or for clients to indirectly
|
||||
# locate IPs to contact the Newcoin network.
|
||||
#
|
||||
# This file is UTF-8 with Dos, UNIX, or Mac style end of lines.
|
||||
# Blank lines and lines starting with a '#' are ignored.
|
||||
# All other lines should be hankos or domain names.
|
||||
#
|
||||
# [validators]:
|
||||
# List of nodes to accept as validators speficied by public key or domain.
|
||||
#
|
||||
# For domains, newcoind will probe for https web servers at the specied
|
||||
# domain in the following order: newcoin.DOMAIN, www.DOMAIN, DOMAIN
|
||||
#
|
||||
# Examples: redstem.com
|
||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
||||
#
|
||||
|
||||
[validators]
|
||||
n9LQC4xFSWXNv1SU1sKtjrW6TZpBZSwp1nRWej8saGs155x42YFZ first
|
||||
n9LFzWuhKNvXStHAuemfRKFVECLApowncMAM5chSCL9R5ECHGN4V second
|
||||
n9KXAZxiHkWuVGxDEE8boW7WmcycpZNmWei4vxVaywLZ391Nbuqx third
|
||||
@@ -72,7 +72,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>BOOST_TEST_NO_MAIN;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\OpenSSL\include;..\boost_1_47_0;..\protobuf-2.4.1\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
||||
@@ -100,7 +100,7 @@ bool STAmount::setValue(const std::string& sAmount, const std::string& sCurrency
|
||||
|
||||
if (bInteger)
|
||||
{
|
||||
uValue = sAmount.empty() ? 0 : boost::lexical_cast<unsigned int>(sAmount);
|
||||
uValue = sAmount.empty() ? 0 : boost::lexical_cast<uint64>(sAmount);
|
||||
iOffset = 0;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "../database/SqliteDatabase.h"
|
||||
|
||||
#include "Application.h"
|
||||
@@ -52,6 +55,11 @@ void Application::stop()
|
||||
std::cerr << "Stopped: " << mIOService.stopped() << std::endl;
|
||||
}
|
||||
|
||||
static void InitDB(DatabaseCon** dbCon, const char *fileName, const char *dbInit[], int dbCount)
|
||||
{
|
||||
*dbCon = new DatabaseCon(fileName, dbInit, dbCount);
|
||||
}
|
||||
|
||||
void Application::run()
|
||||
{
|
||||
assert(mTxnDB == NULL);
|
||||
@@ -61,11 +69,12 @@ void Application::run()
|
||||
//
|
||||
// Construct databases.
|
||||
//
|
||||
mTxnDB = new DatabaseCon("transaction.db", TxnDBInit, TxnDBCount);
|
||||
mLedgerDB = new DatabaseCon("ledger.db", LedgerDBInit, LedgerDBCount);
|
||||
mWalletDB = new DatabaseCon("wallet.db", WalletDBInit, WalletDBCount);
|
||||
mHashNodeDB = new DatabaseCon("hashnode.db", HashNodeDBInit, HashNodeDBCount);
|
||||
mNetNodeDB = new DatabaseCon("netnode.db", NetNodeDBInit, NetNodeDBCount);
|
||||
boost::thread t1(boost::bind(&InitDB, &mTxnDB, "transaction.db", TxnDBInit, TxnDBCount));
|
||||
boost::thread t2(boost::bind(&InitDB, &mLedgerDB, "ledger.db", LedgerDBInit, LedgerDBCount));
|
||||
boost::thread t3(boost::bind(&InitDB, &mWalletDB, "wallet.db", WalletDBInit, WalletDBCount));
|
||||
boost::thread t4(boost::bind(&InitDB, &mHashNodeDB, "hashnode.db", HashNodeDBInit, HashNodeDBCount));
|
||||
boost::thread t5(boost::bind(&InitDB, &mNetNodeDB, "netnode.db", NetNodeDBInit, NetNodeDBCount));
|
||||
t1.join(); t2.join(); t3.join(); t4.join(); t5.join();
|
||||
|
||||
//
|
||||
// Begin validation and ip maintenance.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
// Transaction database holds transactions and public keys
|
||||
const char *TxnDBInit[] = {
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE Transactions ( \
|
||||
TransID CHARACTER(64) PRIMARY KEY, \
|
||||
TransType CHARACTER(24), \
|
||||
@@ -21,13 +23,17 @@ const char *TxnDBInit[] = {
|
||||
LedgerSeq BIGINT UNSIGNED \
|
||||
);",
|
||||
"CREATE INDEX AcctTxindex ON \
|
||||
AccountTransactions(Account, LedgerSeq, TransID);"
|
||||
AccountTransactions(Account, LedgerSeq, TransID);",
|
||||
|
||||
"END TRANSACTION;"
|
||||
};
|
||||
|
||||
int TxnDBCount = sizeof(TxnDBInit) / sizeof(const char *);
|
||||
|
||||
// Ledger database holds ledgers and ledger confirmations
|
||||
const char *LedgerDBInit[] = {
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE Ledgers ( \
|
||||
LedgerHash CHARACTER(64) PRIMARY KEY, \
|
||||
LedgerSeq BIGINT UNSIGNED, \
|
||||
@@ -46,8 +52,9 @@ const char *LedgerDBInit[] = {
|
||||
Signature BLOB \
|
||||
);",
|
||||
"CREATE INDEX LedgerConfByHash ON \
|
||||
LedgerConfirmations(LedgerHash)"
|
||||
LedgerConfirmations(LedgerHash)",
|
||||
#endif
|
||||
"END TRANSACTION;"
|
||||
};
|
||||
|
||||
int LedgerDBCount = sizeof(LedgerDBInit) / sizeof(const char *);
|
||||
@@ -55,6 +62,8 @@ int LedgerDBCount = sizeof(LedgerDBInit) / sizeof(const char *);
|
||||
// Wallet database holds local accounts and trusted nodes
|
||||
const char *WalletDBInit[] = {
|
||||
// Node identity must be persisted for CAS routing and responsibilities.
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE NodeIdentity ( \
|
||||
PublicKey CHARACTER(53), \
|
||||
PrivateKey CHARACTER(52), \
|
||||
@@ -221,13 +230,17 @@ const char *WalletDBInit[] = {
|
||||
);",
|
||||
|
||||
"CREATE INDEX PeerScanIndex ON \
|
||||
PeerIps(ScanNext);"
|
||||
PeerIps(ScanNext);",
|
||||
|
||||
"END TRANSACTION;"
|
||||
};
|
||||
|
||||
int WalletDBCount = sizeof(WalletDBInit) / sizeof(const char *);
|
||||
|
||||
// Hash node database holds nodes indexed by hash
|
||||
const char *HashNodeDBInit[] = {
|
||||
"BEGIN TRANSACTION;",
|
||||
|
||||
"CREATE TABLE CommittedObjects ( \
|
||||
Hash CHARACTER(64) PRIMARY KEY, \
|
||||
ObjType CHAR(1) NOT NULL, \
|
||||
@@ -236,7 +249,9 @@ const char *HashNodeDBInit[] = {
|
||||
);",
|
||||
|
||||
"CREATE INDEX ObjectLocate ON \
|
||||
CommittedObjects(LedgerIndex, ObjType);"
|
||||
CommittedObjects(LedgerIndex, ObjType);",
|
||||
|
||||
"END TRANSACTION;"
|
||||
};
|
||||
|
||||
int HashNodeDBCount = sizeof(HashNodeDBInit) / sizeof(const char *);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
// #define LC_DEBUG
|
||||
|
||||
// TODO: If we don't have the previousLCL, check if we got it. If so, change modes
|
||||
|
||||
TransactionAcquire::TransactionAcquire(const uint256& hash)
|
||||
: PeerSet(hash, 1), mFilter(&theApp->getNodeCache()), mHaveRoot(false)
|
||||
{
|
||||
@@ -188,12 +190,15 @@ int LCTransaction::getAgreeLevel()
|
||||
return (mNays * 100 + 100) / (mYays + mNays + 1);
|
||||
}
|
||||
|
||||
LedgerConsensus::LedgerConsensus(Ledger::pointer previousLedger, uint32 closeTime)
|
||||
: mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPreviousLedger(previousLedger)
|
||||
LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint32 closeTime)
|
||||
: mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPrevLedgerHash(prevLCLHash), mPreviousLedger(previousLedger)
|
||||
{
|
||||
mValSeed = theConfig.VALIDATION_SEED;
|
||||
Log(lsDEBUG) << "Creating consensus object";
|
||||
Log(lsTRACE) << "LCL:" << previousLedger->getHash().GetHex() <<", ct=" << closeTime;
|
||||
if (theConfig.VALIDATION_SEED.isValid())
|
||||
if (previousLedger->getHash() != prevLCLHash)
|
||||
mHaveCorrectLCL = mProposing = mValidating = false;
|
||||
else if (mValSeed.isValid())
|
||||
{
|
||||
mValidating = true;
|
||||
mProposing = theApp->getOPs().getOperatingMode() == NetworkOPs::omFULL;
|
||||
@@ -205,7 +210,7 @@ void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger)
|
||||
{
|
||||
SHAMap::pointer initialSet = initialLedger->peekTransactionMap()->snapShot(false);
|
||||
uint256 txSet = initialSet->getHash();
|
||||
assert (initialLedger->getParentHash() == mPreviousLedger->getHash());
|
||||
assert (!mHaveCorrectLCL || (initialLedger->getParentHash() == mPreviousLedger->getHash()));
|
||||
|
||||
// if any peers have taken a contrary position, process disputes
|
||||
boost::unordered_set<uint256> found;
|
||||
@@ -221,9 +226,9 @@ void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger)
|
||||
}
|
||||
}
|
||||
|
||||
if (mProposing)
|
||||
if (mValidating)
|
||||
mOurPosition = boost::make_shared<LedgerProposal>
|
||||
(theConfig.VALIDATION_SEED, initialLedger->getParentHash(), txSet);
|
||||
(mValSeed, initialLedger->getParentHash(), txSet);
|
||||
else
|
||||
mOurPosition = boost::make_shared<LedgerProposal>(initialLedger->getParentHash(), txSet);
|
||||
mapComplete(txSet, initialSet, false);
|
||||
@@ -317,13 +322,21 @@ void LedgerConsensus::adjustCount(SHAMap::pointer map, const std::vector<uint160
|
||||
void LedgerConsensus::statusChange(newcoin::NodeEvent event, Ledger::pointer ledger)
|
||||
{ // Send a node status change message to our peers
|
||||
newcoin::TMStatusChange s;
|
||||
s.set_newevent(event);
|
||||
s.set_ledgerseq(ledger->getLedgerSeq());
|
||||
s.set_networktime(theApp->getOPs().getNetworkTimeNC());
|
||||
uint256 plhash = ledger->getParentHash();
|
||||
s.set_previousledgerhash(plhash.begin(), plhash.size());
|
||||
if (!mHaveCorrectLCL)
|
||||
s.set_newevent(newcoin::neLOST_SYNC);
|
||||
else
|
||||
{
|
||||
s.set_newevent(event);
|
||||
s.set_ledgerseq(ledger->getLedgerSeq());
|
||||
s.set_networktime(theApp->getOPs().getNetworkTimeNC());
|
||||
uint256 hash = ledger->getParentHash();
|
||||
s.set_previousledgerhash(hash.begin(), hash.size());
|
||||
hash = ledger->getHash();
|
||||
s.set_ledgerhash(hash.begin(), hash.size());
|
||||
}
|
||||
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(s, newcoin::mtSTATUS_CHANGE);
|
||||
theApp->getConnectionPool().relayMessage(NULL, packet);
|
||||
Log(lsINFO) << "send status change to peer";
|
||||
}
|
||||
|
||||
void LedgerConsensus::abort()
|
||||
@@ -724,7 +737,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
assert(set->getHash() == mOurPosition->getCurrentHash());
|
||||
Log(lsINFO) << "Computing new LCL based on network consensus";
|
||||
Log(lsDEBUG) << "Consensus " << mOurPosition->getCurrentHash().GetHex();
|
||||
Log(lsDEBUG) << "Previous LCL " << mPreviousLedger->getHash().GetHex();
|
||||
Log(lsDEBUG) << "Previous LCL " << mPrevLedgerHash.GetHex();
|
||||
|
||||
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
|
||||
|
||||
@@ -747,15 +760,6 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
uint256 newLCLHash = newLCL->getHash();
|
||||
Log(lsTRACE) << "newLCL " << newLCLHash.GetHex();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (1)
|
||||
{
|
||||
Log(lsTRACE) << "newLCL after transactions";
|
||||
Json::Value p;
|
||||
newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p);
|
||||
}
|
||||
#endif
|
||||
|
||||
Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL));
|
||||
|
||||
@@ -811,13 +815,17 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
Json::Value p;
|
||||
newOL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p);
|
||||
Log(lsINFO) << "newLCL after transactions";
|
||||
Json::Value p2;
|
||||
newLCL->addJson(p2, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mValidating)
|
||||
{
|
||||
SerializedValidation::pointer v = boost::make_shared<SerializedValidation>
|
||||
(newLCLHash, mOurPosition->peekSeed(), true);
|
||||
(newLCLHash, newLCL->getCloseTimeNC(), mOurPosition->peekSeed(), true);
|
||||
v->setTrusted();
|
||||
// FIXME: If not proposing, set not full
|
||||
theApp->getValidations().addValidation(v);
|
||||
@@ -825,9 +833,10 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
newcoin::TMValidation val;
|
||||
val.set_validation(&validation[0], validation.size());
|
||||
theApp->getConnectionPool().relayMessage(NULL, boost::make_shared<PackedMessage>(val, newcoin::mtVALIDATION));
|
||||
Log(lsINFO) << "Validation sent " << newLCL->getHash().GetHex();
|
||||
Log(lsINFO) << "Validation sent " << newLCLHash.GetHex();
|
||||
}
|
||||
statusChange(newcoin::neACCEPTED_LEDGER, newOL);
|
||||
else Log(lsWARNING) << "Not validating";
|
||||
statusChange(newcoin::neACCEPTED_LEDGER, newLCL);
|
||||
}
|
||||
|
||||
void LedgerConsensus::endConsensus()
|
||||
|
||||
@@ -83,9 +83,11 @@ class LedgerConsensus : public boost::enable_shared_from_this<LedgerConsensus>
|
||||
protected:
|
||||
LCState mState;
|
||||
uint32 mCloseTime;
|
||||
uint256 mPrevLedgerHash;
|
||||
Ledger::pointer mPreviousLedger;
|
||||
LedgerProposal::pointer mOurPosition;
|
||||
bool mProposing, mValidating;
|
||||
NewcoinAddress mValSeed;
|
||||
bool mProposing, mValidating, mHaveCorrectLCL;
|
||||
|
||||
// Convergence tracking, trusted peers indexed by hash of public key
|
||||
boost::unordered_map<uint160, LedgerProposal::pointer> mPeerPositions;
|
||||
@@ -130,7 +132,7 @@ protected:
|
||||
void endConsensus();
|
||||
|
||||
public:
|
||||
LedgerConsensus(Ledger::pointer previousLedger, uint32 closeTime);
|
||||
LedgerConsensus(const uint256& prevLCLHash, Ledger::pointer previousLedger, uint32 closeTime);
|
||||
|
||||
int startup();
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ void NetworkOPs::setStateTimer(int sec)
|
||||
uint64 consensusTime = mLedgerMaster->getCurrentLedger()->getCloseTimeNC() - LEDGER_WOBBLE_TIME;
|
||||
uint64 now = getNetworkTimeNC();
|
||||
|
||||
if (now >= consensusTime) sec = 0;
|
||||
if (now >= consensusTime) sec = 1;
|
||||
else if (sec > (consensusTime - now)) sec = (consensusTime - now);
|
||||
}
|
||||
mNetTimer.expires_from_now(boost::posix_time::seconds(sec));
|
||||
@@ -269,8 +269,6 @@ public:
|
||||
{
|
||||
if (trustedValidations > v.trustedValidations) return true;
|
||||
if (trustedValidations < v.trustedValidations) return false;
|
||||
if (untrustedValidations > v.untrustedValidations) return true;
|
||||
if (untrustedValidations < v.untrustedValidations) return false;
|
||||
if (nodesUsing > v.nodesUsing) return true;
|
||||
if (nodesUsing < v.nodesUsing) return false;
|
||||
return highNode > v.highNode;
|
||||
@@ -308,7 +306,6 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Don't check unless last closed ledger is at least some seconds old
|
||||
// If full or tracking, check only at wobble time!
|
||||
if (checkLastClosedLedger(peerList))
|
||||
@@ -334,14 +331,11 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
|
||||
// check if the ledger is good enough to go to omFULL
|
||||
// Note: Do not go to omFULL if we don't have the previous ledger
|
||||
// check if the ledger is bad enough to go to omCONNECTED -- TODO
|
||||
if (theConfig.VALIDATION_SEED.isValid())
|
||||
{
|
||||
if (theApp->getOPs().getNetworkTimeNC() <
|
||||
(theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC() + 4))
|
||||
setMode(omFULL);
|
||||
else
|
||||
Log(lsWARNING) << "Too late to go to full, try next ledger";
|
||||
}
|
||||
if (theApp->getOPs().getNetworkTimeNC() <
|
||||
(theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC() + 4))
|
||||
setMode(omFULL);
|
||||
else
|
||||
Log(lsWARNING) << "Too late to go to full, will try in consensus window";
|
||||
}
|
||||
|
||||
if (mMode == omFULL)
|
||||
@@ -363,8 +357,11 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
|
||||
// Do we have sufficient validations for our last closed ledger? Or do sufficient nodes
|
||||
// agree? And do we have no better ledger available?
|
||||
// If so, we are either tracking or full.
|
||||
boost::unordered_map<uint256, ValidationCount> ledgers;
|
||||
|
||||
// FIXME: We may have a ledger with many recent validations but that no directly-connected
|
||||
// node is using. THis is kind of fundamental.
|
||||
|
||||
boost::unordered_map<uint256, ValidationCount> ledgers;
|
||||
for (std::vector<Peer::pointer>::const_iterator it = peerList.begin(), end = peerList.end(); it != end; ++it)
|
||||
{
|
||||
if (!*it)
|
||||
@@ -377,11 +374,10 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
|
||||
if (!!peerLedger)
|
||||
{
|
||||
// FIXME: If we have this ledger, don't count it if it's too far past its close time
|
||||
bool isNew = ledgers.find(peerLedger) == ledgers.end();
|
||||
ValidationCount& vc = ledgers[peerLedger];
|
||||
if (isNew)
|
||||
if (vc.nodesUsing == 0)
|
||||
{
|
||||
theApp->getValidations().getValidationCount(peerLedger,
|
||||
theApp->getValidations().getValidationCount(peerLedger, true,
|
||||
vc.trustedValidations, vc.untrustedValidations);
|
||||
Log(lsTRACE) << peerLedger.GetHex() << " has " << vc.trustedValidations <<
|
||||
" trusted validations and " << vc.untrustedValidations << " untrusted";
|
||||
@@ -395,19 +391,27 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
|
||||
|
||||
Ledger::pointer currentClosed = mLedgerMaster->getClosedLedger();
|
||||
uint256 closedLedger = currentClosed->getHash();
|
||||
ValidationCount& vc = ledgers[closedLedger];
|
||||
if ((vc.nodesUsing == 0) || (theApp->getWallet().getNodePublic() > vc.highNode))
|
||||
vc.highNode = theApp->getWallet().getNodePublic();
|
||||
++ledgers[closedLedger].nodesUsing;
|
||||
ValidationCount& ourVC = ledgers[closedLedger];
|
||||
if (ourVC.nodesUsing == 0)
|
||||
{
|
||||
ourVC.highNode = theApp->getWallet().getNodePublic();
|
||||
theApp->getValidations().getValidationCount(closedLedger, true,
|
||||
ourVC.trustedValidations, ourVC.untrustedValidations);
|
||||
}
|
||||
++ourVC.nodesUsing;
|
||||
ValidationCount bestVC = ourVC;
|
||||
|
||||
// 3) Is there a network ledger we'd like to switch to? If so, do we have it?
|
||||
bool switchLedgers = false;
|
||||
for(boost::unordered_map<uint256, ValidationCount>::iterator it = ledgers.begin(), end = ledgers.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
if (it->second > vc)
|
||||
Log(lsTRACE) << "L: " << it->first.GetHex() <<
|
||||
" t=" << it->second.trustedValidations << ", u=" << it->second.untrustedValidations <<
|
||||
", n=" << it->second.nodesUsing;
|
||||
if (it->second > bestVC)
|
||||
{
|
||||
vc = it->second;
|
||||
bestVC = it->second;
|
||||
closedLedger = it->first;
|
||||
switchLedgers = true;
|
||||
}
|
||||
@@ -467,8 +471,10 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger)
|
||||
s.set_newevent(newcoin::neSWITCHED_LEDGER);
|
||||
s.set_ledgerseq(newLedger->getLedgerSeq());
|
||||
s.set_networktime(theApp->getOPs().getNetworkTimeNC());
|
||||
uint256 plhash = newLedger->getParentHash();
|
||||
s.set_previousledgerhash(plhash.begin(), plhash.size());
|
||||
uint256 hash = newLedger->getParentHash();
|
||||
s.set_previousledgerhash(hash.begin(), hash.size());
|
||||
hash = newLedger->getHash();
|
||||
s.set_ledgerhash(hash.begin(), hash.size());
|
||||
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(s, newcoin::mtSTATUS_CHANGE);
|
||||
theApp->getConnectionPool().relayMessage(NULL, packet);
|
||||
}
|
||||
@@ -491,8 +497,9 @@ int NetworkOPs::beginConsensus(Ledger::pointer closingLedger)
|
||||
// Create a consensus object to get consensus on this ledger
|
||||
if (!!mConsensus) mConsensus->abort();
|
||||
prevLedger->setImmutable();
|
||||
mConsensus = boost::make_shared<LedgerConsensus>
|
||||
(prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC());
|
||||
mConsensus = boost::make_shared<LedgerConsensus>(
|
||||
prevLedger->getHash(), // FIXME: Only do this if the previous ledger is the consensus previous ledger
|
||||
prevLedger, theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC());
|
||||
|
||||
Log(lsDEBUG) << "Pre-close time, initiating consensus engine";
|
||||
return mConsensus->startup();
|
||||
@@ -568,6 +575,12 @@ void NetworkOPs::mapComplete(const uint256& hash, SHAMap::pointer map)
|
||||
|
||||
void NetworkOPs::endConsensus()
|
||||
{
|
||||
uint256 deadLedger = theApp->getMasterLedger().getClosedLedger()->getParentHash();
|
||||
Log(lsTRACE) << "Ledger " << deadLedger.GetHex() << " is now dead";
|
||||
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
|
||||
for (std::vector<Peer::pointer>::const_iterator it = peerList.begin(), end = peerList.end(); it != end; ++it)
|
||||
if (*it && ((*it)->getClosedLedgerHash() == deadLedger))
|
||||
(*it)->cycleStatus();
|
||||
mConsensus = boost::shared_ptr<LedgerConsensus>();
|
||||
}
|
||||
|
||||
|
||||
16
src/Peer.cpp
16
src/Peer.cpp
@@ -823,21 +823,23 @@ void Peer::recvStatus(newcoin::TMStatusChange& packet)
|
||||
packet.set_networktime(theApp->getOPs().getNetworkTimeNC());
|
||||
mLastStatus = packet;
|
||||
|
||||
if (packet.newevent() == newcoin::neLOST_SYNC)
|
||||
{
|
||||
mPreviousLedgerHash.zero();
|
||||
mClosedLedgerHash.zero();
|
||||
}
|
||||
if (packet.has_ledgerhash() && (packet.ledgerhash().size() == (256 / 8)))
|
||||
{ // a peer has changed ledgers
|
||||
if (packet.has_previousledgerhash() && (packet.previousledgerhash().size() == (256 / 8)))
|
||||
memcpy(mPreviousLedgerHash.begin(), packet.previousledgerhash().data(), 256 / 8);
|
||||
else
|
||||
mPreviousLedgerHash = mClosedLedgerHash;
|
||||
memcpy(mClosedLedgerHash.begin(), packet.ledgerhash().data(), 256 / 8);
|
||||
mClosedLedgerTime = ptFromSeconds(packet.networktime());
|
||||
Log(lsTRACE) << "peer LCL is " << mClosedLedgerHash.GetHex();
|
||||
}
|
||||
else if(packet.has_previousledgerhash() && packet.previousledgerhash().size() == (256 / 8))
|
||||
else mClosedLedgerHash.zero();
|
||||
if (packet.has_previousledgerhash() && packet.previousledgerhash().size() == (256 / 8))
|
||||
{
|
||||
memcpy(mClosedLedgerHash.begin(), packet.previousledgerhash().data(), 256 / 8);
|
||||
mClosedLedgerTime = ptFromSeconds(packet.networktime());
|
||||
memcpy(mPreviousLedgerHash.begin(), packet.previousledgerhash().data(), 256 / 8);
|
||||
}
|
||||
else mPreviousLedgerHash.zero();
|
||||
}
|
||||
|
||||
void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
|
||||
|
||||
@@ -136,6 +136,7 @@ public:
|
||||
|
||||
uint256 getClosedLedgerHash() const { return mClosedLedgerHash; }
|
||||
NewcoinAddress getNodePublic() const { return mNodePublic; }
|
||||
void cycleStatus() { mPreviousLedgerHash = mClosedLedgerHash; mClosedLedgerHash.zero(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@ enum SOE_Field
|
||||
sfBorrowRate,
|
||||
sfBorrowStart,
|
||||
sfBorrower,
|
||||
sfCloseTime,
|
||||
sfCurrency,
|
||||
sfCurrencyIn,
|
||||
sfCurrencyOut,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
SOElement SerializedValidation::sValidationFormat[] = {
|
||||
{ sfFlags, "Flags", STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ sfLedgerHash, "LedgerHash", STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ sfCloseTime, "CloseTime", STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ sfSigningKey, "SigningKey", STI_VL, SOE_REQUIRED, 0 },
|
||||
{ sfExtensions, "Extensions", STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 },
|
||||
@@ -18,11 +19,14 @@ SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSi
|
||||
if (!isValid()) throw std::runtime_error("Invalid validation");
|
||||
}
|
||||
|
||||
SerializedValidation::SerializedValidation(const uint256& ledgerHash, const NewcoinAddress& naSeed, bool isFull)
|
||||
SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint64 closeTime,
|
||||
const NewcoinAddress& naSeed, bool isFull)
|
||||
: STObject(sValidationFormat), mSignature("Signature"), mTrusted(false)
|
||||
{
|
||||
setValueFieldH256(sfLedgerHash, ledgerHash);
|
||||
setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic());
|
||||
setValueFieldU64(sfCloseTime, closeTime);
|
||||
if (naSeed.isValid())
|
||||
setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic());
|
||||
if (!isFull) setFlag(sFullFlag);
|
||||
|
||||
NewcoinAddress::createNodePrivate(naSeed).signNodePrivate(getSigningHash(), mSignature.peekValue());
|
||||
@@ -46,6 +50,11 @@ uint256 SerializedValidation::getLedgerHash() const
|
||||
return getValueFieldH256(sfLedgerHash);
|
||||
}
|
||||
|
||||
uint64 SerializedValidation::getCloseTime() const
|
||||
{
|
||||
return getValueFieldU64(sfCloseTime);
|
||||
}
|
||||
|
||||
bool SerializedValidation::isValid() const
|
||||
{
|
||||
try
|
||||
|
||||
@@ -23,9 +23,10 @@ public:
|
||||
SerializedValidation(SerializerIterator& sit, bool checkSignature = true);
|
||||
SerializedValidation(const Serializer& s, bool checkSignature = true);
|
||||
|
||||
SerializedValidation(const uint256& ledgerHash, const NewcoinAddress& naSeed, bool isFull);
|
||||
SerializedValidation(const uint256& ledgerHash, uint64 closeTime, const NewcoinAddress& naSeed, bool isFull);
|
||||
|
||||
uint256 getLedgerHash() const;
|
||||
uint64 getCloseTime() const;
|
||||
NewcoinAddress getSignerPublic() const;
|
||||
bool isValid() const;
|
||||
bool isFull() const;
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
CKey::pointer getSigningKey() const;
|
||||
uint256 getSigningHash() const;
|
||||
|
||||
void setTrusted() { mTrusted = true; }
|
||||
void setTrusted() { mTrusted = true; }
|
||||
void addSigned(Serializer&) const;
|
||||
void addSignature(Serializer&) const;
|
||||
std::vector<unsigned char> getSigned() const;
|
||||
|
||||
@@ -2,22 +2,40 @@
|
||||
#include "ValidationCollection.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "LedgerTiming.h"
|
||||
#include "Log.h"
|
||||
|
||||
bool ValidationCollection::addValidation(SerializedValidation::pointer val)
|
||||
{
|
||||
if(theApp->getUNL().nodeInUNL(val->getSignerPublic()))
|
||||
val->setTrusted();
|
||||
bool isTrusted = false;
|
||||
if (theApp->getUNL().nodeInUNL(val->getSignerPublic()))
|
||||
{
|
||||
uint64 now = theApp->getOPs().getNetworkTimeNC();
|
||||
uint64 valClose = val->getCloseTime();
|
||||
if ((now > valClose) && (now < (valClose + 2 * LEDGER_INTERVAL)))
|
||||
isTrusted = true;
|
||||
else
|
||||
Log(lsWARNING) << "Received stale validation";
|
||||
}
|
||||
|
||||
uint256 hash = val->getLedgerHash();
|
||||
uint160 node = val->getSignerPublic().getNodeID();
|
||||
|
||||
boost::mutex::scoped_lock sl(mValidationLock);
|
||||
bool ret = mValidations[hash].insert(std::make_pair(node, val)).second;
|
||||
if (ret)
|
||||
Log(lsINFO) << "Val for " << hash.GetHex() << " from " << node.GetHex() << " added " <<
|
||||
(val->isTrusted() ? "trusted" : "UNtrusted");
|
||||
return ret;
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mValidationLock);
|
||||
if (!mValidations[hash].insert(std::make_pair(node, val)).second)
|
||||
return false;
|
||||
if (isTrusted)
|
||||
{
|
||||
boost::unordered_map<uint160, SerializedValidation::pointer>::iterator it = mCurrentValidations.find(node);
|
||||
if ((it == mCurrentValidations.end()) || (val->getCloseTime() >= it->second->getCloseTime()))
|
||||
mCurrentValidations[node] = val;
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsINFO) << "Val for " << hash.GetHex() << " from " << node.GetHex() << " added " <<
|
||||
(val->isTrusted() ? "trusted" : "UNtrusted");
|
||||
return true;
|
||||
}
|
||||
|
||||
ValidationSet ValidationCollection::getValidations(const uint256& ledger)
|
||||
@@ -31,17 +49,24 @@ ValidationSet ValidationCollection::getValidations(const uint256& ledger)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ValidationCollection::getValidationCount(const uint256& ledger, int& trusted, int &untrusted)
|
||||
void ValidationCollection::getValidationCount(const uint256& ledger, bool currentOnly, int& trusted, int &untrusted)
|
||||
{
|
||||
trusted = untrusted = 0;
|
||||
boost::mutex::scoped_lock sl(mValidationLock);
|
||||
boost::unordered_map<uint256, ValidationSet>::iterator it = mValidations.find(ledger);
|
||||
uint64 now = theApp->getOPs().getNetworkTimeNC();
|
||||
if (it != mValidations.end())
|
||||
{
|
||||
for (ValidationSet::iterator vit = it->second.begin(), end = it->second.end();
|
||||
vit != end; ++vit)
|
||||
for (ValidationSet::iterator vit = it->second.begin(), end = it->second.end(); vit != end; ++vit)
|
||||
{
|
||||
if(vit->second->isTrusted())
|
||||
bool trusted = vit->second->isTrusted();
|
||||
if (trusted && currentOnly)
|
||||
{
|
||||
uint64 closeTime = vit->second->getCloseTime();
|
||||
if ((now < closeTime) || (now > (closeTime + 2 * LEDGER_INTERVAL)))
|
||||
trusted = false;
|
||||
}
|
||||
if (trusted)
|
||||
++trusted;
|
||||
else
|
||||
++untrusted;
|
||||
|
||||
@@ -16,13 +16,14 @@ class ValidationCollection
|
||||
|
||||
boost::mutex mValidationLock;
|
||||
boost::unordered_map<uint256, ValidationSet> mValidations;
|
||||
boost::unordered_map<uint160, SerializedValidation::pointer> mCurrentValidations;
|
||||
|
||||
public:
|
||||
ValidationCollection() { ; }
|
||||
|
||||
bool addValidation(SerializedValidation::pointer);
|
||||
ValidationSet getValidations(const uint256& ledger);
|
||||
void getValidationCount(const uint256& ledger, int& trusted, int& untrusted);
|
||||
void getValidationCount(const uint256& ledger, bool currentOnly, int& trusted, int& untrusted);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -88,6 +88,7 @@ enum NodeEvent {
|
||||
neCLOSING_LEDGER = 1; // closing a ledger because its close time has come
|
||||
neACCEPTED_LEDGER = 2; // accepting a closed ledger, we have finished computing it
|
||||
neSWITCHED_LEDGER = 3; // changing due to network consensus
|
||||
neLOST_SYNC = 4;
|
||||
}
|
||||
|
||||
message TMStatusChange {
|
||||
|
||||
Reference in New Issue
Block a user