Skip to content

Commit

Permalink
[wip] add auxpow miner
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklodder committed Jul 9, 2024
1 parent 962b020 commit 26bc1b4
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
71 changes: 71 additions & 0 deletions qa/rpc-tests/test_framework/auxpow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,77 @@

import binascii
import hashlib
from .mininode import (
CBlockHeader, CBlock, CTransaction, deser_uint256_vector, deser_uint256,
ser_uint256, ser_uint256_vector, deser_vector
)

class CAuxData(object):
def __init__(self, auxdata=None):
if auxdata is None:
self.tx = None
self.blockhash = None
self.index = 0
self.merkle_branch = []
self.chain_index = 0
self.chain_merkle_branch = []
self.parent_blockhdr = None
else:
self.tx = auxdata.tx
self.blockhash = auxdata.blockhash
self.index = auxdata.index
self.merkle_branch = auxdata.merkleBranch
self.chain_index = auxdata.chainIndex
self.chain_merkle_branch = auxdata.chainMerkleBranch
self.parent_blockhdr = auxdata.parentBlock

def deserialize(self, f):
self.tx = CTransaction()
self.tx.deserialize(f)
self.blockhash = deser_uint256(f)
self.index = struct.unpack("<I", f.read(4))[0]
self.merkle_branch = deser_uint256_vector(f)
self.chain_index = struct.unpack("<I", f.read(4))[0]
self.chain_merkle_branch = deser_uint256_vector(f)
self.parent_blockhdr = CBlockHeader()
self.parent_blockhdr.deserialize(f)

def serialize(self):
r = b""
r += self.tx.serialize()
r += ser_uint256(self.blockhash)
r += struct.pack("<I", self.index)
r += ser_uint256_vector(self.merkle_branch)
r += struct.pack("<I", self.chain_index)
r += ser_uint256_vector(self.chain_merkle_branch)
r += self.parent_blockhdr.serialize()
return r

class CAuxpowBlock(CBlock):
def __init__(self, header=None, auxdata=None):
super(CBlock, self).__init__(header)
if self.is_auxpow():
assert auxdata is not None
self.auxdata = CAuxData(auxdata)

def is_auxpow(self):
return (self.version & 0xffff0000 == 0x0062) and (self.version & 0x000001000 == 0x0100)

def deserialize(self, f):
CBlockHeader.deserialize(self, f)
if self.is_auxpow():
self.auxdata = CAuxData()
self.auxdata.deserialize(f)
self.vtx = deser_vector(f, CTransaction)

def serialize(self):
r = b""
r += CBlockHeader.deserialize(self)
if self.is_auxpow():
r += self.auxdata.deserialize()
r += ser_vector(self.vtx)
return r


def computeAuxpow (block, target, ok):
"""
Expand Down
51 changes: 51 additions & 0 deletions qa/rpc-tests/test_framework/scrypt_auxpow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
# https://pypi.python.org/packages/source/l/ltc_scrypt/ltc_scrypt-1.0.tar.gz

from .auxpow import *
from .mininode import (
CBlock, CBlockHeader, CTransaction, CTxIn, CTxOut,
COutPoint, ser_uint256, ser_string, uint256_from_compact,
)
from .script import CScript
import ltc_scrypt
import binascii

Expand Down Expand Up @@ -77,6 +82,52 @@ def mineScryptAux (node, chainid, ok):
res = node.getauxblock (auxblock['hash'], apow)
return res

def mineSimpleEmptyAuxBlock(version, time, prevBlock, target, coinbasetx, ok=True):
# Construct the auxpow proven block
block = CAuxpowBlock()
block.nVersion = version
block.nTime = time
block.hashPrevBlock = prevBlock
block.nBits = target
block.vtx.append(coinbasetx)
block.hashMerkleRoot = block.calc_merkle_root()
block.calc_sha256()

# now that we have a hash, create the parent coinbase
mm_coinbase = struct.pack("<I", 0xfabe) + (b"m" * 2) + ser_uint256(block.sha256)
parent_coinbasetx = CTransaction()
parent_coinbasetx.vin.append(CTxIn(COutPoint(0, 0xffffffff), ser_string(mm_coinbase)), 0xffffffff)
parent_coinbasetx.vout.append(CTxOut(0, CScript([OP_TRUE])))
parent_coinbasetx.calc_sha256()

# create the parent block
parent_block = CBlock()
parent_block.nTime = time
parent_block.nBits = target
parent_block.vtx.append(parent_coinbasetx)
parent_block.hashMerkleRoot = parent_block.calc_merkle_root()

# mine the parent block
parent_blockhdr = mineScryptHeader(parent_block, target, ok)

# create auxdata - we can leave all the merkle branches empty in this case
auxdata = CAuxData()
auxdata.tx = parent_coinbasetx
auxdata.parent_blockhdr = parent_blockhdr
block.auxdata = auxdata

return block

def mineScryptHeader(header, bits, ok):
"""Mine a CBlockHeader with scrypt"""
target = uint256_from_compact(bits)
while True:
header.nNonce += 1
header.calc_sha256() #TODO: may want to fix in mininode - bit of a misnomer
if (ok and header.scrypt256 < target) or ((not ok) and header.scrypt256 > target):
break
return CBlockHeader(header)

def mineScryptBlock (header, target, ok):
"""
Given a block header, update the nonce until it is ok (or not)
Expand Down

0 comments on commit 26bc1b4

Please sign in to comment.