Cleanups and fixes.

This commit is contained in:
JoelKatz
2011-12-20 22:01:06 -08:00
parent d4276bfbec
commit 780f94798e
6 changed files with 54 additions and 292 deletions

View File

@@ -260,26 +260,26 @@ Ledger::pointer Ledger::closeLedger(uint64 timeStamp)
bool Ledger::unitTest()
{
LocalAccount l1(true), l2(true);
assert(l1.peekPubKey());
LocalAccount l1(true), l2(true);
assert(l1.peekPubKey());
uint160 la1(l1.getAddress()), la2(l2.getAddress());
uint160 la1(l1.getAddress()), la2(l2.getAddress());
#ifdef DEBUG
std::cerr << "Account1: " << la1.GetHex() << std::endl;
std::cerr << "Account2: " << la2.GetHex() << std::endl;
std::cerr << "Account1: " << la1.GetHex() << std::endl;
std::cerr << "Account2: " << la2.GetHex() << std::endl;
#endif
Ledger::pointer ledger(new Ledger(la1, 100000));
l1.mAmount=100000;
ledger=Ledger::pointer(new Ledger(*ledger, 0));
Ledger::pointer ledger(new Ledger(la1, 100000));
l1.mAmount=100000;
ledger=Ledger::pointer(new Ledger(*ledger, 0));
AccountState::pointer as=ledger->getAccountState(la1);
assert(as);
assert(as->getBalance()==100000);
assert(as->getSeq()==0);
as=ledger->getAccountState(la2);
assert(!as);
AccountState::pointer as=ledger->getAccountState(la1);
assert(as);
assert(as->getBalance()==100000);
assert(as->getSeq()==0);
as=ledger->getAccountState(la2);
assert(!as);
Transaction::pointer t(new Transaction(NEW, l1, l1.mSeqNum, l2.getAddress(), 2500, 0, 1));
assert(!!t->getID());
@@ -290,10 +290,9 @@ bool Ledger::unitTest()
#endif
assert(tr==TR_SUCCESS);
return true;
return true;
}
uint256 Ledger::getHash()
{
if(!mValidHash) updateHash();
@@ -383,106 +382,6 @@ Ledger::pointer Ledger::loadByHash(const uint256& ledgerHash)
}
#if 0
Ledger::pointer Ledger::getParent()
{
if(!mParent)
{
mParent=theApp->getLedgerMaster().getLedger(mParentHash);
}
return(mParent);
}
// TODO: we can optimize so the ledgers only hold the delta from the accepted ledger
// TODO: check to make sure the ledger is consistent after we load it
bool Ledger::load(const uint256& hash)
{
Database* db=theApp->getDB();
string sql="SELECT * from Ledgers where hash=";
string hashStr;
db->escape(hash.begin(),hash.GetSerializeSize(),hashStr);
sql.append(hashStr);
if(db->executeSQL(sql.c_str()))
{
if(db->getNextRow())
{
mIndex=db->getInt("LedgerIndex");
mHash=hash;
mValidSig=false;
mAccounts.clear();
mTransactions.clear();
mDiscardedTransactions.clear();
db->getBinary("ParentHash",mParentHash.begin(),mParentHash.GetSerializeSize());
mFeeHeld=db->getBigInt("FeeHeld");
char buf[100];
sql="SELECT Transactions.* from Transactions,LedgerTransactionMap where Transactions.TransactionID=LedgerTransactionMap.TransactionID and LedgerTransactionMap.LedgerID=";
sprintf(buf, "%d", db->getInt(0));
sql.append(buf);
if(db->executeSQL(sql.c_str()))
{
unsigned char tbuf[1000];
while(db->getNextRow())
{
Transaction::pointer trans=Transaction::pointer(new newcoin::Transaction());
trans->set_amount( db->getBigInt("Amount"));
trans->set_seqnum( db->getInt("seqnum"));
trans->set_ledgerindex( db->getInt("ledgerIndex"));
db->getBinary("from",tbuf,1000);
trans->set_from(tbuf,20);
db->getBinary("dest",tbuf,1000);
trans->set_dest(tbuf,20);
db->getBinary("pubkey",tbuf,1000);
trans->set_pubkey(tbuf,128);
db->getBinary("sig",tbuf,1000);
trans->set_sig(tbuf,32);
mTransactions.push_back(trans);
}
}
sql="SELECT Accounts.* from Acconts,LedgerAcountMap where Accounts.AccountID=LedgerAccountMap.AccountID and LedgerAccountMap.LedgerID=";
sql.append(buf);
if(db->executeSQL(sql.c_str()))
{
while(db->getNextRow())
{
uint160 address;
db->getBinary("Address",address.begin(),address.GetSerializeSize());
mAccounts[address].first=db->getBigInt("Amount");
mAccounts[address].second=db->getInt("SeqNum");
}
}
return(true);
}
}
return(false);
}
uint256& Ledger::getSignature()
{
if(!mValidSig) sign();
return(mSignature);
}
void Ledger::publishValidation()
{
PackedMessage::pointer packet=Peer::createValidation(shared_from_this());
theApp->getConnectionPool().relayMessage(NULL,packet);
}
/*
uint64 Ledger::getAmount(std::string address)
{
return(mAccounts[NewcoinAddress:: address].first);
}*/
// returns true if the from account has enough for the transaction and seq num is correct
bool Ledger::addTransaction(Transaction::pointer trans,bool checkDuplicate)
{
@@ -587,150 +486,6 @@ void Ledger::addTransactionAllowNeg(Transaction::pointer trans)
// start from your parent and go through every transaction
// calls this on its child if recursive is set
void Ledger::recalculate(bool recursive)
{
if(mParent)
{
mValidSig=false;
mValidHash=false;
mAccounts.clear();
mAccounts=mParent->getAccounts();
list<Transaction::pointer> firstTransactions=mTransactions;
list<Transaction::pointer> secondTransactions=mDiscardedTransactions;
mTransactions.clear();
mDiscardedTransactions.clear();
firstTransactions.sort(gTransactionSorter);
secondTransactions.sort(gTransactionSorter);
// don't check balances until the end
BOOST_FOREACH(Transaction::pointer trans,firstTransactions)
{
addTransactionAllowNeg(trans);
}
BOOST_FOREACH(Transaction::pointer trans,secondTransactions)
{
addTransactionAllowNeg(trans);
}
correctAccounts();
if(mChild && recursive) mChild->recalculate();
}else
{
cout << "Can't recalculate if there is no parent" << endl;
}
}
void Ledger::parentAddedTransaction(Transaction::pointer cause)
{
// TODO: optimize we can make this more efficient at some point. For now just redo everything
recalculate();
/*
// IMPORTANT: these changes can't change the sequence number. This means we only need to check the dest account
// If there was a seqnum change we have to re-do all the transactions again
// There was a change to the balances of the parent ledger
// This could cause:
// an account to now be negative so we have to discard one
// a discarded transaction to be pulled back in
// seqnum invalidation
uint160 fromAddress=protobufTo160(cause->from());
uint160 destAddress=protobufTo160(cause->dest());
Account* fromAccount=getAccount(fromAddress);
Account* destAccount=getAccount(destAddress);
if(fromAccount)
{
if(fromAccount->first<cause->amount())
{
fromAccount->first -= cause->amount();
fromAccount->second = cause->seqnum()+1;
mAccounts[fromAddress] = *fromAccount;
}else cout << "This shouldn't happen2" << endl;
}else
{
cout << "This shouldn't happen" << endl;
}
if(destAccount)
{
destAccount->first += cause->amount();
mAccounts[destAddress]= *destAccount;
}else
{
mAccounts[destAddress]=pair<uint64,uint32>(cause->amount(),cause->seqnum());
}
// look for discarded transactions
BOOST_FOREACH(Transaction::pointer trans,)
*/
}
bool Ledger::hasTransaction(Transaction::pointer needle)
{
BOOST_FOREACH(Transaction::pointer trans,mTransactions)
{
if( Transaction::isEqual(needle,trans) ) return(true);
}
BOOST_FOREACH(Transaction::pointer disTrans,mDiscardedTransactions)
{
if( Transaction::isEqual(needle,disTrans) ) return(true);
}
return(false);
}
// Ledgers are compatible if both sets of transactions merged together would lead to the same ending balance
bool Ledger::isCompatible(Ledger::pointer other)
{
Ledger::pointer l1=Ledger::pointer(new Ledger(*this));
Ledger::pointer l2=Ledger::pointer(new Ledger(*other));
l1->mergeIn(l2);
l2->mergeIn(l1);
map<uint160, Account > a1=l1->getAccounts();
map<uint160, Account > a2=l2->getAccounts();
return(a1==a2);
}
void Ledger::mergeIn(Ledger::pointer other)
{
list<Transaction::pointer>& otherTransactions=other->getTransactions();
BOOST_FOREACH(Transaction::pointer trans,otherTransactions)
{
addTransactionAllowNeg(trans);
}
correctAccounts();
}
void Ledger::correctAccounts()
{
BOOST_FOREACH(PAIR(const uint160, Account)& fullAccount, mAccounts)
{
if(fullAccount.second.first <0 )
{
correctAccount(fullAccount.first);
}
}
}
// Must look for transactions to discard to make this account positive
// When we chuck transactions it might cause other accounts to need correcting
void Ledger::correctAccount(const uint160& address)

View File

@@ -445,7 +445,7 @@ bool SHAMap::addGiveItem(const SHAMapItem::pointer item)
#endif
return false;
}
if(!leaf->addUpdateItem(item))
if(!leaf->addUpdateItem(item, true))
{
assert(false);
return false;
@@ -464,7 +464,7 @@ bool SHAMap::updateGiveItem(SHAMapItem::pointer item)
boost::recursive_mutex::scoped_lock sl(mLock);
SHAMapLeafNode::pointer leaf=walkToLeaf(item->getTag(), true, true);
if(!leaf) return false;
if(!leaf->addUpdateItem(item)) return false;
if(!leaf->addUpdateItem(item, true)) return false;
dirtyUp(item->getTag());
return true;
}

View File

@@ -125,7 +125,7 @@ private:
SHAMapLeafNode& operator=(const SHAMapLeafNode&); // no implementation
protected:
bool addUpdateItem(SHAMapItem::pointer);
bool addUpdateItem(SHAMapItem::pointer, bool doHash);
bool delItem(const SHAMapItem::pointer i) { return delItem(i->getTag()); }
bool delItem(const uint256& tag);

View File

@@ -61,15 +61,14 @@ void SHAMapNode::ClassInit()
for(int i=0; i<=leafDepth; i++)
{
smMasks[i]=selector;
*(selector.begin()+i)=0x1f;
*(selector.begin()+i)=0x1F;
}
}
uint256 SHAMapNode::getNodeID(int depth, const uint256& hash)
{
assert(depth>=0 && depth<=leafDepth);
uint256 ret = hash & smMasks[depth];
return ret;
return hash & smMasks[depth];
}
SHAMapNode::SHAMapNode(int depth, const uint256 &hash) : mDepth(depth)
@@ -103,7 +102,7 @@ int SHAMapNode::selectBranch(const uint256 &hash)
return -1; // does not go under this node
}
uint256 selector=hash&smMasks[mDepth+1];
uint256 selector(hash & smMasks[mDepth+1]);
int branch=*(selector.begin()+mDepth);
assert(branch>=0 && branch<32);
return branch;
@@ -127,7 +126,7 @@ SHAMapLeafNode::SHAMapLeafNode(const SHAMapLeafNode& node, uint32 seq) : SHAMapN
SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& id, const std::vector<unsigned char>& rawLeaf, uint32 seq)
: SHAMapNode(id), mSeq(seq)
{ // OPTIMIZEME:: addUpdateItem updates the hash
{
Serializer s(rawLeaf);
int pos=0;
while(pos<s.getLength())
@@ -138,7 +137,7 @@ SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& id, const std::vector<unsigned
if(!s.get16(len, pos)) throw SHAMapException(InvalidNode);
pos+=2;
if(!id || !len || ((pos+len)>s.getLength())) throw SHAMapException(InvalidNode);
addUpdateItem(SHAMapItem::pointer(new SHAMapItem(id, s.getRaw(pos, len))));
addUpdateItem(SHAMapItem::pointer(new SHAMapItem(id, s.getRaw(pos, len))), false);
pos+=len;
}
updateHash();
@@ -161,7 +160,7 @@ bool SHAMapLeafNode::hasItem(const uint256& item) const
return false;
}
bool SHAMapLeafNode::addUpdateItem(SHAMapItem::pointer item)
bool SHAMapLeafNode::addUpdateItem(SHAMapItem::pointer item, bool doHash)
{ // The node will almost never have more than one item in it
#ifdef DEBUG
std::cerr << "Leaf(" << getString() << ")" << std::endl;
@@ -176,16 +175,20 @@ bool SHAMapLeafNode::addUpdateItem(SHAMapItem::pointer item)
if(nodeItem.peekData()==item->peekData())
return false; // no change
nodeItem.updateData(item->peekData());
return updateHash();
if(doHash) return updateHash();
return true;
}
if(nodeItem.getTag()>item->getTag())
{
mItems.insert(it, item);
return updateHash();
if(doHash) return updateHash();
return true;
}
}
mItems.push_back(item);
return updateHash();
if(doHash) return updateHash();
return true;
}
bool SHAMapLeafNode::delItem(const uint256& tag)
@@ -258,7 +261,6 @@ SHAMapItem::pointer SHAMapLeafNode::lastItem()
return *(mItems.rbegin());
}
bool SHAMapLeafNode::updateHash()
{
uint256 nh;
@@ -289,6 +291,7 @@ SHAMapInnerNode::SHAMapInnerNode(const SHAMapNode& id, const std::vector<unsigne
: SHAMapNode(id), mSeq(seq)
{
assert(!id.isLeaf());
assert(contents.size()==32*256/8);
Serializer s(contents);
for(int i=0; i<32; i++)
mHashes[i]=s.get256(i*32);
@@ -340,7 +343,7 @@ const uint256& SHAMapInnerNode::getChildHash(int m) const
bool SHAMapInnerNode::updateHash()
{
int nc=0;
Serializer s;
Serializer s(1024);
for(int i=0; i<32; i++)
{
if(mHashes[i]!=0) nc++;

View File

@@ -12,26 +12,25 @@
std::vector<unsigned char> CKeyStore::GenerateNewKey()
{
RandAddSeedPerfmon();
CKey key;
key.MakeNewKey();
if (!AddKey(key))
throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
return key.GetPubKey();
RandAddSeedPerfmon();
CKey key;
key.MakeNewKey();
if (!AddKey(key))
throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
return key.GetPubKey();
}
bool CKeyStore::GetPubKey(const NewcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
bool CKeyStore::GetPubKey(const NewcoinAddress& address, std::vector<unsigned char>& vchPubKeyOut) const
{
CKey key;
if (!GetKey(address, key))
return false;
vchPubKeyOut = key.GetPubKey();
return true;
CKey key;
if (!GetKey(address, key))
return false;
vchPubKeyOut = key.GetPubKey();
return true;
}
bool CBasicKeyStore::AddKey(const CKey& key)
{
mapKeys[key.GetAddress()] = key.GetSecret();
return true;
mapKeys[key.GetAddress()] = key.GetSecret();
return true;
}

View File

@@ -1,3 +1,6 @@
#ifndef __TYPES_HH__
#define __TYPES_HH__
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 int64;
@@ -17,4 +20,6 @@ typedef int int32;
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
#define for if (false) ; else for
#endif
#endif
#endif