Skip to content

Commit

Permalink
bolt2: coop-close channel between two nodes
Browse files Browse the repository at this point in the history
Signed-off-by: Vincenzo Palazzo <[email protected]>
  • Loading branch information
vincenzopalazzo committed Mar 15, 2022
1 parent ae3702c commit f202fb3
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 61 deletions.
1 change: 1 addition & 0 deletions lnprototest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
negotiated,
DualFundAccept,
Wait,
CloseChannel,
)
from .structure import Sequence, OneOf, AnyOrder, TryAll
from .runner import (
Expand Down
54 changes: 27 additions & 27 deletions lnprototest/clightning/clightning.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ def __init__(self, config: Any):
stdout=subprocess.PIPE,
check=True,
)
.stdout.decode("utf-8")
.splitlines()
.stdout.decode("utf-8")
.splitlines()
)
self.options: Dict[str, str] = {}
for o in opts:
Expand Down Expand Up @@ -232,12 +232,12 @@ def recv(self, event: Event, conn: Conn, outbuf: bytes) -> None:
raise EventError(event, "Connection closed")

def fundchannel(
self,
event: Event,
conn: Conn,
amount: int,
feerate: int = 253,
expect_fail: bool = False,
self,
event: Event,
conn: Conn,
amount: int,
feerate: int = 253,
expect_fail: bool = False,
) -> None:
"""
event - the event which cause this, for error logging
Expand All @@ -257,11 +257,11 @@ def fundchannel(
self.fundchannel_future = None

def _fundchannel(
runner: Runner,
conn: Conn,
amount: int,
feerate: int,
expect_fail: bool = False,
runner: Runner,
conn: Conn,
amount: int,
feerate: int,
expect_fail: bool = False,
) -> str:
peer_id = conn.pubkey.format().hex()
# Need to supply feerate here, since regtest cannot estimate fees
Expand All @@ -285,14 +285,14 @@ def _done(fut: Any) -> None:
self.cleanup_callbacks.append(self.kill_fundchannel)

def init_rbf(
self,
event: Event,
conn: Conn,
channel_id: str,
amount: int,
utxo_txid: str,
utxo_outnum: int,
feerate: int,
self,
event: Event,
conn: Conn,
channel_id: str,
amount: int,
utxo_txid: str,
utxo_outnum: int,
feerate: int,
) -> None:

if self.fundchannel_future:
Expand Down Expand Up @@ -365,7 +365,7 @@ def addhtlc(self, event: Event, conn: Conn, amount: int, preimage: str) -> None:
self.rpc.sendpay([routestep], payhash)

def get_output_message(
self, conn: Conn, event: Event, timeout: int = TIMEOUT
self, conn: Conn, event: Event, timeout: int = TIMEOUT
) -> Optional[bytes]:
fut = self.executor.submit(cast(CLightningConn, conn).connection.read_message)
try:
Expand All @@ -382,11 +382,11 @@ def check_error(self, event: Event, conn: Conn) -> Optional[str]:
return msg.hex()

def check_final_error(
self,
event: Event,
conn: Conn,
expected: bool,
must_not_events: List[MustNotMsg],
self,
event: Event,
conn: Conn,
expected: bool,
must_not_events: List[MustNotMsg],
) -> None:
if not expected:
# Inject raw packet to ensure it hangs up *after* processing all previous ones.
Expand Down
65 changes: 32 additions & 33 deletions lnprototest/dummyrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@


class DummyRunner(Runner):

def __init__(self, config: Any):
super().__init__(config)

Expand Down Expand Up @@ -87,12 +86,12 @@ def recv(self, event: Event, conn: Conn, outbuf: bytes) -> None:
print("[RECV {} {}]".format(event, outbuf.hex()))

def fundchannel(
self,
event: Event,
conn: Conn,
amount: int,
feerate: int = 253,
expect_fail: bool = False,
self,
event: Event,
conn: Conn,
amount: int,
feerate: int = 253,
expect_fail: bool = False,
) -> None:
if self.config.getoption("verbose"):
print(
Expand All @@ -102,14 +101,14 @@ def fundchannel(
)

def init_rbf(
self,
event: Event,
conn: Conn,
channel_id: str,
amount: int,
utxo_txid: str,
utxo_outnum: int,
feerate: int,
self,
event: Event,
conn: Conn,
channel_id: str,
amount: int,
utxo_txid: str,
utxo_outnum: int,
feerate: int,
) -> None:
if self.config.getoption("verbose"):
print(
Expand Down Expand Up @@ -144,21 +143,21 @@ def fake_field(ftype: FieldType) -> str:
if ftype.elemtype.name == "byte":
return "00" * ftype.arraysize
return (
"["
+ ",".join([DummyRunner.fake_field(ftype.elemtype)] * ftype.arraysize)
+ "]"
"["
+ ",".join([DummyRunner.fake_field(ftype.elemtype)] * ftype.arraysize)
+ "]"
)
elif ftype.name in (
"byte",
"u8",
"u16",
"u32",
"u64",
"tu16",
"tu32",
"tu64",
"bigsize",
"varint",
"byte",
"u8",
"u16",
"u32",
"u64",
"tu16",
"tu32",
"tu64",
"bigsize",
"varint",
):
return "0"
elif ftype.name in ("chain_hash", "channel_id", "sha256"):
Expand Down Expand Up @@ -201,11 +200,11 @@ def check_error(self, event: Event, conn: Conn) -> Optional[str]:
return "Dummy error"

def check_final_error(
self,
event: Event,
conn: Conn,
expected: bool,
must_not_events: List[MustNotMsg],
self,
event: Event,
conn: Conn,
expected: bool,
must_not_events: List[MustNotMsg],
) -> None:
pass

Expand Down
14 changes: 14 additions & 0 deletions lnprototest/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,20 @@ def action(self, runner: "Runner") -> bool:
return True


class CloseChannel(Event):
"""Implementing the lnprototest event related to the
close channel operation.
BOLT 2"""

def __init__(self, channel_id: str):
super(CloseChannel, self).__init__()
self.channel_id = channel_id

def action(self, runner: "Runner") -> bool:
super().action(runner)
return runner.close_channel(self.channel_id)


def msg_to_stash(runner: "Runner", event: Event, msg: Message) -> None:
"""ExpectMsg and Msg save every field to the stash, in order"""
fields = msg.to_py()
Expand Down
13 changes: 12 additions & 1 deletion tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import bitcoin.core
import coincurve
from typing import Tuple
from lnprototest import privkey_expand
from lnprototest import privkey_expand, KeySet

# Here are the keys to spend funds, derived from BIP32 seed
# `0000000000000000000000000000000000000000000000000000000000000001`:
Expand Down Expand Up @@ -134,3 +134,14 @@ def pubkey_of(privkey: str) -> str:
return (
coincurve.PublicKey.from_secret(privkey_expand(privkey).secret).format().hex()
)


def gen_random_keyset(counter: int = 20) -> KeySet:
"""Helper function to generate a random keyset with the possibility."""
return KeySet(
revocation_base_secret=f"{counter + 1}",
payment_base_secret=f"{counter + 2}",
htlc_base_secret=f"{counter + 3}",
delayed_payment_base_secret=f"{counter + 4}",
shachain_seed="00" * 32,
)
Loading

0 comments on commit f202fb3

Please sign in to comment.