Remove /explorer part from URL, blockbook status with external explorer

pull/56/head
Martin Boehm 2018-09-20 22:07:42 +02:00
parent 5f0b4e5c5a
commit 8ad6d1d52c
17 changed files with 95 additions and 90 deletions

View File

@ -44,7 +44,7 @@
"system_user": "blockbook-bcash",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,

View File

@ -44,7 +44,7 @@
"system_user": "blockbook-bcash",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,

View File

@ -239,7 +239,7 @@
"system_user": "blockbook-bgold",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "-dbmaxopenfiles=128",
"block_chain": {
"parse": true,

View File

@ -47,7 +47,7 @@
"system_user": "blockbook-bitcoin",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "-dbcache=1073741824",
"block_chain": {
"parse": true,

View File

@ -47,7 +47,7 @@
"system_user": "blockbook-bitcoin",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,

View File

@ -47,7 +47,7 @@
"system_user": "blockbook-zcash",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,

View File

@ -47,7 +47,7 @@
"system_user": "blockbook-zcash",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "/explorer",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,

View File

@ -79,7 +79,7 @@ Good examples of coin configuration are
* `system_user` User used to run Blockbook service. See convention note in [build guide](/docs/build.md#on-naming-conventions-and-versioning).
* `internal_binding_template` Template for *-internal* parameter. See note on templates below.
* `public_binding_template` Template for *-public* parameter. See note on templates below.
* `explorer_url` URL of blockchain explorer.
* `explorer_url` URL of blockchain explorer. Leave empty for internal explorer.
* `additional_params` Additional params of exec command (see [Dogecoin definition](configs/coins/dogecoin.json)).
* `block_chain` Configuration of BlockChain type that ensures communication with back-end service. All options
must be tweaked for each individual coin separely.

View File

@ -25,20 +25,21 @@ const txsInAPI = 1000
// PublicServer is a handle to public http server
type PublicServer struct {
binding string
certFiles string
socketio *SocketIoServer
https *http.Server
db *db.RocksDB
txCache *db.TxCache
chain bchain.BlockChain
chainParser bchain.BlockChainParser
api *api.Worker
explorerURL string
metrics *common.Metrics
is *common.InternalState
templates []*template.Template
debug bool
binding string
certFiles string
socketio *SocketIoServer
https *http.Server
db *db.RocksDB
txCache *db.TxCache
chain bchain.BlockChain
chainParser bchain.BlockChainParser
api *api.Worker
explorerURL string
internalExplorer bool
metrics *common.Metrics
is *common.InternalState
templates []*template.Template
debug bool
}
// NewPublicServer creates new public server http interface to blockbook and returns its handle
@ -63,19 +64,20 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch
}
s := &PublicServer{
binding: binding,
certFiles: certFiles,
https: https,
api: api,
socketio: socketio,
db: db,
txCache: txCache,
chain: chain,
chainParser: chain.GetChainParser(),
explorerURL: explorerURL,
metrics: metrics,
is: is,
debug: debugMode,
binding: binding,
certFiles: certFiles,
https: https,
api: api,
socketio: socketio,
db: db,
txCache: txCache,
chain: chain,
chainParser: chain.GetChainParser(),
explorerURL: explorerURL,
internalExplorer: explorerURL == "",
metrics: metrics,
is: is,
debug: debugMode,
}
s.templates = parseTemplates()
@ -106,15 +108,18 @@ func (s *PublicServer) ConnectFullPublicInterface() {
_, path := splitBinding(s.binding)
// support for tests of socket.io interface
serveMux.Handle(path+"test.html", http.FileServer(http.Dir("./static/")))
// redirect to wallet requests for tx and address, possibly to external site
serveMux.HandleFunc(path+"tx/", s.txRedirect)
serveMux.HandleFunc(path+"address/", s.addressRedirect)
// explorer
serveMux.HandleFunc(path+"explorer/tx/", s.htmlTemplateHandler(s.explorerTx))
serveMux.HandleFunc(path+"explorer/address/", s.htmlTemplateHandler(s.explorerAddress))
serveMux.HandleFunc(path+"explorer/search/", s.htmlTemplateHandler(s.explorerSearch))
serveMux.HandleFunc(path+"explorer/blocks", s.htmlTemplateHandler(s.explorerBlocks))
serveMux.HandleFunc(path+"explorer/block/", s.htmlTemplateHandler(s.explorerBlock))
if s.internalExplorer {
// internal explorer handlers
serveMux.HandleFunc(path+"tx/", s.htmlTemplateHandler(s.explorerTx))
serveMux.HandleFunc(path+"address/", s.htmlTemplateHandler(s.explorerAddress))
serveMux.HandleFunc(path+"search/", s.htmlTemplateHandler(s.explorerSearch))
serveMux.HandleFunc(path+"blocks", s.htmlTemplateHandler(s.explorerBlocks))
serveMux.HandleFunc(path+"block/", s.htmlTemplateHandler(s.explorerBlock))
} else {
// redirect to wallet requests for tx and address, possibly to external site
serveMux.HandleFunc(path+"tx/", s.txRedirect)
serveMux.HandleFunc(path+"address/", s.addressRedirect)
}
// API calls
serveMux.HandleFunc(path+"api/block-index/", s.jsonHandler(s.apiBlockIndex))
serveMux.HandleFunc(path+"api/tx/", s.jsonHandler(s.apiTx))
@ -147,17 +152,13 @@ func (s *PublicServer) OnNewTxAddr(txid string, addr string, isOutput bool) {
}
func (s *PublicServer) txRedirect(w http.ResponseWriter, r *http.Request) {
if s.explorerURL != "" {
http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302)
s.metrics.ExplorerViews.With(common.Labels{"action": "tx-redirect"}).Inc()
}
http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302)
s.metrics.ExplorerViews.With(common.Labels{"action": "tx-redirect"}).Inc()
}
func (s *PublicServer) addressRedirect(w http.ResponseWriter, r *http.Request) {
if s.explorerURL != "" {
http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302)
s.metrics.ExplorerViews.With(common.Labels{"action": "address-redirect"}).Inc()
}
http.Redirect(w, r, joinURL(s.explorerURL, r.URL.Path), 302)
s.metrics.ExplorerViews.With(common.Labels{"action": "address-redirect"}).Inc()
}
func splitBinding(binding string) (addr string, path string) {
@ -221,8 +222,9 @@ func (s *PublicServer) jsonHandler(handler func(r *http.Request) (interface{}, e
func (s *PublicServer) newTemplateData() *TemplateData {
return &TemplateData{
CoinName: s.is.Coin,
CoinShortcut: s.is.CoinShortcut,
CoinName: s.is.Coin,
CoinShortcut: s.is.CoinShortcut,
InternalExplorer: s.internalExplorer,
}
}
@ -296,19 +298,20 @@ const (
)
type TemplateData struct {
CoinName string
CoinShortcut string
Address *api.Address
AddrStr string
Tx *api.Tx
Error *api.ApiError
Blocks *api.Blocks
Block *api.Block
Info *api.SystemInfo
Page int
PrevPage int
NextPage int
PagingRange []int
CoinName string
CoinShortcut string
InternalExplorer bool
Address *api.Address
AddrStr string
Tx *api.Tx
Error *api.ApiError
Blocks *api.Blocks
Block *api.Block
Info *api.SystemInfo
Page int
PrevPage int
NextPage int
PagingRange []int
}
func parseTemplates() []*template.Template {
@ -453,20 +456,20 @@ func (s *PublicServer) explorerSearch(w http.ResponseWriter, r *http.Request) (t
if len(q) > 0 {
block, err = s.api.GetBlock(q, 0, 1)
if err == nil {
http.Redirect(w, r, joinURL("/explorer/block/", block.Hash), 302)
http.Redirect(w, r, joinURL("/block/", block.Hash), 302)
return noTpl, nil, nil
}
bestheight, _, err = s.db.GetBestBlock()
if err == nil {
tx, err = s.api.GetTransaction(q, bestheight, false)
if err == nil {
http.Redirect(w, r, joinURL("/explorer/tx/", tx.Txid), 302)
http.Redirect(w, r, joinURL("/tx/", tx.Txid), 302)
return noTpl, nil, nil
}
}
address, err = s.api.GetAddress(q, 0, 1, true)
if err == nil {
http.Redirect(w, r, joinURL("/explorer/address/", address.AddrStr), 302)
http.Redirect(w, r, joinURL("/address/", address.AddrStr), 302)
return noTpl, nil, nil
}
}

View File

@ -135,7 +135,7 @@ h3 {
.line-top {
border-top: 1px solid #EAEAEA;
padding: 15px 0 0;
padding: 10px 0 0;
}
.line-mid {
@ -157,6 +157,7 @@ h3 {
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
margin-top: 5px;
}
.txvalues:not(:last-child) {

View File

@ -2,8 +2,8 @@
<h1>Address
<small class="text-muted">{{formatAmount $addr.Balance}} {{$cs}}</small>
</h1>
<div class="alert alert-data">
<span class="ellipsis data">{{$addr.AddrStr}}</span>
<div class="alert alert-data ellipsis">
<span class="data">{{$addr.AddrStr}}</span>
</div>
<h3>Confirmed</h3>
<div class="data-div row">

View File

@ -14,8 +14,7 @@
<body>
<header id="header">
<div class="container">
<nav class="navbar navbar-expand-lg navbar-dark bg-trezor">
<!-- <a class="navbar-brand" href="#">Navbar w/ text</a> -->
<nav class="navbar navbar-expand navbar-dark bg-trezor">
<a class="navbar-brand" href="/" title="Home">
<div alt="TREZOR Wallet" class="trezor-logo-svg-white">
<svg width="100" height="42" version="1.1" id="logotyp" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 163.7 41.9" space="preserve">
@ -32,19 +31,21 @@
<span class="navbar-text ml-md-auto">
<a href="/" class="nav-link">{{.CoinName}} Explorer</a>
</span>
{{- if .InternalExplorer -}}
<ul class="navbar-nav flex-row ml-md-auto d-none d-lg-flex">
<li class="nav-item">
<a href="/explorer/blocks" class="nav-link">Blocks</a>
<a href="/blocks" class="nav-link">Blocks</a>
</li>
<li class="nav-item">
<a href="/" class="nav-link">Status</a>
</li>
</ul>
<span class="d-none ml-md-auto d-md-flex navbar-form navbar-left">
<form id="search" action="/explorer/search" method="get">
<form id="search" action="/search" method="get">
<input name="q" type="text" class="form-control" placeholder="Search for block, transaction or address" focus="true">
</form>
</span>
{{- end -}}
<ul class="navbar-nav flex-row ml-md-auto d-none d-lg-flex ">
<li class="nav-item">
<a href="https://trezor.io/" class="nav-link">TREZOR</a>

View File

@ -1,14 +1,14 @@
{{define "specific"}}{{$cs := .CoinShortcut}}{{$b := .Block}}{{$data := . -}}
<h1>Block {{$b.Height}}</h1>
<div class="alert alert-data">
<span class="ellipsis data">{{$b.Hash}}</span>
<div class="alert alert-data ellipsis">
<span class="data">{{$b.Hash}}</span>
</div>
<div class="h-container">
<h3 class="h-container-6">Summary</h3>
<nav class="h-container-6">
<ul class="pagination justify-content-end">
<li class="page-item">{{if $b.Prev}}<a class="page-link" href="/explorer/block/{{$b.Prev}}">Previous Block</a>{{else}}<span class="page-link text-muted disabled">Previous Block</span>{{end}}</li>
<li class="page-item">{{if $b.Next}}<a class="page-link" href="/explorer/block/{{$b.Next}}">Next Block</a>{{else}}<span class="page-link text-muted disabled">Next Block</span>{{end}}</li>
<li class="page-item">{{if $b.Prev}}<a class="page-link" href="/block/{{$b.Prev}}">Previous Block</a>{{else}}<span class="page-link text-muted disabled">Previous Block</span>{{end}}</li>
<li class="page-item">{{if $b.Next}}<a class="page-link" href="/block/{{$b.Next}}">Next Block</a>{{else}}<span class="page-link text-muted disabled">Next Block</span>{{end}}</li>
</ul>
</nav>
</div>

View File

@ -17,7 +17,7 @@
<tbody>
{{- range $b := $blocks.Blocks -}}
<tr>
<td><a href="/explorer/block/{{$b.Height}}">{{$b.Height}}</a></td>
<td><a href="/block/{{$b.Height}}">{{$b.Height}}</a></td>
<td>{{formatUnixTime $b.Time}}</td>
<td class="text-right">{{$b.Txs}}</td>
<td class="text-right">{{$b.Size}}</td>

View File

@ -29,7 +29,7 @@
</tr>
<tr>
<td>Last Block</td>
<td class="data"><a href="/explorer/block/{{$bb.BestHeight}}">{{$bb.BestHeight}}</a></td>
<td class="data">{{if .InternalExplorer}}<a href="/block/{{$bb.BestHeight}}">{{$bb.BestHeight}}</a>{{else}}{{$bb.BestHeight}}{{end}}</td>
</tr>
<tr>
<td>Last Block Update</td>

View File

@ -1,7 +1,7 @@
{{define "specific"}}{{$cs := .CoinShortcut}}{{$tx := .Tx}}
<h1>Transaction</h1>
<div class="alert alert-data">
<span class="ellipsis data">{{$tx.Txid}}</span>
<div class="alert alert-data ellipsis">
<span class="data">{{$tx.Txid}}</span>
</div>
<h3>Summary</h3>
<div class="data-div">

View File

@ -2,7 +2,7 @@
<div class="alert alert-data">
<div class="row line-bot">
<div class="col-xs-7 col-md-8 ellipsis">
<a href="/explorer/tx/{{$tx.Txid}}">{{$tx.Txid}}</a>
<a href="/tx/{{$tx.Txid}}">{{$tx.Txid}}</a>
</div>
{{- if $tx.Confirmations -}}
<div class="col-xs-5 col-md-4 text-muted text-right">mined {{formatUnixTime $tx.Blocktime}}</div>
@ -17,11 +17,11 @@
<tr>
<td>
{{- if $vin.Txid -}}
<a class="float-left text-muted" href="/explorer/tx/{{$vin.Txid}}" title="Outpoint {{$vin.Txid}},{{$vin.Vout}}">&nbsp;</a>
<a class="float-left text-muted" href="/tx/{{$vin.Txid}}" title="Outpoint {{$vin.Txid}},{{$vin.Vout}}">&nbsp;</a>
{{- end -}}
{{- range $a := $vin.Addresses -}}
<span class="ellipsis float-left">
{{if and (ne $a $addr) $vin.Searchable}}<a href="/explorer/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{end}}
{{if and (ne $a $addr) $vin.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{end}}
</span>
{{- else -}}
<span class="float-left">No Inputs (Newly Generated Coins)</span>
@ -53,13 +53,13 @@
<td>
{{- range $a := $vout.ScriptPubKey.Addresses -}}
<span class="ellipsis float-left">
{{- if and (ne $a $addr) $vout.ScriptPubKey.Searchable}}<a href="/explorer/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
{{- if and (ne $a $addr) $vout.ScriptPubKey.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
</span>
{{- else -}}
<span class="float-left">Unparsed address</span>
{{- end -}}
<span class="float-right{{if stringInSlice $addr $vout.ScriptPubKey.Addresses}} text-success{{end}}">
{{formatAmount $vout.Value}} {{$cs}} {{if $vout.Spent}}{{if $vout.SpentTxID}}<a class="text-danger" href="/explorer/tx/{{$vout.SpentTxID}}" title="Spent"></a>{{else}}<span class="text-danger" title="Spent"></span>{{end}}{{else -}}
{{formatAmount $vout.Value}} {{$cs}} {{if $vout.Spent}}{{if $vout.SpentTxID}}<a class="text-danger" href="/tx/{{$vout.SpentTxID}}" title="Spent"></a>{{else}}<span class="text-danger" title="Spent"></span>{{end}}{{else -}}
<span class="text-success" title="Unspent"> <b>×</b></span>
{{- end -}}
</span>