Browse Source

WIP: Test merged mining.

merge-test
Jianping Wu 5 years ago
parent
commit
5b1150fd21
  1. 2
      cnutil/CMakeLists.txt
  2. 13
      cnutil/cnutil.go
  3. 211
      cnutil/src/cnutil.cpp
  4. 1
      cnutil/src/cnutil.h
  5. 44
      cnutil/src/main.cc
  6. 4
      rpc/rpc.go
  7. 4
      stratum/miner.go

2
cnutil/CMakeLists.txt

@ -16,7 +16,7 @@ include_directories("src/external/easylogging++") @@ -16,7 +16,7 @@ include_directories("src/external/easylogging++")
include_directories("src/external/unbound")
# Build library
add_library(${CXXLIB} SHARED src/main.cc src/cryptonote_basic/cryptonote_format_utils.cpp
add_library(${CXXLIB} SHARED src/cnutil.cpp src/cryptonote_basic/cryptonote_format_utils.cpp
src/crypto/tree-hash.c src/crypto/crypto.cpp src/crypto/crypto-ops.c src/crypto/crypto-ops-data.c
src/crypto/hash.c src/crypto/slow-hash.c
src/crypto/oaes_lib.c src/crypto/aesb.c

13
cnutil/cnutil.go

@ -3,6 +3,7 @@ package cnutil @@ -3,6 +3,7 @@ package cnutil
// #cgo CFLAGS: -std=c11 -D_GNU_SOURCE
// #cgo LDFLAGS: -L${SRCDIR} -Wl,-rpath=\$ORIGIN/cnutil -lcnutil -Wl,-rpath ${SRCDIR} -lstdc++
// #include <stdlib.h>
// #include <string.h>
// #include "src/cnutil.h"
import "C"
import "unsafe"
@ -18,6 +19,18 @@ func ConvertBlob(blob []byte) []byte { @@ -18,6 +19,18 @@ func ConvertBlob(blob []byte) []byte {
return output
}
func GenerateAuxBlob(blob []byte) []byte {
input := (*C.char)(unsafe.Pointer(&blob[0]))
size := (C.uint32_t)(len(blob))
var out *C.char
blobSize := C.convert_blob_to_auxpow_blob(input, size, &out)
defer C.free(unsafe.Pointer(out))
output := make([]byte, blobSize)
C.memcpy(unsafe.Pointer(&output[0]), unsafe.Pointer(out), (C.size_t)(blobSize))
return output
}
func ValidateAddress(addr string) bool {
input := C.CString(addr)
defer C.free(unsafe.Pointer(input))

211
cnutil/src/cnutil.cpp

@ -1,11 +1,193 @@ @@ -1,11 +1,193 @@
#include <cmath>
#include <stdint.h>
#include <string>
#include <algorithm>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/blobdatatype.h"
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "common/base58.h"
#include "serialization/binary_utils.h"
using namespace cryptonote;
extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) {
#define HASH_SIZE 32
/*******************************************************************************************/
/* Helper functions for merged mining - for merkle tree branch compuation. */
static size_t tree_depth(size_t count)
{
size_t i;
size_t depth = 0;
assert(count > 0);
for (i = sizeof(size_t) << 2; i > 0; i >>= 1)
{
if (count >> i > 0)
{
count >>= i;
depth += i;
}
}
return depth;
}
static void tree_branch(const char (*hashes)[HASH_SIZE], size_t count, char (*branch)[HASH_SIZE])
{
size_t i, j;
size_t cnt = 1;
size_t depth = 0;
char (*ints)[HASH_SIZE];
assert(count > 0);
for (i = sizeof(size_t) << 2; i > 0; i >>= 1)
{
if (cnt << i <= count)
{
cnt <<= i;
depth += i;
}
}
assert(cnt == 1ULL << depth);
assert(depth == tree_depth(count));
ints = reinterpret_cast<char(*)[HASH_SIZE]>(alloca((cnt - 1) * HASH_SIZE));
memcpy(ints, hashes + 1, (2 * cnt - count - 1) * HASH_SIZE);
for (i = 2 * cnt - count, j = 2 * cnt - count - 1; j < cnt - 1; i += 2, ++j)
{
crypto::cn_fast_hash(hashes[i], 2 * HASH_SIZE, ints[j]);
}
assert(i == count);
while (depth > 0)
{
assert(cnt == 1ULL << depth);
cnt >>= 1;
--depth;
memcpy(branch[depth], ints[0], HASH_SIZE);
for (i = 1, j = 0; j < cnt - 1; i += 2, ++j)
{
crypto::cn_fast_hash(ints[i], 2 * HASH_SIZE, ints[j]);
}
}
}
static void tree_hash_from_branch(const char (*branch)[HASH_SIZE], size_t depth, const char* leaf, const void* path, char* root_hash)
{
if (depth == 0)
{
memcpy(root_hash, leaf, HASH_SIZE);
}
else
{
char buffer[2][HASH_SIZE];
int from_leaf = 1;
char *leaf_path, *branch_path;
while (depth > 0)
{
--depth;
if (path && (((const char*) path)[depth >> 3] & (1 << (depth & 7))) != 0)
{
leaf_path = buffer[1];
branch_path = buffer[0];
}
else
{
leaf_path = buffer[0];
branch_path = buffer[1];
}
if (from_leaf)
{
memcpy(leaf_path, leaf, HASH_SIZE);
from_leaf = 0;
}
else
{
crypto::cn_fast_hash(buffer, 2 * HASH_SIZE, leaf_path);
}
memcpy(branch_path, branch[depth], HASH_SIZE);
}
crypto::cn_fast_hash(buffer, 2 * HASH_SIZE, root_hash);
}
}
#if 0
class CAuxPow
{
public:
// Cryptnote coinbase tx, which contains the block hash of kevacoin block.
cryptonote::transaction miner_tx;
// Merkle branch is used to establish that miner_tx is part of the
// merkel tree whose root is merkle_root.
std::vector<crypto::hash> merkle_branch;
// load
template <template <bool> class Archive>
bool do_serialize(Archive<false>& ar)
{
FIELD(miner_tx)
FIELD(merkle_branch)
return true;
}
// store
template <template <bool> class Archive>
bool do_serialize(Archive<true>& ar)
{
FIELD(miner_tx)
FIELD(merkle_branch)
return true;
}
};
#endif
class CAuxPow
{
public:
// Cryptnote coinbase tx, which contains the block hash of kevacoin block.
cryptonote::transaction miner_tx;
// Merkle branch is used to establish that miner_tx is part of the
// merkel tree whose root is merkle_root.
std::vector<crypto::hash> merkle_branch;
// load
template <template <bool> class Archive>
bool do_serialize(Archive<false>& ar)
{
FIELD(miner_tx)
FIELD(merkle_branch)
return true;
}
// store
template <template <bool> class Archive>
bool do_serialize(Archive<true>& ar)
{
FIELD(miner_tx)
FIELD(merkle_branch)
return true;
}
};
// Merkle branch and the whole miner tx.
static blobdata get_block_auxpow_blob(const block& b)
{
CAuxPow auxPow;
auxPow.miner_tx = b.miner_tx;
std::vector<crypto::hash> transactionHashes;
transactionHashes.push_back(cryptonote::get_transaction_hash(b.miner_tx));
std::copy(b.tx_hashes.begin(), b.tx_hashes.end(), std::back_inserter(transactionHashes));
auxPow.merkle_branch.resize(tree_depth(b.tx_hashes.size() + 1));
tree_branch(reinterpret_cast<const char(*)[HASH_SIZE]>(transactionHashes.data()), transactionHashes.size(),
reinterpret_cast<char(*)[HASH_SIZE]>(auxPow.merkle_branch.data()));
return t_serializable_object_to_blob(auxPow);
}
extern "C" uint32_t convert_blob_to_auxpow_blob(const char *blob, uint32_t len, char** out) {
std::string input = std::string(blob, len);
std::string output = "";
@ -14,7 +196,22 @@ extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) { @@ -14,7 +196,22 @@ extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) {
return 0;
}
output = get_block_hashing_blob(b);
output = get_block_auxpow_blob(b);
*out = (char*)malloc(output.length());
output.copy(*out, output.length(), 0);
return output.length();
}
extern "C" uint32_t convert_blob(const char *blob, uint32_t len, char *out) {
std::string input = std::string(blob, len);
blobdata output = "";
block b = AUTO_VAL_INIT(b);
if (!cryptonote::parse_and_validate_block_from_blob(input, b)) {
return 0;
}
output = cryptonote::get_block_hashing_blob(b);
output.copy(out, output.length(), 0);
return output.length();
}
@ -25,3 +222,13 @@ extern "C" bool validate_address(const char *addr, size_t len) { @@ -25,3 +222,13 @@ extern "C" bool validate_address(const char *addr, size_t len) {
uint64_t prefix;
return tools::base58::decode_addr(addr, prefix, output);
}
extern "C" void cryptonight_hash(const char* input, char* output, uint32_t len) {
const int variant = input[0] >= 7 ? input[0] - 6 : 0;
crypto::cn_slow_hash(input, len, output, variant, 0, 0);
}
extern "C" void cryptonight_fast_hash(const char* input, char* output, uint32_t len) {
crypto::cn_fast_hash(input, len, output);
}

1
cnutil/src/cnutil.h

@ -6,6 +6,7 @@ extern "C" { @@ -6,6 +6,7 @@ extern "C" {
#endif
uint32_t convert_blob(const char *blob, uint32_t len, char *out);
uint32_t convert_blob_to_auxpow_blob(const char *blob, uint32_t len, char** out);
bool validate_address(const char *addr, uint32_t len);
void cryptonight_hash(const char* input, char* output, uint32_t len);

44
cnutil/src/main.cc

@ -1,44 +0,0 @@ @@ -1,44 +0,0 @@
#include <cmath>
#include <stdint.h>
#include <string>
#include <algorithm>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/blobdatatype.h"
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "common/base58.h"
#include "serialization/binary_utils.h"
using namespace cryptonote;
extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) {
std::string input = std::string(blob, len);
blobdata output = "";
block b = AUTO_VAL_INIT(b);
if (!cryptonote::parse_and_validate_block_from_blob(input, b)) {
return 0;
}
output = cryptonote::get_block_hashing_blob(b);
output.copy(out, output.length(), 0);
return output.length();
}
extern "C" bool validate_address(const char *addr, size_t len) {
std::string input = std::string(addr, len);
std::string output = "";
uint64_t prefix;
return tools::base58::decode_addr(addr, prefix, output);
}
extern "C" void cryptonight_hash(const char* input, char* output, uint32_t len) {
const int variant = input[0] >= 7 ? input[0] - 6 : 0;
crypto::cn_slow_hash(input, len, output, variant, 0, 0);
}
extern "C" void cryptonight_fast_hash(const char* input, char* output, uint32_t len) {
crypto::cn_fast_hash(input, len, output);
}

4
rpc/rpc.go

@ -94,8 +94,8 @@ func (r *RPCClient) GetInfo() (*GetInfoReply, error) { @@ -94,8 +94,8 @@ func (r *RPCClient) GetInfo() (*GetInfoReply, error) {
return reply, err
}
func (r *RPCClient) SubmitBlock(hash string) (*JSONRpcResp, error) {
return r.doPost(r.Url.String(), "submitblock", []string{hash})
func (r *RPCClient) SubmitBlock(hash string, auxBlock string) (*JSONRpcResp, error) {
return r.doPost(r.Url.String(), "submitblock", []string{hash, auxBlock})
}
func (r *RPCClient) doPost(url, method string, params interface{}) (*JSONRpcResp, error) {

4
stratum/miner.go

@ -169,7 +169,9 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe @@ -169,7 +169,9 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe
block := hashDiff.Cmp(t.difficulty) >= 0
if block {
_, err := r.SubmitBlock(hex.EncodeToString(shareBuff))
// Testing, force AuxPow
auxBuf := cnutil.GenerateAuxBlob(shareBuff)
_, err := r.SubmitBlock(hex.EncodeToString(shareBuff), hex.EncodeToString(auxBuf))
if err != nil {
atomic.AddInt64(&m.rejects, 1)
atomic.AddInt64(&r.Rejects, 1)

Loading…
Cancel
Save