Skip to content

Commit

Permalink
Implement scrape addresses
Browse files Browse the repository at this point in the history
Enable setting a scrape address for any in wallet address:
This will scrape all stake rewards at a transaction level and send the reward to
the scrape address.
Scrape addresses are stored in their own database and can be set, listed or
deleted using RPC via daemon or the in QT RPC console.
  • Loading branch information
IngCr3at1on committed Sep 14, 2015
1 parent b90e520 commit a775971
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 10 deletions.
2 changes: 2 additions & 0 deletions paycoin.pro
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ HEADERS += src/qt/bitcoingui.h \
src/script.h \
src/init.h \
src/mruset.h \
src/scrapesdb.h \
src/json/json_spirit_writer_template.h \
src/json/json_spirit_writer.h \
src/json/json_spirit_value.h \
Expand Down Expand Up @@ -204,6 +205,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/db.cpp \
src/walletdb.cpp \
src/primekeys.cpp \
src/scrapesdb.cpp \
src/json/json_spirit_writer.cpp \
src/json/json_spirit_value.cpp \
src/json/json_spirit_reader.cpp \
Expand Down
9 changes: 9 additions & 0 deletions src/bitcoinrpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ extern Value createrawtransaction(const Array& params, bool fHelp);
extern Value decoderawtransaction(const Array& params, bool fHelp);
extern Value signrawtransaction(const Array& params, bool fHelp);
extern Value sendrawtransaction(const Array& params, bool fHelp);
// In scrapesdb.cpp
extern Value setscrapeaddress(const Array& params, bool fHelp);
extern Value getscrapeaddress(const Array& params, bool fHelp);
extern Value listscrapeaddresses(const Array& params, bool fHelp);
extern Value deletescrapeaddress(const Array& params, bool fHelp);

Object JSONRPCError(int code, const string& message)
{
Expand Down Expand Up @@ -2889,6 +2894,10 @@ static const CRPCCommand vRPCCommands[] =
{ "gettxout", &gettxout, true },
{ "getrawmempool", &getrawmempool, true },
{ "clearorphans", &clearorphans, true },
{ "getscrapeaddress", &getscrapeaddress, true },
{ "listscrapeaddresses", &listscrapeaddresses, true },
{ "setscrapeaddress", &setscrapeaddress, true },
{ "deletescrapeaddress", &deletescrapeaddress, true }
};

CRPCTable::CRPCTable()
Expand Down
4 changes: 2 additions & 2 deletions src/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ void CDB::Close()
nMinutes = 2;
if (strFile == "blkindex.dat")
nMinutes = 2;
if (strFile == "scrapes.dat")
nMinutes = 2;
if (strFile == "blkindex.dat" && IsInitialBlockDownload())
nMinutes = 5;

Expand Down Expand Up @@ -851,5 +853,3 @@ bool LoadAddresses()
{
return CAddrDB("cr+").LoadAddresses();
}


6 changes: 6 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "ui_interface.h"
#include "checkpoints.h"
#include "version.h"
#include "scrapesdb.h"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
Expand All @@ -29,6 +30,7 @@ using namespace std;
using namespace boost;

CWallet* pwalletMain;
CScrapesDB* scrapesDB;
int MIN_PROTO_VERSION = 70003;

//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -73,12 +75,14 @@ void Shutdown(void* parg)
{
fShutdown = true;
nTransactionsUpdated++;
scrapesDB->Close();
DBFlush(false);
StopNode();
DBFlush(true);
boost::filesystem::remove(GetPidFile());
UnregisterWallet(pwalletMain);
delete pwalletMain;
delete scrapesDB;
NewThread(ExitTimeout, NULL);
Sleep(50);
printf("Paycoin exiting\n\n");
Expand Down Expand Up @@ -508,6 +512,8 @@ bool AppInit2(int argc, char* argv[])
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
}

scrapesDB = new CScrapesDB("cw");

InitMessage(_("Done loading"));
printf("Done loading\n");

Expand Down
3 changes: 2 additions & 1 deletion src/makefile.linux-mingw
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ OBJS= \
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
obj/primekeys.o
obj/primekeys.o \
obj/scrapesdb.o

all: paycoind.exe

Expand Down
3 changes: 2 additions & 1 deletion src/makefile.mingw
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ OBJS= \
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
obj/primekeys.o
obj/primekeys.o \
obj/scrapesdb.o


all: paycoind.exe
Expand Down
3 changes: 2 additions & 1 deletion src/makefile.osx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ OBJS= \
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
obj/primekeys.o
obj/primekeys.o \
obj/scrapesdb.o

ifdef USE_UPNP
DEFS += -DUSE_UPNP=$(USE_UPNP)
Expand Down
3 changes: 2 additions & 1 deletion src/makefile.osx-mavericks
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ OBJS= \
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
obj/primekeys.o
obj/primekeys.o \
obj/scrapesdb.o

ifdef USE_UPNP
DEFS += -DUSE_UPNP=$(USE_UPNP)
Expand Down
4 changes: 2 additions & 2 deletions src/makefile.unix
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ OBJS= \
obj/walletdb.o \
obj/noui.o \
obj/kernel.o \
obj/primekeys.o

obj/primekeys.o \
obj/scrapesdb.o

all: paycoind

Expand Down
188 changes: 188 additions & 0 deletions src/scrapesdb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// Copyright (c) 2015 The Paycoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "init.h"
#include "bitcoinrpc.h"
#include "scrapesdb.h"

#define printf OutputDebugStringF

using namespace json_spirit;
using namespace std;

extern CScrapesDB* scrapesDB;

Value setscrapeaddress(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 2)
throw runtime_error(
"setscrapeaddress <staking address>, <address to stake to>\n"
"Set an auto scrape address to send stake rewards to from a given address."
);

string strAddress = params[0].get_str();
CBitcoinAddress address(strAddress);
string strScrapeAddress = params[1].get_str();
CBitcoinAddress scrapeAddress(strScrapeAddress);

if (address.Get() == scrapeAddress.Get())
throw runtime_error(
"Cannot set scrape address to the same as staking address."
);

if (!IsMine(*pwalletMain, address.Get()))
throw runtime_error(
"Staking address must be in wallet."
);

if (!scrapeAddress.IsValid())
throw runtime_error(
"Invalid scrape address."
);

string oldScrapeAddress;
bool warn = false;
if (scrapesDB->ReadScrapeAddress(strAddress, oldScrapeAddress)) {
if (strScrapeAddress == oldScrapeAddress)
throw runtime_error(strprintf("Scrape address is already set to %s", oldScrapeAddress.c_str()));

warn = true;
}

if (scrapesDB->WriteScrapeAddress(strAddress, strScrapeAddress)) {
if (warn)
return strprintf("Warning overwriting %s with %s", oldScrapeAddress.c_str(), strScrapeAddress.c_str());

Object obj;
obj.push_back(Pair(strAddress, strScrapeAddress));
return obj;
}

// This should never happen.
throw runtime_error(
"setscrapeaddress: unknown error"
);
}

Value getscrapeaddress(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
"getscrapeaddress <staking address>\n"
"Get the auto scrape address for a given address."
);

string strAddress = params[0].get_str();
CBitcoinAddress address(strAddress);

if (!IsMine(*pwalletMain, address.Get()))
throw runtime_error(
"Staking address must be in wallet."
);

string strScrapeAddress;
if (!scrapesDB->ReadScrapeAddress(strAddress, strScrapeAddress)) {
string ret = "No scrape address set for address ";
ret += strAddress;
throw runtime_error(ret);
}

Object obj;
obj.push_back(Pair(strAddress, strScrapeAddress));
return obj;
}

Value listscrapeaddresses(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
"listscrapeaddresses\n"
"List all the defined scrape addresses."
);

Object obj;
scrapesDB->DumpScrapeAddresses(obj);

return obj;
}

Value deletescrapeaddress(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
"deletescrapeaddress <staking address>\n"
"Delete the auto scrape address for a given address."
);

string strAddress = params[0].get_str();
CBitcoinAddress address(strAddress);

if (!IsMine(*pwalletMain, address.Get()))
throw runtime_error(
"Staking address must be in wallet."
);

if (!scrapesDB->HasScrapeAddress(strAddress)) {
string ret = "No scrape address set for address ";
ret += strAddress;
throw runtime_error(ret);
}

return scrapesDB->EraseScrapeAddress(strAddress);
}

bool CScrapesDB::WriteScrapeAddress(const string strAddress, const string strScrapeAddress)
{
return Write(make_pair(string("scrapeaddress"), strAddress), strScrapeAddress);
}

bool CScrapesDB::EraseScrapeAddress(const string strAddress)
{
return Erase(make_pair(string("scrapeaddress"), strAddress));
}

bool CScrapesDB::ReadScrapeAddress(const string strAddress, string &strScrapeAddress)
{
return Read(make_pair(string("scrapeaddress"), strAddress), strScrapeAddress);
}

bool CScrapesDB::HasScrapeAddress(const string strAddress)
{
return Exists(make_pair(string("scrapeaddress"), strAddress));
}

bool CScrapesDB::DumpScrapeAddresses(Object &ScrapeAddresses) {
Dbc* pcursor = GetCursor();
if (!pcursor)
throw runtime_error("DumpScrapeAddresses() : cannot create DB cursor");
unsigned int fFlags = DB_SET_RANGE;

for (;;)
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
if (fFlags == DB_SET_RANGE)
ssKey << make_pair(std::string("scrapeaddress"), string(""));
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
break;

else if (ret != 0)
{
pcursor->close();
throw runtime_error("DumpScrapeAddresses() : error scanning DB");
}
// Unserialize
string strType, address, scrape_address;
ssKey >> strType;
if (strType != "scrapeaddress")
break;
ssKey >> address;
ssValue >> scrape_address;
ScrapeAddresses.push_back(Pair(address, scrape_address));
}

pcursor->close();
return true;
}
25 changes: 25 additions & 0 deletions src/scrapesdb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2015 The Paycoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef SCRAPESDB_H
#define SCRAPESDB_H

#include "db.h"
#include "json/json_spirit_value.h"

class CScrapesDB : public CDB
{
public:
CScrapesDB(const char* pszMode="r+") : CDB("scrapes.dat", pszMode) { }
private:
CScrapesDB(const CScrapesDB&);
void operator=(const CScrapesDB);
public:
bool WriteScrapeAddress(const std::string /*strAddress*/, const std::string /*strScrapeAddress*/);
bool EraseScrapeAddress(const std::string /*strAddress*/);
bool ReadScrapeAddress(const std::string /*strAddress*/, std::string &/*strScrapeAddress*/);
bool DumpScrapeAddresses(json_spirit::Object &/*ScrapeAddresses*/);
bool HasScrapeAddress(const std::string /*strAddress*/);
};

#endif // SCRAPESDB_H
Loading

0 comments on commit a775971

Please sign in to comment.