[bitcoin-dev] Advances in Bitcoin Contracting : Uniform Policy and Package Relay

2020-07-29 Thread Antoine Riard via bitcoin-dev
Hi list,

Security and operations of higher-layer protocols (vaults, LN, CoinJoin,
watchtowers, ...) come with different assumptions and demands with regards
to tx-relay and fee models. As the Bitcoin stack is quite young, it would
be great to make those ones more understood and what p2p/mempool changes we
might adopt at the base layer to better answer them. I would like to
explore this with my current post.

### Time-Sensitive Protocols Security-Model (you can skip this if you know
LN)

Lightning, the most deployed time-sensitive protocol as of now, relies on
the timely confirmations of some of its transactions to enforce its
security model. Like timing out an outgoing HTLC, claiming an incoming HTLC
or punishing a revoked commitment. Ensuring timely confirmation is
two-fold: a) propagating well-transactions across the network to quickly
hit miner mempools b) offering a competitive feerate to get in next coming
blocks.

Updating feerate just-in-time is quite challenging for LN as you can't
resign a commitment once your counterparty is non-responsive or malicious,
and thus any fee strategy assuming interactivity is closed. With current
constraints of maintaining a trustless chain of transactions (no
Parent-Pay-For-Child), the only option is a CPFP. Ongoing update of LN
protocol (anchor-outputs) will allow a channel participant to unilaterally
bump feerate of its commitment/HTLCs txn, assuming there is no
_adversarial_ network mempool conditions like a concurrent broadcast.

Beyond enforcing the need to secure its funds by bumping feerate, an
offchain user might be willingly to accelerate confirmation of a broadcast
for liquidity management in face of mempool-congestion. This issue is
likely shared by any multi-party protocol like Coinjoins where resigning is
painful and a party may have different liquidity preferences than other
participants and would like to express them in an unilateral fee bumping.

### Effective Transaction Propagation and Uniform Relay Policy

Even before competing on feerate, the first and foremost point of the
laid-out security model was the well-propagation of transactions across the
p2p network. Its effectiveness is determined by compliance to 1) consensus
rules 2) policy rules. This second set is a tighter one governing different
aspects of your transactions (like size, output type, feerate,
ancestors/descendants, ...) and introduced to sanitize the p2p network
against a wide scope of resources abuses (RBF bandwidth waste, package
evaluation CPU DoS, economic nonsense outputs, ...)

These rules diverge across implementations/versions and a subset of them
can be tightened or relaxed by node operators. This heterogeneity is
actually where the risk is scored for higher protocols, your LN's full-node
might be connected to tx-relay peers with more constraining policies than
yours and thus will always reject your time-sensitive transactions,
silently breaking security of your channels [0].

Of course, LN protocols devs have always been aware of these issues and
carefully reflect policies enforcement in their codebase. That said an
important subset of them aren't documented or even standardized and thus
hard to incorporate in upper layers specs. Testing them in a black box
approach (i.e `testmempoolaccept`) before production doesn't work as your
broadcast has to be valid against the union of your yet-unknown tx-relay
topology, further static checks are blurred with dynamic ones (the feerate
now is different than the one at a future broadcast), and your transaction
might be malleate by your counterparty (like a ridiculous feerate).

And the other side, AFAIK, Core developers have always acknowledged these
issues and been really conscientious when updating such API policy. The
concerning change with protocol like LN is the severity consequences in
case of incompatible changes. Previously, your basic transaction would have
been rejected by the network and your application could have been updated
before successfully rebroadcasting. Now, such changes potentially outlawing
your time-sensitive broadcasts is a direct, measurable risk of fund loss,
either triggered by mempool-congestion or exploited by a malicious
counterparty.

Therefore, moving towards such stable tx-relay/bumping API, I propose:
a) Identifying and documenting the subset of policy rules on which upper
layers have to rely on to enforce their security model
b) Guaranteeing backward-compatibility of those rules or, in case of
tightening change, making sure there is ecosystem coordination with some
minimal warning period (1 release ?)

Committing to a uniform policy would be a philosophical change, it would
ossify some parts of full-node implementations. Another side-effect means
that upper layer devs would be incentivized to rely on such stable API. In
case of new DoS on the base layer, we might have to tighten them in a short
timeline at the price of breaking some offchain applications [1] On the
other side, full-node operators 

[bitcoin-dev] Minsc, a Miniscript-based scripting language

2020-07-29 Thread Nadav Ivgi via bitcoin-dev
Hi all,

I recently released Minsc, a high-level scripting language for expressing
Bitcoin Script spending conditions using a simple and familiar syntax.

Minsc is based on the Miniscript Policy language, with additional features
and syntactic sugar sprinkled on top, including variables, functions, infix
notation, human-readable times and more.

A live compiler (Minsc->Policy->Miniscript->Script) and documentation are
available on the website: https://min.sc

Source code (in Rust) is available on github:
https://github.com/shesek/minsc

Some example Minsc scripts:

- A user and a 2FA service need to sign off, but after 90 days the user
alone is enough

  pk(user_pk) && (9@pk(service_pk) || older(90 days))

- Traditional preimage-based HTLC

  $redeem = pk(A) && sha256(H);
  $refund = pk(B) && older(10);

  likely@$redeem || $refund

- Liquid-like federated pegin with emergency recovery keys

  $federation = 4 of [ pk(A), pk(B), pk(C), pk(D), pk(E) ];
  $recovery = 2 of [ pk(F), pk(G), pk(H) ];
  $timeout = older(heightwise 2 weeks);

  likely@$federation || ($timeout && $recovery)

- The BOLT #3 received HTLC policy

  fn htlc_received($revoke_pk, $local_pk, $remote_pk, $secret, $delay) {
$success = pk($local_pk) && hash160($secret);
$timeout = older($delay);

pk($revoke_pk) || (pk($remote_pk) && ($success || $timeout))
  }

  htlc_received(A, B, C, H, 3 hours)

- 2FA where the user has a 2-of-2 setup and the service provider is a
3-of-4 federation

  fn two_factor($user, $provider, $delay) =
$user && (likely@$provider || older($delay));

  $user = pk(user_desktop) && pk(user_mobile);
  $providers = [ pk(P1), pk(P2), pk(P3), pk(P4) ];

  two_factor($user, 3 of $providers, 4 months)

- Easily add NSA backdoors to everything ️

  _backdoor=pk(usgovt), _pk=pk, _older=older, _after=after,
  _sha256=sha256, _ripemd160=ripemd160;

  fn pk(x) = _pk(x) || _backdoor;
  fn older(x) = _older(x) || _backdoor;
  fn after(x) = _after(x) || _backdoor;
  fn sha256(x) = _sha256(x) || _backdoor;
  fn ripemd160(x) = _ripemd160(x) || _backdoor;

  (pk(A) && sha256(H)) || (pk(B) && older(10))

Feedback is appreciated!

Nadav

P.S Since every Miniscript Policy is also a valid Minsc expression, the
min.sc web code editor UI could also be useful for experimenting with bare
policies. You'll get syntax highlighting, parentheses matching, real-time
compilation (in a web worker so the browser doesn't freeze) and syntax
error reporting.
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev