Bitcoin Forum

Bitcoin => Bitcoin Discussion => Topic started by: chriswilmer on June 05, 2013, 06:21:15 PM



Title: What's the largest number of transactions that have been in a block so far?
Post by: chriswilmer on June 05, 2013, 06:21:15 PM
I haven't figured out how to find this information. The "number of transactions per block" chart on Blockchain.info shows the daily average, which is not what I want.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: chriswilmer on June 05, 2013, 10:18:16 PM
Really, nobody knows the answer?

I found this block today that has 1200+ transactions (size ~700 KB), which is kind of what I was looking for. The max size right now is 1 MB right?

http://blockchain.info/block-index/389710/00000000000000bee901ddf3cc51943b22e0915ede7818131597c4f4cc5b3d13


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: threeip on June 05, 2013, 10:28:07 PM
Maybe try over at Technical Discussion (https://bitcointalk.org/index.php?board=6.0)?

Edit; someone on Reddit claims 2.5k per block limit (http://www.reddit.com/r/Bitcoin/comments/17vcnh/im_gathering_common_bitcoin_technical/c8960k3)


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 05, 2013, 10:33:06 PM
Shouldn't be too difficult to write a script that will walk through the blockchain and find the block with the largest number of transactions and/or the largest blocksize.

If you don't receive a satisfying answer tonight perhaps I'll try and write such a script.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 05, 2013, 11:37:26 PM
Script written and running.

bitcoind seems to respond to a getblock request pretty slowly, so it will take a while to scan the entire blockchain, but so far after scanning backwards through the 1500 most recent blocks, the one with the most transactions has been https://blockchain.info/block-index/388153/00000000000000a8dcc7b7f534b74c0e7e43686407e687217a1d10b40f0bea32 with 1,323 transactions.  I'll post another update later when the script has made more progress.

Note: I am only scanning the current best chain.  Orphaned blocks will not be included in this analysis.

Given the fact that the smallest transactions are typically about 225 bytes in size, and the header is only 80 bytes, I'd think that the most transactions that could potentially fit in a 1,048,576 byte block would be somewhere around 4,600.  That would require some extraordinary circumstances though.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: chriswilmer on June 05, 2013, 11:55:44 PM
Script written and running.

bitcoind seems to respond to a getblock request pretty slowly, so it will take a while to scan the entire blockchain, but so far after scanning backwards through the 1500 most recent blocks, the one with the most transactions has been https://blockchain.info/block-index/388153/00000000000000a8dcc7b7f534b74c0e7e43686407e687217a1d10b40f0bea32 with 1,323 transactions.  I'll post another update later when the script has made more progress.

Note: I am only scanning the current best chain.  Orphaned blocks will not be included in this analysis.

Thanks for doing this! You should post your findings somewhere and collect donations! (I'll donate something if you do)


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: wachtwoord on June 05, 2013, 11:58:30 PM
And the fee is 4.24% of the block reward. Very cool :)


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 12:11:09 AM
Script written and running.

bitcoind seems to respond to a getblock request pretty slowly, so it will take a while to scan the entire blockchain, but so far after scanning backwards through the 1500 most recent blocks, the one with the most transactions has been https://blockchain.info/block-index/388153/00000000000000a8dcc7b7f534b74c0e7e43686407e687217a1d10b40f0bea32 with 1,323 transactions.  I'll post another update later when the script has made more progress.

Note: I am only scanning the current best chain.  Orphaned blocks will not be included in this analysis.

Thanks for doing this! You should post your findings somewhere and collect donations! (I'll donate something if you do)

What sort of findings?  I can modify the script to look for other information if there's something you want to know.  Right now, it's just running backwards through every block and printing out the hash and number of transactions whenever it encounters a block that has more transactions than the max seen so far.

Output so far after searching back through the 18,700 most recent blocks (approximately the most recent 129 days):

Code:
hash:00000000000000b31371edd3656af35ef5ddf71aab394ffbdbe14c06a0c9d3ad , txQty:733
hash:00000000000000bee901ddf3cc51943b22e0915ede7818131597c4f4cc5b3d13 , txQty:1263
hash:00000000000000a8dcc7b7f534b74c0e7e43686407e687217a1d10b40f0bea32 , txQty:1323
hash:0000000000000052e1ab840ab54644689275b031fb493a9cbdf6af8cb8c99f1c , txQty:1333
hash:0000000000000013b9efa409b459baf11b4ccb43a60f853bdd8d25fb9b867ec3 , txQty:1399
hash:0000000000000068a1197cfe03640004ea2d0e45776b5c40d4044dc1d1599ca5 , txQty:1432
hash:00000000000000f99af4a59d3105cd411fd0adf42225f6857e6f75837c7ea97e , txQty:1495
hash:000000000000000e00d6df5ea6cbbb5ea12bc634668f18480c8e7eeb41c8af41 , txQty:1544
hash:00000000000000832b120849bb5201d10d4a698a3574bd9da2ab970c5dc1287c , txQty:1678
hash:000000000000033818fb20338be1fe1b223f7018bdad8ee4cea5f396cf5523e8 , txQty:1976

Note that at slightly less than half a megabyte and 1,976 transactions block https://blockchain.info/block-index/357198/000000000000033818fb20338be1fe1b223f7018bdad8ee4cea5f396cf5523e8 seems to be an indication that the maximum number of transactions that a one megabyte block could potentially contain is likely to be more than 3,952.  I'd actually guesstimate the number to be somewhere around 4,600.

This would seem to indicate that the reddit post from the OP that describes a "the 360,000 limit" per day should probably be more like 662,400 per day.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: Cubic Earth on June 06, 2013, 12:15:15 AM
Well I'll just tack this question on here:  Anyone know what block has the smallest hash, or how small that hash was?


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 12:19:28 AM
Well I'll just tack this question on here:  Anyone know what block has the smallest hash, or how small that hash was?

Hmm, that script would probably run much faster.  Maybe I'll try and create/run it simultaneously.  If I do, I'll be back with an update in a half hour or so.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: chriswilmer on June 06, 2013, 12:27:28 AM
Well I'll just tack this question on here:  Anyone know what block has the smallest hash, or how small that hash was?

Hmm, that script would probably run much faster.  Maybe I'll try and create/run it simultaneously.  If I do, I'll be back with an update in a half hour or so.

What address do you want us to tip you at? :)


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 12:42:51 AM
Well I'll just tack this question on here:  Anyone know what block has the smallest hash, or how small that hash was?
Hmm, that script would probably run much faster.  Maybe I'll try and create/run it simultaneously.  If I do, I'll be back with an update in a half hour or so.
What address do you want us to tip you at? :)
As recommended by Mr. Nakamoto, I generally prefer to use a new address for every transaction.  If anyone is serious about offering a gratuity, contact me via PM, and I'll send you a unique address for the purpose to be used only once.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 12:45:22 AM
I suspect we've found the block with the largest number of transactions.  The search has now run through the most recent 2 years and it hasn't yet found any blocks with more transactions than 1,976.  I'll leave it running just in case, but I suspect that as we work our way backwards through time, we'll reach times when bitcoin was slightly less popular and therefore the total number of transactions will begin to drop.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 01:08:42 AM
Well I'll just tack this question on here:  Anyone know what block has the smallest hash, or how small that hash was?

Having searched back though the most recent 90 days, the block with the smallest hash so far was:

https://blockchain.info/block-index/389012/000000000000000006582fa9652895fda92c757ae6beee9dfbc3932125b5ab8e

And the value of the hash was:

0x000000000000000006582fa9652895fda92c757ae6beee9dfbc3932125b5ab8e

or in decimal:

155,566,129,756,877,957,177,939,281,690,389,061,013,955,286,756,511,558,542
(1.5556613x1056)

I'll post an update if I encounter a smaller hash, but since difficulty is reduced as we get further into the past, I suspect that most blocks will have a larger hash value.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: Cubic Earth on June 06, 2013, 01:37:52 AM
The chance of finding a lower hash earlier in the blockchain would just be proportional to the area under the hash rate graph.  It is a function of the total number of hashes performed.  So, 50% of all hashes have been performed in the last 90 days, then there would be a 50% chance of finding a lower hash in all previous days had their blocks examined.

And that hash you found was about 1000x 'rarer' than was necessary to be in included.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 02:15:45 AM
The chance of finding a lower hash earlier in the blockchain would just be proportional to the area under the hash rate graph.  It is a function of the total number of hashes performed.  So, 50% of all hashes have been performed in the last 90 days, then there would be a 50% chance of finding a lower hash in all previous days had their blocks examined.

I'm not sure that is true.

Taking an extreme example:

Assume that there are only 2 hashes performed total in the history of a crypto-currency.
Assume that the second hash has a value of 0x000000000000000000000000000000000000000000000000000000000000000F

If the first hash had to meet a difficulty that would result in a hash lower than 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
I don't think that you can say that there is a 50% chance that the first hash will have a lower value than this second hash.

If the first hash had to meet a difficulty that would result in a hash lower than 0x000000000000000000000000000000000000000000000000000000000000000F
I think you can say there is a 100% chance that the first hash will have a lower value than this second hash.

It seems that you have to take into consideration how low the current value is as well as what the previous difficulties were somehow as well.

Having searched back through 11 months, there still are no lower value hashes yet.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: Cubic Earth on June 06, 2013, 04:56:29 AM
I agree with your example, but I don't think it addresses my point.  When I said 'function of total hashes performed', I was not referring to the set of hashes that solved blocks and are available for inspection in the blockchain.  I was speaking of all hashes performed on mining equipment thus far.

Lets say that 500 hashes have been performed in the last 3 months, and 500 in 3 years prior.  Every time the hash function is performed, it is equally likely to result in a value below 0x000000000000000000000000000000000000000000000000000000000000000F.  Such a hash would be included in the blockchain unless the difficulty was absurdly high.

Now that you have searched back 11 months, I'll guess that accounts for over 90% of hashes performed thus far.  So I'll give there being a 10% of finding a lower hash if you keep going.  Clearly this won't be proved nor disproved by what you find.

Also, my argument is not based on the particular hash value you found.  If you had found 0x000000000000000000000000000000000000000000000000000000000000000F in the first 90 days, the chances of finding a lower value would of course be essentially zero even if you looked back very far.  Mine is a very general argument.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: dserrano5 on June 06, 2013, 07:00:53 AM
Top 20 blocks sorted by number of transactions, with their block height:

Code:
1976,225203
1871,191716
1852,193271
1836,193645
1833,191652
1798,194208
1771,193419
1721,224986
1684,224982
1678,230532
1633,213772
1601,230037
1589,192627
1552,213616
1544,231376
1506,220277
1495,232259
1491,230732
1483,191384
1480,230389


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 06, 2013, 02:57:46 PM
Mine is a very general argument.

And therefor not mathematically accurate.

Regardless, having searched through the entire blockchain, the block with the lowest value hash so far is:
000000000000000006582fa9652895fda92c757ae6beee9dfbc3932125b5ab8e


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: chriswilmer on June 07, 2013, 06:55:22 AM
Top 20 blocks sorted by number of transactions, with their block height:

Code:
1976,225203
1871,191716
1852,193271
1836,193645
1833,191652
1798,194208
1771,193419
1721,224986
1684,224982
1678,230532
1633,213772
1601,230037
1589,192627
1552,213616
1544,231376
1506,220277
1495,232259
1491,230732
1483,191384
1480,230389

Thanks!

Where's your tip address?!!?


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: dserrano5 on June 07, 2013, 07:53:21 AM
Where's your tip address?!!?

Oh nice :)

<--- Firstbits 12345, ie 12345Vypv2QSmuRXcciT5oEB27mPbWGeva


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: kjj on June 07, 2013, 12:13:09 PM
Script written and running.

bitcoind seems to respond to a getblock request pretty slowly, so it will take a while to scan the entire blockchain...

Reading the block files directly would be much faster.


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: DannyHamilton on June 07, 2013, 03:34:11 PM
Script written and running.
bitcoind seems to respond to a getblock request pretty slowly, so it will take a while to scan the entire blockchain...
Reading the block files directly would be much faster.

Absolutely, but I haven't figured out a good way to deal with variable length integers in perl yet.  I was able to write this script in 10 minutes and get an answer within a few hours.  That's much sooner than I would have gotten a full blockchain parser written.

The script I used was pretty simple and quick to put together, it isn't pretty, but it gets the job done:

Code:
#! /usr/bin/perl

use strict;
use warnings;
use mylibs::json;

sub get_credentials {
        my $envUserName = $ENV{'USER'};
        my $confFile = "/Users/".$envUserName."/Library/Application Support/Bitcoin/bitcoin.conf";
        my ($user, $password);
        my $server = 0;

        chomp $confFile;

        if (open(MYCONFFILE, "< " . $confFile)) {
                my(@lines) = <MYCONFFILE>;
                close(MYCONFFILE);

                foreach (@lines)
                {
                        chomp;
                        if ( /^rpcuser=(.*)$/i ) { $user = $1 }
                        elsif ( /^rpcpassword=(.*)$/i ) { $password = $1 }
                        elsif ( /server=1/i ) { $server = 1 }
                }
        }
        else {
                print "Error opening bitcoin.conf file $!\n";
                exit;
        }

        return $user, $password, $server;
}

################################################
#
#  BEGIN Main
#
################################################


###########
# Authentication
###########
my ($user, $password, $server) = get_credentials();


if ($server != 1) {
        print "ERROR: client is not running in server mode\n";
        exit;
}

###########
# Current Block Height
###########
my $currBlockCommand = "curl --silent --user " .
        $user                       .
        ":"                         .
        $password                   .
        " --data-binary '{\"method\": \"getblockcount\"}' http://127.0.0.1:8332/";

my $currIndexLine = `$currBlockCommand`;

my %currIndex = parse_json($currIndexLine);

###########
# Current Block Hash
###########
my $currHashCommand = "curl --silent --user " .
        $user                       .
        ":"                         .
        $password                   .
        " --data-binary '{\"method\": \"getblockhash\", \"params\": [" .
        ${$currIndex{"result"}} .
        "] }' http://127.0.0.1:8332/";

my $currHashLine = `$currHashCommand`;

my %currHash = parse_json($currHashLine);

###########
# Current Block Details
###########
my $blockDetailsCommand = "curl --silent --user " .
        $user                       .
        ":"                         .
        $password                   .
        " --data-binary '{\"method\": \"getblock\", \"params\": [\"" .
        ${$currHash{"result"}} .
        "\"] }' http://127.0.0.1:8332/";

my $blockDetailsLine = `$blockDetailsCommand`;

my %blockDetails = parse_json($blockDetailsLine);

###########
# Loop through blocks
###########
my $maxTxQty = @{$blockDetails{"result"}{"tx"}};
my $biggestBlock = ${$blockDetails{"result"}{"hash"}};
my $blockTxQty;
my $progress = 0;

while (exists $blockDetails{"result"}{"previousblockhash"}) {
  if ( $progress++ % 100 == 0) {
    print $progress . " , " . $biggestBlock . " , " . $maxTxQty . "\n";
  }
  $blockDetailsCommand = "curl --silent --user " .
          $user                       .
          ":"                         .
          $password                   .
          " --data-binary '{\"method\": \"getblock\", \"params\": [\"" .
          ${$blockDetails{"result"}{"previousblockhash"}} .
          "\"] }' http://127.0.0.1:8332/";

  $blockDetailsLine = `$blockDetailsCommand`;

  %blockDetails = parse_json($blockDetailsLine);

  $blockTxQty = @{$blockDetails{"result"}{"tx"}};
  if ($maxTxQty < $blockTxQty) {
    $maxTxQty = $blockTxQty;
    $biggestBlock = ${$blockDetails{"result"}{"hash"}}
  }
}

print "Block:" . $biggestBlock . ", TxQty:" . $maxTxQty . "\n";


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: sgravina on June 07, 2013, 04:41:22 PM
Mine is a very general argument.

And therefor not mathematically accurate.

Regardless, having searched through the entire blockchain, the block with the lowest value hash so far is:
000000000000000006582fa9652895fda92c757ae6beee9dfbc3932125b5ab8e

What difficulty does this correspond to.  Looks like it wins my contest (https://bitcointalk.org/index.php?topic=145960.msg2352655#msg2352655).


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: chriswilmer on June 08, 2013, 07:32:25 AM
Where's your tip address?!!?

Oh nice :)

<--- Firstbits 12345, ie 12345Vypv2QSmuRXcciT5oEB27mPbWGeva

Sent!


Title: Re: What's the largest number of transactions that have been in a block so far?
Post by: dserrano5 on June 08, 2013, 01:47:00 PM
Absolutely, but I haven't figured out a good way to deal with variable length integers in perl yet.  I was able to write this script in 10 minutes and get an answer within a few hours.  That's much sooner than I would have gotten a full blockchain parser written.

Look at sub read_var_int in my quick n dirty parser:

Code:
#!/usr/bin/perl

use warnings;
use strict;
use List::MoreUtils qw/natatime/;
use Data::Dumper;

my $MAGIC = 3652501241;
my $BLOCKS_DIR = '/home/btc/.bitcoin/blocks';

## xxd-like output
sub print_dump {
    my ($data) = @_;

    my $offset = 0;
    open my $fd, '<', \$data or die "open: $!";
    while (1) {
        my $read = read $fd, my $bytes, 16;
        last unless $read;
        my @bytes = split '', $bytes;
        my $rawchars = $bytes; $rawchars =~ s/[^ -~]/./g;
        my @hexpairs;
        my $iter = natatime 2, @bytes;
        while (my @vals = $iter->()) {
            push @hexpairs, join '', map { sprintf '%02x', ord } @vals;
        }
        printf "%08x: %-39s  %s\n", $offset, (join ' ', @hexpairs), $rawchars;
        $offset += $read;
    }
    close $fd;
}

sub read_var_int {
    my ($fd, $rem) = @_;
    my $val;

    my $read = read $fd, $val, 1; $$rem -= 1;
    if (!$read) { return undef; }
    $val = unpack 'C', $val;
    if ($val == 0xfd) {
        $read = read $fd, $val, 2; $$rem -= 2;
        $val = unpack 'S', $val;
    } elsif ($val == 0xfe) {
        $read = read $fd, $val, 4; $$rem -= 4;
        $val = unpack 'L', $val;
    } elsif ($val == 0xff) {
        $read = read $fd, $val, 8; $$rem -= 8;
        $val = unpack 'Q', $val;
    }

    return $val;
}

sub read_inputs {
    my ($fd, $count, $rem) = @_;
    my $read;  ## should be used to check ret vals from read/sysread
    my $inputs;

    for my $input (1 .. $count) {
        my ($prev_txid, $prev_idx, $sig_script, $seq);

        $read = read $fd, $prev_txid, 32; $$rem -= 32;
        $prev_txid = unpack 'H64', $prev_txid;
        #print "    prev_txid ($prev_txid)\n";

        $read = read $fd, $prev_idx, 4; $$rem -= 4;
        $prev_idx = unpack 'L', $prev_idx;
        #print "    prev_idx ($prev_idx)\n";

        my $sig_script_len = read_var_int $fd, $rem;
        if (!defined $sig_script_len) { print 'sig_script_len undef'; die; }

        $read = read $fd, $sig_script, $sig_script_len; $$rem -= $sig_script_len;
        #printf "    sig_script: %d bytes\n", length $sig_script;

        $read = read $fd, $seq, 4; $$rem -= 4;
        $seq = unpack 'L', $seq;
        #print "    seq ($seq)\n";

        push @$inputs, {
            prev_txid  => $prev_txid,
            prev_idx   => $prev_idx,
            sig_script => $sig_script,
            seq        => $seq,
        }
    }

    return $inputs;
}

sub read_outputs {
    my ($fd, $count, $rem) = @_;
    my $read;  ## should be used to check ret vals from read/sysread
    my $outputs;

    for my $output (1 .. $count) {
        my ($val, $pubkey_script_len, $pubkey_script);

        $read = read $fd, $val, 8; $$rem -= 8;
        $val = unpack 'Q', $val;

        $pubkey_script_len = read_var_int $fd, $rem;
        if (!defined $pubkey_script_len) { print 'pubkey_script_len undef'; die; }

        $read = read $fd, $pubkey_script, $pubkey_script_len; $$rem -= $pubkey_script_len;
        #printf "    pubkey_script: %d bytes\n", length $pubkey_script;

        push @$outputs, {
            val           => $val,
            pubkey_script => $pubkey_script,
        };
    }

    return $outputs;
}

sub parse_txs {
    my ($txn_data, $len) = @_;
    my $read;  ## should be used to check ret vals from read/sysread
    my $txs;

    my $remaining = $len;
    open my $txn_fd, '<', \$txn_data or die "open: $!";

    my $txn_count = read_var_int $txn_fd, \$remaining;
    if (!defined $txn_count) { print 'txn_count undef'; die; }
    #print "  txn_count ($txn_count)\n";

    #print_dump $txn_data;

    my ($tx_ver, $input_count, $inputs, $output_count, $outputs, $lock_time);
    for my $tx_idx (1 .. $txn_count) {
        $read = read $txn_fd, $tx_ver, 4; $remaining -= 4;
        $tx_ver = unpack 'L', $tx_ver;
        #print "    tx_ver ($tx_ver)\n";

        $input_count = read_var_int $txn_fd, \$remaining;
        if (!defined $input_count) { print 'input_count undef'; die; }
        #print "    input_count ($input_count)\n";

        $inputs = read_inputs $txn_fd, $input_count, \$remaining;
        #print Data::Dumper->Dump ([$inputs],['inputs']);

        $output_count = read_var_int $txn_fd, \$remaining;
        if (!defined $output_count) { print 'output_count undef'; die; }
        #print "    output_count ($output_count)\n";

        $outputs = read_outputs $txn_fd, $output_count, \$remaining;
        #print Data::Dumper->Dump ([$outputs],['outputs']);

        $read = read $txn_fd, $lock_time, 4; $remaining -= 4;
        $lock_time = unpack 'L', $lock_time;
        #print "    lock_time ($lock_time)\n";

        push @$txs, {
            version   => $tx_ver,
            inputs    => $inputs,
            outputs   => $outputs,
            lock_time => $lock_time,
        };
    }

    return $txs;
}

sub parse_block {
    my ($height, $block_data, $len) = @_;
    my $read;  ## should be used to check ret vals from read/sysread

    my $remaining = $len;
    open my $block_fd, '<', \$block_data or die "open: $!";

    my $block_header;
    $read = read $block_fd, $block_header, 80; $remaining -= 80;

    my ($ver, $prev_block, $mrkl, $ts, $bits, $nonce) = unpack 'L H64 H64 L H8 L', $block_header;
    $prev_block = reverse $prev_block=~/../g;
    $mrkl = reverse $mrkl=~/../g;

    my $txn_data;
    $read = read $block_fd, $txn_data, $remaining;

    close $block_fd;

    #my $tx = parse_txs $txn_data, $remaining;  ## commented out for faster parsing

    return {
        version     => $ver,
        height      => $height,
        prev_block  => $prev_block,
        merkle_tree => $mrkl,
        timestamp   => $ts,
        bits        => $bits,
        nonce       => $nonce,
        #tx          => $tx,
    };
}

my $blk_file_num = -1;
my $fd;
sub open_next_blk_file {
    close $fd if defined $fd;
    $blk_file_num++;
    my $blkfile = sprintf "$BLOCKS_DIR/blk%05d.dat", $blk_file_num;
    sysopen $fd, $blkfile, 0 or die "sysopen: $!";
    binmode $fd;
}

#################################################################################################

open_next_blk_file;

my $height = 0;
my %prev_blocks_seen;
while (1) {
    my $read;  ## should be used to check ret vals from read/sysread
    my $data;
    my ($magic, $len, $remaining);

    $read = sysread $fd, $data, 8;
    if (!defined $read) { die "sysread: $!"; }
    if (!$read) {
        warn "sysread: null, going to next file";
        open_next_blk_file;
        redo;
    }
    if ($read < 8) {
        warn "sysread: short read, going to next file";
        open_next_blk_file;
        redo;
    }
    ($magic, $len) = unpack 'L L', $data;
    $remaining = $len;
    next unless $magic;    ## magic == 0, probably near end of file
    if ($MAGIC != $magic) { die "got magic ($magic) instead of ($MAGIC) at block $height\n"; }
    ## read whole block
    $read = sysread $fd, $data, $len;
    if ($len != $read) { $read or last; die "sysread: $!"; }

    #print_dump $block_data;
    my $block = parse_block $height, $data, $len;
    ## orphan detection, untested on orphan chains larger than one single block
    if ($height and exists $prev_blocks_seen{ $block->{'prev_block'} }) {
        my $to_downgrade = ($height-1) - $prev_blocks_seen{ $block->{'prev_block'} };
        warn "orphan, height ($block->{'height'}) pb ($block->{'prev_block'}) ts ($block->{'timestamp'}) to_downgrade ($to_downgrade)\n";
        $height -= ($height-1) - $prev_blocks_seen{ $block->{'prev_block'} };
        next;
    }
    print "$height,$len\n";
#    if (128352 == $block->{'height'}) {
#        use bignum;
#        my $bits = join '', reverse $block->{'bits'} =~ /../g;
#        my ($b1, $b2) = map { hex $_ } $bits =~ /^(..)(.*)$/;
#        my $diff = (0xffff << 208) / ($b2 * 2 ** (8 * ($b1-3)));
#        $block->{'difficulty'} = "$diff";
#
#        print Data::Dumper->Dump ([$block],['block']);
#    }

    $prev_blocks_seen{ $block->{'prev_block'} } = $height;
    $height++;
}
close $fd;


Sent!

Thank you!