diff --git a/collector/collector.pl b/collector/collector.pl
index 77966456eb62a25a3bad2f007fa060d1badc9a6d..297cba143cdda2fefba510b09387db60f9f88f21 100755
--- a/collector/collector.pl
+++ b/collector/collector.pl
@@ -9,7 +9,7 @@ use     Data::Dumper;
 use     Math::BigInt;
 use     LWP;
 use     JSON;
-use	    Net::DNS;
+use     Net::DNS;
 use     Net::DNS::Resolver;
 use     lib '/home/bfa/collector';
 use     lib 'collector';
@@ -17,10 +17,11 @@ use     lib '.';
 use     sql;
 
 # 47525974938;
-my      $netversion         =   Math::BigInt->new( "0xb10c4d39a" );
+my      $netversion                 =   Math::BigInt->new( "0xb10c4d39a" );
 # 200941592
-my      $chainid            =   Math::BigInt->new( "0xbfa2018"   );
-my      $idcounter          =   0;
+my      $chainid                    =   Math::BigInt->new( "0xbfa2018"   );
+my      $idcounter                  =   0;
+my      $stop_request               =   0;
 my      $ua;
 my      @blockqueue;
 my      %sealers;
@@ -32,90 +33,99 @@ sub     info(@)
     # if 1 param only
     unshift @_, '%s'
         if $#_ == 0;
-    my      $format         =   shift;
-    $format                 =   "%s: " . $format;
-    printf  $format, astime(time), @_;
+    my      $format                 =   shift;
+    $format                         =   "%s: " . $format;
+    my      $txt                    =   sprintf $format, astime(time), @_;
+    $txt                            .=  "\n" if $txt !~ /\n$/;
+    print   $txt;
 }
 
 sub     astime
 {
-    my  @t                  =   localtime( $_[0] );
-    $t[5]                   +=  1900;
-    $t[4]                   +=  1;
+    my  @t                          =   localtime( $_[0] );
+    $t[5]                           +=  1900;
+    $t[4]                           +=  1;
     return sprintf '%04d%02d%02d-%02d%02d%02d', @t[5,4,3,2,1,0];
 }
 
 sub     shorthash($)
 {
-    local   $_              =   $_[0];
+    local   $_                      =   $_[0];
+    return unless defined $_;
     s/^(0x.......).*(.......)$/$1..$2/;
     return $_;
 }
 
+sub     stop
+{
+    $stop_request                   =   1;
+    print STDERR "\rStop request received ($_[0]).\n";
+}
+
 sub     rpcreq
 {
     my  ( $opname, @params )=   @_;
-    $ua                     =   LWP::UserAgent->new( keep_alive => 10 )
+    $ua                             =   LWP::UserAgent->new( keep_alive => 10 )
         if not defined $ua;
     # $ua->ssl_opts( 'verify_hostname' => 0 );
-    my      %args           =   (
-        jsonrpc             =>  '2.0',
-        method              =>  $opname,
-        id                  =>  $idcounter++,
+    my      %args                   =   (
+        jsonrpc                     =>  '2.0',
+        method                      =>  $opname,
+        id                          =>  $idcounter++,
     );
-    my  @args               =   map {
-            my  $v          =   $args{$_};
-            $v              =   qq/"${v}"/ if $v !~ /^\d+$/;
+    my  @args                       =   map {
+            my  $v                  =   $args{$_};
+            $v                      =   qq/"${v}"/ if $v !~ /^\d+$/;
             sprintf qq/"%s":%s/, $_, $v;
         } keys %args;
     if ( scalar @params )
     {
-        my  $p              =   '"params":[';
+        my  $p                      =   '"params":[';
         foreach my $param ( @params )
         {
             $param = '"' . $param . '"'
                 if  $param ne 'true'
                 and $param ne 'false'
                 and $param !~ /^\d+$/;
-            $p              .=  $param . ',';
+            $p                      .=  $param . ',';
         }
         chop $p;
-        $p                  .=  ']';
+        $p                          .=  ']';
         push @args, $p;
     }
-    my  $args               =   '{' . join(',',@args) . '}';
+    my  $args                       =   '{' . join(',',@args) . '}';
     die 'The environment variable $BFANODE must contain a URL for a ' .
         'server to connect to (e.g. https://10.20.30.40/), but it it ' .
         'not set. Stopped'
         unless defined $ENV{'BFANODE'};
-    my  $res                =   $ua->post(
+    my  $res                        =   $ua->post(
         $ENV{BFANODE},
-        'Content-Type'      =>  'application/json',
-        'Content'           =>  $args,
+        'Content-Type'              =>  'application/json',
+        'Content'                   =>  $args,
     );
     die $res->status_line
         unless $res->is_success;
-    my  $json               =   decode_json($res->content);
+    my  $json                       =   decode_json($res->content);
     return $json->{'result'};
 }
 
 sub     getblock
 {
-    my      $block          =   lc shift;
+    my      $block                  =   lc shift;
     my      $rpccmd;
     if ( $block =~ /^0x[\da-f]{64}$/ )
     {
-        $rpccmd             =   'eth_getBlockByHash';
+        $rpccmd                     =   'eth_getBlockByHash';
     }
     else
     {
-        $rpccmd             =   'eth_getBlockByNumber';
+        $rpccmd                     =   'eth_getBlockByNumber';
         if ( $block =~ /^\d+$/ )
         {
-            $block          =   Math::BigInt->new( $block )->as_hex;
+            $block                  =   Math::BigInt->new( $block )->as_hex;
         }
     }
-    my  $json               =   rpcreq( $rpccmd, $block, 'false' );
+    my  $json                       =   rpcreq( $rpccmd, $block, 'false' );
     die "We should have received some kind of JSON from our RPC call, " .
         "but apparently not. Stopped "
         if not defined $json;
@@ -123,10 +133,10 @@ sub     getblock
     foreach my $key (qw(
         timestamp gasUsed gasLimit difficulty number totalDifficulty size
     )) {
-        $json->{$key}       =   Math::BigInt->new( $json->{$key} )->bstr
+        $json->{$key}               =   Math::BigInt->new( $json->{$key} )->bstr
             if exists $json->{$key};
     }
-    info "B %s %s %s %s %s %s/%s\n",
+    info "B %s %s %s %s %s %s/%s",
         shorthash $json->{'hash'},
         astime($json->{'timestamp'}),
         $json->{'number'},
@@ -151,25 +161,26 @@ sub     getblock
             getTransByHash( $txhash );
         }
     }
+    # Put the parent block in front in @blockqueue
     unshift @blockqueue, lc $json->{'parentHash'}
         if $json->{'number'} != 0;
 }
 
 sub     getTransByHash
 {
-    my  $hash               =   shift;
+    my  $hash                       =   shift;
     # Don't get it via RPC if we already have it in the database
     return
         if $sql->selectTransactionByHash( $hash );
-    my  $json               =   rpcreq(
+    my  $json                       =   rpcreq(
         'eth_getTransactionByHash',
         $hash
     );
     die "Invalid object received when asking for $hash:\n".Dumper($json) if not exists $json->{'blockNumber'};
-    my  $max                    =   0;
-    my  $rcpt                   =   undef;
+    my  $max                        =   0;
+    my  $rcpt                       =   undef;
     do {
-        $rcpt                   =   rpcreq(
+        $rcpt                       =   rpcreq(
             'eth_getTransactionReceipt',
             $hash
         );
@@ -179,40 +190,44 @@ sub     getTransByHash
             warn "Couldn't get the transaction receipt for $hash\n";
         }
     } while not $rcpt and $max++ < 10;
-    die "Couldn't get the transaction receipt for $hash\n" if not $rcpt;
-    $json->{'status'}       =   $rcpt->{'status'};
-    $json->{'gasUsed'}      =   $rcpt->{'gasUsed'};
+    die "Couldn't get the transaction receipt for $hash:\n" if not $rcpt;
+    foreach my $key (qw( hash blockHash nonce gas gasPrice value from to input ))
+    {
+        die "JSON missing key $key:".Dumper($json) unless exists $json->{$key};
+    }
+    $json->{'status'}               =   $rcpt->{'status'};
+    $json->{'gasUsed'}              =   $rcpt->{'gasUsed'};
     $json->{'contractAddress'}
-                            =   $rcpt->{'contractAddress'};
+                                    =   $rcpt->{'contractAddress'};
     foreach my $key (qw( nonce value gas gasPrice gasUsed status))
     {
-        $json->{$key}       =   Math::BigInt->new( $json->{$key} )->bstr;
+        $json->{$key}               =   Math::BigInt->new( $json->{$key} )->bstr;
     }
-    info    "T  %s %s %s %s -> %s\n",
+    info    "T  %s %s %s %s -> %s",
             shorthash $json->{'hash'},
             $json->{'nonce'},
             $json->{'value'},
             shorthash $json->{'from'},
-            shorthash $json->{'to'};
-    my      $input          =   $json->{'input'};
-    my      $inputlen       =   0;
+            shorthash ($json->{'to'}||'<NULL>');
+    my      $input                  =   $json->{'input'};
+    my      $inputlen               =   0;
     if ( $input =~  /^0x/ )
     {
-        $inputlen           =   (length($input)-2) / 2;
+        $inputlen                   =   (length($input)-2) / 2;
     }
-    my      @args           =   (
+    my      @args                   =   (
         lc $json->{'hash'},
         lc $json->{'blockHash'},
-        $json->{'nonce'},
-        $json->{'gas'},
-        $json->{'gasPrice'},
-        $json->{'value'},
+           $json->{'nonce'},
+           $json->{'gas'},
+           $json->{'gasPrice'},
+           $json->{'value'},
         lc $json->{'from'},
-        lc $json->{'to'},
-        $json->{'status'},
-        $json->{'gasUsed'},
+        defined $json->{'to'} ? lc $json->{'to'} : undef,
+           $json->{'status'},
+           $json->{'gasUsed'},
         $input,
-        $inputlen,
+        $inputlen
     );
     if ( $json->{'contractAddress'} )
     {
@@ -227,8 +242,8 @@ sub     getTransByHash
 sub     versioncheck
 {
     my      $n;
-    my      $ok             =   1;
-    $n                      =   Math::BigInt->new( rpcreq( "net_version" ) );
+    my      $ok                     =   1;
+    $n                              =   Math::BigInt->new( rpcreq( "net_version" ) );
     if ( $n->bcmp( $netversion ) != 0 )
     {
         warn "Network says it has net.version "
@@ -238,13 +253,13 @@ sub     versioncheck
             . "). Expected $netversion ("
             . $netversion->as_hex
             . ").\n";
-        $ok                 =   0;
+        $ok                         =   0;
     }
-    $n                      =   Math::BigInt->new( rpcreq( "eth_chainId" ) );
+    $n                              =   Math::BigInt->new( rpcreq( "eth_chainId" ) );
     if ( $n->bcmp( $chainid ) != 0 )
     {
         warn sprintf("Network says it has eth.chainId %s (%s). Expected %s (%s).\n", $n->bstr, $n->as_hex, $chainid->bstr, $chainid->as_hex);
-        $ok                 =   0;
+        $ok                         =   0;
     }
     exit 1 if not $ok;
     return $ok;
@@ -252,80 +267,94 @@ sub     versioncheck
 
 sub     getsnap
 {
-    my      $blockhash      =   $_[0];
-    my      $json           =   rpcreq(
+    my      $blockhash              =   $_[0];
+    my      $json                   =   rpcreq(
         'clique_getSnapshotAtHash',
         $blockhash
     );
     # Sanity check 1 - does the lookup return the block?
     return if not defined $json;
-    my      $recents        =   $json->{'recents'};
+    my      $recents                =   $json->{'recents'};
     # Blockhash of the requested block - we must use this for the insert
-    $blockhash              =   $json->{'hash'};
-    my      $blocknumber    =   Math::BigInt->new( $json->{'number'} );
+    $blockhash                      =   $json->{'hash'};
+    my      $blocknumber            =   Math::BigInt->new( $json->{'number'} );
     my      @infonumbers;
     while ( not $blocknumber->is_zero )
     {
-        my  $sealerhash     =   $recents->{$blocknumber->bstr};
-        last if not defined $sealerhash;
+        my  $sealerhash             =   $recents->{$blocknumber->bstr};
+        last                            if not defined $sealerhash;
         push    @infonumbers, $blocknumber->bstr;
-        my  $ref            =   $sql->selectBlockByHash( $blockhash );
+        my  $ref                    =   $sql->selectBlockByHash( $blockhash );
         # Stop if we get to blocks which we still haven't stored in the db
-        return ( undef, $blocknumber )
-            if not defined $ref;
+        if ( not defined $ref )
+        {
+          $blockhash                =   undef;
+          last;
+        }
         # Stop if we got to a block with sealers.
-        return ( undef, $blocknumber )
-            if exists $ref->{'sealerAccountId'} and defined $ref->{'sealerAccountId'};
+        if ( exists $ref->{'sealerAccountId'} and defined $ref->{'sealerAccountId'} )
+        {
+          $blockhash                =   undef;
+          last;
+        }
         $sql->updateWhoSealed( $sealerhash, $blockhash );
-        my  $parentblockid  =   $ref->{'parentBlockhashId'};
+        my  $parentblockid          =   $ref->{'parentBlockhashId'};
         # For next block...
-        $blockhash          =   $sql->selectBlockhashById( $parentblockid );
+        $blockhash                  =   $sql->selectBlockhashById( $parentblockid );
         $blocknumber->bsub(1);
     }
-    info    "S Snapshot at block # @infonumbers.\n";
+    info    "S Snapshot at block # @infonumbers."
+                                        if @infonumbers;
     return  ($blockhash, $blocknumber);
 }
 
 # Find strands of blocks in the database which have their sealer set to NULL
 sub     allsnaps
 {
-    my      $blockhash      =   $sql->selectMaxUnknownSigned;
-    my      $committer      =   0;
+    my      $blockhash              =   $sql->selectMaxUnknownSigned;
     while ( defined $blockhash )
     {
         my  $blocknumber;
-        ( $blockhash, $blocknumber )
-                            =   getsnap( $blockhash );
-        $sql->commit
-            if ( $committer++ % 75 ) == 0;
+        ( $blockhash, $blocknumber )=   getsnap( $blockhash );
         last if $blocknumber->is_zero;
     }
 }
 
 sub     main
 {
-    $|                      =   1;
     versioncheck();
     # Give Postgres time to start up.
-    sleep(3);
-    $sql                    =   sql->new();
-    info                        "Looking for orphaned blocks in the "
-                            .   "database.\n";
-    push @blockqueue,           $sql->listOrphans();
-    
-    while ( 1 )
+    sleep( 3 );
+    $sql                            =   sql->new();
+    my      $lastorphancheck=   0;
+    $SIG{'HUP'}                     =   \&stop;
+    $SIG{'INT'}                     =   \&stop;
+    $SIG{'TERM'}                    =   \&stop;
+    $SIG{'TSTP'}                    =   \&stop;
+    while ( not $stop_request )
     {
-        unshift @blockqueue,    'latest';
-        while ( @blockqueue )
+        my  $now                    =   time();
+        if ( $lastorphancheck <= $now+600 )
         {
-            my  $maxinarow      =   100;
+            $lastorphancheck        =   $now;
+            # Orphans happen if some blocks have been deleted
+            # or if the initial synchronization hasn't finished.
+            # This check should be done when orphans can be
+            # suspected, but when is that? Maybe every 10 minutes.
+            push @blockqueue,           $sql->listOrphans();
+        }
+        do
+        {
+            unshift @blockqueue,        'latest';
+            my  $maxinarow          =   100;
             getblock( shift @blockqueue )
-                while @blockqueue and --$maxinarow;
+                while @blockqueue and --$maxinarow and not $stop_request;
             # Find out who signed all blocks
-            allsnaps();
+            allsnaps()                  if not $stop_request;
+            info "Committing.";
             $sql->commit;
-        }
-        sleep 5;
+        } while @blockqueue and not $stop_request;
+        sleep 5                         if not @blockqueue and not $stop_request;
     }
 }
 
diff --git a/collector/sql.pm b/collector/sql.pm
index 28cec895035f46093c3f11897bda3d3539b68ed2..204baa39e26a0bb0ae00d632d4f59dbc3fa5cf31 100644
--- a/collector/sql.pm
+++ b/collector/sql.pm
@@ -12,8 +12,8 @@ use     base qw( Class::Accessor );
 __PACKAGE__->mk_accessors( 'dbh' );
 sub     new
 {
-    my      ( $class )      =   @_;
-    my      $self           =   bless {}, ref $class || $class;
+    my      ( $class )              =   @_;
+    my      $self                   =   bless {}, ref $class || $class;
     $self->dbh( DBI->connect(
         'dbi:Pg:dbname=postgres;host=postgres','postgres',$ENV{'POSTGRES_PASSWORD'},
         {AutoCommit=>0,RaiseError=>1}
@@ -23,37 +23,80 @@ sub     new
 
 sub     commit
 {
-    my      ( $self )       =   @_;
+    my      ( $self )               =   @_;
     $self->dbh->commit;
 }
 
 sub     listOrphans
 {
-    my      ( $self )       =   @_;
-    my      $sth            =   $self->dbh->prepare(q(
-        SELECT  "parentBlockhashId", id
-        FROM    block
-        WHERE   "parentBlockhashId" NOT IN (
-            SELECT  id
-            FROM    block
-        )
+    my      ( $self )               =   @_;
+    my	    $max	            =   $self->maxBlockNumber;
+    # max will be NULL when there are no blocks in the table.
+    return unless defined $max;
+    my      $sth_orphan             =   $self->dbh->prepare(q(
+	    SELECT "parentBlockhashId", id
+	    FROM   block
+	    WHERE  number >= ?
+	    AND    number <= ?
+	    AND    "parentBlockhashId" NOT IN (
+	    	   SELECT id FROM block
+		   WHERE number >= ?-1
+		   AND   number <= ?-1
+	    )
+	    ORDER BY number;
     ));
     my      @results;
-    $sth->execute();
-    while ( my $row         =   $sth->fetchrow_arrayref )
+    my      $stepping               =   50000;
+    my      $i                      =   0;
+    # Had to split this into sections or it would take too long
+    # (1.4M rows, 3 CPUs, stopped after 8 hours of execution)
+    # This takes less than 10 seconds with 1.4M rows.
+    while ( $i < $max )
     {
-        # Block 0 has it's parent listed as 0x0{64}
-        next if $row->[0]   =~  /^0x0{64}$/;
-        push @results,          $self->selectBlockhashById( $row->[0] );
+	my  $bottom                 =   $i;
+	my  $top                    =   $i + $stepping;
+    	$sth_orphan->execute($bottom, $top, $bottom, $top);
+	$i                          +=  $stepping;
+        while ( my $row             =   $sth_orphan->fetchrow_arrayref )
+	{
+            next
+	        if $row->[0]=~  /^0x0{64}$/;
+            push @results,      $self->selectBlockhashById( $row->[0] );
+        }
     }
-    $sth->finish;
+    $sth_orphan->finish;
+    # Take the lowest number and put it in the back
+    my      $first                  =   shift @results;
+    push    @results, $first
+      if defined $first;
     return  @results;
 }
 
+__PACKAGE__->mk_accessors( 'sth_max' );
+sub	maxBlockNumber
+{
+    my      ( $self )               =   @_;
+    if ( not defined $self->sth_max )
+    {
+        $self->sth_max(
+	    $self->dbh->prepare(q(
+	        SELECT MAX(number)
+	        FROM   block
+            ))
+        );
+    }
+    $self->sth_max->execute;
+    my	    $ref	            =   $self->sth_max->fetchrow_arrayref;
+    $self->sth_max->finish;
+    die "Unable to get the highest block number. Stopped"
+    	if not defined $ref;
+    return $ref->[0];
+}
+
 __PACKAGE__->mk_accessors( 'sth_insertTransactionWithContractAddress' );
 sub     insertTransactionWithContractAddress
 {
-    my      $self           =   shift;
+    my      $self                   =   shift;
     if ( not defined $self->sth_insertTransactionWithContractAddress )
     {
         $self->sth_insertTransactionWithContractAddress(
@@ -67,17 +110,17 @@ sub     insertTransactionWithContractAddress
             ))
         );
     }
-    $_[1]                   =   $self->selectBlockhashByHash( $_[1] );
-    $_[6]                   =   $self->selectAccountIdByAddress( $_[6] );
-    $_[7]                   =   $self->selectAccountIdByAddress( $_[7] );
-    $_[12]                  =   $self->selectAccountIdByAddress( $_[12] );
+    $_[1]                           =   $self->selectBlockhashByHash( $_[1] );
+    $_[6]                           =   $self->selectAccountIdByAddress( $_[6] );
+    $_[7]                           =   $self->selectAccountIdByAddress( $_[7] ) if defined $_[7];
+    $_[12]                          =   $self->selectAccountIdByAddress( $_[12] ) if defined $_[12];
     $self->sth_insertTransactionWithContractAddress->execute( @_, 'explicit' );
 }
 
 __PACKAGE__->mk_accessors( 'sth_insertTransaction' );
 sub     insertTransaction
 {
-    my      $self           =   shift;
+    my      $self                   =   shift;
     if ( not defined $self->sth_insertTransaction )
     {
         $self->sth_insertTransaction(
@@ -91,16 +134,82 @@ sub     insertTransaction
             ))
         );
     }
-    $_[1]                   =   $self->selectBlockhashByHash( $_[1] );
-    $_[6]                   =   $self->selectAccountIdByAddress( $_[6] );
-    $_[7]                   =   $self->selectAccountIdByAddress( $_[7] );
+    $_[1]                           =   $self->selectBlockhashByHash( $_[1] );
+    $_[6]                           =   $self->selectAccountIdByAddress( $_[6] );
+    $_[7]                           =   $self->selectAccountIdByAddress( $_[7] ) if defined $_[7];
     $self->sth_insertTransaction->execute( @_, 'explicit' );
 }
 
+my	@cacheBlockhash;
+sub	_cacheBlockhash
+{
+    my      $args                   =   shift;
+    my      $i                      =   scalar @cacheBlockhash;
+    if ( exists $args->{'id'} and exists $args->{'hash'} )
+    {
+	# Don't put something in the cache, if it's already there
+	while ( $i-- > 0 )
+	{
+	    if ( $cacheBlockhash[$i]->{'id'} eq $args->{'id'} )
+	    {
+                return;
+	    }
+	}
+	# Store in the cache
+  	push   @cacheBlockhash, { 'id' => $args->{'id'}, 'hash' => $args->{'hash'} };
+	# may 10 entries
+        splice @cacheBlockhash, 10;
+	return;
+    }
+    # If just one element is given, then it is a lookup
+    if ( defined $args->{'id'} )
+    {
+	while ( $i-- > 0 )
+	{
+	    if ( $cacheBlockhash[$i]->{'id'} eq $args->{'id'} )
+	    {
+	    	return $cacheBlockhash[$i]->{'hash'}
+	    }
+	}
+	return;
+    }
+    if ( defined $args->{'hash'} )
+    {
+	while ( $i-- > 0 )
+	{
+	    if ( $cacheBlockhash[$i]->{'hash'} eq $args->{'hash'} )
+	    {
+	        return $cacheBlockhash[$i]->{'id'};
+	    }
+	}
+	return;
+    }
+    return;
+}
+
+__PACKAGE__->mk_accessors( 'sth_insertBlockhash' );
+sub     insertBlockhash
+{
+    my      ( $self, $hash )        =   @_;
+    $hash                           =   lc $hash;
+    if ( not defined $self->sth_insertBlockhash )
+    {
+        $self->sth_insertBlockhash(
+            $self->dbh->prepare(q(
+                INSERT INTO blockhash
+                (   hash    )
+                VALUES  (?)
+            ))
+        )
+    }
+    $self->sth_insertBlockhash->execute( $hash );
+    return $self->dbh->last_insert_id(undef,undef,undef,undef,{sequence=>'blockhash_id_seq'});
+}
+
 __PACKAGE__->mk_accessors( 'sth_selectBlockhashById' );
 sub     selectBlockhashById
 {
-    my      ( $self, $id )  =   @_;
+    my      ( $self, $id )          =   @_;
     if ( not defined $self->sth_selectBlockhashById )
     {
         $self->sth_selectBlockhashById(
@@ -111,19 +220,22 @@ sub     selectBlockhashById
             ))
         );
     }
+    my      $hash                   =   _cacheBlockhash( {'id'=>$id} );
+    return  $hash                       if defined $hash;
+    # Ask the database
     $self->sth_selectBlockhashById->execute( $id );
-    my      $ref            =   $self->sth_selectBlockhashById->fetchrow_arrayref;
+    my      $ref                    =   $self->sth_selectBlockhashById->fetchrow_arrayref;
     $self->sth_selectBlockhashById->finish;
-    return
-        if not defined $ref;
-    return $ref->[0];
+    return                              if not defined $ref;
+    $hash                           =   $ref->[0];
+    _cacheBlockhash( {'hash'=>$hash, 'id'=>$id} );
+    return $hash;
 }
 
 __PACKAGE__->mk_accessors( 'sth_selectBlockhashByHash' );
 sub     selectBlockhashByHash
 {
     my      ( $self, $hash )=   @_;
-    $hash                   =   lc $hash;
     if ( not defined $self->sth_selectBlockhashByHash )
     {
         $self->sth_selectBlockhashByHash(
@@ -134,47 +246,68 @@ sub     selectBlockhashByHash
             ))
         );
     }
-    my      $inserts        =   0;
-    while ( 1 )
-    {
-        # Try to look up the hash
-        $self->sth_selectBlockhashByHash->execute( $hash );
-        my $ref             =   $self->sth_selectBlockhashByHash->fetchrow_arrayref;
-        $self->sth_selectBlockhashByHash->finish;
-        # If found, return it immediately
-        return $ref->[0]        if defined $ref;
-        # Do maximum 1 attempt to insert a hash
-        return                  if $inserts > 0;
-        # Insert a hash, because it is not already in the database.
-        $self->insertBlockhash( $hash );
-        # Avoid loops.
-        $inserts++;
-    }
+    $hash                           =   lc $hash;
+    my      $id                     =   _cacheBlockhash( {'hash'=>$hash} );
+    return  $id                         if defined $id;
+    $self->sth_selectBlockhashByHash->execute( $hash );
+    my     $ref                     =   $self->sth_selectBlockhashByHash->fetchrow_arrayref;
+    $self->sth_selectBlockhashByHash->finish;
+    $id                             =   defined $ref
+                                    ?   $ref->[0]
+			            :    $self->insertBlockhash( $hash );
+    die                                 if not defined $id;
+    _cacheBlockhash( {'id'=>$id, 'hash'=>$hash} );
+    return $id;
 }
 
-__PACKAGE__->mk_accessors( 'sth_insertBlockhash' );
-sub     insertBlockhash
+my	@cacheAccount;
+sub	_cacheAccount
 {
-    my      ( $self, $hash )=   @_;
-    $hash                   =   lc $hash;
-    if ( not defined $self->sth_insertBlockhash )
+    my      $args                   =   shift;
+    my      $i                      =   scalar @cacheAccount;
+    if ( exists $args->{'id'} and exists $args->{'account'} )
     {
-        $self->sth_insertBlockhash(
-            $self->dbh->prepare(q(
-                INSERT INTO blockhash
-                (   hash    )
-                VALUES  (?)
-            ))
-        )
+	# Don't put something in the cache, if it's already there
+	while ( $i-- > 0 )
+	{
+	    if ( $cacheAccount[$i]->{'id'} eq $args->{'id'} )
+	    {
+                return;
+	    }
+	}
+	# Store in the cache
+  	push   @cacheAccount, { 'id' => $args->{'id'}, 'account' => $args->{'account'} };
+	# may 10 entries
+        splice @cacheAccount, 10;
+	return;
     }
-    $self->sth_insertBlockhash->execute( $hash );
+    # If just one element is given, then it is a lookup
+    if ( defined $args->{'id'} )
+    {
+	while ( $i-- > 0 )
+	{
+	    return $cacheAccount[$i]->{'account'}
+	        if $cacheAccount[$i]->{'id'} eq $args->{'id'};
+	}
+	return;
+    }
+    if ( defined $args->{'account'} )
+    {
+	while ( $i-- > 0 )
+	{
+	    return $cacheAccount[$i]->{'id'}
+	        if $cacheAccount[$i]->{'account'} eq $args->{'account'};
+	}
+	return;
+    }
+    return;
 }
 
 __PACKAGE__->mk_accessors( 'sth_selectAccountIdByAddress' );
 my      %account;
 sub     selectAccountIdByAddress
 {
-    my      ( $self, $address )=   @_;
+    my      ( $self, $address )     =   @_;
     $address                =   lc $address;
     if ( not defined $self->sth_selectAccountIdByAddress )
     {
@@ -186,23 +319,18 @@ sub     selectAccountIdByAddress
             ))
         );
     }
-    return $account{$address} if exists $account{$address};
-    while ( not exists $account{$address} )
-    {
-        # Try to look up the hash
-        $self->sth_selectAccountIdByAddress->execute( $address );
-        my  $ref                    =   $self->sth_selectAccountIdByAddress->fetchrow_arrayref;
-        $self->sth_selectAccountIdByAddress->finish;
-        # If found, return it immediately
-        if ( defined $ref )
-        {
-            $account{$address}      =   $ref->[0];
-            last;
-        }
-        # Insert a hash, because it is not already in the database.
-        $self->insertAccount( $address );
-    }
-    return $account{$address};
+    my      $id                     =   _cacheAccount( {'address'=>$address} );
+    return  $id                         if defined $id;
+    # Try to look up the hash
+    $self->sth_selectAccountIdByAddress->execute( $address );
+    my  $ref                        =   $self->sth_selectAccountIdByAddress->fetchrow_arrayref;
+    $self->sth_selectAccountIdByAddress->finish;
+    $id                             =   defined $ref
+                                    ?   $ref->[0]
+				    :   $self->insertAccount( $address );
+    die                                 if not defined $id;
+    _cacheAccount( {'id'=>$id, 'address'=>$address} );
+    return $id;
 }
 
 __PACKAGE__->mk_accessors( 'sth_insertAccount' );
@@ -221,13 +349,14 @@ sub     insertAccount
         );
     }
     $self->sth_insertAccount->execute( $address );
+    return $self->dbh->last_insert_id(undef,undef,undef,undef,{sequence=>'account_id_seq'});
 }
 
 __PACKAGE__->mk_accessors( 'sth_insertBlock' );
 sub     insertBlock
 {
     my      ( $self, $hash, $parentHash, $number, $timestamp, $difficulty, $gasUsed, $gasLimit, $size )
-                            =   @_;
+                                    =   @_;
     if ( not defined $self->sth_insertBlock )
     {
         $self->sth_insertBlock(
@@ -239,16 +368,16 @@ sub     insertBlock
             ))
         );
     }
-    my      $id             =   $self->selectBlockhashByHash( $hash );
-    my      $parentid       =   $self->selectBlockhashByHash( $parentHash );
+    my      $id                     =   $self->selectBlockhashByHash( $hash );
+    my      $parentid               =   $self->selectBlockhashByHash( $parentHash );
     $self->sth_insertBlock->execute( $id, $parentid, $number, $timestamp, $difficulty, $gasUsed, $gasLimit, $size );
 }
 
 __PACKAGE__->mk_accessors( 'sth_selectBlockByHash' );
 sub     selectBlockByHash
 {
-    my      ( $self, $hash) =   @_;
-    $hash                   =   lc $hash;
+    my      ( $self, $hash)         =   @_;
+    $hash                           =   lc $hash;
     if ( not defined $self->sth_selectBlockByHash )
     {
         $self->sth_selectBlockByHash(
@@ -259,20 +388,19 @@ sub     selectBlockByHash
             ))
         );
     }
-    my      $blockid        =   $self->selectBlockhashByHash( $hash );
+    my      $blockid                =   $self->selectBlockhashByHash( $hash );
     $self->sth_selectBlockByHash->execute( $blockid );
-    my      $ref            =   $self->sth_selectBlockByHash->fetchrow_hashref;
+    my      $ref                    =   $self->sth_selectBlockByHash->fetchrow_hashref;
     $self->sth_selectBlockByHash->finish;
-    return
-        if not defined $ref;
-    return  $ref;
+    return  $ref                        if defined $ref;
+    return;
 }
 
 __PACKAGE__->mk_accessors( 'sth_selectTransactionByHash' );
 sub     selectTransactionByHash
 {
-    my      ( $self, $hash) =   @_;
-    $hash                   =   lc $hash;
+    my      ( $self, $hash)         =   @_;
+    $hash                           =   lc $hash;
     if ( not defined $self->sth_selectTransactionByHash )
     {
         $self->sth_selectTransactionByHash(
@@ -284,17 +412,17 @@ sub     selectTransactionByHash
         );
     }
     $self->sth_selectTransactionByHash->execute( $hash );
-    my      $ref            =   $self->sth_selectTransactionByHash->fetchrow_hashref;
+    my      $ref                    =   $self->sth_selectTransactionByHash->fetchrow_hashref;
     $self->sth_selectTransactionByHash->finish;
-    return  $ref
-        if defined $ref;
+    return  $ref                        if defined $ref;
     return;
 }
 
 __PACKAGE__->mk_accessors( 'sth_updateWhoSealed' );
 sub     updateWhoSealed
 {
-    my  ( $self, $sealerhash, $blockhash  )  =   @_;
+    my  ( $self, $sealerhash, $blockhash  )
+                                    =   @_;
     if ( not defined $self->sth_updateWhoSealed )
     {
         $self->sth_updateWhoSealed(
@@ -306,15 +434,15 @@ sub     updateWhoSealed
             ))
         );
     }
-    my  $blockid        =   $self->selectBlockhashByHash(    $blockhash  );
-    my  $sealerid       =   $self->selectAccountIdByAddress( $sealerhash );
+    my  $blockid                    =   $self->selectBlockhashByHash(    $blockhash  );
+    my  $sealerid                   =   $self->selectAccountIdByAddress( $sealerhash );
     $self->sth_updateWhoSealed->execute( $sealerid, $blockid );
 }
 
 __PACKAGE__->mk_accessors( 'sth_selectmaxunknownsigned' );
 sub     selectMaxUnknownSigned
 {
-    my      ( $self )       =   @_;
+    my      ( $self )               =   @_;
     if ( not defined $self->sth_selectmaxunknownsigned )
     {
         $self->sth_selectmaxunknownsigned(
@@ -330,12 +458,12 @@ sub     selectMaxUnknownSigned
         );
     }
     $self->sth_selectmaxunknownsigned->execute();
-    my      $ref            =   $self->sth_selectmaxunknownsigned->fetchrow_arrayref;
+    my      $ref                    =   $self->sth_selectmaxunknownsigned->fetchrow_arrayref;
     $self->sth_selectmaxunknownsigned->finish();
-    return if not defined $ref;
-    my      $blockid        =   $ref->[0];
-    my      $blockhash      =   $self->selectBlockhashById( $blockid );
-    return                      $blockhash;
+    return                              if not defined $ref;
+    my      $blockid                =   $ref->[0];
+    my      $blockhash              =   $self->selectBlockhashById( $blockid );
+    return                              $blockhash;
 }
 
 1;
diff --git a/docker-compose.yml b/docker-compose.yml
index ec74c3e876ec06e4f231d5e39eeaf132e378612b..b46eaec5ca0da61c9e4d0be0c6474e1f63bbfec4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,7 +12,7 @@ services:
     build: postgres
     restart: always
     environment:
-      POSTGRES_PASSWORD: onlythelonely
+      POSTGRES_PASSWORD: theswampthing
     volumes:
       - pgdata:/var/lib/postgresql/data
     ports:
@@ -22,8 +22,10 @@ services:
     build: collector
     restart: always
     environment:
-      POSTGRES_PASSWORD: onlythelonely
+      POSTGRES_PASSWORD: theswampthing
       BFANODE: http://200.108.146.200:8545/
+    volumes:
+      - ./collector:/home/bfa/collector
 
 #  adminer:
 #    image: adminer
diff --git a/postgres/10-postgres.sql b/postgres/10-postgres.sql
index 20fcab06cb209ef6d9f294a4cdd6ff68d95ef5c6..b58fe7ccbe6334eb6f4453564def524486c798ca 100644
--- a/postgres/10-postgres.sql
+++ b/postgres/10-postgres.sql
@@ -50,8 +50,8 @@ CREATE TABLE "public"."block" (
     "sealerAccountId"   bigint,
     "timestamp"         bigint      NOT NULL,
     "difficulty"        smallint    NOT NULL,
-    "gasUsed"           bigint      NOT NULL,
-    "gasLimit"          bigint      NOT NULL,
+    "gasUsed"           numeric(79)      NOT NULL,
+    "gasLimit"          numeric(79)      NOT NULL,
     "size"              bigint      NOT NULL,
     CONSTRAINT          "block_id"
         PRIMARY KEY     ("id"),
@@ -90,23 +90,22 @@ CREATE TABLE "public"."transaction" (
         NOT NULL,
     "nonce"             bigint
         NOT NULL,
-    "gas"               bigint
+    "gas"               numeric(79)
         NOT NULL,
-    "gasPrice"          bigint
+    "gasPrice"          numeric(79)
         NOT NULL,
-    "value"             bigint
+    "value"             numeric(79)
         NOT NULL,
     "fromAccountId"     bigint
         NOT NULL,
-    "toAccountId"       bigint
-        NOT NULL,
+    "toAccountId"       bigint,
     "contractaddressAccountId"
                         bigint,
     "status"            smallint
         NOT NULL,
-    "gasUsed"           bigint
+    "gasUsed"           numeric(79)
         NOT NULL,
-    "inputlen"          smallint
+    "inputlen"          integer
         NOT NULL,
     "input"             text
         NOT NULL,
@@ -162,6 +161,7 @@ CREATE VIEW             t
     AS
     SELECT              transaction.hash "transaction hash",
                         block.number "block number",
+			block.timestamp "block timestamp",
                         "type",
                         nonce,
                         gas,
diff --git a/postgres/90-add-db-user.sh b/postgres/90-add-db-user.sh
index f734ed5ebf72951ab0d1b1ed88118f1d66cadab8..87657edc7fc72f5dfe6f2797db240b667e59ecef 100755
--- a/postgres/90-add-db-user.sh
+++ b/postgres/90-add-db-user.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 
 psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
-	CREATE USER leer WITH PASSWORD 'bfa';
-        GRANT CONNECT ON DATABASE postgres TO leer;
-        GRANT SELECT ON ALL TABLES IN SCHEMA public TO leer;
-        GRANT UPDATE (shortname,name) ON TABLE public.account TO leer;
+	CREATE USER dgsi WITH PASSWORD 'bfa';
+        GRANT CONNECT ON DATABASE postgres TO dgsi;
+        GRANT SELECT ON ALL TABLES IN SCHEMA public TO dgsi;
+        GRANT UPDATE (shortname,name) ON TABLE public.account TO dgsi;
 EOSQL