diff --git a/README.md b/README.md index 622d9dd..d1e7f84 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,66 @@ # Siona -This is Siona, a maximum privacy block explorer designed for chains which support zaddrs -and which runs explorer.hush.is and explorer.hush.land. - -It is written in Perl 5 and generates static HTML with no Javascript and basic inline CSS for styling. It requires a Redis server +This is Siona, a maximum privacy block explorer designed for chains which support zaddrs. It is written in Perl 5 and generates static HTML with no Javascript and basic inline CSS for styling. It requires a Redis server running on localhost, which is for caching and reduces disk i/o. -# Installing dependencies +Siona runs on the following private blockchains: + +- explorer.hush.is +- explorer.hush.land +- explorer.dragonx.is + +# Install dependencies on Debian/Ubuntu + +Install redis-server and cpan: + +``` +sudo apt-get install redis-server +sudo apt-get install libpath-tiny-perl +``` + +Install JSON::Any.pm and Redis.pm Perl modules: +``` +sudo cpan install JSON::Any.pm +sudo cpan install Redis.pm +``` + +# Git clone + +Move to the root directory of the Explorer, it must be empty. + +``` +cd /var/www/dragonx.hush.land +git clone https://git.hush.is/hush/siona.git . +``` -Requires JSON::Any and Redis Perl modules and redis-server an Debian package. +# First time run and update -On Debian 11, install by running `sudo apt install redis libjson-perl libredis-perl` +``` +CLI=/root/hush3/src/hush-cli DIR=/var/www/dragonx.hush.land/api DOMAIN=dragonx.hush.land ARRAKIS=DRAGONX ./run_siona.sh +``` -Please contribute back package names for other Linux distros. +### Need support? -# Instructions +* Matrix: https://hush.is/matrix +* Telegram: https://hush.is/tg -Assume you put `update.sh` in /home/$USER and your Hush source code in ~/git/hush3 , add this to your $USER crontab with `crontab -e` : +# Update Explorer every 5 minutes with cron ``` -# set env vars that Siona will use -SIONA_DOMAIN=explorer.some.poop -SIONA_ACNAME=GAZOOTZ -SIONA_CLI=~/git/hush3/src/hush-cli -ac_NAME=${SIONA_ACNAME} +ARRAKIS=DRAGONX + +DOMAIN=dragonx.hush.land + +CLI=/root/hush3/src/hush-cli + +DIR=/var/www/dragonx.hush.land/api -# update explorer data every 5 minutes -*/5 * * * * ~/update.sh +*/5 * * * * cd /var/www/$DOMAIN && ./run_siona.sh ``` # Copyright -2016-2022 The Hush Developers +2016-2024 The Hush Developers # License diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/address/template.html b/address/template.html similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/address/template.html rename to address/template.html diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/addresses/template.html b/addresses/template.html similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/addresses/template.html rename to addresses/template.html diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/anonset.json b/api/anonset.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/anonset.json rename to api/anonset.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/coinsupply.json b/api/coinsupply.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/coinsupply.json rename to api/coinsupply.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/getblockchain.json b/api/getblockchain.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/getblockchain.json rename to api/getblockchain.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintips.json b/api/getchaintips.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintips.json rename to api/getchaintips.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintxstats.json b/api/getchaintxstats.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/getchaintxstats.json rename to api/getchaintxstats.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/getinfo.json b/api/getinfo.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/getinfo.json rename to api/getinfo.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/getmininginfo.json b/api/getmininginfo.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/getmininginfo.json rename to api/getmininginfo.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/gettxoutsetinfo.json b/api/gettxoutsetinfo.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/gettxoutsetinfo.json rename to api/gettxoutsetinfo.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/index.html b/api/index.html similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/index.html rename to api/index.html diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot-old.json b/api/snapshots/snapshot-old.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot-old.json rename to api/snapshots/snapshot-old.json diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot.json b/api/snapshots/snapshot.json similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/api/snapshots/snapshot.json rename to api/snapshots/snapshot.json diff --git a/var/www/explorer.hush.land/bin/HOWTO b/bin/HOWTO similarity index 100% rename from var/www/explorer.hush.land/bin/HOWTO rename to bin/HOWTO diff --git a/var/www/explorer.hush.land/bin/Makefile b/bin/Makefile similarity index 100% rename from var/www/explorer.hush.land/bin/Makefile rename to bin/Makefile diff --git a/var/www/explorer.hush.land/bin/backup/update_blocks_redis.pl b/bin/backup/update_blocks_redis.pl similarity index 100% rename from var/www/explorer.hush.land/bin/backup/update_blocks_redis.pl rename to bin/backup/update_blocks_redis.pl diff --git a/var/www/explorer.hush.land/bin/balances.pl b/bin/balances.pl similarity index 100% rename from var/www/explorer.hush.land/bin/balances.pl rename to bin/balances.pl diff --git a/var/www/explorer.hush.land/bin/block-340k.json b/bin/block-340k.json similarity index 100% rename from var/www/explorer.hush.land/bin/block-340k.json rename to bin/block-340k.json diff --git a/var/www/explorer.hush.land/bin/update_blocks_redis.pl b/bin/blocks_update.pl old mode 100644 new mode 100755 similarity index 82% rename from var/www/explorer.hush.land/bin/update_blocks_redis.pl rename to bin/blocks_update.pl index de6829d..f4745df --- a/var/www/explorer.hush.land/bin/update_blocks_redis.pl +++ b/bin/blocks_update.pl @@ -15,17 +15,14 @@ my $j = JSON::Any->new; #sleep 10; # While Siona swims, we pave with bricks on the road she will run on... -my $acname = $ENV{SIONA_ACNAME} || 'HUSH'; -my $ticker = $acname eq 'HUSH3' ? 'HUSH' : $acname; -my $domain = $ENV{SIONA_DOMAIN} || 'explorer.hush.land'; -my $root = "/var/www/$domain"; -my $basedir = "/var/www/$domain/var/www/$domain"; -my $dir = shift || "$basedir/api"; -my $cli = $ENV{SIONA_CLI} || "/home/hush/git/hush3/src/hush-cli"; +my $domain = $ENV{DOMAIN}; +my $cli = $ENV{CLI}; +my $arrakis = $ENV{ARRAKIS}; +my $dir = $ENV{DIR}; my $getinfo = readfile("$dir/getinfo.json"); my $mining = readfile("$dir/getmininginfo.json"); -my $blocksdir = "$basedir/blocks"; -my $template = readfile("$blocksdir/template.html"); +my $template = readfile("/var/www/$domain/blocks/template.html"); +my $blocksdir = "/var/www/$domain/blocks/"; if($getinfo =~ m/"blocks": (\d+)/){ $STATS->{BLOCKS} ||= $1; } if($getinfo =~ m/"tls_connections": (\d+)/){ $STATS->{TLS_CONNECTIONS} ||= $1; } if($getinfo =~ m/"connections": (\d+)/){ $STATS->{CONNECTIONS} ||= $1; } @@ -40,13 +37,12 @@ $STATS->{BLOCKS_TABLE} = ""; $STATS->{TX_TABLE} = ""; my $mineraddress = ""; -for my $h ($height-80 .. $height) { +for my $h ($height-50 .. $height) { #for my $h (910265 .. 910270) { #last if($h < 0); my $thisminer = ""; - # TODO: actually look at the block reward for this height via - # the tx data from the very first txid in this block - my $reward = $h > 340000 ? "3.125 $ticker" : "12.5 $ticker"; + # TODO: fix this garbage + my $reward = $h > 340000 ? "3.125 HUSH" : "12.5 HUSH"; my $block = get_block($h); #die Dumper $block; my $time = $block->{time}; @@ -54,13 +50,14 @@ for my $h ($height-80 .. $height) { my @txs = @{ $block->{tx} }; my $numtx = @txs; # TODO: look on filesystem first? redis cache? - my $hash = qx!$cli getblockhash $h!; + my $hash = qx!$cli -ac_name=$arrakis getblockhash $h!; chomp $hash; - my $blockdir = "$root/var/www/$domain/block/$hash"; + my $root = "/var/www/$domain"; + my $blockdir = "$root/block/$hash"; if (!-e "$root/block/$h") { # make /block/HEIGHT work - my $cmd = "ln -s $blockdir $root/var/www/$domain/block/$h"; + my $cmd = "ln -s $blockdir $root/block/$h"; qx{$cmd}; warn $cmd; } @@ -69,8 +66,8 @@ for my $h ($height-80 .. $height) { my $cmd = "mkdir -p $blockdir"; qx{$cmd}; warn $cmd; - my $block_template_file = "$basedir/block/template.html"; - my $new_block_file = "$blockdir/index.html"; + my $block_template_file = "/var/www/$domain/block/template.html"; + my $new_block_file = "/var/www/$domain/block/$hash/index.html"; # TODO: process template with block details my $block_template = readfile($block_template_file); $block_template =~ s/#BLOCKS#/$h/g; @@ -84,9 +81,8 @@ for my $h ($height-80 .. $height) { $block_template =~ s/#CHAINWORK#/$block->{chainwork}/ge; $block_template =~ s/#MERKLEROOT#/$block->{merkleroot}/ge; $block_template =~ s/#FINALSAPLINGROOT#/$block->{finalsaplingroot}/ge; - # TODO: fix block reward - my $blockreward = "3.125 $ticker"; - $block_template =~ s/#BLOCKREWARD#/$blockreward/g; + # TODO + $block_template =~ s/#BLOCKREWARD#/3.125 HUSH/g; $block_template =~ s/#BLOCKNONCE#/$block->{nonce}/ge; $block_template =~ s/#DIFFICULTY#/$block->{difficulty}/ge; $block_template =~ s/#NUM_TXS#/$numtx/g; @@ -100,7 +96,7 @@ HTML my $txi = 0; for my $tx (@txs) { - my $json = qx!$cli getrawtransaction $tx 1!; + my $json = qx!$cli -ac_name=$arrakis getrawtransaction $tx 1!; # "vout": 0, # "address": "RBHHGTQoULWb8gPD6Nj4fix6ov46hzzQMj", # address is duplicated in the JSON of getrawtransaction !! fuck. @@ -122,9 +118,9 @@ HTML next if $@; $TX->{$tx} = $o; - my $tx_dir = "$root/var/www/$domain/tx/$tx"; - my $tx_file = "$root/var/www/$domain/tx/$tx/index.html"; - my $tx_template_file = "$root/var/www/$domain/tx/template.html"; + my $tx_dir = "$root/tx/$tx"; + my $tx_file = "$root/tx/$tx/index.html"; + my $tx_template_file = "$root/tx/template.html"; my $tx_template = readfile($tx_template_file); my $txtime = localtime($o->{time}); #my $txsize = $o->{size} . " bytes"; @@ -242,7 +238,7 @@ STUFF } elsif ($txtype eq "Shielding") { $stuff =< zs1??? (shielding) +$from ($valueBalanceThird HUSH) => zs1??? (shielding) STUFF } elsif ($txtype eq "Notary") { @@ -279,7 +275,7 @@ STUFF $stuff $txtime -$valueBalance $ticker +$valueBalance HUSH HTML @@ -318,9 +314,48 @@ HTML ; } +my $total_block_duration = 0; +for my $duration (@block_durations) { + if ($duration ne '--') { + $total_block_duration += $duration; + } +} + +$avg_block_duration = $total_block_duration / $NUM_BLOCKS_TO_SHOW; + +if ($avg_block_duration > 0) { + $avg_block_duration = sprintf "%.2f", $avg_block_duration; + my $blocktime = 75; # please Satoshi let this never change again + my $deviation = 100*($avg_block_duration / $blocktime); + my $word = ($avg_block_duration > $blocktime) ? "above" : "below"; + if ($word eq 'above') { $deviation -= 100; } + if ($word eq 'below') { $deviation -= 100; } + + $word .= "!" if ($deviation >= 20); + + my $num_miners = keys %unique_miners; + + my $longblock_multiplier = sprintf "%.2f", $longest_blocktime / $avg_block_duration; + + $deviation = sprintf "%.2f", $deviation; + my $tx_per_block = sprintf("%.2f", $total_txs / $NUM_BLOCKS_TO_SHOW); + $STATS->{BLOCKS_STATS} =< +Block Stats in the last $NUM_BLOCKS_TO_SHOW blocks +Average Blocktime$avg_block_duration sec +Blocktime Deviation $deviation% $word 75 sec +Longest Blocktime $longest_blocktime sec (${longblock_multiplier}X average) +Total Transactions $total_txs +Transactions Per Block $tx_per_block +Unique Miner Addresses $num_miners + +
+STATS +} + sub get_raw { my $tx = shift; - my $cmd = "$cli getrawtransaction $tx 1"; + my $cmd = "$cli -ac_name=$arrakis getrawtransaction $tx 1"; warn $cmd; my $json = qx!$cmd!; # "vout": 0, @@ -383,7 +418,7 @@ sub get_block { # create data if it's not there if( $block =~ m/^HASH/ || length($block) == 0 ) { - my $cmd = "$cli getblock $height"; + my $cmd = "$cli -ac_name=$arrakis getblock $height"; warn $cmd; $block = qx/$cmd/; } @@ -411,4 +446,4 @@ sub readfile { } close($fh); return $data; -} +} \ No newline at end of file diff --git a/var/www/explorer.hush.land/bin/example.html b/bin/example.html similarity index 100% rename from var/www/explorer.hush.land/bin/example.html rename to bin/example.html diff --git a/var/www/explorer.hush.land/bin/update.pl b/bin/home_update.pl old mode 100644 new mode 100755 similarity index 90% rename from var/www/explorer.hush.land/bin/update.pl rename to bin/home_update.pl index 4962080..751a508 --- a/var/www/explorer.hush.land/bin/update.pl +++ b/bin/home_update.pl @@ -9,14 +9,14 @@ $|=1; sleep 30; # While Siona swims, we pave with bricks on the road she will run on... -# my $dir = shift || $ENV{HOME} . "/data"; -my $dir = shift || '/var/www/explorer.hush.land/var/www/explorer.hush.land/api'; +my $domain = $ENV{DOMAIN}; +my $dir = $ENV{DIR}; my $getinfo = readfile("$dir/getinfo.json"); my $mining = readfile("$dir/getmininginfo.json"); my $txstats = readfile("$dir/getchaintxstats.json"); # run the slowest last so the RPC interface isn't juggling my $coinsupply = readfile("$dir/coinsupply.json"); -my $template = readfile("/var/www/explorer.hush.land/var/www/explorer.hush.land/template.html"); +my $template = readfile("/var/www/$domain/template.html"); #say $template; @@ -71,4 +71,4 @@ sub readfile { return $data; } # "connections": 48, -# "tls_connections": 28, +# "tls_connections": 28, \ No newline at end of file diff --git a/var/www/explorer.hush.land/bin/nope/README b/bin/nope/README similarity index 100% rename from var/www/explorer.hush.land/bin/nope/README rename to bin/nope/README diff --git a/var/www/explorer.hush.land/bin/nope/update_addresses.pl b/bin/nope/update_addresses.pl similarity index 100% rename from var/www/explorer.hush.land/bin/nope/update_addresses.pl rename to bin/nope/update_addresses.pl diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/block/template.html b/block/template.html similarity index 100% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/block/template.html rename to block/template.html diff --git a/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html b/blocks/template.html similarity index 99% rename from var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html rename to blocks/template.html index b96747f..aac029d 100644 --- a/var/www/explorer.hush.land/var/www/explorer.hush.land/blocks/template.html +++ b/blocks/template.html @@ -66,6 +66,7 @@ a:hover { color: #b3b3b3 } Team +#BLOCKS_STATS# #BLOCKS_TABLE#