mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 10:35:50 +00:00
Infrastructure for local transactions, wallet interface.
Transaction JSON code.
This commit is contained in:
@@ -285,7 +285,7 @@ bool Ledger::unitTest()
|
||||
as=ledger->getAccountState(la2);
|
||||
assert(!as);
|
||||
|
||||
Transaction::pointer t(new Transaction(NEW, l1, l1->getAcctSeq(), l2->getAddress(), 2500, 0, 1));
|
||||
Transaction::pointer t(new Transaction(l1, l2->getAddress(), 2500, 0, 1));
|
||||
assert(!!t->getID());
|
||||
|
||||
Ledger::TransResult tr=ledger->applyTransaction(t);
|
||||
|
||||
17
LocalTransaction.cpp
Normal file
17
LocalTransaction.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
#include "LocalTransaction.h"
|
||||
#include "Application.h"
|
||||
#include "Wallet.h"
|
||||
|
||||
bool LocalTransaction::makeTransaction()
|
||||
{
|
||||
if(!!mTransaction) return true;
|
||||
|
||||
LocalAccount::pointer lac(theApp->getWallet().findAccountForTransaction(mAmount));
|
||||
if(!lac) return false;
|
||||
|
||||
mTransaction=Transaction::pointer(new Transaction(lac, mDestAcctID, mAmount, mTag,
|
||||
theApp->getOPs().getCurrentLedgerID()));
|
||||
if(mTransaction->getStatus()!=NEW) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
const std::string& getComment() const { return mComment; }
|
||||
Transaction::pointer getTransaction() { return mTransaction; }
|
||||
|
||||
bool makeTransaction(void);
|
||||
bool makeTransaction();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
4
Makefile
4
Makefile
@@ -71,10 +71,10 @@ SRCS= keystore.cpp BitcoinUtil.cpp \
|
||||
Application.cpp TimingService.cpp KnownNodeList.cpp ConnectionPool.cpp Peer.cpp \
|
||||
PeerDoor.cpp RPCDoor.cpp RPCServer.cpp rpc.cpp Conversion.cpp RequestParser.cpp HashedObject.cpp \
|
||||
UniqueNodeList.cpp PubKeyCache.cpp SHAMapDiff.cpp DeterministicKeys.cpp LedgerMaster.cpp \
|
||||
LedgerHistory.cpp NetworkOPs.cpp CallRPC.cpp DBInit.cpp
|
||||
LedgerHistory.cpp NetworkOPs.cpp CallRPC.cpp DBInit.cpp LocalTransaction.cpp
|
||||
|
||||
DBSRCS= SqliteDatabase.cpp database.cpp
|
||||
DBSRCC=sqlite3.c
|
||||
DBSRCC= sqlite3.c
|
||||
|
||||
UTILSRCS= pugixml.cpp
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "RPC.h"
|
||||
#include "Wallet.h"
|
||||
#include "Conversion.h"
|
||||
#include "LocalTransaction.h"
|
||||
|
||||
/*
|
||||
Just read from wire until the entire request is in.
|
||||
@@ -103,7 +104,7 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
|
||||
w.write(std::cerr, valParams);
|
||||
#endif
|
||||
|
||||
Json::Value result=doCommand(strMethod, valParams);
|
||||
Json::Value result(doCommand(strMethod, valParams));
|
||||
|
||||
#ifdef DEBUG
|
||||
w.write(std::cerr, result);
|
||||
@@ -317,8 +318,57 @@ Json::Value RPCServer::doSendTo(Json::Value& params)
|
||||
// sendto <destination> <amount> <tag>
|
||||
if(!params.isArray() || (params.size()<2))
|
||||
return JSONRPCError(500, "Invalid parameters");
|
||||
|
||||
int paramCount=getParamCount(params);
|
||||
if((paramCount<2)||(paramCount>3))
|
||||
return JSONRPCError(500, "Invalid parameters");
|
||||
|
||||
return "Not yet";
|
||||
std::string sDest, sAmount;
|
||||
if(!extractString(sDest, params, 0) || !extractString(sAmount, params, 1))
|
||||
return JSONRPCError(500, "Invalid parameters");
|
||||
|
||||
uint160 destAccount=parseAccount(sDest);
|
||||
if(!destAccount)
|
||||
return JSONRPCError(500, "Unable to parse destination account");
|
||||
|
||||
uint64 iAmount;
|
||||
try
|
||||
{
|
||||
iAmount=boost::lexical_cast<uint64>(sAmount);
|
||||
if(iAmount<=0) return JSONRPCError(500, "Invalid amount");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return JSONRPCError(500, "Invalid amount");
|
||||
}
|
||||
|
||||
uint32 iTag(0);
|
||||
try
|
||||
{
|
||||
if(paramCount>2)
|
||||
{
|
||||
std::string sTag;
|
||||
extractString(sTag, params, 2);
|
||||
iTag=boost::lexical_cast<uint32>(sTag);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return JSONRPCError(500, "Invalid tag");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cerr << "SendTo(" << destAccount.GetHex() << ") amount=" << iAmount <<
|
||||
", tag=" << iTag << std::endl;
|
||||
#endif
|
||||
|
||||
LocalTransaction::pointer lt(new LocalTransaction(destAccount, iAmount, iTag));
|
||||
if(!lt->makeTransaction())
|
||||
return JSONRPCError(500, "Insufficient funds in unlocked accounts");
|
||||
|
||||
// WRITEME - process transaction
|
||||
|
||||
return lt->getTransaction()->getJson(true);
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params)
|
||||
|
||||
@@ -14,16 +14,17 @@ Transaction::Transaction() : mTransactionID(0), mAccountFrom(0), mAccountTo(0),
|
||||
{
|
||||
}
|
||||
|
||||
Transaction::Transaction(TransStatus status, LocalAccount::pointer fromLocalAccount, uint32 fromSeq,
|
||||
const uint160& toAccount, uint64 amount, uint32 ident, uint32 ledger) :
|
||||
mAccountTo(toAccount), mAmount(amount), mFromAccountSeq(fromSeq), mSourceLedger(ledger),
|
||||
mIdent(ident), mInLedger(0), mStatus(NEW)
|
||||
Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const uint160& toAccount, uint64 amount,
|
||||
uint32 ident, uint32 ledger) :
|
||||
mAccountTo(toAccount), mAmount(amount), mSourceLedger(ledger), mIdent(ident), mInLedger(0), mStatus(NEW)
|
||||
{
|
||||
mAccountFrom=fromLocalAccount->getAddress();
|
||||
mFromPubKey=fromLocalAccount->getPublicKey();
|
||||
mFromAccountSeq=fromLocalAccount->getAcctSeq();
|
||||
if(!mFromAccountSeq) mStatus=INCOMPLETE;
|
||||
assert(mFromPubKey);
|
||||
updateFee();
|
||||
sign(fromLocalAccount);
|
||||
if(!sign(fromLocalAccount)) mStatus=INCOMPLETE;
|
||||
}
|
||||
|
||||
Transaction::Transaction(const std::vector<unsigned char> &t, bool validate) : mStatus(INVALID)
|
||||
@@ -279,3 +280,46 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value Transaction::getJson(bool decorate) const
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
ret["TransactionID"]=mTransactionID.GetHex();
|
||||
ret["Amount"]=boost::lexical_cast<std::string>(mAmount);
|
||||
ret["Fee"]=boost::lexical_cast<std::string>(mFee);
|
||||
if(mInLedger) ret["InLedger"]=mInLedger;
|
||||
|
||||
switch(mStatus)
|
||||
{
|
||||
case NEW: ret["Status"]="new"; break;
|
||||
case INVALID: ret["Status"]="invalid"; break;
|
||||
case INCLUDED: ret["Status"]="included"; break;
|
||||
case CONFLICTED: ret["Status"]="conflicted"; break;
|
||||
case COMMITTED: ret["Status"]="committed"; break;
|
||||
case HELD: ret["Status"]="held"; break;
|
||||
case REMOVED: ret["Status"]="removed"; break;
|
||||
case OBSOLETE: ret["Status"]="obsolete"; break;
|
||||
case INCOMPLETE: ret["Status"]="incomplete"; break;
|
||||
default: ret["Status"]="unknown";
|
||||
}
|
||||
|
||||
Json::Value source(Json::objectValue);
|
||||
source["AccountID"]=NewcoinAddress(mAccountFrom).GetString();
|
||||
source["AccountSeq"]=mFromAccountSeq;
|
||||
source["Ledger"]=mSourceLedger;
|
||||
if(!!mIdent) source["Identifier"]=mIdent;
|
||||
|
||||
Json::Value destination(Json::objectValue);
|
||||
destination["AccountID"]=NewcoinAddress(mAccountTo).GetString();
|
||||
|
||||
if(decorate)
|
||||
{
|
||||
LocalAccount::pointer lac=theApp->getWallet().getLocalAccount(mAccountFrom);
|
||||
if(!!lac) source=lac->getJson();
|
||||
lac=theApp->getWallet().getLocalAccount(mAccountTo);
|
||||
if(!!lac) destination=lac->getJson();
|
||||
}
|
||||
ret["Source"]=source;
|
||||
ret["Destination"]=destination;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#ifndef __TRANSACTION__
|
||||
#define __TRANSACTION__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include "json/value.h"
|
||||
|
||||
#include "key.h"
|
||||
#include "uint256.h"
|
||||
#include "newcoin.pb.h"
|
||||
@@ -52,8 +56,7 @@ private:
|
||||
public:
|
||||
Transaction();
|
||||
Transaction(const std::vector<unsigned char>& rawTransaction, bool validate);
|
||||
Transaction(TransStatus Status, LocalAccount::pointer fromLocal, uint32 fromSeq, const uint160& to, uint64 amount,
|
||||
uint32 ident, uint32 ledger);
|
||||
Transaction(LocalAccount::pointer fromLocal, const uint160& to, uint64 amount, uint32 ident, uint32 ledger);
|
||||
|
||||
bool sign(LocalAccount::pointer fromLocalAccount);
|
||||
bool checkSign() const;
|
||||
@@ -96,6 +99,8 @@ public:
|
||||
bool operator<=(const Transaction&) const;
|
||||
bool operator>=(const Transaction&) const;
|
||||
|
||||
Json::Value getJson(bool decorate) const;
|
||||
|
||||
protected:
|
||||
static Transaction::pointer transactionFromSQL(const std::string& statement);
|
||||
Transaction(const uint256& transactionID, const uint160& accountFrom, const uint160& accountTo,
|
||||
|
||||
15
Wallet.cpp
15
Wallet.cpp
@@ -4,6 +4,7 @@
|
||||
#include "openssl/rand.h"
|
||||
#include "openssl/ec.h"
|
||||
|
||||
#include "boost/foreach.hpp"
|
||||
#include "boost/lexical_cast.hpp"
|
||||
|
||||
#include "Wallet.h"
|
||||
@@ -361,6 +362,11 @@ std::string LocalAccount::getFullName() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool LocalAccount::isLocked() const
|
||||
{
|
||||
return mFamily->isLocked();
|
||||
}
|
||||
|
||||
std::string LocalAccount::getFamilyName() const
|
||||
{
|
||||
return mFamily->getShortName();
|
||||
@@ -549,6 +555,15 @@ LocalAccount::pointer Wallet::getLocalAccount(const uint160& acctID)
|
||||
return ait->second;
|
||||
}
|
||||
|
||||
LocalAccount::pointer Wallet::findAccountForTransaction(uint64 amount)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
for(std::map<uint160, LocalAccount::pointer>::iterator it=mAccounts.begin(); it!=mAccounts.end(); ++it)
|
||||
if(!it->second->isLocked() && (it->second->getBalance()>=amount) )
|
||||
return it->second;
|
||||
return LocalAccount::pointer();
|
||||
}
|
||||
|
||||
LocalAccount::pointer Wallet::parseAccount(const std::string& specifier)
|
||||
{ // <family>:<seq> or <acct_id>
|
||||
|
||||
|
||||
1
Wallet.h
1
Wallet.h
@@ -181,6 +181,7 @@ public:
|
||||
LocalAccount::pointer getLocalAccount(const uint160& famBase, int seq);
|
||||
LocalAccount::pointer getLocalAccount(const uint160& acctID);
|
||||
LocalAccount::pointer getNewLocalAccount(const uint160& family);
|
||||
LocalAccount::pointer findAccountForTransaction(uint64 amount);
|
||||
uint160 peekKey(const uint160& family, int seq);
|
||||
std::string getPubGenHex(const uint160& famBase);
|
||||
std::string getShortName(const uint160& famBase);
|
||||
|
||||
Reference in New Issue
Block a user