-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
fiatjaf
committed
Aug 12, 2020
0 parents
commit f8e3023
Showing
11 changed files
with
766 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dist/* | ||
trustedcoin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dist: $(shell find . -name "*.go") | ||
mkdir -p dist | ||
gox -ldflags="-s -w" -tags="full" -osarch="darwin/amd64 linux/386 linux/amd64 linux/arm freebsd/amd64" -output="dist/trustedcoin_{{.OS}}_{{.Arch}}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
## The `trustedcoin` plugin | ||
|
||
A plugin that uses block explorers (blockstream.info, mempool.space, blockchair.com and blockchain.info) as backends instead of your own Bitcoin node. | ||
|
||
This isn't what you should be doing, but sometimes you may need it. | ||
|
||
(Remember this will download all blocks c-lightning needs from blockchain.info or blockchair.com in raw, hex format.) | ||
|
||
## How to install | ||
|
||
This is distributed as a single binary for your delight (or you can compile it yourself with `go get`, or ask me for binaries for other systems if you need them). | ||
|
||
[Download it](https://github.com/fiatjaf/trustedcoin/releases), call `chmod +x <binary>` and put it in `~/.lightning/plugins` (create that directory if it doesn't exist). | ||
|
||
You only need the binary you can get in [the releases page](https://github.com/fiatjaf/trustedcoin/releases), nothing else. | ||
|
||
Then add the following line to your `~/.lightning/config` file: | ||
|
||
``` | ||
disable-plugin=bcli | ||
``` | ||
|
||
This disables the default Bitcoin backend plugin so `trustedcoin` can take its place. | ||
|
||
### Extra: how to bootstrap a Lightning node from scratch, without Bitcoin Core, on Ubuntu amd64 | ||
|
||
``` | ||
add-apt-repository ppa:lightningnetwork/ppa | ||
apt update | ||
apt install lightningd | ||
mkdir -p ~/.lightning/plugins | ||
echo 'disable-plugin=bcli' >> .lightning/config | ||
cd ~/.lightning/plugins | ||
wget https://github.com/fiatjaf/lightningd-gjson-rpc/releases/download/trustedcoin-v0.2.4/trustedcoin_linux_amd64 | ||
chmod +x trustedcoin_linux_amd64 | ||
cd | ||
lightningd | ||
``` | ||
|
||
## Built with [](https://godoc.org/github.com/fiatjaf/lightningd-gjson-rpc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"net/http" | ||
) | ||
|
||
type EstimatedFees struct { | ||
Opening *int `json:"opening"` | ||
MutualClose *int `json:"mutual_close"` | ||
UnilateralClose *int `json:"unilateral_close"` | ||
DelayedToUs *int `json:"delayed_to_us"` | ||
HTLCResolution *int `json:"htlc_resolution"` | ||
Penalty *int `json:"penalty"` | ||
MinAcceptable *int `json:"min_acceptable"` | ||
MaxAcceptable *int `json:"max_acceptable"` | ||
} | ||
|
||
func getFeeRatesFromEsplora() (feerates map[string]float64, err error) { | ||
for _, endpoint := range esploras() { | ||
w, errW := http.Get(endpoint + "/fee-estimates") | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
defer w.Body.Close() | ||
|
||
if w.StatusCode >= 300 { | ||
err = errors.New(endpoint + " error: " + w.Status) | ||
return | ||
} | ||
|
||
err = json.NewDecoder(w.Body).Decode(&feerates) | ||
return | ||
} | ||
|
||
err = errors.New("none of the esploras returned usable responses") | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/hex" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/btcsuite/btcd/chaincfg/chainhash" | ||
"github.com/btcsuite/btcutil" | ||
) | ||
|
||
var heightCache = make(map[int64]string) | ||
|
||
func getBlock(height int64) (block, hash string, err error) { | ||
hash, err = getHash(height) | ||
if err != nil { | ||
return | ||
} | ||
if hash == "" /* block unavailable */ { | ||
return | ||
} | ||
|
||
for _, try := range []func(string) (string, error){ | ||
blockFromBlockchainInfo, | ||
blockFromBlockchair, | ||
} { | ||
blockhex, errW := try(hash) | ||
if errW != nil || blockhex == "" { | ||
err = errW | ||
continue | ||
} | ||
|
||
// verify and hash | ||
blockbytes, errW := hex.DecodeString(blockhex) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
|
||
blockparsed, errW := btcutil.NewBlockFromBytes(blockbytes) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
header := blockparsed.MsgBlock().Header | ||
|
||
blockhash := hex.EncodeToString(reverseHash(blockparsed.Hash())) | ||
if blockhash != hash { | ||
err = fmt.Errorf("fetched block hash %s doesn't match expected %s", | ||
blockhash, hash) | ||
continue | ||
} | ||
|
||
prevHash := hex.EncodeToString(header.PrevBlock[:]) | ||
if cachedPrevHash, ok := heightCache[height-1]; ok { | ||
if prevHash != cachedPrevHash { | ||
// something is badly wrong with this block | ||
err = fmt.Errorf("block %d (%s): prev block hash %d (%s) doesn't match what we know from previous block %d (%s)", height, blockhash, height-1, prevHash, height-1, cachedPrevHash) | ||
continue | ||
} | ||
} | ||
|
||
delete(heightCache, height) | ||
return blockhex, hash, nil | ||
} | ||
|
||
return | ||
} | ||
|
||
func getHash(height int64) (hash string, err error) { | ||
for _, endpoint := range esploras() { | ||
w, errW := http.Get(fmt.Sprintf(endpoint+"/block-height/%d", height)) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
defer w.Body.Close() | ||
|
||
if w.StatusCode >= 404 { | ||
continue | ||
} | ||
|
||
data, errW := ioutil.ReadAll(w.Body) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
|
||
hash = strings.TrimSpace(string(data)) | ||
|
||
if len(hash) > 64 { | ||
err = errors.New("got something that isn't a block hash: " + hash[:64]) | ||
continue | ||
} | ||
|
||
heightCache[height] = hash | ||
|
||
return hash, nil | ||
} | ||
|
||
return "", err | ||
} | ||
|
||
func blockFromBlockchainInfo(hash string) (string, error) { | ||
w, err := http.Get(fmt.Sprintf("https://blockchain.info/block/%s?format=hex", hash)) | ||
if err != nil { | ||
return "", fmt.Errorf("failed to get raw block %s from blockchain.info: %s", hash, err.Error()) | ||
} | ||
defer w.Body.Close() | ||
|
||
block, _ := ioutil.ReadAll(w.Body) | ||
if len(block) < 100 { | ||
// block not available here yet | ||
return "", nil | ||
} | ||
|
||
return string(block), nil | ||
} | ||
|
||
func blockFromBlockchair(hash string) (string, error) { | ||
w, err := http.Get("https://api.blockchair.com/bitcoin/raw/block/" + hash) | ||
if err != nil { | ||
return "", fmt.Errorf("failed to get raw block %s from blockchair.com: %s", hash, err.Error()) | ||
} | ||
defer w.Body.Close() | ||
|
||
var data struct { | ||
Data map[string]struct { | ||
RawBlock string `json:"raw_block"` | ||
} `json:"data"` | ||
} | ||
err = json.NewDecoder(w.Body).Decode(&data) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
if bdata, ok := data.Data[hash]; ok { | ||
return bdata.RawBlock, nil | ||
} else { | ||
// block not available here yet | ||
return "", nil | ||
} | ||
} | ||
|
||
func reverseHash(hash *chainhash.Hash) []byte { | ||
r := make([]byte, chainhash.HashSize) | ||
for i, b := range hash { | ||
r[chainhash.HashSize-i-1] = b | ||
} | ||
return r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package main | ||
|
||
import ( | ||
"io/ioutil" | ||
"net/http" | ||
"strconv" | ||
) | ||
|
||
func getTip() (tip int64, err error) { | ||
for _, endpoint := range esploras() { | ||
w, errW := http.Get(endpoint + "/blocks/tip/height") | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
defer w.Body.Close() | ||
|
||
data, errW := ioutil.ReadAll(w.Body) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
|
||
tip, errW = strconv.ParseInt(string(data), 10, 64) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
|
||
return tip, nil | ||
} | ||
|
||
return 0, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
) | ||
|
||
type UTXOResponse struct { | ||
Amount *int64 `json:"amount"` | ||
Script *string `json:"script"` | ||
} | ||
|
||
func getTransaction(txid string) (tx struct { | ||
TXID string `json:"txid"` | ||
Vout []struct { | ||
ScriptPubKey string `json:"scriptPubKey"` | ||
Value int64 `json:"value"` | ||
} `json:"vout"` | ||
}, err error) { | ||
for _, endpoint := range esploras() { | ||
w, errW := http.Get(endpoint + "/tx/" + txid) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
defer w.Body.Close() | ||
|
||
errW = json.NewDecoder(w.Body).Decode(&tx) | ||
if errW != nil { | ||
err = errW | ||
continue | ||
} | ||
|
||
return tx, nil | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module github.com/fiatjaf/trustedcoin | ||
|
||
go 1.14 | ||
|
||
require ( | ||
github.com/btcsuite/btcd v0.20.1-beta.0.20200515232429-9f0179fd2c46 | ||
github.com/btcsuite/btcutil v1.0.2 | ||
github.com/fiatjaf/lightningd-gjson-rpc v1.0.1 | ||
) |
Oops, something went wrong.