Browse Source

Finds blocks\!

peercoin
Intel 11 years ago
parent
commit
ddd5fdeb2d
  1. 9
      src/server/poolserver/Server/Server.cpp
  2. 77
      src/server/poolserver/Stratum/Client.cpp
  3. 30
      src/server/poolserver/Stratum/Client.h
  4. 2
      src/server/poolserver/Stratum/Job.h
  5. 56
      src/server/poolserver/Stratum/Server.cpp
  6. 94
      src/server/poolserver/Stratum/Server.h
  7. 8
      src/server/shared/Bitcoin/Bitcoin.h

9
src/server/poolserver/Server/Server.cpp

@ -81,11 +81,16 @@ int Server::Run() @@ -81,11 +81,16 @@ int Server::Run()
Stratum::Server srv(io_service);
// Init Bitcoin RPC
JSONRPCConnectionInfo coninfo;
/*JSONRPCConnectionInfo coninfo;
coninfo.Host = "84.240.15.208";
coninfo.Port = "8332";
coninfo.User = "user";
coninfo.Pass = "DYAL6bC4RUHksL6ikdx7";
coninfo.Pass = "DYAL6bC4RUHksL6ikdx7";*/
JSONRPCConnectionInfo coninfo;
coninfo.Host = "127.0.0.1";
coninfo.Port = "19001";
coninfo.User = "test";
coninfo.Pass = "123";
JSONRPC* bitcoinrpc = new JSONRPC();
bitcoinrpc->Connect(coninfo);

77
src/server/poolserver/Stratum/Client.cpp

@ -53,7 +53,6 @@ namespace Stratum @@ -53,7 +53,6 @@ namespace Stratum
void Client::OnMiningSubmit(JSON msg)
{
//msg = JSON::FromString("{\"params\": [\"slush.miner1\", \"00000000\", \"00000001\", \"504e86ed\", \"b2957c02\"], \"id\": 4, \"method\": \"mining.submit\"}");
JSON params = msg["params"];
std::string username = params[0].GetString();
@ -102,55 +101,61 @@ namespace Stratum @@ -102,55 +101,61 @@ namespace Stratum
return;
}
// Get block we are working on
// Copy block we are working on
Bitcoin::Block block = *job.block;
// Start assembling the block
timebuf >> block.time;
noncebuf >> block.nonce;
// Assemble coinbase
Bitcoin::Transaction coinbasetx;
ByteBuffer coinbasebuf;
coinbasebuf << job.coinbase1 << _extranonce << extranonce2 << job.coinbase2;
coinbasebuf >> coinbasetx;
// Set coinbase tx
block.tx[0] = coinbasetx;
ByteBuffer test;
test << coinbasetx;
sLog.Info(LOG_SERVER, "Coinbase: %s", Util::BinToASCII(test.Binary()).c_str());
sLog.Info(LOG_SERVER, "Coinbase hash1: %s", Util::BinToASCII(Crypto::SHA256D(coinbasebuf.Binary())).c_str());
sLog.Info(LOG_SERVER, "Coinbase hash2: %s", Util::BinToASCII(coinbasetx.GetHash()).c_str());
// Rebuilds only left side of merkle tree
block.RebuildMerkleTree();
sLog.Info(LOG_SERVER, "Merklehash: %s", Util::BinToASCII(block.merkleRootHash).c_str());
// Get block hash
BinaryData hash = block.GetHash();
sLog.Info(LOG_SERVER, "Block hash: %s", Util::BinToASCII(hash).c_str());
// Get block target
BigInt target(Util::BinToASCII(Util::Reverse(hash)), 16);
// Network target criteria
BigInt criteria(Bitcoin::TargetFromBits(block.bits));
BigInt diff = Bitcoin::TargetConvert(criteria);
BigInt diff = Bitcoin::TargetToDiff(criteria);
std::cout << "Target: " << target << std::endl;
std::cout << "Criteria: " << criteria << std::endl;
std::cout << "Diff: " << diff << std::endl;
// Check if block meets criteria
if (target <= criteria) {
sLog.Info(LOG_SERVER, "We have found a block candidate!");
// Serialize block
ByteBuffer blockbuf;
blockbuf << block;
JSON params;
params.Add(Util::BinToASCII(blockbuf.Binary()));
JSON response = _bitcoinrpc->Query("submitblock", params);
_server->SubmitBlock(block);
}
}
void Client::OnMiningSubscribe(JSON msg)
{
_subscribed = true;
// Get extranonce from server
_extranonce = _server->GetExtranonce();
ByteBuffer noncebuf;
noncebuf << _extranonce;
JSON notify;
notify.Add("mining.notify");
@ -158,8 +163,6 @@ namespace Stratum @@ -158,8 +163,6 @@ namespace Stratum
JSON result;
result.Add(notify);
ByteBuffer noncebuf;
noncebuf << _extranonce;
result.Add(Util::BinToASCII(noncebuf.Binary()));
result.Add(int64(4));
@ -170,14 +173,14 @@ namespace Stratum @@ -170,14 +173,14 @@ namespace Stratum
SendMessage(response);
SendJob(true);
SendJob(false);
}
void Client::OnMiningAuthorize(JSON msg)
{
sLog.Info(LOG_SERVER, "Test: %s", msg["params"].ToString().c_str());
std::string username = msg["params"][0].GetString();
std::string password = msg["params"][1].GetString();
JSON response;
response["id"] = msg["id"].GetInt();
response["error"];
@ -190,15 +193,51 @@ namespace Stratum @@ -190,15 +193,51 @@ namespace Stratum
Job job;
job.block = _server->GetWork();
// Coinbase parts
// Serialize transaction
ByteBuffer coinbasebuf;
coinbasebuf << job.block->tx[0];
BinaryData coinbase = coinbasebuf.Binary();
// tx.version + tx.in[0].outpoint.hash + tx.in[0].outpoint.n + tx.script (size) + tx.script (block height)
// Split coinbase
// tx.version - 4 bytes
// tx.in[0].outpoint.hash - 32 bytes
// tx.in[0].outpoint.n - 4 bytes
// tx.script (varint) - 2 bytes
// tx.script (block height) - 4 bytes
uint32 cbsplit = 4 + 32 + 4 + 2 + 4;
job.coinbase1 = BinaryData(coinbase.begin(), coinbase.begin() + cbsplit);
job.coinbase2 = BinaryData(coinbase.begin() + cbsplit + 8, coinbase.end()); // plus extranonce size
return job;
}
void Client::_OnReceive(const boost::system::error_code& error, size_t bytes_transferred)
{
if (!error) {
std::istream is(&_recvBuffer);
std::stringstream iss;
iss << is.rdbuf();
sLog.Debug(LOG_SERVER, "Received: %s", iss.str().c_str());
OnMessage(JSON::FromString(iss.str()));
StartRead();
} else {
// Client disconnected
if ((error == asio::error::eof) || (error == asio::error::connection_reset)) {
_server->Disconnect(shared_from_this());
}
}
}
void Client::_OnSend(const boost::system::error_code& error)
{
if (!error) {
// Party
} else {
// Client disconnected
if ((error == asio::error::eof) || (error == asio::error::connection_reset)) {
_server->Disconnect(shared_from_this());
}
}
}
}

30
src/server/poolserver/Stratum/Client.h

@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#define MAX_PACKET 2048
@ -19,7 +21,7 @@ namespace Stratum @@ -19,7 +21,7 @@ namespace Stratum
{
class Server;
class Client
class Client : public boost::enable_shared_from_this<Client>
{
public:
Client(Server* server, asio::io_service& io_service) : _server(server), _socket(io_service), _subscribed(false), _jobid(0)
@ -33,11 +35,13 @@ namespace Stratum @@ -33,11 +35,13 @@ namespace Stratum
void Start()
{
// Start reading socket
StartRead();
}
void StartRead()
{
// Read until newline
boost::asio::async_read_until(
_socket,
_recvBuffer,
@ -77,25 +81,17 @@ namespace Stratum @@ -77,25 +81,17 @@ namespace Stratum
sLog.Error(LOG_SERVER, "Method '%s' not found.", method.c_str());
}
// Gets new job from the server
Job GetJob();
public:
void _OnReceive(const boost::system::error_code& error, size_t bytes_transferred)
{
std::istream is(&_recvBuffer);
std::stringstream iss;
iss << is.rdbuf();
sLog.Debug(LOG_SERVER, "Received: %s", iss.str().c_str());
OnMessage(JSON::FromString(iss.str()));
StartRead();
}
void _OnSend(const boost::system::error_code& error)
void Disconnect()
{
if (error)
sLog.Error(LOG_SERVER, "Failed to send data");
else
sLog.Debug(LOG_SERVER, "Data sent");
_socket.close();
}
public:
void _OnReceive(const boost::system::error_code& error, size_t bytes_transferred);
void _OnSend(const boost::system::error_code& error);
private:
// Networking
asio::streambuf _recvBuffer;
@ -113,6 +109,8 @@ namespace Stratum @@ -113,6 +109,8 @@ namespace Stratum
std::map<uint64, Job> _jobs;
uint32 _jobid;
};
typedef boost::shared_ptr<Client> ClientPtr;
}
#endif

2
src/server/poolserver/Stratum/Job.h

@ -16,6 +16,8 @@ namespace Stratum @@ -16,6 +16,8 @@ namespace Stratum
BinaryData coinbase2;
std::set<std::string> shares;
// Submits share to a job
// Returns false if the same share already exists
bool SubmitShare(BinaryData share)
{
std::string sharestr = Util::BinToASCII(Crypto::SHA256(share));

56
src/server/poolserver/Stratum/Server.cpp

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
#include "Server.h"
namespace Stratum
{
void Server::Start(tcp::endpoint endpoint)
{
// Start block checking timer
_CheckBlocksTimer();
_acceptor.open(endpoint.protocol());
_acceptor.set_option(tcp::acceptor::reuse_address(true));
_acceptor.bind(endpoint);
_acceptor.listen();
_StartAccept();
sLog.Debug(LOG_STRATUM, "Stratum server started");
}
void Server::SendToAll(JSON msg)
{
std::set<ClientPtr>::iterator it;
for (it = _clients.begin(); it != _clients.end(); ++it)
_io_service.post(boost::bind(&Client::SendMessage, (*it), msg));
}
void Server::ResetWork()
{
std::set<ClientPtr>::iterator it;
for (it = _clients.begin(); it != _clients.end(); ++it)
_io_service.post(boost::bind(&Client::SendJob, (*it), true));
}
bool Server::SubmitBlock(Bitcoin::Block block)
{
// Serialize block
ByteBuffer blockbuf;
blockbuf << block;
try {
JSON params;
params.Add(Util::BinToASCII(blockbuf.Binary()));
JSON response = _bitcoinrpc->Query("submitblock", params);
if (response["result"].GetType() == JSON_NULL) {
sLog.Info(LOG_STRATUM, "Block accepted! YAY!");
_io_service.post(boost::bind(&Server::_CheckBlocks, this));
return true;
} else {
sLog.Info(LOG_STRATUM, "Block rejected! Booooo");
}
} catch (...) {
return false;
}
}
}

94
src/server/poolserver/Stratum/Server.h

@ -13,7 +13,8 @@ @@ -13,7 +13,8 @@
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <list>
#include <boost/thread/mutex.hpp>
#include <set>
using namespace boost;
using namespace boost::asio::ip;
@ -36,66 +37,64 @@ namespace Stratum @@ -36,66 +37,64 @@ namespace Stratum
~Server()
{
std::list<Client*>::iterator it;
std::set<ClientPtr>::iterator it;
for (it = _clients.begin(); it != _clients.end(); ++it)
delete *it;
(*it)->Disconnect();
}
void Start(tcp::endpoint endpoint)
{
_CheckBlocks();
_acceptor.open(endpoint.protocol());
_acceptor.set_option(tcp::acceptor::reuse_address(true));
_acceptor.bind(endpoint);
_acceptor.listen();
_StartAccept();
sLog.Debug(LOG_STRATUM, "Stratum server started");
}
// Starts accepting connections
void Start(tcp::endpoint endpoint);
void SetBitcoinRPC(JSONRPC* bitcoinrpc)
{
_bitcoinrpc = bitcoinrpc;
}
void SendToAll(JSON msg)
{
std::list<Client*>::iterator it;
for (it = _clients.begin(); it != _clients.end(); ++it)
(*it)->SendMessage(msg);
}
// Sends message to all clients
void SendToAll(JSON msg);
// Returns new extranonce
uint32 GetExtranonce()
{
//return 134217730;
return 33554440;
//return _extranonce++;
return _extranonce++;
}
// Returns current work
Bitcoin::BlockPtr GetWork()
{
boost::lock_guard<boost::mutex> guard(_mtx_workupdate);
return _currentWork;
}
// Resets work for all clients
void ResetWork();
// Submits block to bitcoind
bool SubmitBlock(Bitcoin::Block block);
// Disconnects client
void Disconnect(ClientPtr client)
{
client->Disconnect();
_clients.erase(client);
}
private:
void _StartAccept()
{
Client* client = new Client(this, _io_service);
ClientPtr client = ClientPtr(new Client(this, _io_service));
_acceptor.async_accept(client->GetSocket(), boost::bind(&Server::_OnAccept, this, client, asio::placeholders::error));
}
void _OnAccept(Client* client, const boost::system::error_code& error)
void _OnAccept(ClientPtr client, const boost::system::error_code& error)
{
if (!error) {
sLog.Debug(LOG_STRATUM, "New stratum client accepted");
client->Start();
_clients.push_back(client);
_clients.insert(client);
} else {
sLog.Debug(LOG_STRATUM, "Failed to accept stratum client");
delete client;
}
_StartAccept();
@ -118,30 +117,40 @@ namespace Stratum @@ -118,30 +117,40 @@ namespace Stratum
block->tx.push_back(CreateCoinbaseTX(_blockHeight, _pubkey, response["coinbasevalue"].GetInt()));
// Add other transactions
/*JSON trans = response["transactions"];
JSON trans = response["transactions"];
for (uint64 i = 0; i < trans.Size(); ++i) {
ByteBuffer txbuf(Util::ASCIIToBin(trans[i]["data"].GetString()));
Bitcoin::Transaction tx;
txbuf >> tx;
block->tx.push_back(tx);
}*/
/*Bitcoin::BlockPtr block = Bitcoin::BlockPtr(new Bitcoin::Block());
block->version = 2;
block->prevBlockHash = Util::Reverse(Util::ASCIIToBin("00000000440b921e1b77c6c0487ae5616de67f788f44ae2a5af6e2194d16b6f8"));
block->time = 1347323629;
block->bits = 472564911;
block->tx.push_back(CreateCoinbaseTX(25096, _pubkey, 50));*/
}
// Genrate merkle tree
block->BuildMerkleTree();
// Set current work
_mtx_workupdate.lock();
_currentWork = block;
_mtx_workupdate.unlock();
// Requests all clients to reset work
if (reset)
ResetWork();
}
void _CheckBlocksTimer()
{
_CheckBlocks();
_blockCheckTimer.expires_from_now(boost::posix_time::milliseconds(sConfig.Get<uint32>("StratumBlockCheckTime")));
_blockCheckTimer.async_wait(boost::bind(&Server::_CheckBlocksTimer, this));
}
void _CheckBlocks()
{
sLog.Debug(LOG_STRATUM, "Checking for new blocks...");
// Might be called twice from timer and when block is found
boost::lock_guard<boost::mutex> guard(_mtx_checkblock);
sLog.Debug(LOG_STRATUM, "Clients: %u", _clients.size());
JSON response = _bitcoinrpc->Query("getinfo");
uint32 curBlock = response["blocks"].GetInt();
@ -151,9 +160,6 @@ namespace Stratum @@ -151,9 +160,6 @@ namespace Stratum
_blockHeight = curBlock;
_UpdateWork(true);
}
_blockCheckTimer.expires_from_now(boost::posix_time::milliseconds(sConfig.Get<uint32>("StratumBlockCheckTime")));
_blockCheckTimer.async_wait(boost::bind(&Server::_CheckBlocks, this));
}
Bitcoin::Transaction CreateCoinbaseTX(uint32 blockHeight, BinaryData pubkey, int64 value)
@ -186,10 +192,14 @@ namespace Stratum @@ -186,10 +192,14 @@ namespace Stratum
}
private:
// Network
std::list<Client*> _clients;
std::set<ClientPtr> _clients;
asio::io_service& _io_service;
tcp::acceptor _acceptor;
// Mutexes
boost::mutex _mtx_checkblock;
boost::mutex _mtx_workupdate;
// RPC
JSONRPC* _bitcoinrpc;

8
src/server/shared/Bitcoin/Bitcoin.h

@ -10,12 +10,18 @@ @@ -10,12 +10,18 @@
namespace Bitcoin
{
inline BigInt TargetConvert(BigInt val)
inline BigInt TargetToDiff(BigInt val)
{
static BigInt c("0x00000000ffff0000000000000000000000000000000000000000000000000000");
return (c / val);
}
inline BigInt DiffToTarget(BigInt val)
{
// Algebra says that it is the same!
return TargetToDiff(val);
}
inline BigInt TargetFromBits(uint32 bits)
{
uint8 nbytes = (bits >> 24) & 0xFF;

Loading…
Cancel
Save