예제 #1
0
static void parseBlock(
    const Block *block
) {
    startBlock(block);
        auto p = block->chunk->getData();

            auto header = p;
            SKIP(uint32_t, version, p);
            SKIP(uint256_t, prevBlkHash, p);
            SKIP(uint256_t, blkMerkleRoot, p);
            SKIP(uint32_t, blkTime, p);
            SKIP(uint32_t, blkBits, p);
            SKIP(uint32_t, blkNonce, p);

            #if defined PROTOSHARES
                SKIP(uint32_t, nBirthdayA, p);
                SKIP(uint32_t, nBirthdayB, p);
            #endif

            startTXs(p);
                LOAD_VARINT(nbTX, p);
                for(uint64_t txIndex=0; likely(txIndex<nbTX); ++txIndex) {
                    parseTX<false>(block, p);
                }
            endTXs(p);

            #if defined(PEERCOIN) || defined(CLAM) || defined(JUMBUCKS)
                LOAD_VARINT(vchBlockSigSize, p);
                p += vchBlockSigSize;
            #endif

        block->chunk->releaseData();
    endBlock(block);
}
예제 #2
0
static void parseOutputs(
    const uint8_t *&p,
    const uint8_t *txHash,
    uint64_t      stopAtIndex = -1,
    const uint8_t *downTXHash = 0,
    uint64_t      downInputIndex = 0,
    const uint8_t *downInputScript = 0,
    uint64_t      downInputScriptSize = 0
)
{
    if(!skip && !fullContext) startOutputs(p);

        LOAD_VARINT(nbOutputs, p);
        for(uint64_t outputIndex=0; outputIndex<nbOutputs; ++outputIndex) {
            bool found = fullContext && !skip && (stopAtIndex==outputIndex);
            parseOutput<skip, fullContext>(
                p,
                txHash,
                outputIndex,
                downTXHash,
                downInputIndex,
                downInputScript,
                downInputScriptSize,
                found
            );
            if(found) break;
        }

    if(!skip && !fullContext) endOutputs(p);
}
예제 #3
0
    virtual void startInput(
        const uint8_t *p
    )
    {
        if(dump) {
            printf(
                "    input[%" PRIu64 "] = {\n\n",
                nbInputs++
            );

            static uint256_t gNullHash;
            LOAD(uint256_t, upTXHash, p);
            LOAD(uint32_t, upOutputIndex, p);
            LOAD_VARINT(inputScriptSize, p);
            isGenTX = (0==memcmp(gNullHash.v, upTXHash.v, sizeof(gNullHash)));
            if(isGenTX) {
                //uint64_t reward = getBaseReward(currBlock);
                printf("        generation transaction\n");
                //printf("        proof of work block reward:, reward = %.8f\n", 1e-6*reward);
                printf("        hex dump of coinbase follows:\n\n");
                canonicalHexDump(p, inputScriptSize, "        ");
                //valueIn += reward;
            }
        }
    }
예제 #4
0
    virtual void startInput(
        const uint8_t *p
    ) {
        if(dump) {
            printf(
                "    input[%" PRIu64 "] = {\n\n",
                nbInputs++
            );

            static uint256_t gNullHash;
            LOAD(uint256_t, upTXHash, p);
            LOAD(uint32_t, upOutputIndex, p);
            LOAD_VARINT(inputScriptSize, p);
            showScript(p, inputScriptSize, 0, "        ");

            isGenTX = (0==memcmp(gNullHash.v, upTXHash.v, sizeof(gNullHash)));
            if(isGenTX) {
                uint64_t reward = getBaseReward(currBlock);
                printf("        generation transaction\n");
                printf("        based on block height, reward = %.8f\n", satoshisToNormaForm(reward));
                printf("        hex dump of coinbase follows:\n\n");
                canonicalHexDump(p, inputScriptSize, "        ");
                valueIn += reward;
            }
        }
    }
예제 #5
0
static void parseInputs(
    const uint8_t *&p,
    const uint8_t *txHash
)
{
    if(!skip) startInputs(p);

        LOAD_VARINT(nbInputs, p);
        for(uint64_t inputIndex=0; inputIndex<nbInputs; ++inputIndex)
            parseInput<skip>(p, txHash, inputIndex);

    if(!skip) endInputs(p);
}
예제 #6
0
static void parseInput(
    const Block   *block,
    const uint8_t *&p,
    const uint8_t *txHash,
    uint64_t      inputIndex
) {
    if(!skip) {
        startInput(p);
    }

        auto upTXHash = p;
        const Chunk *upTX = 0;
        if(gNeedTXHash && !skip) {
            auto isGenTX = (0==memcmp(gNullHash.v, upTXHash, sizeof(gNullHash)));
            if(likely(false==isGenTX)) {
                auto i = gTXOMap.find(upTXHash);
                if(unlikely(gTXOMap.end()==i)) {
                    errFatal("failed to locate upstream transaction");
                }
                upTX = i->second;
            }
        }

        SKIP(uint256_t, dummyUpTXhash, p);
        LOAD(uint32_t, upOutputIndex, p);
        LOAD_VARINT(inputScriptSize, p);

        if(!skip && 0!=upTX) {
            auto inputScript = p;
            auto upTXOutputs = upTX->getData();
                parseOutputs<false, true>(
                    upTXOutputs,
                    upTXHash,
                    upOutputIndex,
                    txHash,
                    inputIndex,
                    inputScript,
                    inputScriptSize
                );
            upTX->releaseData();
        }

        p += inputScriptSize;
        SKIP(uint32_t, sequence, p);

    if(!skip) {
        endInput(p);
    }
}
예제 #7
0
 virtual void endOutputs(
     const uint8_t *p
 ) {
     #if defined(CLAM)
         if(1<txVersion) {
             LOAD_VARINT(strCLAMSpeechLen, p);
             printf("    comment = '\n");
                 canonicalHexDump(
                     p,
                     strCLAMSpeechLen,
                     "    "
                 );
             printf("'\n");
         }
     #endif
 }
예제 #8
0
    // Called when a TX input is encountered
    virtual void startInput(
        const uint8_t *p
    ) {
        printf(
            "%sinput%d = {\n",
            spaces,
            (int)inputId
        );
        push();

        static uint256_t gNullHash;
        LOAD(uint256_t, upTXHash, p);
        LOAD(uint32_t, upOutputIndex, p);
        LOAD_VARINT(inputScriptSize, p);

        printf("%sscript = '\n", spaces);
            pop();
                showScript(p, inputScriptSize, 0, (const char *)spaces);
            push();
        printf("%s'\n", spaces);

        p += inputScriptSize;
        LOAD(uint32_t, sequence, p);
        printf("%snsequence = %" PRIu32 "\n",spaces, sequence);

        isCoinBase = (0==memcmp(gNullHash.v, upTXHash.v, sizeof(gNullHash)));
        if(isCoinBase) {
            uint64_t value = getBaseReward(currBlock);
            printf("%sisCoinBase = true\n", spaces);
            printf(
                "%svalue = %" PRIu64 " # %.08f\n",
                spaces,
                value,
                satoshisToNormaForm(value)
            );
            printf("%scoinBase = '\n", spaces);
            push();
                canonicalHexDump(
                    p,
                    inputScriptSize,
                    (const char *)spaces
                );
            pop();
            printf("%s'\n", spaces);
        }
    }
예제 #9
0
static void parseOutput(
    const uint8_t *&p,
    const uint8_t *txHash,
    uint64_t      outputIndex,
    const uint8_t *downTXHash,
    uint64_t      downInputIndex,
    const uint8_t *downInputScript,
    uint64_t      downInputScriptSize,
    bool          found = false
) {
    if(!skip && !fullContext) {
        startOutput(p);
    }

        LOAD(uint64_t, value, p);
        LOAD_VARINT(outputScriptSize, p);

        auto outputScript = p;
        p += outputScriptSize;

        if(!skip && fullContext && found) {
            edge(
                value,
                txHash,
                outputIndex,
                outputScript,
                outputScriptSize,
                downTXHash,
                downInputIndex,
                downInputScript,
                downInputScriptSize
            );
        }

    if(!skip && !fullContext) {
        endOutput(
            p,
            value,
            txHash,
            outputIndex,
            outputScript,
            outputScriptSize
        );
    }
}
예제 #10
0
static void parseInputs(
    const Block   *block,
    const uint8_t *&p,
    const uint8_t *txHash
) {
    if(!skip) {
        startInputs(p);
    }

    LOAD_VARINT(nbInputs, p);
    for(uint64_t inputIndex=0; inputIndex<nbInputs; ++inputIndex) {
        parseInput<skip>(block, p, txHash, inputIndex);
    }

    if(!skip) {
        endInputs(p);
    }
}
예제 #11
0
static void parseInput(
    const uint8_t *&p,
    const uint8_t *txHash,
    uint64_t      inputIndex
)
{
    if(!skip) startInput(p);

        const uint8_t *upTXHash = p;
        const uint8_t *upTXOutputs = 0;

        if(gNeedTXHash && !skip) {
            bool isGenTX = (0==memcmp(gNullHash.v, upTXHash, sizeof(gNullHash)));
            if(likely(false==isGenTX)) {
                auto i = gTXMap.find(upTXHash);
                if(unlikely(gTXMap.end()==i))
                    errFatal("failed to locate upstream TX");
                upTXOutputs = i->second;
            }
        }

        SKIP(uint256_t, dummyUpTXhash, p);
        LOAD(uint32_t, upOutputIndex, p);
        LOAD_VARINT(inputScriptSize, p);

        if(!skip && 0!=upTXOutputs) {
            const uint8_t *inputScript = p;
            parseOutputs<false, true>(
                upTXOutputs,
                upTXHash,
                upOutputIndex,
                txHash,
                inputIndex,
                inputScript,
                inputScriptSize
            );
        }

        p += inputScriptSize;
        SKIP(uint32_t, sequence, p);

    if(!skip) endInput(p);
}
예제 #12
0
static void parseBlock(
    const Block *block
)
{
    startBlock(block);

        const uint8_t *p = block->data;
        const uint8_t *header = p;
        SKIP(uint32_t, version, p);
        SKIP(uint256_t, prevBlkHash, p);
        SKIP(uint256_t, blkMerkleRoot, p);
        SKIP(uint32_t, blkTime, p);
        SKIP(uint32_t, blkBits, p);
        SKIP(uint32_t, blkNonce, p);
        LOAD_VARINT(nbTX, p);
        for(uint64_t txIndex=0; likely(txIndex<nbTX); ++txIndex)
            parseTX<false>(p);

    endBlock(block);
}
예제 #13
0
    // Called when the end of a TX's output array is encountered
    virtual void endOutputs(
        const uint8_t *p
    ) {
        #if defined(CLAM)
            if(1<txVersion) {
                LOAD_VARINT(strCLAMSpeechLen, p);
                printf("%stxComment = '\n", spaces);
                    push();
                        canonicalHexDump(
                            p,
                            strCLAMSpeechLen,
                            (const char *)spaces
                        );
                    pop();
                printf("%s'\n", spaces);
            }
        #endif

        pop();
        printf("%s}\n", spaces);
    }
예제 #14
0
static void parseTX(
    const Block   *block,
    const uint8_t *&p
) {
    auto txStart = p;
    uint8_t *txHash = 0;

    if(gNeedTXHash && !skip) {
        auto txEnd = p;
        txHash = allocHash256();
        parseTX<true>(block, txEnd);
        sha256Twice(txHash, txStart, txEnd - txStart);
    }

    if(!skip) {
        startTX(p, txHash);
    }

        #if defined(CLAM)
            LOAD(uint32_t, nVersion, p);
        #else
            SKIP(uint32_t, nVersion, p);
        #endif

        #if defined(PEERCOIN) || defined(CLAM) || defined(JUMBUCKS)
            SKIP(uint32_t, nTime, p);
        #endif

        parseInputs<skip>(block, p, txHash);

        Chunk *txo = 0;
        size_t txoOffset = -1;
        const uint8_t *outputsStart = p;
        if(gNeedTXHash && !skip) {
            txo = Chunk::alloc();
            txoOffset = block->chunk->getOffset() + (p - block->chunk->getData());
            gTXOMap[txHash] = txo;
        }

        parseOutputs<skip, false>(p, txHash);

        if(txo) {
            size_t txoSize = p - outputsStart;
            txo->init(
                block->chunk->getMap(),
                txoSize,
                txoOffset
            );
        }

        SKIP(uint32_t, lockTime, p);

        #if defined(CLAM)
            if(1<nVersion) {
                LOAD_VARINT(strCLAMSpeechLen, p);
                p += strCLAMSpeechLen;
            }
        #endif

    if(!skip) {
        endTX(p);
    }
}