mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'bootstrap'
This commit is contained in:
@@ -52,7 +52,6 @@ DB_SRCS = glob.glob('database/*.c') + glob.glob('database/*.cpp')
|
||||
JSON_SRCS = glob.glob('json/*.cpp')
|
||||
NEWCOIN_SRCS = glob.glob('src/*.cpp')
|
||||
PROTO_SRCS = env.Protoc([], 'src/newcoin.proto', PROTOCOUTDIR='obj', PROTOCPYTHONOUTDIR=None)
|
||||
UTIL_SRCS = glob.glob('util/*.cpp')
|
||||
|
||||
env.Clean(PROTO_SRCS, 'site_scons/site_tools/protoc.pyc')
|
||||
|
||||
@@ -62,7 +61,7 @@ UNUSED_SRCS = ['src/HttpReply.cpp', 'src/ValidationCollection.cpp']
|
||||
for file in UNUSED_SRCS:
|
||||
NEWCOIN_SRCS.remove(file)
|
||||
|
||||
NEWCOIN_SRCS += DB_SRCS + JSON_SRCS + UTIL_SRCS
|
||||
NEWCOIN_SRCS += DB_SRCS + JSON_SRCS
|
||||
|
||||
# Derive the object files from the source files.
|
||||
NEWCOIN_OBJS = []
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// need to make this compatible with at least SQLite and Mysql
|
||||
|
||||
// SQLite
|
||||
CREATE TABLE UNL (Hanko BLOB PRIMARY KEY, PubKey BLOB);
|
||||
CREATE TABLE Transactions (TransactionID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, From BLOB, Dest BLOB, Amount BIGINT UNSIGNED, LedgerIndex INT UNSIGNED, SeqNum INT, PubKey BLOB, Sig BLOB);
|
||||
CREATE TABLE Ledgers (LedgerID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, LedgerIndex INT UNSIGNED, Hash BLOB, ParentHash BLOB,FeeHeld BIGINT UNSIGNED);
|
||||
CREATE TABLE Validations(ValidationID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, LedgerIndex INT UNSIGNED, Hash BLOB, Hanko BLOB, SeqNum INT UNSIGNED, Sig BLOB, WeCare TINYINT);
|
||||
CREATE TABLE LedgerTransactionMap (LedgerID INT UNSIGNED, TransactionID INT UNSIGNED, Include TINYINT);
|
||||
CREATE TABLE LedgerAccountMap(LedgerID INT UNSIGNED,AccountID INT UNSIGNED);
|
||||
CREATE TABLE Accounts (AccountID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, Address BLOB, Amount BIGINT UNSIGNED, SeqNum INT);
|
||||
CREATE TABLE AcceptedLedgers (LedgerIndex INT UNSIGNED PRIMARY KEY, LedgerID INT UNSIGNED);
|
||||
|
||||
CREATE TABLE Wallet (Address BLOB,PubKey BLOB,PrivateKey BLOB,int SeqNum);
|
||||
CREATE TABLE YourValidations(LedgerIndex INT UNSIGNED PRIMARY KEY, Hash BLOB, SeqNum INT UNSIGNED );
|
||||
|
||||
|
||||
|
||||
// MYSQL
|
||||
drop database if exists newcoin;
|
||||
CREATE DATABASE newcoin;
|
||||
use newcoin;
|
||||
CREATE TABLE UNL (Hanko BINARY(20) PRIMARY KEY, PubKey BINARY(128));
|
||||
CREATE TABLE Transactions (TransactionID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, From BINARY(20), Dest BINARY(20), Amount BIGINT UNSIGNED, LedgerIndex INT UNSIGNED, SeqNum INT, PubKey BINARY(64), Sig BINARY(32));
|
||||
CREATE TABLE Ledgers (LedgerID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, LedgerIndex INT UNSIGNED, Hash BINARY(32), ParentHash BINARY(32),FeeHeld BIGINT UNSIGNED); //, Accepted TINYINT
|
||||
CREATE TABLE Validations(LedgerIndex INT UNSIGNED, Hash BINARY(32), Hanko BINARY(20), SeqNum INT UNSIGNED, Sig BINARY(32), WeCare TINYINT);
|
||||
CREATE TABLE LedgerTransactionMap (LedgerID INT UNSIGNED, TransactionID INT UNSIGNED, Include TINYINT);
|
||||
CREATE TABLE LedgerAccountMap(LedgerID INT UNSIGNED,AccountID INT UNSIGNED);
|
||||
CREATE TABLE Accounts (AccountID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, Address BINARY(20), Amount BIGINT UNSIGNED, SeqNum INT);
|
||||
CREATE TABLE AcceptedLedgers (LedgerIndex INT UNSIGNED PRIMARY KEY, LedgerID INT UNSIGNED);
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
AccountState::AccountState(const NewcoinAddress& id) : mAccountID(id), mValid(false)
|
||||
{
|
||||
if (!id.IsValid()) return;
|
||||
if (!id.isValid()) return;
|
||||
mLedgerEntry = boost::make_shared<SerializedLedgerEntry>(ltACCOUNT_ROOT);
|
||||
mLedgerEntry->setIndex(Ledger::getAccountRootIndex(id));
|
||||
mLedgerEntry->setIFieldAccount(sfAccount, id);
|
||||
@@ -21,7 +21,7 @@ AccountState::AccountState(SerializedLedgerEntry::pointer ledgerEntry) : mLedger
|
||||
if (!mLedgerEntry) return;
|
||||
if (mLedgerEntry->getType()!=ltACCOUNT_ROOT) return;
|
||||
mAccountID = mLedgerEntry->getValueFieldAccount(sfAccount);
|
||||
if (mAccountID.IsValid()) mValid = true;
|
||||
if (mAccountID.isValid()) mValid = true;
|
||||
}
|
||||
|
||||
void AccountState::addJson(Json::Value& val)
|
||||
|
||||
@@ -73,8 +73,8 @@ void Application::run()
|
||||
|
||||
//
|
||||
// Begin validation and ip maintenance.
|
||||
// - Wallet maintains local information: including identity and network connection persistency information.
|
||||
//
|
||||
|
||||
mWallet.start();
|
||||
|
||||
//
|
||||
@@ -93,10 +93,12 @@ void Application::run()
|
||||
mRPCDoor=new RPCDoor(mIOService);
|
||||
}//else BOOST_LOG_TRIVIAL(info) << "No RPC Port set. Not listening for commands.";
|
||||
|
||||
mConnectionPool.connectToNetwork(mKnownNodes, mIOService);
|
||||
mTimingService.start(mIOService);
|
||||
//
|
||||
// Begin connectting to network.
|
||||
//
|
||||
mConnectionPool.start();
|
||||
|
||||
std::cout << "Before Run." << std::endl;
|
||||
mTimingService.start(mIOService);
|
||||
|
||||
// Temporary root account will be ["This is my payphrase."]:0
|
||||
NewcoinAddress rootFamilySeed; // Hold the 128 password.
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "UniqueNodeList.h"
|
||||
#include "ConnectionPool.h"
|
||||
#include "KnownNodeList.h"
|
||||
#include "TimingService.h"
|
||||
#include "PubKeyCache.h"
|
||||
#include "ScopedLock.h"
|
||||
@@ -42,7 +41,6 @@ class Application
|
||||
|
||||
TimingService mTimingService;
|
||||
UniqueNodeList mUNL;
|
||||
KnownNodeList mKnownNodes;
|
||||
PubKeyCache mPKCache;
|
||||
LedgerMaster mMasterLedger;
|
||||
LedgerAcquireMaster mMasterLedgerAcquire;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <fstream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#define CONFIG_FILE_NAME "newcoind.cfg"
|
||||
#define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg
|
||||
#define SECTION_PEER_IP "peer_ip"
|
||||
#define SECTION_PEER_PORT "peer_port"
|
||||
#define SECTION_RPC_IP "rpc_ip"
|
||||
@@ -22,8 +22,7 @@ Config::Config()
|
||||
|
||||
NETWORK_START_TIME=1319844908;
|
||||
|
||||
|
||||
PEER_PORT=6561;
|
||||
PEER_PORT=SYSTEM_PEER_PORT;
|
||||
RPC_PORT=5001;
|
||||
NUMBER_CONNECTIONS=30;
|
||||
|
||||
|
||||
16
src/Config.h
16
src/Config.h
@@ -1,4 +1,11 @@
|
||||
#include "string"
|
||||
#ifndef __CONFIG__
|
||||
#define __CONFIG__
|
||||
|
||||
#include <string>
|
||||
|
||||
#define SYSTEM_NAME "newcoin"
|
||||
|
||||
const int SYSTEM_PEER_PORT=6561;
|
||||
|
||||
class Config
|
||||
{
|
||||
@@ -8,9 +15,7 @@ public:
|
||||
std::string VERSION_STR;
|
||||
|
||||
// network parameters
|
||||
// std::string NETWORK_ID;
|
||||
// std::string NETWORK_DNS_SEEDS;
|
||||
int NETWORK_START_TIME; // The Unix time we start ledger 0
|
||||
int NETWORK_START_TIME; // The Unix time we start ledger 0
|
||||
int TRANSACTION_FEE_BASE;
|
||||
int LEDGER_SECONDS;
|
||||
int LEDGER_PROPOSAL_DELAY_SECONDS;
|
||||
@@ -28,8 +33,6 @@ public:
|
||||
// bool NODE_DUMB; // we are a 'dumb' client
|
||||
// bool NODE_SMART; // we offer services to 'dumb' clients
|
||||
|
||||
// std::string HANKO_PRIVATE;
|
||||
|
||||
// RPC parameters
|
||||
std::string RPC_IP;
|
||||
int RPC_PORT;
|
||||
@@ -48,3 +51,4 @@ public:
|
||||
};
|
||||
|
||||
extern Config theConfig;
|
||||
#endif
|
||||
|
||||
@@ -1,32 +1,163 @@
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "ConnectionPool.h"
|
||||
#include "Config.h"
|
||||
#include "KnownNodeList.h"
|
||||
#include "Peer.h"
|
||||
#include "Application.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
ConnectionPool::ConnectionPool()
|
||||
ConnectionPool::ConnectionPool() :
|
||||
iConnecting(0)
|
||||
{ ; }
|
||||
|
||||
|
||||
void ConnectionPool::connectToNetwork(KnownNodeList& nodeList,boost::asio::io_service& io_service)
|
||||
void ConnectionPool::start()
|
||||
{
|
||||
for(int n=0; n<theConfig.NUMBER_CONNECTIONS; n++)
|
||||
// XXX Start running policy.
|
||||
}
|
||||
|
||||
// XXX Broken don't send a message to a peer if we got it from the peer.
|
||||
void ConnectionPool::relayMessage(Peer* fromPeer, PackedMessage::pointer msg)
|
||||
{
|
||||
BOOST_FOREACH(naPeer pair, mConnectedMap)
|
||||
{
|
||||
KnownNode* node=nodeList.getNextNode();
|
||||
if(!node) return;
|
||||
|
||||
Peer::pointer peer=Peer::create(io_service);
|
||||
// peer->connectTo(*node); // FIXME
|
||||
mPeers.push_back(peer);
|
||||
|
||||
Peer::pointer peer = pair.second;
|
||||
|
||||
if(!fromPeer || !(peer.get() == fromPeer))
|
||||
peer->sendPacket(msg);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
// Inbound connection, false=reject
|
||||
// Reject addresses we already have in our table.
|
||||
// XXX Reject, if we have too many connections.
|
||||
bool ConnectionPool::peerAccepted(Peer::pointer peer, const std::string& strIp, int iPort)
|
||||
{
|
||||
bool bAccept;
|
||||
ipPort ip = make_pair(strIp, iPort);
|
||||
|
||||
boost::unordered_map<ipPort, Peer::pointer>::iterator it;
|
||||
|
||||
boost::mutex::scoped_lock sl(mPeerLock);
|
||||
|
||||
it = mIpMap.find(ip);
|
||||
|
||||
if (it == mIpMap.end())
|
||||
{
|
||||
// Did not find it. Not already connecting or connected.
|
||||
|
||||
std::cerr << "ConnectionPool::peerAccepted: " << ip.first << " " << ip.second << std::endl;
|
||||
// Mark as connecting.
|
||||
mIpMap[ip] = peer;
|
||||
bAccept = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found it. Already connected or connecting.
|
||||
|
||||
bAccept = false;
|
||||
}
|
||||
|
||||
return bAccept;
|
||||
}
|
||||
|
||||
bool ConnectionPool::connectTo(const std::string& strIp, int iPort)
|
||||
{
|
||||
ipPort ip = make_pair(strIp, iPort);
|
||||
|
||||
boost::unordered_map<ipPort, Peer::pointer>::iterator it;
|
||||
|
||||
boost::mutex::scoped_lock sl(mPeerLock);
|
||||
|
||||
it = mIpMap.find(ip);
|
||||
|
||||
if (it == mIpMap.end())
|
||||
{
|
||||
// Did not find it. Not already connecting or connected.
|
||||
|
||||
Peer::pointer peer(Peer::create(theApp->getIOService()));
|
||||
|
||||
mIpMap[ip] = peer;
|
||||
|
||||
peer->connect(strIp, iPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found it. Already connected.
|
||||
std::cerr << "ConnectionPool::connectTo: Already connected: "
|
||||
<< strIp << " " << iPort << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Json::Value ConnectionPool::getPeersJson()
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
BOOST_FOREACH(naPeer pair, mConnectedMap)
|
||||
{
|
||||
Peer::pointer peer = pair.second;
|
||||
|
||||
ret.append(peer->getJson());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ConnectionPool::peerConnected(Peer::pointer peer)
|
||||
{
|
||||
std::cerr << "ConnectionPool::peerConnected" << std::endl;
|
||||
}
|
||||
|
||||
void ConnectionPool::peerDisconnected(Peer::pointer peer)
|
||||
{
|
||||
std::cerr << "ConnectionPool::peerDisconnected: " << peer->mIpPort.first << " " << peer->mIpPort.second << std::endl;
|
||||
|
||||
boost::mutex::scoped_lock sl(mPeerLock);
|
||||
|
||||
// XXX Don't access member variable directly.
|
||||
if (peer->mPublicKey.isValid())
|
||||
{
|
||||
boost::unordered_map<NewcoinAddress, Peer::pointer>::iterator itCm;
|
||||
|
||||
itCm = mConnectedMap.find(peer->mPublicKey);
|
||||
|
||||
if (itCm == mConnectedMap.end())
|
||||
{
|
||||
// Did not find it. Not already connecting or connected.
|
||||
std::cerr << "Internal Error: peer connection was inconsistent." << std::endl;
|
||||
// XXX Bad error.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found it. Delete it.
|
||||
mConnectedMap.erase(itCm);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Don't access member variable directly.
|
||||
boost::unordered_map<ipPort, Peer::pointer>::iterator itIp;
|
||||
|
||||
itIp = mIpMap.find(peer->mIpPort);
|
||||
|
||||
if (itIp == mIpMap.end())
|
||||
{
|
||||
// Did not find it. Not already connecting or connected.
|
||||
std::cerr << "Internal Error: peer wasn't connected." << std::endl;
|
||||
// XXX Bad error.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found it. Delete it.
|
||||
mIpMap.erase(itIp);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool ConnectionPool::isMessageKnown(PackedMessage::pointer msg)
|
||||
{
|
||||
for(unsigned int n=0; n<mBroadcastMessages.size(); n++)
|
||||
@@ -35,89 +166,6 @@ bool ConnectionPool::isMessageKnown(PackedMessage::pointer msg)
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
void ConnectionPool::relayMessage(Peer* fromPeer, PackedMessage::pointer msg)
|
||||
{
|
||||
BOOST_FOREACH(Peer::pointer peer, mPeers)
|
||||
{
|
||||
if(!fromPeer || !(peer.get() == fromPeer))
|
||||
peer->sendPacket(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConnectionPool::addToMap(const uint160& hanko, Peer::pointer peer)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(peerLock);
|
||||
return peerMap.insert(std::make_pair(hanko, peer)).second;
|
||||
}
|
||||
|
||||
bool ConnectionPool::delFromMap(const uint160& hanko)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(peerLock);
|
||||
std::map<uint160, Peer::pointer>::iterator it=peerMap.find(hanko);
|
||||
if((it==peerMap.end()) || (it->first!=hanko)) return false;
|
||||
peerMap.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
Peer::pointer ConnectionPool::findInMap(const uint160& hanko)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(peerLock);
|
||||
std::map<uint160, Peer::pointer>::iterator it=peerMap.find(hanko);
|
||||
if(it==peerMap.end()) return Peer::pointer();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool ConnectionPool::inMap(const uint160& hanko)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(peerLock);
|
||||
return peerMap.find(hanko) != peerMap.end();
|
||||
}
|
||||
|
||||
std::map<uint160, Peer::pointer> ConnectionPool::getAllConnected()
|
||||
{
|
||||
boost::mutex::scoped_lock sl(peerLock);
|
||||
return peerMap;
|
||||
}
|
||||
|
||||
bool ConnectionPool::connectTo(const std::string& host, const std::string& port)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::asio::ip::tcp::resolver res(theApp->getIOService());
|
||||
boost::asio::ip::tcp::resolver::query query(host.c_str(), port.c_str());
|
||||
boost::asio::ip::tcp::resolver::iterator it(res.resolve(query)), end;
|
||||
|
||||
Peer::pointer peer(Peer::create(theApp->getIOService()));
|
||||
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||
while (error && (it!=end))
|
||||
{
|
||||
peer->getSocket().close();
|
||||
peer->getSocket().connect(*it++, error);
|
||||
}
|
||||
if(error) return false;
|
||||
boost::mutex::scoped_lock sl(peerLock);
|
||||
mPeers.push_back(peer);
|
||||
peer->connected(boost::system::error_code());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Json::Value ConnectionPool::getPeersJson()
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
BOOST_FOREACH(Peer::pointer peer, mPeers)
|
||||
{
|
||||
ret.append(peer->getJson());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
// vim:ts=4
|
||||
|
||||
@@ -1,41 +1,65 @@
|
||||
#ifndef __CONNECTION_POOL__
|
||||
#define __CONNECTION_POOL__
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include "Peer.h"
|
||||
#include "PackedMessage.h"
|
||||
#include "types.h"
|
||||
|
||||
class KnownNodeList;
|
||||
|
||||
/*
|
||||
This is the list of all the Peers we are currently connected to
|
||||
*/
|
||||
//
|
||||
// Access to the Newcoin network.
|
||||
//
|
||||
class ConnectionPool
|
||||
{
|
||||
boost::mutex peerLock;
|
||||
std::vector<Peer::pointer> mPeers; // FIXME
|
||||
std::map<uint160, Peer::pointer> peerMap;
|
||||
//std::vector<std::pair<PackedMessage::pointer,int> > mBroadcastMessages;
|
||||
private:
|
||||
boost::mutex mPeerLock;
|
||||
|
||||
typedef std::pair<NewcoinAddress, Peer::pointer> naPeer;
|
||||
|
||||
// Count of peers we are in progress of connecting to.
|
||||
// We are in progress until we know their network public key.
|
||||
int iConnecting;
|
||||
|
||||
// Peers we are connecting with and non-thin peers we are connected to.
|
||||
boost::unordered_map<ipPort, Peer::pointer> mIpMap;
|
||||
|
||||
// Non-thin peers which we are connected to.
|
||||
boost::unordered_map<NewcoinAddress, Peer::pointer> mConnectedMap;
|
||||
|
||||
public:
|
||||
ConnectionPool();
|
||||
void connectToNetwork(KnownNodeList& nodeList, boost::asio::io_service& io_service);
|
||||
|
||||
// Begin enforcing connection policy.
|
||||
void start();
|
||||
|
||||
// Send message to network.
|
||||
void relayMessage(Peer* fromPeer, PackedMessage::pointer msg);
|
||||
//bool isMessageKnown(PackedMessage::pointer msg);
|
||||
|
||||
// hanko->peer mapping functions
|
||||
bool inMap(const uint160& hanko);
|
||||
bool addToMap(const uint160& hanko, Peer::pointer peer);
|
||||
bool delFromMap(const uint160& hanko);
|
||||
Peer::pointer findInMap(const uint160& hanko);
|
||||
std::map<uint160, Peer::pointer> getAllConnected();
|
||||
// Manual connection request.
|
||||
// Queue for immediate scanning.
|
||||
bool connectTo(const std::string& strIp, int iPort);
|
||||
|
||||
bool connectTo(const std::string& host, const std::string& port);
|
||||
//
|
||||
// Peer connectivity notification.
|
||||
//
|
||||
|
||||
// Inbound connection, false=reject
|
||||
bool peerAccepted(Peer::pointer peer, const std::string& strIp, int iPort);
|
||||
|
||||
// We know peers node public key.
|
||||
void peerConnected(Peer::pointer peer);
|
||||
|
||||
// No longer connected.
|
||||
void peerDisconnected(Peer::pointer peer);
|
||||
|
||||
Json::Value getPeersJson();
|
||||
|
||||
#if 0
|
||||
//std::vector<std::pair<PackedMessage::pointer,int> > mBroadcastMessages;
|
||||
|
||||
bool isMessageKnown(PackedMessage::pointer msg);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "KnownNodeList.h"
|
||||
#include "../util/pugixml.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
KnownNode::KnownNode(const char* ip,int port,int lastSeen,int lastTried)
|
||||
: mIP(ip), mPort(port), mLastSeen(lastSeen), mLastTried(lastTried)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
KnownNodeList::KnownNodeList()
|
||||
{
|
||||
mTriedIndex=0;
|
||||
}
|
||||
|
||||
void KnownNodeList::load()
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result result = doc.load_file("nodes.xml");
|
||||
xml_node nodes=doc.child("nodes");
|
||||
for(xml_node child = nodes.first_child(); child; child = child.next_sibling())
|
||||
{
|
||||
mNodes.push_back(KnownNode(child.attribute("ip").value(),child.attribute("port").as_int(),child.attribute("last").as_int(),0));
|
||||
}
|
||||
}
|
||||
|
||||
KnownNode* KnownNodeList::getNextNode()
|
||||
{
|
||||
if(mTriedIndex>=mNodes.size())
|
||||
{
|
||||
return(NULL);
|
||||
}else
|
||||
{
|
||||
mTriedIndex++;
|
||||
return(&(mNodes[mTriedIndex-1]));
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef __KNOWNNODELIST__
|
||||
#define __KNOWNNODELIST__
|
||||
|
||||
#include "vector"
|
||||
#include <string>
|
||||
|
||||
class KnownNode
|
||||
{
|
||||
public:
|
||||
std::string mIP;
|
||||
int mPort;
|
||||
int mLastSeen;
|
||||
int mLastTried;
|
||||
|
||||
KnownNode(const char* ip,int port,int lastSeen,int lastTried);
|
||||
};
|
||||
|
||||
class KnownNodeList
|
||||
{
|
||||
unsigned int mTriedIndex;
|
||||
std::vector <KnownNode> mNodes;
|
||||
public:
|
||||
KnownNodeList();
|
||||
|
||||
void load();
|
||||
void addNode();
|
||||
KnownNode* getNextNode();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,13 +10,14 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
NewcoinAddress::NewcoinAddress()
|
||||
{
|
||||
nVersion = VER_NONE;
|
||||
}
|
||||
|
||||
bool NewcoinAddress::IsValid() const
|
||||
bool NewcoinAddress::isValid() const
|
||||
{
|
||||
return !vchData.empty();
|
||||
}
|
||||
@@ -26,8 +27,9 @@ void NewcoinAddress::clear()
|
||||
nVersion = VER_NONE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Hanko
|
||||
// Hanko - OBSOLETE
|
||||
//
|
||||
|
||||
uint160 NewcoinAddress::getHanko() const
|
||||
@@ -84,6 +86,7 @@ void NewcoinAddress::setHanko(const uint160& hash160)
|
||||
void NewcoinAddress::setHanko(const NewcoinAddress& nodePublic) {
|
||||
setHanko(nodePublic.getHanko());
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// NodePublic
|
||||
|
||||
@@ -27,11 +27,11 @@ private:
|
||||
public:
|
||||
NewcoinAddress();
|
||||
|
||||
bool IsValid() const;
|
||||
bool isValid() const;
|
||||
void clear();
|
||||
|
||||
#if 0
|
||||
//
|
||||
// hanko
|
||||
// hanko - OBSOLETE
|
||||
//
|
||||
uint160 getHanko() const;
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
bool setHanko(const std::string& strHanko);
|
||||
void setHanko(const uint160& hash160);
|
||||
void setHanko(const NewcoinAddress& nodePublic);
|
||||
|
||||
#endif
|
||||
//
|
||||
// Node Public
|
||||
//
|
||||
|
||||
111
src/Peer.cpp
111
src/Peer.cpp
@@ -1,23 +1,24 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
//#include <boost/log/trivial.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
//#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "../json/writer.h"
|
||||
|
||||
#include "Peer.h"
|
||||
#include "KnownNodeList.h"
|
||||
#include "Config.h"
|
||||
#include "Application.h"
|
||||
#include "Conversion.h"
|
||||
#include "SerializedTransaction.h"
|
||||
|
||||
Peer::Peer(boost::asio::io_service& io_service)
|
||||
: mSocket(io_service)
|
||||
: mSocket(io_service),
|
||||
mCtx(boost::asio::ssl::context::sslv23),
|
||||
mSocketSsl(io_service, mCtx)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -53,22 +54,102 @@ void Peer::detach()
|
||||
{
|
||||
mSendQ.clear();
|
||||
mSocket.close();
|
||||
if(!!mHanko) theApp->getConnectionPool().delFromMap(mHanko);
|
||||
|
||||
theApp->getConnectionPool().peerDisconnected(shared_from_this());
|
||||
}
|
||||
|
||||
void Peer::connected(const boost::system::error_code& error)
|
||||
// Begin trying to connect. We are not connected till we know and accept peer's public key.
|
||||
// Only takes IP addresses (not domains).
|
||||
void Peer::connect(const std::string strIp, int iPort)
|
||||
{
|
||||
if(!error)
|
||||
{
|
||||
std::cout << "Connected to Peer." << std::endl; //BOOST_LOG_TRIVIAL(info) << "Connected to Peer.";
|
||||
int iPortAct = iPort < 0 ? SYSTEM_PEER_PORT : iPort;
|
||||
|
||||
sendHello();
|
||||
start_read_header();
|
||||
boost::asio::ip::tcp::resolver::query query(strIp, boost::lexical_cast<std::string>(iPortAct),
|
||||
boost::asio::ip::resolver_query_base::numeric_host|boost::asio::ip::resolver_query_base::numeric_service);
|
||||
boost::asio::ip::tcp::resolver resolver(theApp->getIOService());
|
||||
boost::system::error_code err;
|
||||
boost::asio::ip::tcp::resolver::iterator itrEndpoint = resolver.resolve(query, err);
|
||||
|
||||
if (err || itrEndpoint == boost::asio::ip::tcp::resolver::iterator())
|
||||
{
|
||||
// Failed to resolve ip.
|
||||
detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
mIpPort = make_pair(strIp, iPort);
|
||||
#if 1
|
||||
boost::asio::async_connect(
|
||||
mSocket,
|
||||
itrEndpoint,
|
||||
boost::bind(
|
||||
&Peer::handleConnect,
|
||||
shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::iterator));
|
||||
#else
|
||||
// Connect via ssl.
|
||||
// XXX Why doesn't handler need an iterator?
|
||||
boost::asio::async_connect(
|
||||
mSocketSsl.lowest_layer(),
|
||||
itrEndpoint,
|
||||
boost::bind(
|
||||
&Peer::handleConnect,
|
||||
shared_from_this(),
|
||||
boost::asio::placeholders::error));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// SSL connection.
|
||||
void Peer::handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
std::cout << "Socket Connect failed:" << error << std::endl;
|
||||
detach();
|
||||
std::cout << "Peer::connected Error: " << error << std::endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Socket Connected." << std::endl;
|
||||
// XXX Exchange public keys.
|
||||
sendHello();
|
||||
start_read_header();
|
||||
}
|
||||
}
|
||||
|
||||
// Peer connected via door.
|
||||
void Peer::connected(const boost::system::error_code& error)
|
||||
{
|
||||
boost::asio::ip::tcp::endpoint ep = mSocket.remote_endpoint();
|
||||
int iPort = ep.port();
|
||||
std::string strIp = ep.address().to_string();
|
||||
|
||||
if (iPort == SYSTEM_PEER_PORT)
|
||||
iPort = -1;
|
||||
|
||||
std::cout << "Remote peer: accept: " << strIp << " " << iPort << std::endl;
|
||||
|
||||
if (error)
|
||||
{
|
||||
std::cout << "Remote peer: accept error: " << error << std::endl;
|
||||
detach();
|
||||
}
|
||||
else if (!theApp->getConnectionPool().peerAccepted(shared_from_this(), strIp, iPort))
|
||||
{
|
||||
std::cout << "Remote peer: rejecting." << std::endl;
|
||||
// XXX Reject with a rejection message: already connected
|
||||
detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Remote peer: accepted." << std::endl;
|
||||
//BOOST_LOG_TRIVIAL(info) << "Connected to Peer.";
|
||||
|
||||
// Not redundant, add to connection list.
|
||||
// XXX Exchange public keys.
|
||||
sendHello();
|
||||
start_read_header();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,9 +632,9 @@ void Peer::punishPeer(PeerPunish)
|
||||
Json::Value Peer::getJson() {
|
||||
Json::Value ret(Json::objectValue);
|
||||
|
||||
ret["ip"] = mSocket.remote_endpoint().address().to_string();
|
||||
ret["port"] = mSocket.remote_endpoint().port();
|
||||
ret["hanko"] = mHanko.ToString();
|
||||
ret["ip"] = mSocket.remote_endpoint().address().to_string();
|
||||
ret["port"] = mSocket.remote_endpoint().port();
|
||||
ret["public_key"] = mPublicKey.ToString();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
23
src/Peer.h
23
src/Peer.h
@@ -2,9 +2,10 @@
|
||||
#define __PEER__
|
||||
|
||||
#include <bitset>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "../obj/src/newcoin.pb.h"
|
||||
#include "PackedMessage.h"
|
||||
@@ -19,19 +20,30 @@ enum PeerPunish
|
||||
PP_UNWANTED_DATA=3, // The peer sent us data we didn't want/need
|
||||
};
|
||||
|
||||
typedef std::pair<std::string,int> ipPort;
|
||||
|
||||
class Peer : public boost::enable_shared_from_this<Peer>
|
||||
{
|
||||
public:
|
||||
static const int psbGotHello=0, psbSentHello=1, psbInMap=2, psbTrusted=3;
|
||||
static const int psbNoLedgers=4, psbNoTransactions=5, psbDownLevel=6;
|
||||
|
||||
protected:
|
||||
NewcoinAddress mPublicKey; // Public key of peer.
|
||||
ipPort mIpPort;
|
||||
|
||||
void handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it);
|
||||
|
||||
private:
|
||||
boost::asio::ip::tcp::socket mSocket;
|
||||
boost::asio::ssl::context mCtx;
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> mSocketSsl;
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<uint8_t> mReadbuf;
|
||||
std::list<PackedMessage::pointer> mSendQ;
|
||||
PackedMessage::pointer mSendingPacket;
|
||||
std::bitset<32> mPeerBits;
|
||||
uint160 mHanko;
|
||||
|
||||
Peer(boost::asio::io_service& io_service);
|
||||
|
||||
@@ -42,7 +54,7 @@ protected:
|
||||
void processReadBuffer();
|
||||
void start_read_header();
|
||||
void start_read_body(unsigned msg_len);
|
||||
|
||||
|
||||
void sendPacketForce(PackedMessage::pointer packet);
|
||||
|
||||
void sendHello();
|
||||
@@ -81,6 +93,7 @@ public:
|
||||
return mSocket;
|
||||
}
|
||||
|
||||
void connect(const std::string strIp, int iPort);
|
||||
void connected(const boost::system::error_code& error);
|
||||
void detach();
|
||||
bool samePeer(Peer::pointer p) { return samePeer(*p); }
|
||||
|
||||
@@ -205,12 +205,12 @@ Json::Value RPCServer::doCreateFamily(Json::Value& params)
|
||||
family=theApp->getWallet().addFamily(query, false);
|
||||
}
|
||||
|
||||
if(!family.IsValid())
|
||||
if(!family.isValid())
|
||||
return JSONRPCError(500, "Invalid family specifier");
|
||||
|
||||
Json::Value ret(theApp->getWallet().getFamilyJson(family));
|
||||
if(ret.isNull()) return JSONRPCError(500, "Invalid family");
|
||||
if(seed.IsValid())
|
||||
if(seed.isValid())
|
||||
{
|
||||
ret["FamilySeed"]=seed.humanFamilySeed();
|
||||
}
|
||||
@@ -255,7 +255,7 @@ Json::Value RPCServer::doNewAccount(Json::Value ¶ms)
|
||||
return JSONRPCError(500, "Family required");
|
||||
|
||||
NewcoinAddress family = parseFamily(fParam);
|
||||
if(!family.IsValid()) return JSONRPCError(500, "Family not found.");
|
||||
if(!family.isValid()) return JSONRPCError(500, "Family not found.");
|
||||
|
||||
LocalAccount::pointer account(theApp->getWallet().getNewLocalAccount(family));
|
||||
if(!account)
|
||||
@@ -272,7 +272,7 @@ Json::Value RPCServer::doLock(Json::Value ¶ms)
|
||||
if(extractString(fParam, params, 0))
|
||||
{ // local <family>
|
||||
NewcoinAddress family = parseFamily(fParam);
|
||||
if(!family.IsValid()) return JSONRPCError(500, "Family not found");
|
||||
if(!family.isValid()) return JSONRPCError(500, "Family not found");
|
||||
|
||||
theApp->getWallet().lock(family);
|
||||
}
|
||||
@@ -304,7 +304,7 @@ Json::Value RPCServer::doUnlock(Json::Value ¶ms)
|
||||
// pass phrase
|
||||
family=theApp->getWallet().addFamily(param, false);
|
||||
|
||||
if(!family.IsValid())
|
||||
if(!family.isValid())
|
||||
return JSONRPCError(500, "Bad family");
|
||||
|
||||
Json::Value ret(theApp->getWallet().getFamilyJson(family));
|
||||
@@ -339,7 +339,7 @@ Json::Value RPCServer::doFamilyInfo(Json::Value ¶ms)
|
||||
extractString(fParam, params, 0);
|
||||
|
||||
NewcoinAddress family=parseFamily(fParam);
|
||||
if(!family.IsValid()) return JSONRPCError(500, "No such family");
|
||||
if(!family.isValid()) return JSONRPCError(500, "No such family");
|
||||
|
||||
Json::Value obj(theApp->getWallet().getFamilyJson(family));
|
||||
if(obj.isNull())
|
||||
@@ -352,7 +352,7 @@ Json::Value RPCServer::doFamilyInfo(Json::Value ¶ms)
|
||||
int kn=boost::lexical_cast<int>(keyNum);
|
||||
NewcoinAddress k=theApp->getWallet().peekKey(family, kn);
|
||||
|
||||
if(k.IsValid())
|
||||
if(k.isValid())
|
||||
{
|
||||
Json::Value key(Json::objectValue);
|
||||
key["Number"]=kn;
|
||||
@@ -367,14 +367,30 @@ Json::Value RPCServer::doFamilyInfo(Json::Value ¶ms)
|
||||
Json::Value RPCServer::doConnect(Json::Value& params)
|
||||
{
|
||||
// connect <ip> [port]
|
||||
std::string host, port;
|
||||
std::string strIp;
|
||||
int iPort = -1;
|
||||
|
||||
if(!extractString(host, params, 0))
|
||||
return JSONRPCError(500, "Host required");
|
||||
if(!extractString(port, params, 1))
|
||||
port="6561";
|
||||
if(!theApp->getConnectionPool().connectTo(host, port))
|
||||
if(!params.isArray() || !params.size() || params.size() > 2)
|
||||
return JSONRPCError(500, "Invalid parameters");
|
||||
|
||||
// XXX Might allow domain for manual connections.
|
||||
if(!extractString(strIp, params, 0))
|
||||
return JSONRPCError(500, "Host IP required");
|
||||
|
||||
if(params.size() == 2)
|
||||
{
|
||||
std::string strPort;
|
||||
|
||||
// YYY Should make an extract int.
|
||||
if (!extractString(strPort, params, 1))
|
||||
return JSONRPCError(500, "Bad port");
|
||||
|
||||
iPort = boost::lexical_cast<int>(strPort);
|
||||
}
|
||||
|
||||
if(!theApp->getConnectionPool().connectTo(strIp, iPort))
|
||||
return JSONRPCError(500, "Unable to connect");
|
||||
|
||||
return "connecting";
|
||||
}
|
||||
|
||||
@@ -400,7 +416,7 @@ Json::Value RPCServer::doSendTo(Json::Value& params)
|
||||
return JSONRPCError(500, "Invalid parameters");
|
||||
|
||||
NewcoinAddress destAccount = parseAccount(sDest);
|
||||
if(!destAccount.IsValid())
|
||||
if(!destAccount.isValid())
|
||||
return JSONRPCError(500, "Unable to parse destination account");
|
||||
|
||||
uint64 iAmount;
|
||||
@@ -713,7 +729,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{
|
||||
theApp->stop();
|
||||
|
||||
return "newcoin server stopping";
|
||||
return SYSTEM_NAME " server stopping";
|
||||
}
|
||||
|
||||
if(command=="unl_add") return doUnlAdd(params);
|
||||
|
||||
@@ -1117,7 +1117,7 @@ void UniqueNodeList::setSeedDomains(const seedDomain& sdSource, bool bNext)
|
||||
|
||||
std::string strSql = str(boost::format("REPLACE INTO SeedDomains (Domain,PublicKey,Source,Next,Scan,Fetch,Sha256,Comment) VALUES (%s, %s, %s, %d, %d, %d, '%s', %s);")
|
||||
% db->escape(sdSource.strDomain)
|
||||
% (sdSource.naPublicKey.IsValid() ? db->escape(sdSource.naPublicKey.humanNodePublic()) : "NULL")
|
||||
% (sdSource.naPublicKey.isValid() ? db->escape(sdSource.naPublicKey.humanNodePublic()) : "NULL")
|
||||
% db->escape(std::string(1, static_cast<char>(sdSource.vsSource)))
|
||||
% iNext
|
||||
% iScan
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
#include "../json/value.h"
|
||||
|
||||
#include "NewcoinAddress.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "HttpsClient.h"
|
||||
#include "ParseSection.h"
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#define SYSTEM_NAME "newcoin"
|
||||
|
||||
// Guarantees minimum thoughput of 1 node per second.
|
||||
#define NODE_FETCH_JOBS 10
|
||||
#define NODE_FETCH_SECONDS 10
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#include "openssl/ec.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include "Wallet.h"
|
||||
@@ -347,32 +348,47 @@ Json::Value Wallet::getFamilyJson(const NewcoinAddress& family)
|
||||
|
||||
void Wallet::start()
|
||||
{
|
||||
// We need our node identity before we begin networking.
|
||||
// - Allows others to identify if they have connected multiple times.
|
||||
// - Determines our CAS routing and responsibilities.
|
||||
// - This is not our validation identity.
|
||||
if (!nodeIdentityLoad()) {
|
||||
nodeIdentityCreate();
|
||||
if (!nodeIdentityLoad())
|
||||
throw std::runtime_error("unable to retrieve new node identity.");
|
||||
}
|
||||
|
||||
std::cerr << "NodeIdentity: " << mNodePublicKey.humanNodePublic() << std::endl;
|
||||
|
||||
theApp->getUNL().start();
|
||||
}
|
||||
|
||||
// Retrieve network identity.
|
||||
bool Wallet::nodeIdentityLoad()
|
||||
{
|
||||
std::string strSql("SELECT * FROM NodeIdentity;");
|
||||
|
||||
Database* db=theApp->getWalletDB()->getDB();
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
bool bSuccess = false;
|
||||
|
||||
if(!db->executeSQL(strSql.c_str())) return false;
|
||||
if(!db->startIterRows()) return false;
|
||||
|
||||
std::string strPublicKey, strPrivateKey;
|
||||
if(db->executeSQL("SELECT * FROM NodeIdentity;") && db->startIterRows())
|
||||
{
|
||||
std::string strPublicKey, strPrivateKey;
|
||||
|
||||
db->getStr("PublicKey", strPublicKey);
|
||||
db->getStr("PrivateKey", strPrivateKey);
|
||||
db->getStr("PublicKey", strPublicKey);
|
||||
db->getStr("PrivateKey", strPrivateKey);
|
||||
|
||||
mNodePublicKey.setNodePublic(strPublicKey);
|
||||
mNodePrivateKey.setNodePrivate(strPrivateKey);
|
||||
mNodePublicKey.setNodePublic(strPublicKey);
|
||||
mNodePrivateKey.setNodePrivate(strPrivateKey);
|
||||
|
||||
db->endIterRows();
|
||||
db->endIterRows();
|
||||
bSuccess = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// Create and store a network identity.
|
||||
bool Wallet::nodeIdentityCreate() {
|
||||
//
|
||||
// Generate the public and private key
|
||||
@@ -389,48 +405,24 @@ bool Wallet::nodeIdentityCreate() {
|
||||
nodePublicKey.setNodePublic(CKey(familyGenerator, 0).GetPubKey());
|
||||
nodePrivateKey.setNodePrivate(CKey(familyGenerator, familySeed.getFamilyPrivateKey(), 0).GetSecret());
|
||||
|
||||
std::cerr << "New NodeIdentity:" << std::endl;
|
||||
fprintf(stderr, "public: %s\n", nodePublicKey.humanNodePublic().c_str());
|
||||
fprintf(stderr, "private: %s\n", nodePrivateKey.humanNodePrivate().c_str());
|
||||
std::cerr << "NodeIdentity: Created." << std::endl;
|
||||
|
||||
//
|
||||
// Store the node information
|
||||
//
|
||||
Database* db = theApp->getWalletDB()->getDB();
|
||||
|
||||
std::string strTmp;
|
||||
|
||||
std::string strPublicKey = nodePublicKey.humanNodePublic();
|
||||
std::string strPrivateKey = nodePrivateKey.humanNodePrivate();
|
||||
|
||||
std::string strSql = "INSERT INTO NodeIdentity (PublicKey,PrivateKey) VALUES (";
|
||||
db->escape(reinterpret_cast<const unsigned char*>(strPublicKey.c_str()), strPublicKey.size(), strTmp);
|
||||
strSql.append(strTmp);
|
||||
strSql.append(",");
|
||||
db->escape(reinterpret_cast<const unsigned char*>(strPrivateKey.c_str()), strPrivateKey.size(), strTmp);
|
||||
strSql.append(strTmp);
|
||||
strSql.append(");");
|
||||
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
db->executeSQL(strSql.c_str());
|
||||
db->executeSQL(str(boost::format("INSERT INTO NodeIdentity (PublicKey,PrivateKey) VALUES (%s,%s);")
|
||||
% db->escape(nodePublicKey.humanNodePublic())
|
||||
% db->escape(nodePrivateKey.humanNodePrivate())));
|
||||
// XXX Check error result.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wallet::load()
|
||||
{
|
||||
#if 0
|
||||
// XXX Commented out because not currently used.
|
||||
if (!nodeIdentityLoad()) {
|
||||
nodeIdentityCreate();
|
||||
if (!nodeIdentityLoad())
|
||||
throw std::runtime_error("unable to retrieve new node identity.");
|
||||
}
|
||||
|
||||
std::cerr << "NodeIdentity:" << std::endl;
|
||||
fprintf(stderr, "public: %s\n", mNodePublicKey.humanNodePublic().c_str());
|
||||
fprintf(stderr, "private: %s\n", mNodePrivateKey.humanNodePrivate().c_str());
|
||||
#endif
|
||||
std::string sql("SELECT * FROM LocalAcctFamilies;");
|
||||
|
||||
ScopedLock sl(theApp->getWalletDB()->getDBLock());
|
||||
@@ -569,7 +561,7 @@ LocalAccount::pointer Wallet::parseAccount(const std::string& specifier)
|
||||
; // nothing
|
||||
}
|
||||
|
||||
return familyFound.IsValid()
|
||||
return familyFound.isValid()
|
||||
? getLocalAccount(familyFound, boost::lexical_cast<int>(seq))
|
||||
: LocalAccount::pointer();
|
||||
}
|
||||
|
||||
16
src/base58.h
16
src/base58.h
@@ -18,6 +18,8 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include "bignum.h"
|
||||
#include "BitcoinUtil.h"
|
||||
@@ -241,7 +243,21 @@ public:
|
||||
bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
|
||||
bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
|
||||
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
|
||||
friend std::size_t hash_value(CBase58Data const& b58);
|
||||
};
|
||||
|
||||
inline std::size_t hash_value(CBase58Data const& b58)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
boost::hash_combine(seed, b58.nVersion);
|
||||
BOOST_FOREACH(const unsigned char& x, b58.vchData)
|
||||
{
|
||||
boost::hash_combine(seed, x);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
#endif
|
||||
// vim:ts=4
|
||||
|
||||
@@ -225,3 +225,4 @@ message TMErrorMsg {
|
||||
optional int32 errorCode = 1;
|
||||
optional string message = 2;
|
||||
}
|
||||
// vim:ts=4
|
||||
|
||||
Reference in New Issue
Block a user