Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2012-09-07 14:08:35 -07:00
10 changed files with 140 additions and 259 deletions

View File

@@ -124,6 +124,7 @@
<ClCompile Include="src\NetworkOPs.cpp" />
<ClCompile Include="src\NewcoinAddress.cpp" />
<ClCompile Include="src\NicknameState.cpp" />
<ClCompile Include="src\Operation.cpp" />
<ClCompile Include="src\OrderBook.cpp" />
<ClCompile Include="src\OrderBookDB.cpp" />
<ClCompile Include="src\PackedMessage.cpp" />
@@ -216,6 +217,7 @@
<ClInclude Include="src\NetworkStatus.h" />
<ClInclude Include="src\NewcoinAddress.h" />
<ClInclude Include="src\NicknameState.h" />
<ClInclude Include="src\Operation.h" />
<ClInclude Include="src\OrderBook.h" />
<ClInclude Include="src\OrderBookDB.h" />
<ClInclude Include="src\PackedMessage.h" />

View File

@@ -291,6 +291,9 @@
<ClCompile Include="src\ScriptData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Operation.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="KnownNodeList.h">
@@ -542,6 +545,9 @@
<ClInclude Include="src\Interpreter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Operation.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="wallet.xml" />

View File

@@ -1,4 +1,5 @@
#include "Interpreter.h"
#include "Operation.h"
#include "Config.h"
/*
@@ -8,220 +9,6 @@ We also need to charge for each op
namespace Script {
//////////////////////////////////////////////////////////////////////////
/// Operations
int Operation::getFee()
{
return(theConfig.FEE_CONTRACT_OPERATION);
}
// this is just an Int in the code
class IntOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer data=interpreter->getIntData();
if(data->isInt32())
{
interpreter->pushStack( data );
return(true);
}
return(false);
}
};
class FloatOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer data=interpreter->getFloatData();
if(data->isFloat())
{
interpreter->pushStack( data );
return(true);
}
return(false);
}
};
class Uint160Op : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer data=interpreter->getUint160Data();
if(data->isUint160())
{
interpreter->pushStack( data );
return(true);
}
return(false);
}
};
class AddOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer data1=interpreter->popStack();
Data::pointer data2=interpreter->popStack();
if( (data1->isInt32() || data1->isFloat()) &&
(data2->isInt32() || data2->isFloat()) )
{
if(data1->isFloat() || data2->isFloat()) interpreter->pushStack(Data::pointer(new FloatData(data1->getFloat()+data2->getFloat())));
else interpreter->pushStack(Data::pointer(new IntData(data1->getInt()+data2->getInt())));
return(true);
}else
{
return(false);
}
}
};
class SubOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer data1=interpreter->popStack();
Data::pointer data2=interpreter->popStack();
if( (data1->isInt32() || data1->isFloat()) &&
(data2->isInt32() || data2->isFloat()) )
{
if(data1->isFloat() || data2->isFloat()) interpreter->pushStack(Data::pointer(new FloatData(data1->getFloat()-data2->getFloat())));
else interpreter->pushStack(Data::pointer(new IntData(data1->getInt()-data2->getInt())));
return(true);
}else
{
return(false);
}
}
};
class StartBlockOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer offset=interpreter->getIntData();
return(interpreter->startBlock(offset->getInt()));
}
};
class EndBlockOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
return(interpreter->endBlock());
}
};
class StopOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
interpreter->stop();
return(true);
}
};
class AcceptDataOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer data=interpreter->popStack();
if(data->isInt32())
{
interpreter->pushStack( interpreter->getAcceptData(data->getInt()) );
return(true);
}
return(false);
}
};
class JumpIfOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer offset=interpreter->getIntData();
Data::pointer cond=interpreter->popStack();
if(cond->isBool() && offset->isInt32())
{
if(cond->isTrue())
{
return(interpreter->jumpTo(offset->getInt()));
}
return(true);
}
return(false);
}
};
class JumpOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer offset=interpreter->getIntData();
if(offset->isInt32())
{
return(interpreter->jumpTo(offset->getInt()));
}
return(false);
}
};
class SendXNSOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer sourceID=interpreter->popStack();
Data::pointer destID=interpreter->popStack();
Data::pointer amount=interpreter->popStack();
if(sourceID->isUint160() && destID->isUint160() && amount->isInt32() && interpreter->canSign(sourceID->getUint160()))
{
// make sure:
// source is either, this contract, issuer, or acceptor
// TODO do the send
//interpreter->pushStack( send result);
return(true);
}
return(false);
}
};
class GetDataOp : public Operation
{
public:
bool work(Interpreter* interpreter)
{
Data::pointer index=interpreter->popStack();
if(index->isInt32())
{
interpreter->pushStack( interpreter->getContractData(index->getInt()));
return(true);
}
return(false);
}
};
//////////////////////////////////////////////////////////////////////////
Interpreter::Interpreter()
{
mContract=NULL;
@@ -234,14 +21,55 @@ Interpreter::Interpreter()
mBlockJump=0;
mFunctionTable.resize(NUM_OF_OPS);
/*
mFunctionTable[INT_OP]=new IntOp();
mFunctionTable[FLOAT_OP]=new FloatOp();
mFunctionTable[UINT160_OP]=new Uint160Op();
mFunctionTable[BOOL_OP]=new Uint160Op();
mFunctionTable[PATH_OP]=new Uint160Op();
mFunctionTable[ADD_OP]=new AddOp();
mFunctionTable[SUB_OP]=new SubOp();
mFunctionTable[MUL_OP]=new MulOp();
mFunctionTable[DIV_OP]=new DivOp();
mFunctionTable[MOD_OP]=new ModOp();
mFunctionTable[GTR_OP]=new GtrOp();
mFunctionTable[LESS_OP]=new LessOp();
mFunctionTable[EQUAL_OP]=new SubOp();
mFunctionTable[NOT_EQUAL_OP]=new SubOp();
mFunctionTable[AND_OP]=new SubOp();
mFunctionTable[OR_OP]=new SubOp();
mFunctionTable[NOT_OP]=new SubOp();
mFunctionTable[JUMP_OP]=new SubOp();
mFunctionTable[JUMPIF_OP]=new SubOp();
mFunctionTable[STOP_OP]=new SubOp();
mFunctionTable[CANCEL_OP]=new SubOp();
mFunctionTable[BLOCK_OP]=new SubOp();
mFunctionTable[BLOCK_END_OP]=new SubOp();
mFunctionTable[SEND_XNS_OP]=new SendXNSOp();
mFunctionTable[SEND_OP]=new SendOp();
mFunctionTable[REMOVE_CONTRACT_OP]=new SubOp();
mFunctionTable[FEE_OP]=new SubOp();
mFunctionTable[CHANGE_CONTRACT_OWNER_OP]=new SubOp();
mFunctionTable[STOP_REMOVE_OP]=new SubOp();
mFunctionTable[SET_DATA_OP]=new SubOp();
mFunctionTable[GET_DATA_OP]=new SubOp();
mFunctionTable[GET_NUM_DATA_OP]=new SubOp();
mFunctionTable[SET_REGISTER_OP]=new SubOp();
mFunctionTable[GET_REGISTER_OP]=new SubOp();
mFunctionTable[GET_ISSUER_ID_OP]=new SubOp();
mFunctionTable[GET_OWNER_ID_OP]=new SubOp();
mFunctionTable[GET_LEDGER_TIME_OP]=new SubOp();
mFunctionTable[GET_LEDGER_NUM_OP]=new SubOp();
mFunctionTable[GET_RAND_FLOAT_OP]=new SubOp();
mFunctionTable[GET_XNS_ESCROWED_OP]=new SubOp();
mFunctionTable[GET_RIPPLE_ESCROWED_OP]=new SubOp();
mFunctionTable[GET_RIPPLE_ESCROWED_CURRENCY_OP]=new SubOp();
mFunctionTable[GET_RIPPLE_ESCROWED_ISSUER]=new GetRippleEscrowedIssuerOp();
mFunctionTable[GET_ACCEPT_DATA_OP]=new AcceptDataOp();
mFunctionTable[GET_ACCEPTOR_ID_OP]=new GetAcceptorIDOp();
mFunctionTable[GET_CONTRACT_ID_OP]=new GetContractIDOp();
*/
}
Data::pointer Interpreter::popStack()
@@ -361,6 +189,11 @@ Data::pointer Interpreter::getContractData(int index)
return(Data::pointer(new ErrorData()));
}
bool Interpreter::canSign(uint160& signer)
{
return(true);
}

View File

@@ -10,20 +10,9 @@
namespace Script {
class Interpreter;
class Operation;
// Contracts are non typed have variable data types
class Operation
{
public:
// returns false if there was an error
virtual bool work(Interpreter* interpreter)=0;
virtual int getFee();
};
class Interpreter
{
std::vector<Operation*> mFunctionTable;
@@ -40,16 +29,24 @@ class Interpreter
bool mBlockSuccess;
public:
enum { INT_OP,FLOAT_OP,UINT160_OP,BOOL_OP,PATH_OP,
enum { INT_OP=1,FLOAT_OP,UINT160_OP,BOOL_OP,PATH_OP,
ADD_OP,SUB_OP,MUL_OP,DIV_OP,MOD_OP,
GTR_OP,LESS_OP,EQUAL_OP,NOT_EQUAL_OP,
AND_OP,OR_OP,NOT_OP,
BLOCK_OP, BLOCK_END_OP,
JUMP_OP, JUMPIF_OP,
STOP_OP,
SET_DATA_OP,GET_DATA_OP, GET_ISSUER_ID_OP, GET_OWNER_ID_OP, GET_LEDGER_TIME_OP,
ACCEPT_DATA_OP,
SEND_XNS_OP, NUM_OF_OPS };
STOP_OP, CANCEL_OP,
BLOCK_OP, BLOCK_END_OP,
SEND_XNS_OP,SEND_OP,REMOVE_CONTRACT_OP,FEE_OP,CHANGE_CONTRACT_OWNER_OP,
STOP_REMOVE_OP,
SET_DATA_OP,GET_DATA_OP, GET_NUM_DATA_OP,
SET_REGISTER_OP,GET_REGISTER_OP,
GET_ISSUER_ID_OP, GET_OWNER_ID_OP, GET_LEDGER_TIME_OP, GET_LEDGER_NUM_OP, GET_RAND_FLOAT_OP,
GET_XNS_ESCROWED_OP, GET_RIPPLE_ESCROWED_OP, GET_RIPPLE_ESCROWED_CURRENCY_OP, GET_RIPPLE_ESCROWED_ISSUER,
GET_ACCEPT_DATA_OP, GET_ACCEPTOR_ID_OP, GET_CONTRACT_ID_OP,
NUM_OF_OPS };
Interpreter();
@@ -58,7 +55,7 @@ public:
void stop();
bool canSign(const uint160& signer);
bool canSign(uint160& signer);
int getInstructionPointer(){ return(mInstructionPointer); }
void setInstructionPointer(int n){ mInstructionPointer=n;}

View File

@@ -321,12 +321,19 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
BOOST_FOREACH(Peer::ref peer, peerList)
mAcquiringLedger->peerHas(peer);
}
if (mHaveCorrectLCL && mProposing)
{
Log(lsINFO) << "Bowing out of consensus";
mOurPosition->bowOut();
propose();
}
mHaveCorrectLCL = false;
mProposing = false;
mValidating = false;
mCloseTimes.clear();
mPeerPositions.clear();
mDisputes.clear();
mDeadNodes.clear();
return;
}
@@ -491,7 +498,7 @@ void LedgerConsensus::statePreClose()
}
else
{
sinceClose = theApp->getOPs().getLastCloseTime();
sinceClose = 1000 * (theApp->getOPs().getCloseTimeNC() - theApp->getOPs().getLastCloseTime());
idleInterval = LEDGER_IDLE_INTERVAL;
}
@@ -517,7 +524,7 @@ void LedgerConsensus::stateEstablish()
if (haveConsensus())
Log(lsINFO) << "We have TX consensus but not CT consensus";
}
if (haveConsensus())
else if (haveConsensus())
{
Log(lsINFO) << "Converge cutoff (" << mPeerPositions.size() << " participants)";
mState = lcsFINISHED;
@@ -638,7 +645,7 @@ void LedgerConsensus::updateOurPositions()
for (std::map<uint32, int>::iterator it = closeTimes.begin(), end = closeTimes.end(); it != end; ++it)
{
Log(lsINFO) << "CCTime: " << it->first << " has " << it->second << " out of " << thresh;
Log(lsINFO) << "CCTime: " << it->first << " has " << it->second << ", " << thresh << " required";
if (it->second > thresh)
{
Log(lsINFO) << "Close time consensus reached: " << it->first;
@@ -794,11 +801,18 @@ void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vec
bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
{
LedgerProposal::pointer& currentPosition = mPeerPositions[newPosition->getPeerID()];
uint160 peerID = newPosition->getPeerID();
if (mDeadNodes.find(peerID) != mDeadNodes.end())
{
Log(lsINFO) << "Position from dead node";
return false;
}
LedgerProposal::pointer& currentPosition = mPeerPositions[peerID];
if (currentPosition)
{
assert(newPosition->getPeerID() == currentPosition->getPeerID());
assert(peerID == currentPosition->getPeerID());
if (newPosition->getProposeSeq() <= currentPosition->getProposeSeq())
return false;
}
@@ -808,14 +822,24 @@ bool LedgerConsensus::peerPosition(const LedgerProposal::pointer& newPosition)
Log(lsTRACE) << "Peer reports close time as " << newPosition->getCloseTime();
++mCloseTimes[newPosition->getCloseTime()];
}
else if (newPosition->getProposeSeq() == LedgerProposal::seqLeave)
{
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
it.second->unVote(peerID);
mPeerPositions.erase(peerID);
mDeadNodes.insert(peerID);
return true;
}
Log(lsINFO) << "Processing peer proposal " << newPosition->getProposeSeq() << "/" << newPosition->getCurrentHash();
currentPosition = newPosition;
SHAMap::pointer set = getTransactionTree(newPosition->getCurrentHash(), true);
if (set)
{
BOOST_FOREACH(u256_lct_pair& it, mDisputes)
it.second->setVote(newPosition->getPeerID(), set->hasItem(it.first));
it.second->setVote(peerID, set->hasItem(it.first));
}
else
Log(lsTRACE) << "Don't have that tx set";

View File

@@ -115,6 +115,9 @@ protected:
// deferred proposals (node ID -> proposals from that peer)
boost::unordered_map< uint160, std::list<LedgerProposal::pointer> > mDeferredProposals;
// nodes that have bowed out of this consensus process
boost::unordered_set<uint160> mDeadNodes;
// final accept logic
static void Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::pointer txSet);
void accept(const SHAMap::pointer& txSet);

View File

@@ -23,6 +23,23 @@ LedgerEntryFormat LedgerFormats[]=
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Contract", ltCONTRACT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(Issuer), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Owner), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Expiration), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(BondAmount), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(CreateCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(FundCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(RemoveCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(ExpireCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "DirectoryNode", ltDIR_NODE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Indexes), STI_VECTOR256, SOE_REQUIRED, 0 },
@@ -75,21 +92,6 @@ LedgerEntryFormat LedgerFormats[]=
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Contract", ltCONTRACT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Issuer), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Owner), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Expiration), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(BondAmount), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(StampEscrow), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(RippleEscrow), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(CreateCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(FundCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(RemoveCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(ExpireCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ NULL, ltINVALID }
};

View File

@@ -62,6 +62,13 @@ void LedgerProposal::changePosition(const uint256& newPosition, uint32 closeTime
++mProposeSeq;
}
void LedgerProposal::bowOut()
{
mCurrentHash = uint256();
mTime = boost::posix_time::second_clock::universal_time();
mProposeSeq = seqLeave;
}
std::vector<unsigned char> LedgerProposal::sign(void)
{
std::vector<unsigned char> ret;
@@ -78,9 +85,14 @@ Json::Value LedgerProposal::getJson() const
{
Json::Value ret = Json::objectValue;
ret["previous_ledger"] = mPreviousLedger.GetHex();
ret["transaction_hash"] = mCurrentHash.GetHex();
if (mProposeSeq != seqLeave)
{
ret["transaction_hash"] = mCurrentHash.GetHex();
ret["propose_seq"] = mProposeSeq;
}
ret["close_time"] = mCloseTime;
ret["propose_seq"] = mProposeSeq;
if (mPublicKey.isValid())
ret["peer_id"] = mPublicKey.humanNodePublic();

View File

@@ -26,6 +26,7 @@ protected:
boost::posix_time::ptime mTime;
public:
static const uint32 seqLeave = 0xffffffff; // leaving the consensus process
typedef boost::shared_ptr<LedgerProposal> pointer;
@@ -63,6 +64,7 @@ public:
bool isStale(boost::posix_time::ptime cutoff) { return mTime <= cutoff; }
void changePosition(const uint256& newPosition, uint32 newCloseTime);
void bowOut();
Json::Value getJson() const;
};

View File

@@ -27,7 +27,7 @@ bool ContinuousLedgerTiming::shouldClose(
boost::str(boost::format("CLC::shouldClose range Trans=%s, Prop: %d/%d, Secs: %d (last:%d)")
% (anyTransactions ? "yes" : "no") % previousProposers % proposersClosed
% currentMSeconds % previousMSeconds);
return true;;
return true;
}
if (!anyTransactions)