How can I belief a brand new block broadcated on the community?

0
77


I’ve an enormous gap in my understanding!

I just lately began utilizing https://github.com/sebicas/bitcoin-sniffer

which is a Python script that allows you to hook up with any node on the Bitcoin Community and triggers occasions:

  • new_block_event(block): Triggered when a Block is discovered
  • new_tx_event(tx): Triggered when a Transactions is discovered

On inspecting a brand new block I used to be fairly stunned to search out that the article doesn’t embrace block.peak!

Then I discovered this query: Is block peak all the time sequential?

Quote:

Block peak is by definition sequential within the sense that adjoining blocks will all the time have heights that differ by 1. However there’s a chicken-and-egg downside: so as to compute the peak, it’s important to have entry to all of the blocks in between the genesis block and the present one. (The peak just isn’t recorded within the block itself.)

There’s additionally the problem that a number of blocks can have the identical peak, if they’re on completely different branches of the chain. So simply because you’ve gotten one block at each peak, doesn’t suggest you’ve gotten all of the blocks on the principle chain; a few of them is likely to be on orphan branches.


So my Query is

How am i able to inform if the block is official / not orphaned and that it’ll not get replaced by a ‘higher’ block?


I see that every block incorporates a earlier block hash so my reasoning is that if a block was orphaned then the following blocks earlier block hash wouldn’t be that blocks hash however one other. However utilizing that as a take a look at to see If the final block turned a part of the community would put the test (time) again by one block… which isn’t realtime nor ideally suited

The bitcoin-sniffer does have one curious perform for a block message referred to as block.is_valid on the finish of the CBlock class:

class CBlock(object):
    def __init__(self):
        self.nVersion = 1
        self.hashPrevBlock = 0
        self.hashMerkleRoot = 0
        self.nTime = 0
        self.nBits = 0
        self.nNonce = 0
        self.vtx = []
        self.sha256 = None
        self.hash = None
    def deserialize(self, f):
        self.nVersion = struct.unpack("<i", f.learn(4))[0]
        self.hashPrevBlock = deser_uint256(f)
        self.hashMerkleRoot = deser_uint256(f)
        self.nTime = struct.unpack("<I", f.learn(4))[0]
        self.nBits = struct.unpack("<I", f.learn(4))[0]
        self.nNonce = struct.unpack("<I", f.learn(4))[0]
        self.vtx = deser_vector(f, CTransaction)
    def serialize(self):
        r = ""
        r += struct.pack("<i", self.nVersion)
        r += ser_uint256(self.hashPrevBlock)
        r += ser_uint256(self.hashMerkleRoot)
        r += struct.pack("<I", self.nTime)
        r += struct.pack("<I", self.nBits)
        r += struct.pack("<I", self.nNonce)
        r += ser_vector(self.vtx)
        return r
    def calc_sha256(self):
        if self.sha256 is None:
            r = ""
            r += struct.pack("<i", self.nVersion)
            r += ser_uint256(self.hashPrevBlock)
            r += ser_uint256(self.hashMerkleRoot)
            r += struct.pack("<I", self.nTime)
            r += struct.pack("<I", self.nBits)
            r += struct.pack("<I", self.nNonce)
            self.sha256 = uint256_from_str(hash256(r))
            self.hash = hash256(r)[::-1].encode('hex_codec')
    def is_valid(self):
        self.calc_sha256()
        goal = uint256_from_compact(self.nBits)
        if self.sha256 > goal:
            return False
        hashes = []
        for tx in self.vtx:
            if not tx.is_valid():
                return False
            tx.calc_sha256()
            hashes.append(ser_uint256(tx.sha256))
        whereas len(hashes) > 1:
            newhashes = []
            for i in xrange(0, len(hashes), 2):
                i2 = min(i+1, len(hashes)-1)
                newhashes.append(hash256(hashes[i] + hashes[i2]))
            hashes = newhashes
        if uint256_from_str(hashes[0]) != self.hashMerkleRoot:
            return False
        return True
    def __repr__(self):
        return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))

The perform is ‘way-over-my-head’ to be trustworthy but it surely appears prefer it is likely to be attempting to find out climate the block might be trusted (as in; not tampered with as its querying the hashMerkleRoot which is a a method hash mechanism) however, I am not educated sufficient to to inform for certain if the is_valid is doing extra like (figuring out that the block is official)

The very last thing I wish to do is:

  1. push a tx to the community
  2. hearken to new_tx_event(tx) get my tx hash
  3. hearken to new_block_event(block) discover my tx hash is accepted within the block
  4. begin to affirm fee counting new blocks as confirmations
  5. discover out later that the block received changed/turned orphaned

Your ideas?

LEAVE A REPLY

Please enter your comment!
Please enter your name here