This commit is contained in:
jed
2011-10-28 16:51:35 -07:00
parent e68b0fb8d1
commit 7436a8deec
29 changed files with 141 additions and 129 deletions

View File

@@ -34,7 +34,8 @@ Application::Application()
void Application::run()
{
theApp->setDB(new SqliteDatabase("data.db"));
string filename=strprintf("%sdata.db",theConfig.DATA_DIR);
theApp->setDB(new SqliteDatabase(filename.c_str()));
mDatabase->connect();
if(theConfig.PEER_PORT)

View File

@@ -13,6 +13,9 @@ Config::Config()
VERSION=1;
TEST_NET=false;
NETWORK_START_TIME=1319844908;
PEER_PORT=6561;
RPC_PORT=5001;
NUMBER_CONNECTIONS=30;
@@ -32,7 +35,7 @@ Config::Config()
RPC_USER="admin";
RPC_PASSWORD="pass";
HISTORY_DIR="history/";
DATA_DIR="";
TRANSACTION_FEE=1000;
ACCOUNT_FEE=1000;

View File

@@ -6,6 +6,7 @@ public:
int VERSION;
std::string VERSION_STR;
bool TEST_NET;
int NETWORK_START_TIME; // The Unix time we start ledger 0
int TRANSACTION_FEE;
int ACCOUNT_FEE;
@@ -22,7 +23,7 @@ public:
std::string RPC_PASSWORD;
std::string HANKO;
std::string HISTORY_DIR;
std::string DATA_DIR;
int MIN_VOTES_FOR_CONSENSUS;

View File

@@ -1,4 +1,4 @@
#include "Convertion.h"
#include "Conversion.h"
#include "base58.h"
using namespace std;
@@ -21,11 +21,8 @@ uint160 humanTo160(const std::string& buf)
vector<unsigned char> retVec;
DecodeBase58(buf,retVec);
uint160 ret;
for(unsigned int n=0; n<retVec.size(); n++)
{
if(n>=ret.GetSerializeSize()) break;
ret.begin()[n]=retVec[n];
}
memcpy((unsigned char*)&ret,&retVec[0],ret.GetSerializeSize());
return(ret);
}

View File

@@ -3,7 +3,7 @@
#include "PackedMessage.h"
#include "Application.h"
#include "Config.h"
#include "Convertion.h"
#include "Conversion.h"
#include "BitcoinUtil.h"
#include <boost/foreach.hpp>
#include <iostream>
@@ -203,41 +203,6 @@ void Ledger::save()
}
}
/*
bool Ledger::load(std::string dir)
{
string filename=strprintf("%s%u.ledger",dir,mIndex);
ifstream loadfile(filename, ios::in | ios::binary);
if(loadfile.is_open()) // TODO: does this fail correctly?
{
newcoin::FullLedger ledger;
ledger.ParseFromIstream(&loadfile);
loadfile.close();
setTo(ledger);
return(true);
}
return(false);
}
void Ledger::save(string dir)
{
string filename=strprintf("%s%u.ledger",dir,mIndex);
newcoin::FullLedger* ledger=createFullLedger();
ofstream savefile(filename, ios::out | ios::trunc | ios::binary);
if(savefile.is_open())
{
ledger->SerializeToOstream(&savefile);
savefile.close();
}
delete(ledger);
}
*/
int64 Ledger::getAmountHeld(uint160& address)
{
if(mAccounts.count(address))
@@ -440,7 +405,7 @@ void Ledger::recalculate(bool recursive)
void Ledger::parentAddedTransaction(TransactionPtr cause)
{
// TODO: we can make this more efficient at some point. For now just redo everything
// TODO: optimize we can make this more efficient at some point. For now just redo everything
recalculate();

View File

@@ -1,14 +1,16 @@
#include "LedgerMaster.h"
#include "Application.h"
#include "NewcoinAddress.h"
#include "Convertion.h"
#include "TimingService.h"
#include "Conversion.h"
#include <boost/foreach.hpp>
using namespace std;
LedgerMaster::LedgerMaster()
{
//mAfterProposed=false;
mFinalizingLedger=Ledger::pointer();
mCurrentLedger=Ledger::pointer(new Ledger(TimingService::getCurrentLedgerIndex()));
}
void LedgerMaster::load()
@@ -128,11 +130,11 @@ bool LedgerMaster::addTransaction(TransactionPtr trans)
void LedgerMaster::addFullLedger(newcoin::FullLedger& ledger)
{
// check if we already have this ledger
// check that the hash is correct
uint256 inHash=protobufTo256(ledger.hash());
Ledger::pointer existingLedger=mLedgerHistory.getLedger( inHash );
if(existingLedger) return;
// check that the hash is correct
Ledger::pointer newLedger=Ledger::pointer(new Ledger(ledger));
if(newLedger->getHash()==inHash)
{
@@ -210,36 +212,39 @@ void LedgerMaster::checkLedgerProposal(Peer::pointer peer, newcoin::ProposeLedge
// if doesn't match and you have <= transactions ask for the complete ledger
// if doesn't match and you have > transactions send your complete ledger
if(otherLedger.ledgerindex()<mFinalizingLedger->getIndex())
{ // you have already closed this ledger
Ledger::pointer oldLedger=mLedgerHistory.getAcceptedLedger(otherLedger.ledgerindex());
if(oldLedger)
{
if( (oldLedger->getHash()!=protobufTo256(otherLedger.hash())) &&
(oldLedger->getNumTransactions()>=otherLedger.numtransactions()))
if(otherLedger.ledgerindex()<mCurrentLedger->getIndex())
{
if( (!mFinalizingLedger) ||
otherLedger.ledgerindex()<mFinalizingLedger->getIndex())
{ // you have already closed this ledger
Ledger::pointer oldLedger=mLedgerHistory.getAcceptedLedger(otherLedger.ledgerindex());
if(oldLedger)
{
peer->sendLedgerProposal(oldLedger);
if( (oldLedger->getHash()!=protobufTo256(otherLedger.hash())) &&
(oldLedger->getNumTransactions()>=otherLedger.numtransactions()))
{
peer->sendLedgerProposal(oldLedger);
}
}
}else
{ // you guys are on the same page
uint256 otherHash=protobufTo256(otherLedger.hash());
if(mFinalizingLedger->getHash()!= otherHash)
{
if( mFinalizingLedger->getNumTransactions()>=otherLedger.numtransactions())
{
peer->sendLedgerProposal(mFinalizingLedger);
}else
{
peer->sendGetFullLedger(otherHash);
}
}
}
}else if(otherLedger.ledgerindex()>mFinalizingLedger->getIndex())
{ // you haven't started finalizing this one yet save it for when you do
addFutureProposal(peer,otherLedger);
}else
{ // you guys are on the same page
uint256 otherHash=protobufTo256(otherLedger.hash());
if(mFinalizingLedger->getHash()!= otherHash)
{
if( mFinalizingLedger->getNumTransactions()>=otherLedger.numtransactions())
{
peer->sendLedgerProposal(mFinalizingLedger);
}else
{
peer->sendGetFullLedger(otherHash);
}
}
{ // you haven't started finalizing this one yet save it for when you do
addFutureProposal(peer,otherLedger);
}
}

View File

@@ -4,6 +4,9 @@
#include "base58.h"
// TODO: https://en.bitcoin.it/wiki/Address
// TODO: Why do we need steps 5 and 6? why not just use a checksum function to get the checksum?
class NewcoinAddress : public CBase58Data
{
public:

View File

@@ -6,7 +6,7 @@
//#include <boost/log/trivial.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include "Convertion.h"
#include "Conversion.h"
using namespace std;
using namespace boost;
@@ -226,14 +226,6 @@ void Peer::processReadBuffer()
}
break;
case newcoin::VALIDATION:
{
newcoin::Validation validation;
if(validation.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
receiveValidation(validation);
else cout << "parse error: " << type << endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
}
break;
case newcoin::FULL_LEDGER:
{
newcoin::FullLedger ledger;
@@ -243,6 +235,23 @@ void Peer::processReadBuffer()
}
break;
case newcoin::VALIDATION:
{
newcoin::Validation validation;
if(validation.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
receiveValidation(validation);
else cout << "parse error: " << type << endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
}
break;
case newcoin::PROPOSE_LEDGER:
{
newcoin::ProposeLedger prop;
if(prop.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
receiveProposeLedger(prop);
else cout << "parse error: " << type << endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
}
break;
case newcoin::GET_FULL_LEDGER:
{
newcoin::GetFullLedger getFullLedger;
@@ -259,14 +268,6 @@ void Peer::processReadBuffer()
else cout << "parse error: " << type << endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
}
case newcoin::PROPOSE_LEDGER:
{
newcoin::ProposeLedger prop;
if(prop.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE))
receiveProposeLedger(prop);
else cout << "parse error: " << type << endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
}
break;
default:
cout << "Unknown Msg: " << type << endl; //else BOOST_LOG_TRIVIAL(info) << "Error: " << error;
}

View File

@@ -9,7 +9,7 @@
#include "json/json_spirit_reader_template.h"
#include "json/json_spirit_writer_template.h"
#include "RPC.h"
#include "Convertion.h"
#include "Conversion.h"
using namespace std;
using namespace json_spirit;

View File

@@ -3,6 +3,7 @@
#include "Application.h"
#include <iostream>
#include <ctime>
#include <boost/bind.hpp>
using namespace std;
@@ -49,3 +50,8 @@ void TimingService::handleValid()
theApp->getLedgerMaster().endFinalization();
}
int TimingService::getCurrentLedgerIndex()
{
return( (time(NULL)-theConfig.NETWORK_START_TIME)/theConfig.LEDGER_SECONDS );
}

View File

@@ -20,7 +20,7 @@ public:
TimingService();
void start(boost::asio::io_service& ioService);
static int getCurrentLedgerIndex();
};
#endif

View File

@@ -37,6 +37,6 @@ uint256 Transaction::calcHash(TransactionPtr trans)
bool Transaction::isSigValid(TransactionPtr trans)
{
// TODO:
// TODO: Transaction::isSigValid
return(true);
}

View File

@@ -1,6 +1,6 @@
#include "UniqueNodeList.h"
#include "Application.h"
#include "Convertion.h"
#include "Conversion.h"
using namespace std;

View File

@@ -2,7 +2,8 @@
#include "Application.h"
#include "NewcoinAddress.h"
#include "Config.h"
#include "Convertion.h"
#include "Conversion.h"
#include "Application.h"
#include <boost/foreach.hpp>
using namespace std;
@@ -27,6 +28,12 @@ void ValidationCollection::load()
}
void ValidationCollection::addToDB(newcoin::Validation& valid,bool weCare)
{
Database* db=theApp->getDB();
}
bool ValidationCollection::hasValidation(uint256& ledgerHash,uint160& hanko,uint32 seqnum)
{
if(mValidations.count(ledgerHash))
@@ -69,11 +76,12 @@ void ValidationCollection::addValidation(newcoin::Validation& valid)
mValidations[hash].push_back(valid);
mIndexValidations[valid.ledgerindex()].push_back(valid);
addToGroup(valid);
addToDB(valid,true);
theApp->getLedgerMaster().checkConsensus(valid.ledgerindex());
}else if(validity==0)
{
mIgnoredValidations[hash].push_back(valid);
addToDB(valid,false);
}else
{ // the signature wasn't valid
cout << "Invalid Validation" << endl;

View File

@@ -11,8 +11,8 @@ class ValidationCollection
{
// from ledger hash to the validation
std::map<uint256, std::vector<newcoin::Validation> > mValidations;
std::map<uint256, std::vector<newcoin::Validation> > mIgnoredValidations;
//std::map<uint256, std::vector<newcoin::Validation> > mValidations;
//std::map<uint256, std::vector<newcoin::Validation> > mIgnoredValidations;
// this maps ledgerIndex to an array of groups. Each group is a list of validations.
// a validation can be in multiple groups since compatibility isn't transitive
@@ -27,10 +27,11 @@ class ValidationCollection
};
std::map<uint32, std::vector< Group > > mIndexGroups; // all the groups at each index
std::map<uint32, std::vector< newcoin::Validation > > mIndexValidations; // all the validations at each index
//std::map<uint32, std::vector< newcoin::Validation > > mIndexValidations; // all the validations at each index
bool hasValidation(uint256& ledgerHash,uint160& hanko,uint32 seqnum);
void addToGroup(newcoin::Validation& valid);
void addToDB(newcoin::Validation& valid,bool weCare);
public:
ValidationCollection();

View File

@@ -1,6 +1,6 @@
#include "Wallet.h"
#include "NewcoinAddress.h"
#include "Convertion.h"
#include "Conversion.h"
#include "Application.h"
#include "LedgerMaster.h"
#include <string>

View File

@@ -23,7 +23,6 @@ class Wallet : public CBasicKeyStore
std::vector<unsigned char> mPublicKey;
std::vector<unsigned char> mPrivateKey;
int64 mAmount;
uint64 mAge; // do we need this
uint32 mSeqNum;

View File

@@ -70,7 +70,13 @@ int SqliteDatabase::getLastInsertID()
// returns false if there are no results
bool SqliteDatabase::startIterRows()
{
needs to fill out the column table
mColNameTable.clear();
mColNameTable.resize(sqlite3_column_count(mCurrentStmt));
for(unsigned n=0; n<mColNameTable.size(); n++)
{
mColNameTable[n]=sqlite3_column_name(mCurrentStmt,n);
}
return(mMoreRows);
}

View File

@@ -7,14 +7,10 @@ Database::Database(const char* host,const char* user,const char* pass) : mNumCol
mDBPass=pass;
mHost=host;
mUser=user;
mColNameTable=NULL;
}
Database::~Database()
{
delete[] mColNameTable;
}
@@ -83,7 +79,7 @@ uint64 Database::getBigInt(const char* colName)
// returns false if can't find col
bool Database::getColNumber(const char* colName,int* retIndex)
{
for(int n=0; n<mNumCol; n++)
for(unsigned int n=0; n<mColNameTable.size(); n++)
{
if(stricmp(colName,mColNameTable[n].c_str())==0)
{

View File

@@ -2,6 +2,7 @@
#define __DATABASE__
#include <string>
#include <vector>
#include "../types.h"
/*
@@ -14,7 +15,7 @@ protected:
std::string mUser;
std::string mHost;
std::string mDBPass;
std::string* mColNameTable;
std::vector<std::string> mColNameTable;
bool getColNumber(const char* colName, int* retIndex);

View File

@@ -10,6 +10,9 @@ 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
@@ -17,7 +20,7 @@ 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(128), Sig BINARY(32));
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);

View File

@@ -2,6 +2,7 @@
#include <iostream>
#include "CallRPC.h"
extern void runTests();
using namespace std;
using namespace boost;
@@ -44,6 +45,8 @@ int parseCommandline(int argc, char* argv[])
int main(int argc, char* argv[])
{
runTests();
return(parseCommandline(argc,argv));
}

View File

@@ -5,11 +5,11 @@ enum Type {
TRANSACTION= 2;
FULL_LEDGER= 3;
VALIDATION= 4;
GET_FULL_LEDGER= 5;
GET_VALIDATIONS= 6;
GET_CONTACTS= 7;
CONTACT= 8;
PROPOSE_LEDGER= 9;
PROPOSE_LEDGER= 5;
GET_FULL_LEDGER= 6;
GET_VALIDATIONS= 7;
GET_CONTACTS= 8;
CONTACT= 9;
ERROR_MSG= 10;
}
@@ -29,14 +29,13 @@ you must first combine coins from one address to another.
// TODO: do we need a transID? I don't think we do
// ledgerIndex should increase the ledger coherence
message Transaction {
required bytes transID = 1;
required bytes from = 2;
required bytes dest = 3;
required uint64 amount = 4;
required uint32 ledgerIndex = 5;
required int32 seqNum = 6;
required bytes pubKey = 7;
required bytes sig = 8;
required bytes from = 1;
required bytes dest = 2;
required uint64 amount = 3;
required uint32 ledgerIndex = 4;
required int32 seqNum = 5;
required bytes pubKey = 6;
required bytes sig = 7;
}
// Sequence number is incremented if you must change the ledger that you are validating

View File

@@ -89,7 +89,7 @@
<ClCompile Include="CallRPC.cpp" />
<ClCompile Include="Config.cpp" />
<ClCompile Include="ConnectionPool.cpp" />
<ClCompile Include="Convertion.cpp" />
<ClCompile Include="Conversion.cpp" />
<ClCompile Include="cryptopp\cpu.cpp" />
<ClCompile Include="cryptopp\sha.cpp" />
<ClCompile Include="database\database.cpp" />
@@ -117,6 +117,7 @@
<ClCompile Include="RPCServer.cpp" />
<ClCompile Include="RPCCommands.cpp" />
<ClCompile Include="RPCDoor.cpp" />
<ClCompile Include="tests.cpp" />
<ClCompile Include="TimingService.cpp" />
<ClCompile Include="Transaction.cpp" />
<ClCompile Include="TransactionBundle.cpp" />
@@ -134,7 +135,7 @@
<ClInclude Include="CallRPC.h" />
<ClInclude Include="Config.h" />
<ClInclude Include="ConnectionPool.h" />
<ClInclude Include="Convertion.h" />
<ClInclude Include="Conversion.h" />
<ClInclude Include="cryptopp\config.h" />
<ClInclude Include="cryptopp\cpu.h" />
<ClInclude Include="cryptopp\cryptlib.h" />
@@ -205,6 +206,7 @@
</None>
<None Include="nodes.xml" />
<None Include="notes.txt" />
<None Include="todo.txt" />
<None Include="unl.xml" />
<None Include="wallet.xml" />
</ItemGroup>

View File

@@ -147,7 +147,10 @@
<ClCompile Include="database\sqlite3.c">
<Filter>Header Files\util</Filter>
</ClCompile>
<ClCompile Include="Convertion.cpp">
<ClCompile Include="tests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Conversion.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -344,7 +347,7 @@
<ClInclude Include="database\sqlite3ext.h">
<Filter>Header Files\util</Filter>
</ClInclude>
<ClInclude Include="Convertion.h">
<ClInclude Include="Conversion.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@@ -358,6 +361,7 @@
<Filter>html</Filter>
</None>
<None Include="db layout.txt" />
<None Include="todo.txt" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="newcoin.proto" />

View File

@@ -25,7 +25,12 @@ code from:
----
libeay32.dll
How much do we want to depend on the DB? Right now we are pulling a lot of stuff out f the DB and storing it in various data structures. but is that necessary?
Can't we keep everything in the DB?
LedgerMaster for example. mFutureTransactions should be in the DB
ValidationCollection
There is some trade off since reconstructing a whole ledger from the DB is a bit intense. So it might be good to cache these in memory.

3
todo.txt Normal file
View File

@@ -0,0 +1,3 @@
Remove data from DB when it is too old.

View File

@@ -24,7 +24,7 @@ typedef unsigned long long uint64;
inline int Testuint256AdHoc(std::vector<std::string> vArg);
// TODO: Do we need these things? Why not just use vector<unsigned char> ?
// We have to keep a separate base class without constructors
// so the compiler will let us use it in a union