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/main.cpp
This commit is contained in:
@@ -118,16 +118,7 @@ void Application::run()
|
||||
|
||||
std::cerr << "Master seed: " << rootSeedMaster.humanFamilySeed() << std::endl;
|
||||
std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl;
|
||||
std::cerr << "Root address: " << rootAddress.humanAccountPublic() << std::endl;
|
||||
|
||||
// Temporary root account will be ["This is my payphrase."]:0
|
||||
NewcoinAddress rootFamilySeed; // Hold the 128 password.
|
||||
NewcoinAddress rootFamilyGenerator; // Hold the generator.
|
||||
// NewcoinAddress rootAddress;
|
||||
|
||||
rootFamilySeed.setFamilySeed(CKey::PassPhraseToKey("This is my payphrase."));
|
||||
rootFamilyGenerator.setFamilyGenerator(rootFamilySeed);
|
||||
rootAddress.setAccountPublic(rootFamilyGenerator, 0);
|
||||
std::cerr << "Root public key: " << rootAddress.humanAccountPublic() << std::endl;
|
||||
std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl;
|
||||
|
||||
Ledger::pointer firstLedger = boost::make_shared<Ledger>(rootAddress, 100000000);
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
#include "BitcoinUtil.h"
|
||||
#include "Wallet.h"
|
||||
#include "BinaryFormats.h"
|
||||
#include "LedgerTiming.h"
|
||||
|
||||
Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount),
|
||||
mCloseTime(0), mLedgerSeq(0), mLedgerInterval(60), mClosed(false), mValidHash(false),
|
||||
mCloseTime(0), mLedgerSeq(0), mLedgerInterval(LEDGER_INTERVAL), mClosed(false), mValidHash(false),
|
||||
mAccepted(false), mImmutable(false)
|
||||
{
|
||||
mTransactionMap = boost::make_shared<SHAMap>();
|
||||
@@ -37,7 +38,7 @@ Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(s
|
||||
Ledger::Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash,
|
||||
uint64 totCoins, uint64 timeStamp, uint32 ledgerSeq)
|
||||
: mParentHash(parentHash), mTransHash(transHash), mAccountHash(accountHash),
|
||||
mTotCoins(totCoins), mCloseTime(timeStamp), mLedgerSeq(ledgerSeq), mLedgerInterval(60),
|
||||
mTotCoins(totCoins), mCloseTime(timeStamp), mLedgerSeq(ledgerSeq), mLedgerInterval(LEDGER_INTERVAL),
|
||||
mClosed(false), mValidHash(false), mAccepted(false), mImmutable(false)
|
||||
{
|
||||
updateHash();
|
||||
|
||||
@@ -220,7 +220,7 @@ void LedgerAcquire::trigger(Peer::pointer peer)
|
||||
tmGL->set_ledgerhash(mHash.begin(), mHash.size());
|
||||
tmGL->set_ledgerseq(mLedger->getLedgerSeq());
|
||||
tmGL->set_itype(newcoin::liAS_NODE);
|
||||
for (std::vector<SHAMapNode>::iterator it =nodeIDs.begin(); it != nodeIDs.end(); ++it)
|
||||
for (std::vector<SHAMapNode>::iterator it = nodeIDs.begin(); it != nodeIDs.end(); ++it)
|
||||
*(tmGL->add_nodeids()) = it->getRawString();
|
||||
if (peer)
|
||||
{
|
||||
@@ -325,7 +325,7 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
#endif
|
||||
if (!mHaveBase) return false;
|
||||
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
|
||||
std::list<std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
|
||||
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
|
||||
while (nodeIDit != nodeIDs.end())
|
||||
{
|
||||
if (nodeIDit->isRoot())
|
||||
@@ -411,10 +411,10 @@ bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, Peer::poi
|
||||
std::list<SHAMapNode> nodeIDs;
|
||||
std::list<std::vector<unsigned char> > nodeData;
|
||||
|
||||
if (packet.nodes().size()<=0) return false;
|
||||
if (packet.nodes().size() <= 0) return false;
|
||||
for (int i = 0; i<packet.nodes().size(); ++i)
|
||||
{
|
||||
const newcoin::TMLedgerNode& node=packet.nodes(i);
|
||||
const newcoin::TMLedgerNode& node = packet.nodes(i);
|
||||
if (!node.has_nodeid() || !node.has_nodedata()) return false;
|
||||
|
||||
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
|
||||
|
||||
@@ -25,6 +25,7 @@ protected:
|
||||
std::list< boost::weak_ptr<Peer> > mPeers;
|
||||
|
||||
PeerSet(const uint256& hash, int interval);
|
||||
virtual ~PeerSet() { ; }
|
||||
|
||||
public:
|
||||
const uint256& getHash() const { return mHash; }
|
||||
@@ -85,6 +86,29 @@ public:
|
||||
Peer::pointer);
|
||||
};
|
||||
|
||||
class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire>
|
||||
{ // A transaction set we are trying to acquire
|
||||
public:
|
||||
typedef boost::shared_ptr<TransactionAcquire> pointer;
|
||||
|
||||
protected:
|
||||
SHAMap::pointer mMap;
|
||||
|
||||
void onTimer() { trigger(Peer::pointer()); }
|
||||
void newPeer(Peer::pointer peer) { trigger(peer); }
|
||||
|
||||
void done();
|
||||
void trigger(Peer::pointer);
|
||||
boost::weak_ptr<PeerSet> pmDowncast();
|
||||
|
||||
public:
|
||||
TransactionAcquire(const uint256& hash);
|
||||
SHAMap::pointer getMap();
|
||||
|
||||
bool takeNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data,
|
||||
Peer::pointer);
|
||||
};
|
||||
|
||||
class LedgerAcquireMaster
|
||||
{
|
||||
protected:
|
||||
|
||||
100
src/LedgerConsensus.h
Normal file
100
src/LedgerConsensus.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef __LEDGER_CONSENSUS__
|
||||
#define __LEDGER_CONSENSUS__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
#include "key.h"
|
||||
#include "Transaction.h"
|
||||
#include "LedgerAcquire.h"
|
||||
|
||||
class LCPosition
|
||||
{ // A position taken by one of our trusted peers
|
||||
protected:
|
||||
uint256 mPubKeyHash;
|
||||
CKey::pointer mPubKey;
|
||||
uint256 mCurrentPosition;
|
||||
uint32 mSequence;
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<LCPosition> pointer;
|
||||
|
||||
LCPosition(CKey::pointer pubKey, const uint256& currentPosition, uint32 seq) :
|
||||
mPubKey(pubKey), mCurrentPosition(currentPosition), mSequence(seq) { ; }
|
||||
|
||||
const uint256& getPubKeyHash() const { return mPubKeyHash; }
|
||||
const uint256& getCurrentPosition() const { return mCurrentPosition; }
|
||||
uint32 getSeq() const { return mSequence; }
|
||||
|
||||
bool verifySignature(const uint256& hash, const std::vector<unsigned char>& signature) const;
|
||||
void setPosition(const uint256& position, uint32 sequence);
|
||||
};
|
||||
|
||||
|
||||
class LCTransaction
|
||||
{ // A transaction that may be disputed
|
||||
protected:
|
||||
uint256 mTransactionID;
|
||||
int mYays, mNays;
|
||||
bool mOurPosition;
|
||||
boost::unordered_map<uint256, bool> mVotes;
|
||||
Transaction::pointer mTransaction;
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<LCTransaction> pointer;
|
||||
|
||||
LCTransaction(const uint256 &txID, bool ourPosition) : mTransactionID(txID), mYays(0), mNays(0),
|
||||
mOurPosition(ourPosition) { ; }
|
||||
|
||||
const uint256& getTransactionID() const { return mTransactionID; }
|
||||
bool getOurPosition() const { return mOurPosition; }
|
||||
|
||||
bool haveTransaction() const { return !!mTransaction; }
|
||||
Transaction::pointer getTransaction() { return mTransaction; }
|
||||
|
||||
void setVote(const uint256& peer, bool votesYes);
|
||||
|
||||
bool updatePosition(int timePassed);
|
||||
};
|
||||
|
||||
|
||||
class LedgerConsensus
|
||||
{
|
||||
protected:
|
||||
Ledger::pointer mPreviousLedger, mCurrentLedger;
|
||||
|
||||
// Convergence tracking, trusted peers indexed by hash of public key
|
||||
boost::unordered_map<uint256, LCPosition::pointer> mPeerPositions;
|
||||
|
||||
// Transaction Sets, indexed by hash of transaction tree
|
||||
boost::unordered_map<uint256, SHAMap::pointer> mComplete;
|
||||
boost::unordered_map<uint256, TransactionAcquire::pointer> mAcquiring;
|
||||
|
||||
// Peer sets
|
||||
boost::unordered_map<uint256, std::vector< boost::weak_ptr<Peer> > > mPeerData;
|
||||
|
||||
public:
|
||||
LedgerConsensus(Ledger::pointer previousLedger, Ledger::pointer currentLedger) :
|
||||
mPreviousLedger(previousLedger), mCurrentLedger(currentLedger) { ; }
|
||||
|
||||
Ledger::pointer peekPreviousLedger() { return mPreviousLedger; }
|
||||
Ledger::pointer peekCurrentLedger() { return mCurrentLedger; }
|
||||
|
||||
LCPosition::pointer getCreatePeerPosition(const uint256& pubKeyHash);
|
||||
|
||||
SHAMap::pointer getTransactionTree(const uint256& hash);
|
||||
TransactionAcquire::pointer getAcquiring(const uint256& hash);
|
||||
void acquireComplete(const uint256& hash);
|
||||
|
||||
LCPosition::pointer getPeerPosition(const uint256& peer);
|
||||
|
||||
// high-level functions
|
||||
bool peerPosition(Peer::pointer peer, const Serializer& report);
|
||||
bool peerHasSet(Peer::pointer peer, const std::vector<uint256>& sets);
|
||||
bool peerGaveNodes(Peer::pointer peer, const uint256& setHash,
|
||||
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
33
src/LedgerTiming.h
Normal file
33
src/LedgerTiming.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef __LEDGERTIMING__
|
||||
#define __LEDGERTIMING__
|
||||
|
||||
#define LEDGER_CLOSE_FAST
|
||||
// #define LEDGER_CLOSE_SLOW
|
||||
|
||||
#ifdef LEDGER_CLOSE_FAST
|
||||
|
||||
// Time between one ledger close and the next ledger close
|
||||
# define LEDGER_INTERVAL 60
|
||||
|
||||
// Time we expect avalanche to finish
|
||||
# define LEDGER_CONVERGE 20
|
||||
|
||||
// Time we forcibly abort avalanche
|
||||
# define LEDGER_FORCE_CONVERGE 30
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LEDGER_CLOSE_SLOW
|
||||
|
||||
# define LEDGER_INTERVAL 1800
|
||||
|
||||
# define LEDGER_CONVERGE 180
|
||||
|
||||
# define LEDGER_FORCE_CONVERGE 240
|
||||
|
||||
// Time a transaction must be unconflicted before we consider it protected
|
||||
# define LEDGER_PROTECT 90
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -303,6 +303,25 @@ void NewcoinAddress::setAccountPublic(const NewcoinAddress& generator, int seq)
|
||||
setAccountPublic(pubkey.GetPubKey());
|
||||
}
|
||||
|
||||
bool NewcoinAddress::accountPublicVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const
|
||||
{
|
||||
CKey ckPublic;
|
||||
bool bVerified;
|
||||
|
||||
if (!ckPublic.SetPubKey(getAccountPublic()))
|
||||
{
|
||||
// Bad private key.
|
||||
std::cerr << "accountPublicVerify: Bad private key." << std::endl;
|
||||
bVerified = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bVerified = ckPublic.Verify(uHash, vucSig);
|
||||
}
|
||||
|
||||
return bVerified;
|
||||
}
|
||||
|
||||
//
|
||||
// AccountPrivate
|
||||
//
|
||||
@@ -631,16 +650,17 @@ void NewcoinAddress::setFamilySeedGeneric(const std::string& strText)
|
||||
{
|
||||
if (setFamilySeed(strText))
|
||||
{
|
||||
std::cerr << "Recognized seed." << std::endl;
|
||||
// std::cerr << "Recognized seed." << std::endl;
|
||||
nothing();
|
||||
}
|
||||
else if (1 == setFamilySeed1751(strText))
|
||||
{
|
||||
std::cerr << "Recognized 1751 seed." << std::endl;
|
||||
// std::cerr << "Recognized 1751 seed." << std::endl;
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Creating seed from pass phrase." << std::endl;
|
||||
|
||||
// std::cerr << "Creating seed from pass phrase." << std::endl;
|
||||
setFamilySeed(CKey::PassPhraseToKey(strText));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ public:
|
||||
void setAccountPublic(const std::vector<unsigned char>& vPublic);
|
||||
void setAccountPublic(const NewcoinAddress& generator, int seq);
|
||||
|
||||
bool accountPublicVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const;
|
||||
|
||||
//
|
||||
// Accounts Private
|
||||
//
|
||||
|
||||
10
src/Peer.cpp
10
src/Peer.cpp
@@ -749,12 +749,12 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
|
||||
{
|
||||
std::vector<SHAMapNode>::iterator nodeIDIterator;
|
||||
std::list<std::vector<unsigned char> >::iterator rawNodeIterator;
|
||||
for(nodeIDIterator=nodeIDs.begin(), rawNodeIterator=rawNodes.begin();
|
||||
nodeIDIterator!=nodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
|
||||
for(nodeIDIterator = nodeIDs.begin(), rawNodeIterator = rawNodes.begin();
|
||||
nodeIDIterator != nodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
|
||||
{
|
||||
Serializer nID(33);
|
||||
nodeIDIterator->addIDRaw(nID);
|
||||
newcoin::TMLedgerNode* node=data->add_nodes();
|
||||
newcoin::TMLedgerNode* node = data->add_nodes();
|
||||
node->set_nodeid(nID.getDataPtr(), nID.getLength());
|
||||
node->set_nodedata(&rawNodeIterator->front(), rawNodeIterator->size());
|
||||
}
|
||||
@@ -766,14 +766,14 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
|
||||
punishPeer(PP_INVALID_REQUEST);
|
||||
return;
|
||||
}
|
||||
PackedMessage::pointer oPacket=boost::make_shared<PackedMessage>
|
||||
PackedMessage::pointer oPacket = boost::make_shared<PackedMessage>
|
||||
(PackedMessage::MessagePointer(data), newcoin::mtLEDGER);
|
||||
sendPacket(oPacket);
|
||||
}
|
||||
|
||||
void Peer::recvLedger(newcoin::TMLedgerData& packet)
|
||||
{
|
||||
if(!theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this()))
|
||||
if (!theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this()))
|
||||
punishPeer(PP_UNWANTED_DATA);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ NewcoinAddress RPCServer::parseFamily(const std::string& fParam)
|
||||
return family;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Json::Value RPCServer::doCreateFamily(Json::Value& params)
|
||||
{
|
||||
// createfamily FXXXX
|
||||
@@ -216,37 +217,83 @@ Json::Value RPCServer::doCreateFamily(Json::Value& params)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
// account_info <account>|<nickname>|<account_public_key>
|
||||
// account_info <seed>|<pass_phrase>|<key> [<index>]
|
||||
Json::Value RPCServer::doAccountInfo(Json::Value ¶ms)
|
||||
{ // accountinfo <family>:<number>
|
||||
// accountinfo <account>
|
||||
std::string acct;
|
||||
if (!extractString(acct, params, 0))
|
||||
return JSONRPCError(500, "Invalid account identifier");
|
||||
|
||||
LocalAccount::pointer account = theApp->getWallet().parseAccount(acct);
|
||||
if (account) return account->getJson();
|
||||
|
||||
NewcoinAddress acctid;
|
||||
if (!acctid.setAccountID(acct))
|
||||
return JSONRPCError(500, "Unable to parse account");
|
||||
|
||||
LocalAccount::pointer lac(theApp->getWallet().getLocalAccount(acctid));
|
||||
if (!!lac) return lac->getJson();
|
||||
|
||||
AccountState::pointer as=theApp->getMasterLedger().getCurrentLedger()->getAccountState(acctid);
|
||||
Json::Value ret(Json::objectValue);
|
||||
if (as)
|
||||
as->addJson(ret);
|
||||
{
|
||||
if (params.size() < 1 || params.size() > 2)
|
||||
{
|
||||
return "invalid params";
|
||||
}
|
||||
else
|
||||
{
|
||||
NewcoinAddress ad;
|
||||
ad.setAccountID(acct);
|
||||
ret[ad.humanAccountID()]="NotFound";
|
||||
std::string strIdent = params[0u].asString();
|
||||
bool bIndex = 2 == params.size();
|
||||
int iIndex = bIndex ? boost::lexical_cast<int>(params[1u].asString()) : 0;
|
||||
|
||||
NewcoinAddress naAccount;
|
||||
NewcoinAddress naSeed;
|
||||
|
||||
if (!bIndex && (naAccount.setAccountPublic(strIdent) || naAccount.setAccountID(strIdent)))
|
||||
{
|
||||
// Got the account.
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must be a seed.
|
||||
naSeed.setFamilySeedGeneric(strIdent);
|
||||
|
||||
NewcoinAddress naGenerator;
|
||||
NewcoinAddress naRegularReservedPublic;
|
||||
|
||||
naGenerator.setFamilyGenerator(naSeed);
|
||||
|
||||
naRegularReservedPublic.setAccountPublic(naGenerator, -1);
|
||||
|
||||
uint160 uGeneratorID = naRegularReservedPublic.getAccountID();
|
||||
|
||||
// if (probe (uGeneratorID))
|
||||
if (false)
|
||||
{
|
||||
// Found master public key.
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Didn't find a generator map, assume it is a master generator.
|
||||
nothing();
|
||||
}
|
||||
|
||||
bIndex = true;
|
||||
|
||||
naAccount.setAccountPublic(naGenerator, iIndex);
|
||||
}
|
||||
|
||||
// Get info on account.
|
||||
Json::Value ret(Json::objectValue);
|
||||
|
||||
AccountState::pointer as=theApp->getMasterLedger().getCurrentLedger()->getAccountState(naAccount);
|
||||
if (as)
|
||||
{
|
||||
as->addJson(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret["account"] = naAccount.humanAccountID();
|
||||
ret["status"] = "NotFound";
|
||||
ret["bIndex"] = bIndex;
|
||||
if (bIndex)
|
||||
ret["index"] = iIndex;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Json::Value RPCServer::doNewAccount(Json::Value ¶ms)
|
||||
{ // newaccount <family> [<name>]
|
||||
std::string fParam;
|
||||
@@ -262,6 +309,7 @@ Json::Value RPCServer::doNewAccount(Json::Value ¶ms)
|
||||
|
||||
return account->getJson();
|
||||
}
|
||||
#endif
|
||||
|
||||
Json::Value RPCServer::doLock(Json::Value ¶ms)
|
||||
{ // lock <family>
|
||||
@@ -597,10 +645,26 @@ Json::Value RPCServer::doValidatorCreate(Json::Value& params) {
|
||||
// To provide an example to client writers, we do everything we expect a client to do here.
|
||||
Json::Value RPCServer::doWalletClaim(Json::Value& params)
|
||||
{
|
||||
NewcoinAddress naTemp;
|
||||
|
||||
if (params.size() < 2 || params.size() > 4)
|
||||
{
|
||||
return "invalid params";
|
||||
}
|
||||
else if (naTemp.setAccountID(params[0u].asString())
|
||||
|| naTemp.setAccountPublic(params[0u].asString())
|
||||
|| naTemp.setAccountPrivate(params[0u].asString()))
|
||||
{
|
||||
// Should also not allow account id's as seeds.
|
||||
return "master seed expected";
|
||||
}
|
||||
else if (naTemp.setAccountID(params[1u].asString())
|
||||
|| naTemp.setAccountPublic(params[1u].asString())
|
||||
|| naTemp.setAccountPrivate(params[1u].asString()))
|
||||
{
|
||||
// Should also not allow account id's as seeds.
|
||||
return "regular seed expected";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Trying to build:
|
||||
@@ -608,8 +672,9 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params)
|
||||
//
|
||||
// Which has no confidential information.
|
||||
|
||||
// XXX Need better parsing.
|
||||
uint32 uSourceTag = (params.size() == 2) ? 0 : boost::lexical_cast<uint32>(params[2u].asString());
|
||||
// XXX Annotation is ignored.
|
||||
uint32 uSourceTag = (params.size() == 2) ? 0 : params[2u].asUInt();
|
||||
std::string strAnnotation = (params.size() == 3) ? "" : params[3u].asString();
|
||||
|
||||
NewcoinAddress naMasterSeed;
|
||||
@@ -622,7 +687,6 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params)
|
||||
|
||||
NewcoinAddress naAccountPublic;
|
||||
NewcoinAddress naAccountPrivate;
|
||||
NewcoinAddress naUnset;
|
||||
|
||||
naMasterSeed.setFamilySeedGeneric(params[0u].asString());
|
||||
naRegularSeed.setFamilySeedGeneric(params[1u].asString());
|
||||
@@ -640,14 +704,14 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params)
|
||||
uint160 uGeneratorID = naRegularReservedPublic.getAccountID();
|
||||
std::vector<unsigned char> vucGeneratorCipher = naRegularReservedPrivate.accountPrivateEncrypt(naRegularReservedPublic, naMasterGenerator.getFamilyGenerator());
|
||||
|
||||
|
||||
Transaction::pointer trns = boost::make_shared<Transaction>(
|
||||
Transaction::pointer trns = Transaction::sharedClaim(
|
||||
naAccountPublic, naAccountPrivate,
|
||||
naAccountPublic, naUnset,
|
||||
0, // Free
|
||||
0, // Seq
|
||||
uSourceTag, // Source tag
|
||||
0); // Ledger not specified.
|
||||
naAccountPublic,
|
||||
uSourceTag,
|
||||
naRegularReservedPublic, // GeneratorID
|
||||
vucGeneratorCipher);
|
||||
|
||||
(void) theApp->getOPs().processTransaction(trns);
|
||||
|
||||
Json::Value obj(Json::objectValue);
|
||||
|
||||
@@ -662,6 +726,9 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params)
|
||||
obj["generator"] = strHex(vucGeneratorCipher);
|
||||
obj["annotation"] = strAnnotation;
|
||||
|
||||
obj["transaction"] = trns->getSTransaction()->getJson(0);
|
||||
obj["status"] = trns->getStatus();
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -809,38 +876,47 @@ Json::Value RPCServer::doUnlScore(Json::Value& params) {
|
||||
else return "invalid params";
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params)
|
||||
{
|
||||
std::cerr << "RPC:" << command << std::endl;
|
||||
|
||||
if (command== "stop")
|
||||
Json::Value RPCServer::doStop(Json::Value& params) {
|
||||
if (!params.size())
|
||||
{
|
||||
theApp->stop();
|
||||
|
||||
return SYSTEM_NAME " server stopping";
|
||||
}
|
||||
else return "invalid params";
|
||||
}
|
||||
|
||||
if (command=="unl_add") return doUnlAdd(params);
|
||||
if (command=="unl_default") return doUnlDefault(params);
|
||||
if (command=="unl_delete") return doUnlDelete(params);
|
||||
if (command=="unl_list") return doUnlList(params);
|
||||
if (command=="unl_reset") return doUnlReset(params);
|
||||
if (command=="unl_score") return doUnlScore(params);
|
||||
Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params)
|
||||
{
|
||||
std::cerr << "RPC:" << command << std::endl;
|
||||
|
||||
if (command=="validation_create") return doValidatorCreate(params);
|
||||
if (command == "account_info") return doAccountInfo(params);
|
||||
if (command == "connect") return doConnect(params);
|
||||
if (command == "peers") return doPeers(params);
|
||||
if (command == "stop") return doStop(params);
|
||||
|
||||
if (command=="wallet_claim") return doWalletClaim(params);
|
||||
if (command=="wallet_propose") return doWalletPropose(params);
|
||||
if (command == "unl_add") return doUnlAdd(params);
|
||||
if (command == "unl_default") return doUnlDefault(params);
|
||||
if (command == "unl_delete") return doUnlDelete(params);
|
||||
if (command == "unl_list") return doUnlList(params);
|
||||
if (command == "unl_reset") return doUnlReset(params);
|
||||
if (command == "unl_score") return doUnlScore(params);
|
||||
|
||||
if (command=="createfamily") return doCreateFamily(params);
|
||||
if (command == "validation_create") return doValidatorCreate(params);
|
||||
|
||||
if (command == "wallet_claim") return doWalletClaim(params);
|
||||
if (command == "wallet_propose") return doWalletPropose(params);
|
||||
|
||||
//
|
||||
// Obsolete or need rewrite:
|
||||
//
|
||||
|
||||
// if (command=="createfamily") return doCreateFamily(params);
|
||||
if (command=="familyinfo") return doFamilyInfo(params);
|
||||
if (command=="accountinfo") return doAccountInfo(params);
|
||||
if (command=="newaccount") return doNewAccount(params);
|
||||
// if (command=="newaccount") return doNewAccount(params);
|
||||
if (command=="lock") return doLock(params);
|
||||
if (command=="unlock") return doUnlock(params);
|
||||
if (command=="sendto") return doSendTo(params);
|
||||
if (command=="connect") return doConnect(params);
|
||||
if (command=="peers") return doPeers(params);
|
||||
if (command=="tx") return doTx(params);
|
||||
if (command=="ledger") return doLedger(params);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ class RPCServer : public boost::enable_shared_from_this<RPCServer>
|
||||
Json::Value doTx(Json::Value& params);
|
||||
Json::Value doLedger(Json::Value& params);
|
||||
Json::Value doAccount(Json::Value& params);
|
||||
Json::Value doStop(Json::Value& params);
|
||||
|
||||
Json::Value doUnlAdd(Json::Value& params);
|
||||
Json::Value doUnlDefault(Json::Value& params);
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
|
||||
SHAMapNode() : mDepth(0) { ; }
|
||||
SHAMapNode(int depth, const uint256& hash);
|
||||
virtual ~SHAMapNode() { ; }
|
||||
int getDepth() const { return mDepth; }
|
||||
const uint256& getNodeID() const { return mNodeID; }
|
||||
bool isValid() const { return (mDepth >= 0) && (mDepth < 64); }
|
||||
|
||||
@@ -15,9 +15,6 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
|
||||
|
||||
if(root->isFullBelow())
|
||||
{
|
||||
#ifdef GMN_DEBUG
|
||||
std::cerr << "getMissingNodes: root is full below" << std::endl;
|
||||
#endif
|
||||
clearSynching();
|
||||
return;
|
||||
}
|
||||
@@ -31,34 +28,23 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
|
||||
std::stack<SHAMapTreeNode::pointer> stack;
|
||||
stack.push(root);
|
||||
|
||||
while ((max > 0) && (!stack.empty()))
|
||||
while (!stack.empty())
|
||||
{
|
||||
SHAMapTreeNode::pointer node = stack.top();
|
||||
stack.pop();
|
||||
|
||||
#ifdef GMN_DEBUG
|
||||
std::cerr << "gMN: popped " << node->getString() << std::endl;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
if( !node->isEmptyBranch(i))
|
||||
if (!node->isEmptyBranch(i))
|
||||
{
|
||||
#ifdef GMN_DEBUG
|
||||
std::cerr << "gMN: " << node->getString() << " has non-empty branch " << i << std::endl;
|
||||
#endif
|
||||
SHAMapTreeNode::pointer desc = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
|
||||
if(desc)
|
||||
if (!desc)
|
||||
{
|
||||
if (desc->isInner() && !desc->isFullBelow())
|
||||
stack.push(desc);
|
||||
}
|
||||
else if (max-- > 0)
|
||||
{
|
||||
#ifdef GMN_DEBUG
|
||||
std::cerr << "gMN: need " << node->getChildNodeID(i).getString() << std::endl;
|
||||
#endif
|
||||
nodeIDs.push_back(node->getChildNodeID(i));
|
||||
if (--max <= 0)
|
||||
return;
|
||||
}
|
||||
else if (desc->isInner() && !desc->isFullBelow())
|
||||
stack.push(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ protected:
|
||||
STObject mObject;
|
||||
LedgerEntryFormat* mFormat;
|
||||
|
||||
SerializedLedgerEntry* duplicate() const { return new SerializedLedgerEntry(*this); }
|
||||
|
||||
public:
|
||||
SerializedLedgerEntry(const Serializer& s, const uint256& index);
|
||||
SerializedLedgerEntry(SerializerIterator& sit, const uint256& index);
|
||||
@@ -24,7 +26,6 @@ public:
|
||||
|
||||
int getLength() const { return mVersion.getLength() + mObject.getLength(); }
|
||||
SerializedTypeID getSType() const { return STI_LEDGERENTRY; }
|
||||
SerializedLedgerEntry* duplicate() const { return new SerializedLedgerEntry(*this); }
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
Json::Value getJson(int options) const;
|
||||
|
||||
@@ -5,77 +5,88 @@
|
||||
|
||||
#include "../json/writer.h"
|
||||
|
||||
SerializedType* STObject::makeDefaultObject(SerializedTypeID id, const char *name)
|
||||
std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, const char *name)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case STI_NOTPRESENT:
|
||||
return std::auto_ptr<SerializedType>(new SerializedType(name));
|
||||
|
||||
case STI_UINT16:
|
||||
return new STUInt16(name);
|
||||
return std::auto_ptr<SerializedType>(new STUInt16(name));
|
||||
|
||||
case STI_UINT32:
|
||||
return new STUInt32(name);
|
||||
return std::auto_ptr<SerializedType>(new STUInt32(name));
|
||||
|
||||
case STI_UINT64:
|
||||
return new STUInt64(name);
|
||||
return std::auto_ptr<SerializedType>(new STUInt64(name));
|
||||
|
||||
case STI_AMOUNT:
|
||||
return new STAmount(name);
|
||||
return std::auto_ptr<SerializedType>(new STAmount(name));
|
||||
|
||||
case STI_HASH128:
|
||||
return std::auto_ptr<SerializedType>(new STHash128(name));
|
||||
|
||||
case STI_HASH160:
|
||||
return new STHash160(name);
|
||||
return std::auto_ptr<SerializedType>(new STHash160(name));
|
||||
|
||||
case STI_HASH256:
|
||||
return new STHash256(name);
|
||||
return std::auto_ptr<SerializedType>(new STHash256(name));
|
||||
|
||||
case STI_VL:
|
||||
return new STVariableLength(name);
|
||||
return std::auto_ptr<SerializedType>(new STVariableLength(name));
|
||||
|
||||
case STI_TL:
|
||||
return new STTaggedList(name);
|
||||
return std::auto_ptr<SerializedType>(new STTaggedList(name));
|
||||
|
||||
case STI_ACCOUNT:
|
||||
return new STAccount(name);
|
||||
return std::auto_ptr<SerializedType>(new STAccount(name));
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return NULL;
|
||||
throw std::runtime_error("Unknown object type");
|
||||
}
|
||||
}
|
||||
|
||||
SerializedType* STObject::makeDeserializedObject(SerializedTypeID id, const char *name, SerializerIterator& sit)
|
||||
std::auto_ptr<SerializedType> STObject::makeDeserializedObject(SerializedTypeID id, const char *name,
|
||||
SerializerIterator& sit)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case STI_NOTPRESENT:
|
||||
return SerializedType::deserialize(name);
|
||||
|
||||
case STI_UINT16:
|
||||
return STUInt16::construct(sit, name);
|
||||
return STUInt16::deserialize(sit, name);
|
||||
|
||||
case STI_UINT32:
|
||||
return STUInt32::construct(sit, name);
|
||||
return STUInt32::deserialize(sit, name);
|
||||
|
||||
case STI_UINT64:
|
||||
return STUInt64::construct(sit, name);
|
||||
return STUInt64::deserialize(sit, name);
|
||||
|
||||
case STI_AMOUNT:
|
||||
return STAmount::construct(sit, name);
|
||||
return STAmount::deserialize(sit, name);
|
||||
|
||||
case STI_HASH128:
|
||||
return STHash128::deserialize(sit, name);
|
||||
|
||||
case STI_HASH160:
|
||||
return STHash160::construct(sit, name);
|
||||
return STHash160::deserialize(sit, name);
|
||||
|
||||
case STI_HASH256:
|
||||
return STHash256::construct(sit, name);
|
||||
return STHash256::deserialize(sit, name);
|
||||
|
||||
case STI_VL:
|
||||
return STVariableLength::construct(sit, name);
|
||||
return STVariableLength::deserialize(sit, name);
|
||||
|
||||
case STI_TL:
|
||||
return STTaggedList::construct(sit, name);
|
||||
return STTaggedList::deserialize(sit, name);
|
||||
|
||||
case STI_ACCOUNT:
|
||||
return STAccount::construct(sit, name);
|
||||
return STAccount::deserialize(sit, name);
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return NULL;
|
||||
throw std::runtime_error("Unknown object type");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,13 +97,9 @@ STObject::STObject(SOElement* elem, const char *name) : SerializedType(name), mF
|
||||
if (elem->e_type == SOE_FLAGS) mFlagIdx = mType.size();
|
||||
mType.push_back(elem);
|
||||
if (elem->e_type == SOE_IFFLAG)
|
||||
giveObject(new SerializedType(elem->e_name));
|
||||
giveObject(makeDefaultObject(STI_NOTPRESENT, elem->e_name));
|
||||
else
|
||||
{
|
||||
SerializedType* t = makeDefaultObject(elem->e_id, elem->e_name);
|
||||
if (!t) throw std::runtime_error("invalid transaction element");
|
||||
giveObject(t);
|
||||
}
|
||||
giveObject(makeDefaultObject(elem->e_id, elem->e_name));
|
||||
++elem;
|
||||
}
|
||||
}
|
||||
@@ -107,12 +114,20 @@ STObject::STObject(SOElement* elem, SerializerIterator& sit, const char *name) :
|
||||
if (elem->e_type == SOE_IFFLAG)
|
||||
{
|
||||
assert(flags >= 0);
|
||||
if ((flags&elem->e_flags) == 0) done = true;
|
||||
if ((flags&elem->e_flags) == 0)
|
||||
{
|
||||
done = true;
|
||||
giveObject(makeDefaultObject(elem->e_id, elem->e_name));
|
||||
}
|
||||
}
|
||||
else if (elem->e_type == SOE_IFNFLAG)
|
||||
{
|
||||
assert(flags >= 0);
|
||||
if ((flags&elem->e_flags) != 0) done = true;
|
||||
if ((flags&elem->e_flags) != 0)
|
||||
{
|
||||
done = true;
|
||||
giveObject(makeDefaultObject(STI_NOTPRESENT, elem->e_name));
|
||||
}
|
||||
}
|
||||
else if (elem->e_type == SOE_FLAGS)
|
||||
{
|
||||
@@ -122,11 +137,7 @@ STObject::STObject(SOElement* elem, SerializerIterator& sit, const char *name) :
|
||||
done = true;
|
||||
}
|
||||
if (!done)
|
||||
{
|
||||
SerializedType* t = makeDeserializedObject(elem->e_id, elem->e_name, sit);
|
||||
if (!t) throw std::runtime_error("invalid transaction element");
|
||||
giveObject(t);
|
||||
}
|
||||
giveObject(makeDeserializedObject(elem->e_id, elem->e_name, sit));
|
||||
elem++;
|
||||
}
|
||||
}
|
||||
@@ -141,12 +152,14 @@ std::string STObject::getFullText() const
|
||||
ret += " = {";
|
||||
}
|
||||
else ret = "{";
|
||||
|
||||
for (boost::ptr_vector<SerializedType>::const_iterator it = mData.begin(), end = mData.end(); it != end; ++it)
|
||||
{
|
||||
if (!first) ret += ", ";
|
||||
else first = false;
|
||||
ret += it->getFullText();
|
||||
}
|
||||
|
||||
ret += "}";
|
||||
return ret;
|
||||
}
|
||||
@@ -269,23 +282,22 @@ uint32 STObject::getFlags(void) const
|
||||
|
||||
SerializedType* STObject::makeFieldPresent(SOE_Field field)
|
||||
{
|
||||
SerializedType* ret = NULL;
|
||||
int index = getFieldIndex(field);
|
||||
if (index == -1) throw std::runtime_error("Field not found");
|
||||
if ((mType[index]->e_type != SOE_IFFLAG) && (mType[index]->e_type != SOE_IFNFLAG))
|
||||
throw std::runtime_error("field is not optional");
|
||||
|
||||
ret = getPIndex(index);
|
||||
if (ret->getSType() != STI_NOTPRESENT) return ret;
|
||||
ret = makeDefaultObject(mType[index]->e_id, mType[index]->e_name);
|
||||
mData.replace(index, ret);
|
||||
SerializedType* f = getPIndex(index);
|
||||
if (f->getSType() != STI_NOTPRESENT) return f;
|
||||
mData.replace(index, makeDefaultObject(mType[index]->e_id, mType[index]->e_name));
|
||||
f = getPIndex(index);
|
||||
|
||||
if (mType[index]->e_type == SOE_IFFLAG)
|
||||
setFlag(mType[index]->e_flags);
|
||||
else if (mType[index]->e_type == SOE_IFNFLAG)
|
||||
clearFlag(mType[index]->e_flags);
|
||||
|
||||
return ret;
|
||||
return f;
|
||||
}
|
||||
|
||||
void STObject::makeFieldAbsent(SOE_Field field)
|
||||
|
||||
@@ -54,8 +54,10 @@ protected:
|
||||
boost::ptr_vector<SerializedType> mData;
|
||||
std::vector<SOElement*> mType;
|
||||
|
||||
static SerializedType* makeDefaultObject(SerializedTypeID id, const char *name);
|
||||
static SerializedType* makeDeserializedObject(SerializedTypeID id, const char *name, SerializerIterator&);
|
||||
static std::auto_ptr<SerializedType> makeDefaultObject(SerializedTypeID id, const char *name);
|
||||
static std::auto_ptr<SerializedType> makeDeserializedObject(SerializedTypeID id, const char *name,
|
||||
SerializerIterator&);
|
||||
STObject* duplicate() const { return new STObject(*this); }
|
||||
|
||||
public:
|
||||
STObject(const char *n = NULL) : SerializedType(n), mFlagIdx(-1) { ; }
|
||||
@@ -65,7 +67,6 @@ public:
|
||||
|
||||
int getLength() const;
|
||||
SerializedTypeID getSType() const { return STI_OBJECT; }
|
||||
STObject* duplicate() const { return new STObject(*this); }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
|
||||
void add(Serializer& s) const;
|
||||
@@ -74,8 +75,9 @@ public:
|
||||
std::string getText() const;
|
||||
virtual Json::Value getJson(int options) const;
|
||||
|
||||
int addObject(const SerializedType& t) { mData.push_back(t.duplicate()); return mData.size()-1; }
|
||||
int giveObject(SerializedType* t) { mData.push_back(t); return mData.size()-1; }
|
||||
int addObject(const SerializedType& t) { mData.push_back(t.clone()); return mData.size() - 1; }
|
||||
int giveObject(std::auto_ptr<SerializedType> t) { mData.push_back(t); return mData.size() - 1; }
|
||||
int giveObject(SerializedType* t) { mData.push_back(t); return mData.size() - 1; }
|
||||
const boost::ptr_vector<SerializedType>& peekData() const { return mData; }
|
||||
boost::ptr_vector<SerializedType>& peekData() { return mData; }
|
||||
|
||||
|
||||
@@ -136,9 +136,9 @@ bool SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate)
|
||||
return naAccountPrivate.accountPrivateSign(getSigningHash(), mSignature.peekValue());
|
||||
}
|
||||
|
||||
bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPrivate) const
|
||||
bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPublic) const
|
||||
{
|
||||
return naAccountPrivate.accountPrivateVerify(getSigningHash(), mSignature.getValue());
|
||||
return naAccountPublic.accountPublicVerify(getSigningHash(), mSignature.getValue());
|
||||
}
|
||||
|
||||
void SerializedTransaction::setSignature(const std::vector<unsigned char>& sig)
|
||||
|
||||
@@ -23,6 +23,8 @@ protected:
|
||||
STObject mMiddleTxn, mInnerTxn;
|
||||
TransactionFormat* mFormat;
|
||||
|
||||
SerializedTransaction* duplicate() const { return new SerializedTransaction(*this); }
|
||||
|
||||
public:
|
||||
SerializedTransaction(SerializerIterator& sit, int length); // -1=all remaining, 0=get from sit
|
||||
SerializedTransaction(TransactionType type);
|
||||
@@ -30,7 +32,6 @@ public:
|
||||
// STObject functions
|
||||
int getLength() const;
|
||||
SerializedTypeID getSType() const { return STI_TRANSACTION; }
|
||||
SerializedTransaction* duplicate() const { return new SerializedTransaction(*this); }
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { getTransaction(s, true); }
|
||||
@@ -112,7 +113,7 @@ public:
|
||||
virtual Json::Value getJson(int options) const;
|
||||
|
||||
bool sign(const NewcoinAddress& naAccountPrivate);
|
||||
bool checkSign(const NewcoinAddress& naAccountPrivate) const;
|
||||
bool checkSign(const NewcoinAddress& naAccountPublic) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,8 @@ class SerializedType
|
||||
protected:
|
||||
const char *name;
|
||||
|
||||
virtual SerializedType* duplicate() const { return new SerializedType(name); }
|
||||
|
||||
public:
|
||||
|
||||
SerializedType() : name(NULL) { ; }
|
||||
@@ -33,12 +35,15 @@ public:
|
||||
SerializedType(const SerializedType& n) : name(n.name) { ; }
|
||||
virtual ~SerializedType() { ; }
|
||||
|
||||
static std::auto_ptr<SerializedType> deserialize(const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(new SerializedType(name)); }
|
||||
|
||||
void setName(const char *n) { name=n; }
|
||||
const char *getName() const { return name; }
|
||||
|
||||
virtual int getLength() const { return 0; }
|
||||
virtual SerializedTypeID getSType() const { return STI_NOTPRESENT; }
|
||||
virtual SerializedType* duplicate() const { return new SerializedType(name); }
|
||||
std::auto_ptr<SerializedType> clone() const { return std::auto_ptr<SerializedType>(duplicate()); }
|
||||
|
||||
virtual std::string getFullText() const;
|
||||
virtual std::string getText() const // just the value
|
||||
@@ -49,12 +54,12 @@ public:
|
||||
virtual bool isEquivalent(const SerializedType& t) const { return true; }
|
||||
|
||||
bool operator==(const SerializedType& t) const
|
||||
{ return (getSType()==t.getSType()) && isEquivalent(t); }
|
||||
{ return (getSType() == t.getSType()) && isEquivalent(t); }
|
||||
bool operator!=(const SerializedType& t) const
|
||||
{ return (getSType()!=t.getSType()) || !isEquivalent(t); }
|
||||
{ return (getSType() != t.getSType()) || !isEquivalent(t); }
|
||||
};
|
||||
|
||||
inline SerializedType* new_clone(const SerializedType& s) { return s.duplicate(); }
|
||||
inline SerializedType* new_clone(const SerializedType& s) { return s.clone().release(); }
|
||||
inline void delete_clone(const SerializedType* s) { boost::checked_delete(s); }
|
||||
|
||||
class STUInt8 : public SerializedType
|
||||
@@ -62,15 +67,18 @@ class STUInt8 : public SerializedType
|
||||
protected:
|
||||
unsigned char value;
|
||||
|
||||
STUInt8* duplicate() const { return new STUInt8(name, value); }
|
||||
static STUInt8* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STUInt8(unsigned char v=0) : value(v) { ; }
|
||||
STUInt8(const char *n, unsigned char v=0) : SerializedType(n), value(v) { ; }
|
||||
static STUInt8* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 1; }
|
||||
SerializedTypeID getSType() const { return STI_UINT8; }
|
||||
STUInt8* duplicate() const { return new STUInt8(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add8(value); }
|
||||
|
||||
@@ -87,15 +95,18 @@ class STUInt16 : public SerializedType
|
||||
protected:
|
||||
uint16 value;
|
||||
|
||||
STUInt16* duplicate() const { return new STUInt16(name, value); }
|
||||
static STUInt16* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STUInt16(uint16 v=0) : value(v) { ; }
|
||||
STUInt16(const char *n, uint16 v=0) : SerializedType(n), value(v) { ; }
|
||||
static STUInt16* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 2; }
|
||||
SerializedTypeID getSType() const { return STI_UINT16; }
|
||||
STUInt16* duplicate() const { return new STUInt16(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add16(value); }
|
||||
|
||||
@@ -112,15 +123,18 @@ class STUInt32 : public SerializedType
|
||||
protected:
|
||||
uint32 value;
|
||||
|
||||
STUInt32* duplicate() const { return new STUInt32(name, value); }
|
||||
static STUInt32* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STUInt32(uint32 v=0) : value(v) { ; }
|
||||
STUInt32(const char *n, uint32 v=0) : SerializedType(n), value(v) { ; }
|
||||
static STUInt32* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 4; }
|
||||
SerializedTypeID getSType() const { return STI_UINT32; }
|
||||
STUInt32* duplicate() const { return new STUInt32(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add32(value); }
|
||||
|
||||
@@ -137,15 +151,18 @@ class STUInt64 : public SerializedType
|
||||
protected:
|
||||
uint64 value;
|
||||
|
||||
STUInt64* duplicate() const { return new STUInt64(name, value); }
|
||||
static STUInt64* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STUInt64(uint64 v=0) : value(v) { ; }
|
||||
STUInt64(const char *n, uint64 v=0) : SerializedType(n), value(v) { ; }
|
||||
static STUInt64* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 8; }
|
||||
SerializedTypeID getSType() const { return STI_UINT64; }
|
||||
STUInt64* duplicate() const { return new STUInt64(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add64(value); }
|
||||
|
||||
@@ -175,6 +192,8 @@ protected:
|
||||
uint64 value;
|
||||
|
||||
void canonicalize();
|
||||
STAmount* duplicate() const { return new STAmount(name, offset, value); }
|
||||
static STAmount* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
static const int cMinOffset=-96, cMaxOffset=80;
|
||||
static const uint64 cMinValue=1000000000000000ull, cMaxValue=9999999999999999ull;
|
||||
@@ -184,11 +203,11 @@ public:
|
||||
{ canonicalize(); } // (1,0)=$1 (1,-2)=$.01 (100,0)=(10000,-2)=$.01
|
||||
STAmount(const char *n, uint64 v = 0, int off = 0) : SerializedType(n), offset(off), value(v)
|
||||
{ canonicalize(); }
|
||||
static STAmount* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 8; }
|
||||
SerializedTypeID getSType() const { return STI_AMOUNT; }
|
||||
STAmount* duplicate() const { return new STAmount(name, offset, value); }
|
||||
std::string getText() const;
|
||||
std::string getRaw() const;
|
||||
void add(Serializer& s) const;
|
||||
@@ -245,17 +264,20 @@ class STHash128 : public SerializedType
|
||||
protected:
|
||||
uint128 value;
|
||||
|
||||
STHash128* duplicate() const { return new STHash128(name, value); }
|
||||
static STHash128* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STHash128(const uint128& v) : value(v) { ; }
|
||||
STHash128(const char *n, const uint128& v) : SerializedType(n), value(v) { ; }
|
||||
STHash128(const char *n) : SerializedType(n) { ; }
|
||||
STHash128() { ; }
|
||||
static STHash128* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 20; }
|
||||
SerializedTypeID getSType() const { return STI_HASH128; }
|
||||
STHash128* duplicate() const { return new STHash128(name, value); }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.add128(value); }
|
||||
|
||||
@@ -272,17 +294,20 @@ class STHash160 : public SerializedType
|
||||
protected:
|
||||
uint160 value;
|
||||
|
||||
STHash160* duplicate() const { return new STHash160(name, value); }
|
||||
static STHash160* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STHash160(const uint160& v) : value(v) { ; }
|
||||
STHash160(const char *n, const uint160& v) : SerializedType(n), value(v) { ; }
|
||||
STHash160(const char *n) : SerializedType(n) { ; }
|
||||
STHash160() { ; }
|
||||
static STHash160* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 20; }
|
||||
SerializedTypeID getSType() const { return STI_HASH160; }
|
||||
STHash160* duplicate() const { return new STHash160(name, value); }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.add160(value); }
|
||||
|
||||
@@ -299,17 +324,20 @@ class STHash256 : public SerializedType
|
||||
protected:
|
||||
uint256 value;
|
||||
|
||||
STHash256* duplicate() const { return new STHash256(name, value); }
|
||||
static STHash256* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STHash256(const uint256& v) : value(v) { ; }
|
||||
STHash256(const char *n, const uint256& v) : SerializedType(n), value(v) { ; }
|
||||
STHash256(const char *n) : SerializedType(n) { ; }
|
||||
STHash256() { ; }
|
||||
static STHash256* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const { return 32; }
|
||||
SerializedTypeID getSType() const { return STI_HASH256; }
|
||||
STHash256* duplicate() const { return new STHash256(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add256(value); }
|
||||
|
||||
@@ -326,6 +354,9 @@ class STVariableLength : public SerializedType
|
||||
protected:
|
||||
std::vector<unsigned char> value;
|
||||
|
||||
virtual STVariableLength* duplicate() const { return new STVariableLength(name, value); }
|
||||
static STVariableLength* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STVariableLength(const std::vector<unsigned char>& v) : value(v) { ; }
|
||||
@@ -333,11 +364,11 @@ public:
|
||||
STVariableLength(const char *n) : SerializedType(n) { ; }
|
||||
STVariableLength(SerializerIterator&, const char *name = NULL);
|
||||
STVariableLength() { ; }
|
||||
static STVariableLength* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const;
|
||||
virtual SerializedTypeID getSType() const { return STI_VL; }
|
||||
virtual STVariableLength* duplicate() const { return new STVariableLength(name, value); }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.addVL(value); }
|
||||
|
||||
@@ -353,16 +384,20 @@ public:
|
||||
|
||||
class STAccount : public STVariableLength
|
||||
{
|
||||
protected:
|
||||
virtual STAccount* duplicate() const { return new STAccount(name, value); }
|
||||
static STAccount* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STAccount(const std::vector<unsigned char>& v) : STVariableLength(v) { ; }
|
||||
STAccount(const char *n, const std::vector<unsigned char>& v) : STVariableLength(n, v) { ; }
|
||||
STAccount(const char *n) : STVariableLength(n) { ; }
|
||||
STAccount() { ; }
|
||||
static STAccount* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_ACCOUNT; }
|
||||
virtual STAccount* duplicate() const { return new STAccount(name, value); }
|
||||
std::string getText() const;
|
||||
|
||||
NewcoinAddress getValueNCA() const;
|
||||
@@ -378,17 +413,20 @@ class STTaggedList : public SerializedType
|
||||
protected:
|
||||
std::vector<TaggedListItem> value;
|
||||
|
||||
STTaggedList* duplicate() const { return new STTaggedList(name, value); }
|
||||
static STTaggedList* construct(SerializerIterator&, const char *name = NULL);
|
||||
|
||||
public:
|
||||
|
||||
STTaggedList() { ; }
|
||||
STTaggedList(const char *n) : SerializedType(n) { ; }
|
||||
STTaggedList(const std::vector<TaggedListItem>& v) : value(v) { ; }
|
||||
STTaggedList(const char *n, const std::vector<TaggedListItem>& v) : SerializedType(n), value(v) { ; }
|
||||
static STTaggedList* construct(SerializerIterator&, const char *name = NULL);
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char *name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
int getLength() const;
|
||||
SerializedTypeID getSType() const { return STI_TL; }
|
||||
STTaggedList* duplicate() const { return new STTaggedList(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { if(s.addTaggedList(value)<0) throw(0); }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include "boost/lexical_cast.hpp"
|
||||
#include "boost/make_shared.hpp"
|
||||
#include "boost/ref.hpp"
|
||||
@@ -11,47 +12,6 @@
|
||||
#include "Serializer.h"
|
||||
#include "SerializedTransaction.h"
|
||||
|
||||
Transaction::Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount,
|
||||
uint64 amount,
|
||||
uint32 iSeq, uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW)
|
||||
{
|
||||
mAccountFrom = naFromAccount;
|
||||
|
||||
mFromPubKey = naPublicKey;
|
||||
assert(mFromPubKey.isValid());
|
||||
|
||||
mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
|
||||
|
||||
mTransaction->setSigningPubKey(mFromPubKey);
|
||||
mTransaction->setSourceAccount(mAccountFrom);
|
||||
|
||||
mTransaction->setSequence(iSeq);
|
||||
|
||||
mTransaction->setTransactionFee(100); // for now
|
||||
|
||||
mTransaction->setITFieldAccount(sfDestination, toAccount);
|
||||
mTransaction->setITFieldU64(sfAmount, amount);
|
||||
if (ledger != 0)
|
||||
{
|
||||
mTransaction->makeITFieldPresent(sfTargetLedger);
|
||||
mTransaction->setITFieldU32(sfTargetLedger, ledger);
|
||||
}
|
||||
if (ident != 0)
|
||||
{
|
||||
mTransaction->makeITFieldPresent(sfSourceTag);
|
||||
mTransaction->setITFieldU32(sfSourceTag, ident);
|
||||
}
|
||||
|
||||
if (!sign(naPrivateKey))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Unable to sign transaction" << std::endl;
|
||||
#endif
|
||||
mStatus = INCOMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
Transaction::Transaction(const SerializedTransaction::pointer sit, bool bValidate)
|
||||
: mInLedger(0), mStatus(INVALID), mTransaction(sit)
|
||||
{
|
||||
@@ -87,69 +47,146 @@ Transaction::pointer Transaction::sharedTransaction(const std::vector<unsigned c
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
|
||||
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
|
||||
uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st) :
|
||||
mAccountFrom(fromID), mFromPubKey(pubKey), mInLedger(ledgerSeq), mStatus(st)
|
||||
//
|
||||
// Generic transaction construction
|
||||
//
|
||||
|
||||
Transaction::Transaction(
|
||||
TransactionType ttKind,
|
||||
const NewcoinAddress& naPublicKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
uint64 uFee,
|
||||
uint32 uSourceTag) :
|
||||
mInLedger(0), mStatus(NEW)
|
||||
{
|
||||
mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
|
||||
mTransaction->setSignature(signature);
|
||||
mTransaction->setTransactionFee(fee);
|
||||
mTransaction->setSigningPubKey(pubKey); // BROKEN
|
||||
mTransaction->setSourceAccount(mAccountFrom); // BROKEN
|
||||
mTransaction->setSequence(fromSeq);
|
||||
if (fromLedger != 0)
|
||||
{
|
||||
mTransaction->makeITFieldPresent(sfTargetLedger);
|
||||
mTransaction->setITFieldU32(sfTargetLedger, fromLedger);
|
||||
}
|
||||
if (ident != 0)
|
||||
mAccountFrom = naSourceAccount;
|
||||
mFromPubKey = naPublicKey;
|
||||
assert(mFromPubKey.isValid());
|
||||
|
||||
mTransaction = boost::make_shared<SerializedTransaction>(ttKind);
|
||||
|
||||
std::cerr << str(boost::format("Transaction: account: %s") % naSourceAccount.humanAccountID()) << std::endl;
|
||||
std::cerr << str(boost::format("Transaction: mAccountFrom: %s") % mAccountFrom.humanAccountID()) << std::endl;
|
||||
mTransaction->setSigningPubKey(mFromPubKey);
|
||||
mTransaction->setSourceAccount(mAccountFrom);
|
||||
mTransaction->setSequence(uSeq);
|
||||
mTransaction->setTransactionFee(uFee);
|
||||
|
||||
if (uSourceTag)
|
||||
{
|
||||
mTransaction->makeITFieldPresent(sfSourceTag);
|
||||
mTransaction->setITFieldU32(sfSourceTag, ident);
|
||||
mTransaction->setITFieldU32(sfSourceTag, uSourceTag);
|
||||
}
|
||||
mTransaction->setITFieldU64(sfAmount, amount);
|
||||
mTransaction->setITFieldAccount(sfDestination, toID.getAccountID());
|
||||
updateID();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Transaction::sign(const NewcoinAddress& naAccountPrivate)
|
||||
{
|
||||
if(!naAccountPrivate.isValid())
|
||||
bool bResult = true;
|
||||
|
||||
if (!naAccountPrivate.isValid())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "No private key for signing" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
bResult = false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( (mTransaction->getITFieldU64(sfAmount)==0) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Bad amount or destination" << std::endl;
|
||||
#endif
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!getSTransaction()->sign(naAccountPrivate))
|
||||
else if (!getSTransaction()->sign(naAccountPrivate))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Failed to make signature" << std::endl;
|
||||
#endif
|
||||
assert(false);
|
||||
return false;
|
||||
bResult = false;
|
||||
}
|
||||
|
||||
updateID();
|
||||
if (bResult)
|
||||
{
|
||||
updateID();
|
||||
}
|
||||
else
|
||||
{
|
||||
mStatus = INCOMPLETE;
|
||||
}
|
||||
|
||||
return true;
|
||||
return bResult;
|
||||
}
|
||||
|
||||
//
|
||||
// Claim
|
||||
//
|
||||
|
||||
Transaction::pointer Transaction::setClaim(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naGeneratorID,
|
||||
const std::vector<unsigned char>& vucGenerator)
|
||||
{
|
||||
sign(naPrivateKey);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
Transaction::pointer Transaction::sharedClaim(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSourceTag,
|
||||
const NewcoinAddress& naGeneratorID,
|
||||
const std::vector<unsigned char>& vucGenerator)
|
||||
{
|
||||
pointer tResult = boost::make_shared<Transaction>(ttCLAIM,
|
||||
naPublicKey, naSourceAccount,
|
||||
0, // Sequence of 0.
|
||||
0, // Free.
|
||||
uSourceTag);
|
||||
|
||||
return tResult->setClaim(naPrivateKey, naGeneratorID, vucGenerator);
|
||||
}
|
||||
|
||||
//
|
||||
// Payment
|
||||
//
|
||||
|
||||
Transaction::pointer Transaction::setPayment(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& toAccount,
|
||||
uint64 uAmount,
|
||||
uint32 ledger)
|
||||
{
|
||||
mTransaction->setITFieldAccount(sfDestination, toAccount);
|
||||
mTransaction->setITFieldU64(sfAmount, uAmount);
|
||||
|
||||
if (ledger != 0)
|
||||
{
|
||||
mTransaction->makeITFieldPresent(sfTargetLedger);
|
||||
mTransaction->setITFieldU32(sfTargetLedger, ledger);
|
||||
}
|
||||
|
||||
sign(naPrivateKey);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
Transaction::pointer Transaction::sharedPayment(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
uint64 uFee,
|
||||
uint32 uSourceTag,
|
||||
const NewcoinAddress& toAccount,
|
||||
uint64 uAmount,
|
||||
uint32 ledger)
|
||||
{
|
||||
pointer tResult = boost::make_shared<Transaction>(ttMAKE_PAYMENT,
|
||||
naPublicKey, naSourceAccount,
|
||||
uSeq, uFee, uSourceTag);
|
||||
|
||||
return tResult->setPayment(naPrivateKey, toAccount, uAmount, ledger);
|
||||
}
|
||||
|
||||
//
|
||||
// Misc.
|
||||
//
|
||||
|
||||
bool Transaction::checkSign() const
|
||||
{
|
||||
assert(mFromPubKey.isValid());
|
||||
@@ -158,8 +195,8 @@ bool Transaction::checkSign() const
|
||||
|
||||
void Transaction::setStatus(TransStatus ts, uint32 lseq)
|
||||
{
|
||||
mStatus = ts;
|
||||
mInLedger = lseq;
|
||||
mStatus = ts;
|
||||
mInLedger = lseq;
|
||||
}
|
||||
|
||||
void Transaction::saveTransaction(Transaction::pointer txn)
|
||||
@@ -247,7 +284,6 @@ Transaction::pointer Transaction::transactionFromSQL(const std::string& sql)
|
||||
tr->setStatus(st);
|
||||
|
||||
return tr;
|
||||
|
||||
}
|
||||
|
||||
Transaction::pointer Transaction::load(const uint256& id)
|
||||
@@ -311,22 +347,6 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isHex(char j)
|
||||
{
|
||||
if ((j >= '0') && (j <= '9')) return true;
|
||||
if ((j >= 'A') && (j <= 'F')) return true;
|
||||
if ((j >= 'a') && (j <= 'f')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Transaction::isHexTxID(const std::string& txid)
|
||||
{
|
||||
if (txid.size() != 64) return false;
|
||||
for (int i = 0; i < 64; ++i)
|
||||
if (!isHex(txid[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Json::Value Transaction::getJson(bool decorate, bool paid, bool credited) const
|
||||
{
|
||||
Json::Value ret(mTransaction->getJson(0));
|
||||
@@ -360,4 +380,25 @@ Json::Value Transaction::getJson(bool decorate, bool paid, bool credited) const
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// Obsolete
|
||||
//
|
||||
|
||||
static bool isHex(char j)
|
||||
{
|
||||
if ((j >= '0') && (j <= '9')) return true;
|
||||
if ((j >= 'A') && (j <= 'F')) return true;
|
||||
if ((j >= 'a') && (j <= 'f')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Transaction::isHexTxID(const std::string& txid)
|
||||
{
|
||||
if (txid.size() != 64) return false;
|
||||
for (int i = 0; i < 64; ++i)
|
||||
if (!isHex(txid[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -30,35 +30,66 @@ enum TransStatus
|
||||
INCOMPLETE = 8 // needs more signatures
|
||||
};
|
||||
|
||||
// This class is for constructing and examining transactions. Transactions are static so manipulation functions are unnecessary.
|
||||
class Transaction : public boost::enable_shared_from_this<Transaction>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::shared_ptr<Transaction> pointer;
|
||||
|
||||
private:
|
||||
uint256 mTransactionID;
|
||||
NewcoinAddress mAccountFrom;
|
||||
NewcoinAddress mFromPubKey;
|
||||
NewcoinAddress mFromPubKey; // Sign transaction with this. mSignPubKey
|
||||
NewcoinAddress mSourcePrivate; // Sign transaction with this.
|
||||
|
||||
uint32 mInLedger;
|
||||
TransStatus mStatus;
|
||||
uint32 mInLedger;
|
||||
TransStatus mStatus;
|
||||
|
||||
SerializedTransaction::pointer mTransaction;
|
||||
|
||||
Transaction::pointer setPayment(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& toAccount,
|
||||
uint64 uAmount,
|
||||
uint32 ledger);
|
||||
|
||||
Transaction::pointer setClaim(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naGeneratorID,
|
||||
const std::vector<unsigned char>& vucGenerator);
|
||||
|
||||
public:
|
||||
Transaction(const SerializedTransaction::pointer st, bool bValidate);
|
||||
|
||||
static Transaction::pointer sharedTransaction(const std::vector<unsigned char>&vucTransaction, bool bValidate);
|
||||
|
||||
Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount,
|
||||
uint64 amount,
|
||||
uint32 iSeq, uint32 ident, uint32 ledger);
|
||||
Transaction(
|
||||
TransactionType ttKind,
|
||||
const NewcoinAddress& naPublicKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
uint64 uFee,
|
||||
uint32 uSourceTag);
|
||||
|
||||
static Transaction::pointer sharedPayment(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
uint64 uFee,
|
||||
uint32 uSourceTag,
|
||||
const NewcoinAddress& toAccount,
|
||||
uint64 uAmount,
|
||||
uint32 ledger);
|
||||
|
||||
static Transaction::pointer sharedClaim(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSourceTag,
|
||||
const NewcoinAddress& naGeneratorID,
|
||||
const std::vector<unsigned char>& vucGenerator);
|
||||
#if 0
|
||||
Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
|
||||
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
|
||||
CKey::pointer pubKey, uint64 uAmount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
|
||||
uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st);
|
||||
#endif
|
||||
|
||||
@@ -106,9 +137,11 @@ public:
|
||||
|
||||
protected:
|
||||
static Transaction::pointer transactionFromSQL(const std::string& statement);
|
||||
#if 0
|
||||
Transaction(const uint256& transactionID, const NewcoinAddress& accountFrom, const NewcoinAddress& accountTo,
|
||||
CKey::pointer key, uint64 amount, uint64 fee, uint32 fromAccountSeq, uint32 sourceLedger,
|
||||
CKey::pointer key, uint64 uAmount, uint64 fee, uint32 fromAccountSeq, uint32 sourceLedger,
|
||||
uint32 ident, const std::vector<unsigned char>& signature, uint32 inLedger, TransStatus status);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
|
||||
#include "TransactionEngine.h"
|
||||
|
||||
#include "TransactionFormats.h"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
|
||||
TransactionEngineParams params)
|
||||
{
|
||||
std::cerr << "applyTransaction>" << std::endl;
|
||||
|
||||
TransactionEngineResult result = terSUCCESS;
|
||||
|
||||
uint256 txID = txn.getTransactionID();
|
||||
if(!txID) return tenINVALID;
|
||||
if (!txID)
|
||||
{
|
||||
std::cerr << "applyTransaction: invalid transaction id" << std::endl;
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
// Extract signing key
|
||||
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
|
||||
@@ -22,7 +28,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
|
||||
// check signature
|
||||
if (!txn.checkSign(naPubKey))
|
||||
{
|
||||
std::cerr << "applyTransaction: invalid signature" << std::endl;
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
bool bPrepaid = false;
|
||||
|
||||
@@ -40,10 +49,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
break;
|
||||
|
||||
case ttINVALID:
|
||||
std::cerr << "applyTransaction: ttINVALID transaction type" << std::endl;
|
||||
result = tenINVALID;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cerr << "applyTransaction: unknown transaction type" << std::endl;
|
||||
result = tenUNKNOWN;
|
||||
break;
|
||||
}
|
||||
@@ -57,20 +68,30 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
if (bPrepaid)
|
||||
{
|
||||
if (txnFee)
|
||||
{
|
||||
// Transaction is malformed.
|
||||
std::cerr << "applyTransaction: fee not allowed" << std::endl;
|
||||
return tenINSUF_FEE_P;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// WRITEME: Check if fee is adequate
|
||||
if (txnFee == 0)
|
||||
{
|
||||
std::cerr << "applyTransaction: insufficient fee" << std::endl;
|
||||
return tenINSUF_FEE_P;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get source account ID
|
||||
uint160 srcAccount = txn.getSourceAccount().getAccountID();
|
||||
if (!srcAccount) return tenINVALID;
|
||||
if (!srcAccount)
|
||||
{
|
||||
std::cerr << "applyTransaction: bad source id" << std::endl;
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
|
||||
|
||||
@@ -78,7 +99,11 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
// If we are only verifying some transactions, this would be probablistic.
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SerializedLedgerEntry::pointer src = mLedger->getAccountRoot(qry, srcAccount);
|
||||
if (!src) return terNO_ACCOUNT;
|
||||
if (!src)
|
||||
{
|
||||
std::cerr << str(boost::format("applyTransaction: no such account: %s") % txn.getSourceAccount().humanAccountID()) << std::endl;
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
|
||||
// deduct the fee, so it's not available during the transaction
|
||||
// we only write the account back if the transaction succeeds
|
||||
@@ -87,7 +112,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
uint64 balance = src->getIFieldU64(sfBalance);
|
||||
|
||||
if (balance < txnFee)
|
||||
{
|
||||
std::cerr << "applyTransaction: insufficent balance" << std::endl;
|
||||
return terINSUF_FEE_B;
|
||||
}
|
||||
|
||||
src->setIFieldU64(sfBalance, balance - txnFee);
|
||||
}
|
||||
@@ -98,7 +126,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
if (bPrepaid)
|
||||
{
|
||||
if (t_seq)
|
||||
{
|
||||
std::cerr << "applyTransaction: bad sequence for pre-paid transaction" << std::endl;
|
||||
return terPAST_SEQ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -107,9 +138,18 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
if (t_seq != a_seq)
|
||||
{
|
||||
// WRITEME: Special case code for changing transaction key
|
||||
if (a_seq < t_seq) return terPRE_SEQ;
|
||||
if (a_seq < t_seq)
|
||||
{
|
||||
std::cerr << "applyTransaction: future sequence number" << std::endl;
|
||||
return terPRE_SEQ;
|
||||
}
|
||||
if (mLedger->hasTransaction(txID))
|
||||
{
|
||||
std::cerr << "applyTransaction: duplicate sequence number" << std::endl;
|
||||
return terALREADY;
|
||||
}
|
||||
|
||||
std::cerr << "applyTransaction: past sequence number" << std::endl;
|
||||
return terPAST_SEQ;
|
||||
}
|
||||
else src->setIFieldU32(sfSequence, t_seq);
|
||||
@@ -121,6 +161,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
switch(txn.getTxnType())
|
||||
{
|
||||
case ttINVALID:
|
||||
std::cerr << "applyTransaction: invalid type" << std::endl;
|
||||
result = tenINVALID;
|
||||
break;
|
||||
|
||||
@@ -178,6 +219,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
std::cerr << "doClaim>" << std::endl;
|
||||
NewcoinAddress naSigningPubKey;
|
||||
|
||||
naSigningPubKey.setAccountPublic(txn.peekSigningPubKey());
|
||||
@@ -185,15 +227,24 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
|
||||
uint160 sourceAccountID = naSigningPubKey.getAccountID();
|
||||
|
||||
if (sourceAccountID != txn.getSourceAccount().getAccountID())
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl;
|
||||
std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl;
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SerializedLedgerEntry::pointer dest = mLedger->getAccountRoot(qry, sourceAccountID);
|
||||
|
||||
if (!dest)
|
||||
{
|
||||
// Source account does not exist. Could succeed if it was created first.
|
||||
std::cerr << str(boost::format("doClaim: no such account: %s") % txn.getSourceAccount().humanAccountID()) << std::endl;
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
|
||||
std::cerr << str(boost::format("doClaim: %s") % dest->getFullText()) << std::endl;
|
||||
|
||||
if (dest->getIFieldPresent(sfAuthorizedKey))
|
||||
// Source account already claimed.
|
||||
@@ -225,6 +276,7 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
|
||||
|
||||
accounts.push_back(std::make_pair(taaCREATE, gen));
|
||||
|
||||
std::cerr << "doClaim<" << std::endl;
|
||||
return terSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
13
src/main.cpp
13
src/main.cpp
@@ -36,13 +36,12 @@ void printHelp(const po::options_description& desc)
|
||||
cout << desc << endl;
|
||||
|
||||
cout << "Commands: " << endl;
|
||||
cout << " accountinfo <family>:<key>" << endl;
|
||||
cout << " account_info <account>|<nickname>" << endl;
|
||||
cout << " account_info <seed>|<pass_phrase>|<key> [<index>]" << endl;
|
||||
cout << " connect <ip> [<port>]" << endl;
|
||||
cout << " createfamily [<key>]" << endl;
|
||||
cout << " familyinfo" << endl;
|
||||
cout << " ledger" << endl;
|
||||
cout << " lock <family>" << endl;
|
||||
cout << " newaccount <family> [<name>]" << endl;
|
||||
cout << " peers" << endl;
|
||||
cout << " sendto <destination> <amount> [<tag>]" << endl;
|
||||
cout << " stop" << endl;
|
||||
@@ -115,14 +114,14 @@ int main(int argc, char* argv[])
|
||||
if (iCmd)
|
||||
vCmd = vm["parameters"].as<std::vector<std::string> >();
|
||||
|
||||
/*
|
||||
char* pvCmd[iCmd];
|
||||
std::vector<char*> pvCmd;
|
||||
|
||||
pvCmd.resize(iCmd);
|
||||
|
||||
for (int i=0; i != iCmd; ++i)
|
||||
pvCmd[i] = (char*) (vCmd[0].c_str());
|
||||
|
||||
iResult = unit_test_main(init_unit_test, iCmd, pvCmd);
|
||||
*/
|
||||
iResult = unit_test_main(init_unit_test, iCmd, &pvCmd.front());
|
||||
}
|
||||
else if (!vm.count("parameters"))
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ enum MessageType {
|
||||
mtPROPOSE_LEDGER= 33;
|
||||
mtCLOSE_LEDGER= 35;
|
||||
mtSTATUS_CHANGE= 36;
|
||||
mtPEER_POSITION= 37;
|
||||
|
||||
// data replication and synchronization
|
||||
mtGET_VALIDATIONS= 40;
|
||||
@@ -98,10 +99,21 @@ message TMStatusChange {
|
||||
}
|
||||
|
||||
|
||||
message TMPeerPosition {
|
||||
required uint32 ledgerSequence = 1;
|
||||
required bytes pubKey = 2;
|
||||
required uint32 sequence = 3;
|
||||
required bytes transactionHash = 4;
|
||||
required bytes signature = 5;
|
||||
}
|
||||
|
||||
message TMHaveTransactionSet {
|
||||
repeated bytes hashes = 1;
|
||||
}
|
||||
|
||||
message TMProposeLedger {
|
||||
required uint32 closingSeq = 1;
|
||||
required uint32 secondsSinceClose = 2;
|
||||
required uint32 proposeSeq = 2;
|
||||
required bytes previousLedgerHash = 3; // 0 if first proposal, hash we no longer propose
|
||||
required bytes currentLedgerHash = 4; // the hash of the ledger we are proposing
|
||||
required bytes hanko = 5;
|
||||
@@ -110,6 +122,8 @@ message TMProposeLedger {
|
||||
required bytes signature = 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Used to propose/validate during ledger close
|
||||
message TMValidation {
|
||||
required uint32 ledgerIndex = 1;
|
||||
@@ -205,14 +219,15 @@ message TMObjectByHash
|
||||
}
|
||||
|
||||
message TMLedgerNode {
|
||||
optional bytes nodeid = 1;
|
||||
required bytes nodeid = 1;
|
||||
required bytes nodedata = 2;
|
||||
}
|
||||
|
||||
enum TMLedgerInfoType {
|
||||
liBASE = 0; // basic ledger info
|
||||
liTX_NODE = 1; // transaction node
|
||||
liAS_NODE = 2; // account state node
|
||||
liBASE = 0; // basic ledger info
|
||||
liTX_NODE = 1; // transaction node
|
||||
liAS_NODE = 2; // account state node
|
||||
liTS_CANDIDATE = 3; // candidate transaction set
|
||||
}
|
||||
|
||||
enum TMLedgerType {
|
||||
|
||||
Reference in New Issue
Block a user