htlcswitch+router: add onion error obfuscation

Within the network, it's important that when an HTLC forwarding failure
occurs, the recipient is notified in a timely manner in order to ensure
that errors are graceful and not unknown. For that reason with
accordance to BOLT №4 onion failure obfuscation have been added.
This commit is contained in:
Andrey Samokhvalov
2017-06-29 16:40:45 +03:00
committed by Olaoluwa Osuntokun
parent ef73062c14
commit 2d378b3280
13 changed files with 639 additions and 212 deletions

View File

@@ -376,10 +376,10 @@ func TestExitNodeTimelockPayloadMismatch(t *testing.T) {
n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry)
if err == nil {
t.Fatalf("payment should have failed but didn't")
} else if err.Error() != lnwire.UpstreamTimeout.String() {
} else if err.Error() != lnwire.CodeFinalIncorrectCltvExpiry.String() {
// TODO(roasbeef): use proper error after error propagation is
// in
t.Fatalf("incorrect error, expected insufficient value, "+
t.Fatalf("incorrect error, expected incorrect cltv expiry, "+
"instead have: %v", err)
}
}
@@ -413,7 +413,7 @@ func TestExitNodeAmountPayloadMismatch(t *testing.T) {
n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry)
if err == nil {
t.Fatalf("payment should have failed but didn't")
} else if err.Error() != lnwire.IncorrectValue.String() {
} else if err.Error() != lnwire.CodeIncorrectPaymentAmount.String() {
// TODO(roasbeef): use proper error after error propagation is
// in
t.Fatalf("incorrect error, expected insufficient value, "+
@@ -455,10 +455,8 @@ func TestLinkForwardTimelockPolicyMismatch(t *testing.T) {
// should be rejected due to a policy violation.
if err == nil {
t.Fatalf("payment should have failed but didn't")
} else if err.Error() != lnwire.UpstreamTimeout.String() {
// TODO(roasbeef): use proper error after error propagation is
// in
t.Fatalf("incorrect error, expected insufficient value, "+
} else if err.Error() != lnwire.CodeIncorrectCltvExpiry.String() {
t.Fatalf("incorrect error, expected incorrect cltv expiry, "+
"instead have: %v", err)
}
}
@@ -498,10 +496,10 @@ func TestLinkForwardFeePolicyMismatch(t *testing.T) {
// should be rejected due to a policy violation.
if err == nil {
t.Fatalf("payment should have failed but didn't")
} else if err.Error() != lnwire.IncorrectValue.String() {
} else if err.Error() != lnwire.CodeFeeInsufficient.String() {
// TODO(roasbeef): use proper error after error propagation is
// in
t.Fatalf("incorrect error, expected insufficient value, "+
t.Fatalf("incorrect error, expected fee insufficient, "+
"instead have: %v", err)
}
}
@@ -541,10 +539,10 @@ func TestLinkForwardMinHTLCPolicyMismatch(t *testing.T) {
// should be rejected due to a policy violation (below min HTLC).
if err == nil {
t.Fatalf("payment should have failed but didn't")
} else if err.Error() != lnwire.IncorrectValue.String() {
} else if err.Error() != lnwire.CodeAmountBelowMinimum.String() {
// TODO(roasbeef): use proper error after error propagation is
// in
t.Fatalf("incorrect error, expected insufficient value, "+
t.Fatalf("incorrect error, expected amount below minimum, "+
"instead have: %v", err)
}
}
@@ -633,7 +631,7 @@ func TestChannelLinkMultiHopInsufficientPayment(t *testing.T) {
btcutil.SatoshiPerBitcoin*5,
)
if err := n.start(); err != nil {
t.Fatalf("can't start three hop network: %v", err)
t.Fatalf("unable to start three hop network: %v", err)
}
defer n.stop()
@@ -656,7 +654,7 @@ func TestChannelLinkMultiHopInsufficientPayment(t *testing.T) {
n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock)
if err == nil {
t.Fatal("error haven't been received")
} else if err.Error() != errors.New(lnwire.InsufficientCapacity).Error() {
} else if err.Error() != errors.New(lnwire.CodeTemporaryChannelFailure).Error() {
t.Fatalf("wrong error have been received: %v", err)
}
@@ -702,7 +700,7 @@ func TestChannelLinkMultiHopUnknownPaymentHash(t *testing.T) {
btcutil.SatoshiPerBitcoin*5,
)
if err := n.start(); err != nil {
t.Fatalf("can't start three hop network: %v", err)
t.Fatalf("unable to start three hop network: %v", err)
}
defer n.stop()
@@ -733,13 +731,14 @@ func TestChannelLinkMultiHopUnknownPaymentHash(t *testing.T) {
// Check who is last in the route and add invoice to server registry.
if err := n.carolServer.registry.AddInvoice(invoice); err != nil {
t.Fatalf("can't add invoice in carol registry: %v", err)
t.Fatalf("unable to add invoice in carol registry: %v", err)
}
// Send payment and expose err channel.
_, err = n.aliceServer.htlcSwitch.SendHTLC(n.bobServer.PubKey(), htlc)
if err == nil {
t.Fatal("error wasn't received")
_, err = n.aliceServer.htlcSwitch.SendHTLC(n.bobServer.PubKey(), htlc,
newMockDeobfuscator())
if err.Error() != lnwire.CodeUnknownPaymentHash.String() {
t.Fatal("error haven't been received")
}
// Wait for Alice to receive the revocation.
@@ -802,7 +801,7 @@ func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) {
amount, htlcAmt, totalTimelock)
if err == nil {
t.Fatal("error haven't been received")
} else if err.Error() != errors.New(lnwire.UnknownDestination).Error() {
} else if err.Error() != lnwire.CodeUnknownNextPeer.String() {
t.Fatalf("wrong error have been received: %v", err)
}
@@ -848,14 +847,14 @@ func TestChannelLinkMultiHopDecodeError(t *testing.T) {
btcutil.SatoshiPerBitcoin*5,
)
if err := n.start(); err != nil {
t.Fatalf("can't start three hop network: %v", err)
t.Fatalf("unable to start three hop network: %v", err)
}
defer n.stop()
// Replace decode function with another which throws an error.
n.carolChannelLink.cfg.DecodeOnion = func(r io.Reader, meta []byte) (
HopIterator, error) {
return nil, errors.New("some sphinx decode error")
n.carolChannelLink.cfg.DecodeOnionObfuscator = func(
r io.Reader) (Obfuscator, lnwire.FailCode) {
return nil, lnwire.CodeInvalidOnionVersion
}
carolBandwidthBefore := n.carolChannelLink.Bandwidth()
@@ -871,7 +870,7 @@ func TestChannelLinkMultiHopDecodeError(t *testing.T) {
n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock)
if err == nil {
t.Fatal("error haven't been received")
} else if err.Error() != errors.New(lnwire.SphinxParseError).Error() {
} else if err.Error() != lnwire.CodeInvalidOnionVersion.String() {
t.Fatalf("wrong error have been received: %v", err)
}
@@ -994,7 +993,7 @@ func TestChannelLinkSingleHopMessageOrdering(t *testing.T) {
})
if err := n.start(); err != nil {
t.Fatalf("can't start three hop network: %v", err)
t.Fatalf("unable to start three hop network: %v", err)
}
defer n.stop()