routing: return full htlc attempt from router
This commit is contained in:
parent
cc37485432
commit
674c199047
@ -318,25 +318,30 @@ func (s *Server) SendToRoute(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
preimage, err := s.cfg.Router.SendToRoute(hash, route)
|
// Pass route to the router. This call returns the full htlc attempt
|
||||||
|
// information as it is stored in the database. It is possible that both
|
||||||
// In the success case, return the preimage.
|
// the attempt return value and err are non-nil. This can happen when
|
||||||
if err == nil {
|
// the attempt was already initiated before the error happened. In that
|
||||||
return &SendToRouteResponse{
|
// case, we give precedence to the attempt information as stored in the
|
||||||
Preimage: preimage[:],
|
// db.
|
||||||
}, nil
|
attempt, err := s.cfg.Router.SendToRoute(hash, route)
|
||||||
}
|
if attempt != nil {
|
||||||
|
rpcAttempt, err := s.cfg.RouterBackend.MarshalHTLCAttempt(
|
||||||
// In the failure case, marshall the failure message to the rpc format
|
*attempt,
|
||||||
// before returning it to the caller.
|
)
|
||||||
rpcErr, err := marshallError(err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SendToRouteResponse{
|
resp := &SendToRouteResponse{
|
||||||
Failure: rpcErr,
|
Preimage: rpcAttempt.Preimage,
|
||||||
}, nil
|
Failure: rpcAttempt.Failure,
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetMissionControl clears all mission control state and starts with a clean
|
// ResetMissionControl clears all mission control state and starts with a clean
|
||||||
|
@ -1741,10 +1741,12 @@ func (r *ChannelRouter) preparePayment(payment *LightningPayment) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendToRoute attempts to send a payment with the given hash through the
|
// SendToRoute attempts to send a payment with the given hash through the
|
||||||
// provided route. This function is blocking and will return the obtained
|
// provided route. This function is blocking and will return the attempt
|
||||||
// preimage if the payment is successful or the full error in case of a failure.
|
// information as it is stored in the database. For a successful htlc, this
|
||||||
|
// information will contain the preimage. If an error occurs after the attempt
|
||||||
|
// was initiated, both return values will be non-nil.
|
||||||
func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, rt *route.Route) (
|
func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, rt *route.Route) (
|
||||||
lntypes.Preimage, error) {
|
*channeldb.HTLCAttempt, error) {
|
||||||
|
|
||||||
// Calculate amount paid to receiver.
|
// Calculate amount paid to receiver.
|
||||||
amt := rt.ReceiverAmt()
|
amt := rt.ReceiverAmt()
|
||||||
@ -1774,7 +1776,7 @@ func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, rt *route.Route) (
|
|||||||
|
|
||||||
// Any other error is not tolerated.
|
// Any other error is not tolerated.
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return [32]byte{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Tracef("Dispatching SendToRoute for hash %v: %v",
|
log.Tracef("Dispatching SendToRoute for hash %v: %v",
|
||||||
@ -1804,34 +1806,37 @@ func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, rt *route.Route) (
|
|||||||
hash, channeldb.FailureReasonError,
|
hash, channeldb.FailureReasonError,
|
||||||
)
|
)
|
||||||
if controlErr != nil {
|
if controlErr != nil {
|
||||||
return [32]byte{}, controlErr
|
return nil, controlErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In any case, don't continue if there is an error.
|
// In any case, don't continue if there is an error.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lntypes.Preimage{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var htlcAttempt *channeldb.HTLCAttempt
|
||||||
switch {
|
switch {
|
||||||
// Failed to launch shard.
|
// Failed to launch shard.
|
||||||
case outcome.err != nil:
|
case outcome.err != nil:
|
||||||
shardError = outcome.err
|
shardError = outcome.err
|
||||||
|
htlcAttempt = outcome.attempt
|
||||||
|
|
||||||
// Shard successfully launched, wait for the result to be available.
|
// Shard successfully launched, wait for the result to be available.
|
||||||
default:
|
default:
|
||||||
result, err := sh.collectResult(attempt)
|
result, err := sh.collectResult(attempt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lntypes.Preimage{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got a successful result.
|
// We got a successful result.
|
||||||
if result.err == nil {
|
if result.err == nil {
|
||||||
return result.attempt.Settle.Preimage, nil
|
return result.attempt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The shard failed, break switch to handle it.
|
// The shard failed, break switch to handle it.
|
||||||
shardError = result.err
|
shardError = result.err
|
||||||
|
htlcAttempt = result.attempt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since for SendToRoute we won't retry in case the shard fails, we'll
|
// Since for SendToRoute we won't retry in case the shard fails, we'll
|
||||||
@ -1848,10 +1853,10 @@ func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, rt *route.Route) (
|
|||||||
|
|
||||||
err = r.cfg.Control.Fail(hash, *reason)
|
err = r.cfg.Control.Fail(hash, *reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lntypes.Preimage{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return lntypes.Preimage{}, shardError
|
return htlcAttempt, shardError
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendPayment attempts to send a payment to the passed payment hash. This
|
// sendPayment attempts to send a payment to the passed payment hash. This
|
||||||
|
@ -2809,13 +2809,13 @@ func TestSendToRouteMultiShardSend(t *testing.T) {
|
|||||||
|
|
||||||
for i := 0; i < numShards; i++ {
|
for i := 0; i < numShards; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
preimg, err := ctx.router.SendToRoute(payment, rt)
|
attempt, err := ctx.router.SendToRoute(payment, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
successes <- preimg
|
successes <- attempt.Settle.Preimage
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3978,10 +3978,15 @@ func (r *rpcServer) dispatchPaymentIntent(
|
|||||||
payment,
|
payment,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
preImage, routerErr = r.server.chanRouter.SendToRoute(
|
var attempt *channeldb.HTLCAttempt
|
||||||
|
attempt, routerErr = r.server.chanRouter.SendToRoute(
|
||||||
payIntent.rHash, payIntent.route,
|
payIntent.rHash, payIntent.route,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if routerErr == nil {
|
||||||
|
preImage = attempt.Settle.Preimage
|
||||||
|
}
|
||||||
|
|
||||||
route = payIntent.route
|
route = payIntent.route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user