Skip to content

Commit

Permalink
use trustedcoin in integration test, and fix estimatefees and bitcoin…
Browse files Browse the repository at this point in the history
…-datadir errors
  • Loading branch information
1ma authored and fiatjaf committed Nov 12, 2024
1 parent 6df4ea9 commit d76c4c0
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__pycache__/
dist/
trustedcoin
venv/
venv/
14 changes: 13 additions & 1 deletion estimatefees.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,19 @@ type FeeRate struct {
FeeRate int `json:"feerate"`
}

func getFeeRates() (*EstimatedFees, error) {
func getFeeRates(network string) (*EstimatedFees, error) {
if network == "regtest" {
return &EstimatedFees{
FeeRateFloor: 1000,
FeeRates: []FeeRate{
{Blocks: 2, FeeRate: 1000},
{Blocks: 6, FeeRate: 1000},
{Blocks: 12, FeeRate: 1000},
{Blocks: 100, FeeRate: 1000},
},
}, nil
}

// try bitcoind first
if bitcoind != nil {
in2, err2 := bitcoind.EstimateSmartFee(2, &btcjson.EstimateModeConservative)
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/1ma/lightningd-gjson-rpc v0.0.0-20241109130140-ddc6991a26cf h1:4QFQcuL5Fks+WRI+BSrgTxGoJxNUM/Ht8YCgQRoKcDY=
github.com/1ma/lightningd-gjson-rpc v0.0.0-20241109130140-ddc6991a26cf/go.mod h1:DqVHlrgk0q0J08nbPBCwDVuB7vzPohRnrzuGZ0ct0fg=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
Expand Down
40 changes: 10 additions & 30 deletions integration_test.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,31 @@
from pyln.client import RpcError
from pyln.testing.fixtures import *
from pyln.testing.utils import wait_for

def test_bcli(node_factory, bitcoind, chainparams):
"""
This tests the bcli plugin, used to gather Bitcoin data from a local
bitcoind.
Mostly sanity checks of the interface...
Based on the test_bcli from Core Lightning
"""

l1 = node_factory.get_node()
l2 = node_factory.get_node()
node = node_factory.get_node(opts={
"disable-plugin": "bcli",
"plugin": os.path.join(os.getcwd(), 'trustedcoin'),
})

# We cant stop it dynamically
with pytest.raises(RpcError):
l1.rpc.plugin_stop("bcli")
node.rpc.plugin_stop("bcli")

# Failure case of feerate is tested in test_misc.py
estimates = l1.rpc.call("estimatefees")
estimates = node.rpc.call("estimatefees")
assert 'feerate_floor' in estimates
assert [f['blocks'] for f in estimates['feerates']] == [2, 6, 12, 100]

resp = l1.rpc.call("getchaininfo", {"last_height": 0})
resp = node.rpc.call("getchaininfo", {"last_height": 0})
assert resp["chain"] == chainparams['name']
for field in ["headercount", "blockcount", "ibd"]:
assert field in resp

# We shouldn't get upset if we ask for an unknown-yet block
resp = l1.rpc.call("getrawblockbyheight", {"height": 500})
resp = node.rpc.call("getrawblockbyheight", {"height": 500})
assert resp["blockhash"] is resp["block"] is None
resp = l1.rpc.call("getrawblockbyheight", {"height": 50})
resp = node.rpc.call("getrawblockbyheight", {"height": 50})
assert resp["blockhash"] is not None and resp["blockhash"] is not None
# Some other bitcoind-failure cases for this call are covered in
# tests/test_misc.py

l1.fundwallet(10**5)
l1.connect(l2)
fc = l1.rpc.fundchannel(l2.info["id"], 10**4 * 3)
txo = l1.rpc.call("getutxout", {"txid": fc['txid'], "vout": fc['outnum']})
assert (Millisatoshi(txo["amount"]) == Millisatoshi(10**4 * 3 * 10**3)
and txo["script"].startswith("0020"))
l1.rpc.close(l2.info["id"])
# When output is spent, it should give us null !
wait_for(lambda: l1.rpc.call("getutxout", {
"txid": fc['txid'],
"vout": fc['outnum']
})['amount'] is None)

resp = l1.rpc.call("sendrawtransaction", {"tx": "dummy", "allowhighfees": False})
assert not resp["success"] and "decode failed" in resp["errmsg"]
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func main() {
{Name: "bitcoin-rpcport", Type: "string", Description: "Port to bitcoind RPC (optional).", Default: ""},
{Name: "bitcoin-rpcuser", Type: "string", Description: "Username to bitcoind RPC (optional).", Default: ""},
{Name: "bitcoin-rpcpassword", Type: "string", Description: "Password to bitcoind RPC (optional).", Default: ""},
{Name: "bitcoin-datadir", Type: "string", Description: "-datadir arg for bitcoin-cli. For compatibility with bcli, not actually used.", Default: ""},
},
RPCMethods: []plugin.RPCMethod{
{
Expand Down Expand Up @@ -131,7 +132,7 @@ func main() {
Description: "Get the Bitcoin feerate in sat/kilo-vbyte.",
LongDescription: "",
Handler: func(p *plugin.Plugin, params plugin.Params) (resp any, errCode int, err error) {
estfees, err := getFeeRates()
estfees, err := getFeeRates(p.Network)
if err != nil {
p.Logf("estimatefees error: %s", err.Error())
estfees = &EstimatedFees{}
Expand Down
6 changes: 3 additions & 3 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
const executable = "./trustedcoin"

const getManifestRequest = `{"jsonrpc":"2.0","id":"getmanifest","method":"getmanifest","params":{}}`
const getManifestExpectedResponse = `{"jsonrpc":"2.0","id":"getmanifest","result":{"options":[{"name":"bitcoin-rpcconnect","type":"string","default":"","description":"Hostname (IP) to bitcoind RPC (optional)."},{"name":"bitcoin-rpcport","type":"string","default":"","description":"Port to bitcoind RPC (optional)."},{"name":"bitcoin-rpcuser","type":"string","default":"","description":"Username to bitcoind RPC (optional)."},{"name":"bitcoin-rpcpassword","type":"string","default":"","description":"Password to bitcoind RPC (optional)."}],"rpcmethods":[{"name":"getrawblockbyheight","usage":"height","description":"Get the bitcoin block at a given height","long_description":""},{"name":"getchaininfo","usage":"","description":"Get the chain id, the header count, the block count and whether this is IBD.","long_description":""},{"name":"estimatefees","usage":"","description":"Get the Bitcoin feerate in sat/kilo-vbyte.","long_description":""},{"name":"sendrawtransaction","usage":"tx","description":"Send a raw transaction to the Bitcoin network.","long_description":""},{"name":"getutxout","usage":"txid vout","description":"Get informations about an output, identified by a {txid} an a {vout}","long_description":""}],"subscriptions":[],"hooks":[],"featurebits":{"features":"","channel":"","init":"","invoice":""},"dynamic":false,"notifications":[]}}`
const getManifestExpectedResponse = `{"jsonrpc":"2.0","id":"getmanifest","result":{"options":[{"name":"bitcoin-rpcconnect","type":"string","default":"","description":"Hostname (IP) to bitcoind RPC (optional)."},{"name":"bitcoin-rpcport","type":"string","default":"","description":"Port to bitcoind RPC (optional)."},{"name":"bitcoin-rpcuser","type":"string","default":"","description":"Username to bitcoind RPC (optional)."},{"name":"bitcoin-rpcpassword","type":"string","default":"","description":"Password to bitcoind RPC (optional)."},{"name":"bitcoin-datadir","type":"string","default":"","description":"-datadir arg for bitcoin-cli. For compatibility with bcli, not actually used."}],"rpcmethods":[{"name":"getrawblockbyheight","usage":"height","description":"Get the bitcoin block at a given height","long_description":""},{"name":"getchaininfo","usage":"","description":"Get the chain id, the header count, the block count and whether this is IBD.","long_description":""},{"name":"estimatefees","usage":"","description":"Get the Bitcoin feerate in sat/kilo-vbyte.","long_description":""},{"name":"sendrawtransaction","usage":"tx","description":"Send a raw transaction to the Bitcoin network.","long_description":""},{"name":"getutxout","usage":"txid vout","description":"Get informations about an output, identified by a {txid} an a {vout}","long_description":""}],"subscriptions":[],"hooks":[],"featurebits":{"features":"","channel":"","init":"","invoice":""},"dynamic":false,"notifications":[]}}`

const initRequest = `{"jsonrpc":"2.0","id":"init","method":"init","params":{"options":{},"configuration":{"network":"bitcoin","lightning-dir":"/tmp","rpc-file":"foo"}}}`
const initExpectedResponse = `{"jsonrpc":"2.0","id":"init"}`
Expand All @@ -36,12 +36,12 @@ func start(t *testing.T) (*exec.Cmd, io.WriteCloser, io.ReadCloser, io.ReadClose

_, _ = io.WriteString(stdin, getManifestRequest)
if response := readline(stdout); response != getManifestExpectedResponse {
t.Fatalf("unexpected RPC response: %s", response)
t.Fatalf("unexpected manifest response: %s", response)
}

_, _ = io.WriteString(stdin, initRequest)
if response := readline(stdout); response != initExpectedResponse {
t.Fatalf("unexpected RPC response: %s", response)
t.Fatalf("unexpected init response: %s", response)
}

if response := readline(stderr); !strings.Contains(response, "initialized plugin") {
Expand Down

0 comments on commit d76c4c0

Please sign in to comment.