Repository: lightningnetwork/lnd
Pull request #3493 (2019-09-12 10:22:36)

routing: track amt ranges in mission control
Previously we tracked the last result for a node connection only. This could lead to the situation where a meaningful observation would be overwritten by a far less meaningful one. For example: a failure for 100.000 sats is overwritten by a success for 100 sats.

Besides better route selection in general, this also helps with building the bos node score list.

Probing with minimal amounts in particular will likely wipe out useful history for more representative amounts.

This PR changes mission control to track both that the success and the last failure. This creates three amount ranges for which probabilities are calculated differently:
- `<=successAmt`: return a high probability (default 0.95)
- `successAmt+1` to `failAmt-1`: in this range, we don't have much information. Return the a priori (default 0.6)
- `>=failAmt`: penalize the connection and decay over time back to the a priori

Roasbeef: Can be rebased now that the dependent PR is merged. 

Patch:
diff --git a/cmd/lncli/cmd_query_mission_control.go b/cmd/lncli/cmd_query_mission_control.go
index 2b1b99e21..a35c2bb85 100644
--- a/cmd/lncli/cmd_query_mission_control.go
+++ b/cmd/lncli/cmd_query_mission_control.go
@@ -32,10 +32,10 @@ func queryMissionControl(ctx *cli.Context) error {
 	}
 
 	type displayPairHistory struct {
-		NodeFrom, NodeTo      string
-		LastAttemptSuccessful bool
-		Timestamp             int64
-		MinPenalizeAmtSat     int64
+		NodeFrom, NodeTo              string
+		SuccessTime, FailTime         int64
+		FailAmtSat, FailAmtMsat       int64
+		SuccessAmtSat, SuccessAmtMsat int64
 	}
 
 	displayResp := struct {
@@ -46,11 +46,14 @@ func queryMissionControl(ctx *cli.Context) error {
 		displayResp.Pairs = append(
 			displayResp.Pairs,
 			displayPairHistory{
-				NodeFrom:              hex.EncodeToString(n.NodeFrom),
-				NodeTo:                hex.EncodeToString(n.NodeTo),
-				LastAttemptSuccessful: n.History.LastAttemptSuccessful,
-				Timestamp:             n.History.Timestamp,
-				MinPenalizeAmtSat:     n.History.MinPenalizeAmtSat,
+				NodeFrom:       hex.EncodeToString(n.NodeFrom),
+				NodeTo:         hex.EncodeToString(n.NodeTo),
+				FailTime:       n.History.FailTime,
+				SuccessTime:    n.History.SuccessTime,
+				FailAmtSat:     n.History.FailAmtSat,
+				FailAmtMsat:    n.History.FailAmtMsat,
+				SuccessAmtSat:  n.History.SuccessAmtSat,
+				SuccessAmtMsat: n.History.SuccessAmtMsat,
 			},
 		)
 	}
diff --git a/lnrpc/routerrpc/router.pb.go b/lnrpc/routerrpc/router.pb.go
index e8216f17d..38ddbcc6a 100644
--- a/lnrpc/routerrpc/router.pb.go
+++ b/lnrpc/routerrpc/router.pb.go
@@ -1157,15 +1157,25 @@ func (m *PairHistory) GetHistory() *PairData {
 }
 
 type PairData struct {
-	/// Time stamp of last result.
-	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
-	/// Minimum penalization amount (only applies to failed attempts).
-	MinPenalizeAmtSat int64 `protobuf:"varint,2,opt,name=min_penalize_amt_sat,proto3" json:"min_penalize_amt_sat,omitempty"`
-	/// Whether the last payment attempt through this pair was successful.
-	LastAttemptSuccessful bool     `protobuf:"varint,3,opt,name=last_attempt_successful,proto3" json:"last_attempt_successful,omitempty"`
-	XXX_NoUnkeyedLiteral  struct{} `json:"-"`
-	XXX_unrecognized      []byte   `json:"-"`
-	XXX_sizecache         int32    `json:"-"`
+	/// Time of last failure.
+	FailTime int64 `protobuf:"varint,1,opt,name=fail_time,proto3" json:"fail_time,omitempty"`
+	//*
+	//Lowest amount that failed to forward rounded to whole sats. This may be
+	//set to zero if the failure is independent of amount.
+	FailAmtSat int64 `protobuf:"varint,2,opt,name=fail_amt_sat,proto3" json:"fail_amt_sat,omitempty"`
+	//*
+	//Lowest amount that failed to forward in millisats. This may be
+	//set to zero if the failure is independent of amount.
+	FailAmtMsat int64 `protobuf:"varint,4,opt,name=fail_amt_msat,proto3" json:"fail_amt_msat,omitempty"`
+	/// Time of last success.
+	SuccessTime int64 `protobuf:"varint,5,opt,name=success_time,proto3" json:"success_time,omitempty"`
+	/// Highest amount that we could successfully forward rounded to whole sats.
+	SuccessAmtSat int64 `protobuf:"varint,6,opt,name=success_amt_sat,proto3" json:"success_amt_sat,omitempty"`
+	/// Highest amount that we could successfully forward in millisats.
+	SuccessAmtMsat       int64    `protobuf:"varint,7,opt,name=success_amt_msat,proto3" json:"success_amt_msat,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
 }
 
 func (m *PairData) Reset()         { *m = PairData{} }
@@ -1193,25 +1203,46 @@ func (m *PairData) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_PairData proto.InternalMessageInfo
 
-func (m *PairData) GetTimestamp() int64 {
+func (m *PairData) GetFailTime() int64 {
 	if m != nil {
-		return m.Timestamp
+		return m.FailTime
+	}
+	return 0
+}
+
+func (m *PairData) GetFailAmtSat() int64 {
+	if m != nil {
+		return m.FailAmtSat
 	}
 	return 0
 }
 
-func (m *PairData) GetMinPenalizeAmtSat() int64 {
+func (m *PairData) GetFailAmtMsat() int64 {
 	if m != nil {
-		return m.MinPenalizeAmtSat
+		return m.FailAmtMsat
 	}
 	return 0
 }
 
-func (m *PairData) GetLastAttemptSuccessful() bool {
+func (m *PairData) GetSuccessTime() int64 {
 	if m != nil {
-		return m.LastAttemptSuccessful
+		return m.SuccessTime
 	}
-	return false
+	return 0
+}
+
+func (m *PairData) GetSuccessAmtSat() int64 {
+	if m != nil {
+		return m.SuccessAmtSat
+	}
+	return 0
+}
+
+func (m *PairData) GetSuccessAmtMsat() int64 {
+	if m != nil {
+		return m.SuccessAmtMsat
+	}
+	return 0
 }
 
 type QueryProbabilityRequest struct {
@@ -1465,132 +1496,133 @@ func init() {
 func init() { proto.RegisterFile("routerrpc/router.proto", fileDescriptor_7a0613f69d37b0a5) }
 
 var fileDescriptor_7a0613f69d37b0a5 = []byte{
-	// 1993 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x58, 0x4f, 0x73, 0x1a, 0xc9,
-	0x15, 0xdf, 0x11, 0x20, 0xe0, 0x01, 0xd2, 0xa8, 0xa5, 0x95, 0xc7, 0x48, 0x5a, 0x6b, 0xc7, 0x8e,
-	0x57, 0xe5, 0xf2, 0x4a, 0x8e, 0x52, 0xbb, 0xe5, 0xda, 0x43, 0x52, 0x18, 0x86, 0xd5, 0xc8, 0x30,
-	0xc8, 0x0d, 0x78, 0xd7, 0xd9, 0x43, 0x57, 0x0b, 0x5a, 0x62, 0x4a, 0xc3, 0x0c, 0x3b, 0xd3, 0x38,
-	0x56, 0x3e, 0x43, 0x72, 0xcd, 0x57, 0x48, 0x0e, 0xc9, 0x29, 0xdf, 0x29, 0xa9, 0xca, 0x3d, 0xf7,
-	0x54, 0x77, 0xcf, 0xc0, 0x80, 0x90, 0x36, 0x27, 0xa6, 0x7f, 0xef, 0x75, 0xbf, 0xee, 0xf7, 0xe7,
-	0xd7, 0xaf, 0x81, 0xdd, 0x30, 0x98, 0x72, 0x16, 0x86, 0x93, 0xc1, 0x89, 0xfa, 0x3a, 0x9e, 0x84,
-	0x01, 0x0f, 0x50, 0x71, 0x86, 0x57, 0x8b, 0xe1, 0x64, 0xa0, 0x50, 0xf3, 0x3f, 0x59, 0x40, 0x5d,
-	0xe6, 0x0f, 0x2f, 0xe8, 0xed, 0x98, 0xf9, 0x1c, 0xb3, 0x9f, 0xa7, 0x2c, 0xe2, 0x08, 0x41, 0x76,
-	0xc8, 0x22, 0x6e, 0x68, 0x87, 0xda, 0x51, 0x19, 0xcb, 0x6f, 0xa4, 0x43, 0x86, 0x8e, 0xb9, 0xb1,
-	0x76, 0xa8, 0x1d, 0x65, 0xb0, 0xf8, 0x44, 0x8f, 0xa1, 0x40, 0xc7, 0x9c, 0x8c, 0x23, 0xca, 0x8d,
-	0xb2, 0x84, 0xf3, 0x74, 0xcc, 0xdb, 0x11, 0xe5, 0xe8, 0x4b, 0x28, 0x4f, 0xd4, 0x92, 0x64, 0x44,
-	0xa3, 0x91, 0x91, 0x91, 0x0b, 0x95, 0x62, 0xec, 0x8c, 0x46, 0x23, 0x74, 0x04, 0xfa, 0x95, 0xeb,
-	0x53, 0x8f, 0x0c, 0x3c, 0xfe, 0x91, 0x0c, 0x99, 0xc7, 0xa9, 0x91, 0x3d, 0xd4, 0x8e, 0x72, 0x78,
-	0x43, 0xe2, 0x75, 0x8f, 0x7f, 0x6c, 0x08, 0x14, 0x7d, 0x05, 0x9b, 0xc9, 0x62, 0xa1, 0xda, 0xa0,
-	0x91, 0x3b, 0xd4, 0x8e, 0x8a, 0x78, 0x63, 0xb2, 0xb8, 0xed, 0xaf, 0x60, 0x93, 0xbb, 0x63, 0x16,
-	0x4c, 0x39, 0x89, 0xd8, 0x20, 0xf0, 0x87, 0x91, 0xb1, 0xae, 0x56, 0x8c, 0xe1, 0xae, 0x42, 0x91,
-	0x09, 0x95, 0x2b, 0xc6, 0x88, 0xe7, 0x8e, 0x5d, 0x4e, 0xc4, 0xf6, 0xf3, 0x72, 0xfb, 0xa5, 0x2b,
-	0xc6, 0x5a, 0x02, 0xeb, 0x52, 0x8e, 0x9e, 0xc1, 0xc6, 0x5c, 0x47, 0x9e, 0xb1, 0x22, 0x95, 0xca,
-	0x89, 0x92, 0x3c, 0xe8, 0x4b, 0xd0, 0x83, 0x29, 0xbf, 0x0e, 0x5c, 0xff, 0x9a, 0x0c, 0x46, 0xd4,
-	0x27, 0xee, 0xd0, 0x28, 0x1c, 0x6a, 0x47, 0xd9, 0x37, 0x6b, 0xaf, 0x34, 0xbc, 0x91, 0xc8, 0xea,
-	0x23, 0xea, 0xdb, 0x43, 0xf4, 0x1c, 0x36, 0x3d, 0x1a, 0x71, 0x32, 0x0a, 0x26, 0x64, 0x32, 0xbd,
-	0xbc, 0x61, 0xb7, 0xc6, 0x86, 0xf4, 0x4c, 0x45, 0xc0, 0x67, 0xc1, 0xe4, 0x42, 0x82, 0xe8, 0x00,
-	0x40, 0x7a, 0x45, 0x1a, 0x37, 0x8a, 0xf2, 0x0c, 0x45, 0x81, 0x48, 0xc3, 0xe8, 0x14, 0x4a, 0x32,
-	0x9a, 0x64, 0xe4, 0xfa, 0x3c, 0x32, 0xe0, 0x30, 0x73, 0x54, 0x3a, 0xd5, 0x8f, 0x3d, 0x5f, 0x04,
-	0x16, 0x0b, 0xc9, 0x99, 0xeb, 0x73, 0x9c, 0x56, 0x42, 0x16, 0x14, 0x44, 0x18, 0x09, 0xf7, 0x3e,
-	0x1a, 0x25, 0x39, 0xe1, 0xc5, 0xf1, 0x2c, 0x25, 0x8e, 0xef, 0xe6, 0xc0, 0x71, 0x83, 0x45, 0xbc,
-	0xe7, 0x7d, 0xb4, 0x7c, 0x1e, 0xde, 0xe2, 0xfc, 0x50, 0x8d, 0xaa, 0xdf, 0x41, 0x39, 0x2d, 0x10,
-	0x59, 0x21, 0x4e, 0x21, 0x12, 0x25, 0x8b, 0xc5, 0x27, 0xda, 0x81, 0xdc, 0x47, 0xea, 0x4d, 0x99,
-	0xcc, 0x94, 0x32, 0x56, 0x83, 0xef, 0xd6, 0x5e, 0x6b, 0xe6, 0x6b, 0xd8, 0xee, 0x85, 0x74, 0x70,
-	0xb3, 0x94, 0x6c, 0xcb, 0xb9, 0xa2, 0xdd, 0xc9, 0x15, 0xf3, 0x6f, 0x1a, 0x54, 0xe2, 0x59, 0x5d,
-	0x4e, 0xf9, 0x34, 0x42, 0x5f, 0x43, 0x2e, 0xe2, 0x94, 0x33, 0xa9, 0xbd, 0x71, 0xfa, 0x28, 0x75,
-	0x96, 0x94, 0x22, 0xc3, 0x4a, 0x0b, 0x55, 0xa1, 0x30, 0x09, 0x99, 0x3b, 0xa6, 0xd7, 0xc9, 0xbe,
-	0x66, 0x63, 0x64, 0x42, 0x4e, 0x4e, 0x96, 0x49, 0x5a, 0x3a, 0x2d, 0xa7, 0xfd, 0x88, 0x95, 0x08,
-	0x1d, 0x41, 0x6e, 0xc4, 0xbd, 0x41, 0x64, 0x64, 0xa5, 0xeb, 0x50, 0xac, 0x73, 0xd6, 0x6b, 0xd5,
-	0x6b, 0x9c, 0xb3, 0xf1, 0x84, 0x63, 0xa5, 0x60, 0xfe, 0x16, 0x36, 0xe5, 0xcc, 0x26, 0x63, 0x0f,
-	0x55, 0xd3, 0x23, 0x10, 0xb5, 0x22, 0x73, 0x4f, 0x55, 0xd4, 0x3a, 0x1d, 0x8b, 0xb4, 0x33, 0x87,
-	0xa0, 0xcf, 0xe7, 0x47, 0x93, 0xc0, 0x8f, 0x84, 0x75, 0x5d, 0x6c, 0x43, 0xe4, 0x98, 0x48, 0x49,
-	0x99, 0x8c, 0x9a, 0x9c, 0xb5, 0x11, 0xe3, 0x4d, 0xc6, 0x64, 0x3a, 0x3e, 0x57, 0x15, 0x40, 0xbc,
-	0x60, 0x70, 0x23, 0x6a, 0x8a, 0xde, 0xc6, 0xcb, 0x57, 0x04, 0xdc, 0x0a, 0x06, 0x37, 0x0d, 0x01,
-	0x9a, 0x3f, 0xa9, 0xb2, 0xef, 0x05, 0xea, 0x94, 0xff, 0x77, 0x24, 0xe6, 0xce, 0x5a, 0xbb, 0xd7,
-	0x59, 0x26, 0x81, 0xed, 0x85, 0xc5, 0xe3, 0x53, 0xa4, 0x63, 0xa0, 0x2d, 0xc5, 0xe0, 0x25, 0xe4,
-	0xaf, 0xa8, 0xeb, 0x4d, 0xc3, 0x64, 0x61, 0x94, 0x0a, 0x68, 0x53, 0x49, 0x70, 0xa2, 0x62, 0xfe,
-	0x37, 0x0f, 0xf9, 0x18, 0x44, 0xa7, 0x90, 0x1d, 0x04, 0xc3, 0x24, 0x0f, 0xbe, 0xb8, 0x3b, 0x2d,
-	0xf9, 0xad, 0x07, 0x43, 0x86, 0xa5, 0x2e, 0xfa, 0x1d, 0x6c, 0x88, 0x5a, 0xf5, 0x99, 0x47, 0xa6,
-	0x93, 0x21, 0x9d, 0x85, 0xde, 0x48, 0xcd, 0xae, 0x2b, 0x85, 0xbe, 0x94, 0xe3, 0xca, 0x20, 0x3d,
-	0x44, 0x7b, 0x50, 0x14, 0xd1, 0x56, 0x91, 0xc8, 0xca, 0xdc, 0x2f, 0x08, 0x40, 0xc6, 0xc0, 0x84,
-	0x4a, 0xe0, 0xbb, 0x81, 0x4f, 0xa2, 0x11, 0x25, 0xa7, 0xdf, 0x7c, 0x2b, 0xc9, 0xaa, 0x8c, 0x4b,
-	0x12, 0xec, 0x8e, 0xe8, 0xe9, 0x37, 0xdf, 0xa2, 0x27, 0x50, 0x92, 0x05, 0xce, 0x3e, 0x4d, 0xdc,
-	0xf0, 0x56, 0xb2, 0x54, 0x05, 0xcb, 0x9a, 0xb7, 0x24, 0x22, 0xaa, 0xe8, 0xca, 0xa3, 0xd7, 0x91,
-	0x64, 0xa6, 0x0a, 0x56, 0x03, 0xf4, 0x0a, 0x76, 0x62, 0x1f, 0x90, 0x28, 0x98, 0x86, 0x03, 0x46,
-	0x5c, 0x7f, 0xc8, 0x3e, 0x49, 0xc6, 0xa9, 0x60, 0x14, 0xcb, 0xba, 0x52, 0x64, 0x0b, 0x09, 0xda,
-	0x85, 0xf5, 0x11, 0x73, 0xaf, 0x47, 0x8a, 0x45, 0x2a, 0x38, 0x1e, 0x99, 0x7f, 0xcf, 0x41, 0x29,
-	0xe5, 0x18, 0x54, 0x86, 0x02, 0xb6, 0xba, 0x16, 0x7e, 0x6f, 0x35, 0xf4, 0xcf, 0xd0, 0x11, 0x3c,
-	0xb3, 0x9d, 0x7a, 0x07, 0x63, 0xab, 0xde, 0x23, 0x1d, 0x4c, 0xfa, 0xce, 0x5b, 0xa7, 0xf3, 0x83,
-	0x43, 0x2e, 0x6a, 0x1f, 0xda, 0x96, 0xd3, 0x23, 0x0d, 0xab, 0x57, 0xb3, 0x5b, 0x5d, 0x5d, 0x43,
-	0xfb, 0x60, 0xcc, 0x35, 0x13, 0x71, 0xad, 0xdd, 0xe9, 0x3b, 0x3d, 0x7d, 0x0d, 0x3d, 0x81, 0xbd,
-	0xa6, 0xed, 0xd4, 0x5a, 0x64, 0xae, 0x53, 0x6f, 0xf5, 0xde, 0x13, 0xeb, 0xc7, 0x0b, 0x1b, 0x7f,
-	0xd0, 0x33, 0xab, 0x14, 0x44, 0x4d, 0x25, 0x2b, 0x64, 0xd1, 0x63, 0xf8, 0x5c, 0x29, 0xa8, 0x29,
-	0xa4, 0xd7, 0xe9, 0x90, 0x6e, 0xa7, 0xe3, 0xe8, 0x39, 0xb4, 0x05, 0x15, 0xdb, 0x79, 0x5f, 0x6b,
-	0xd9, 0x0d, 0x82, 0xad, 0x5a, 0xab, 0xad, 0xaf, 0xa3, 0x6d, 0xd8, 0x5c, 0xd6, 0xcb, 0x8b, 0x25,
-	0x12, 0xbd, 0x8e, 0x63, 0x77, 0x1c, 0xf2, 0xde, 0xc2, 0x5d, 0xbb, 0xe3, 0xe8, 0x05, 0xb4, 0x0b,
-	0x68, 0x51, 0x74, 0xd6, 0xae, 0xd5, 0xf5, 0x22, 0xfa, 0x1c, 0xb6, 0x16, 0xf1, 0xb7, 0xd6, 0x07,
-	0x1d, 0x90, 0x01, 0x3b, 0x6a, 0x63, 0xe4, 0x8d, 0xd5, 0xea, 0xfc, 0x40, 0xda, 0xb6, 0x63, 0xb7,
-	0xfb, 0x6d, 0xbd, 0x84, 0x76, 0x40, 0x6f, 0x5a, 0x16, 0xb1, 0x9d, 0x6e, 0xbf, 0xd9, 0xb4, 0xeb,
-	0xb6, 0xe5, 0xf4, 0xf4, 0xb2, 0xb2, 0xbc, 0xea, 0xe0, 0x15, 0x31, 0xa1, 0x7e, 0x56, 0x73, 0x1c,
-	0xab, 0x45, 0x1a, 0x76, 0xb7, 0xf6, 0xa6, 0x65, 0x35, 0xf4, 0x0d, 0x74, 0x00, 0x8f, 0x7b, 0x56,
-	0xfb, 0xa2, 0x83, 0x6b, 0xf8, 0x03, 0x49, 0xe4, 0xcd, 0x9a, 0xdd, 0xea, 0x63, 0x4b, 0xdf, 0x44,
-	0x5f, 0xc2, 0x01, 0xb6, 0xde, 0xf5, 0x6d, 0x6c, 0x35, 0x88, 0xd3, 0x69, 0x58, 0xa4, 0x69, 0xd5,
-	0x7a, 0x7d, 0x6c, 0x91, 0xb6, 0xdd, 0xed, 0xda, 0xce, 0xf7, 0xba, 0x8e, 0x9e, 0xc1, 0xe1, 0x4c,
-	0x65, 0xb6, 0xc0, 0x92, 0xd6, 0x96, 0x38, 0x5f, 0x12, 0x52, 0xc7, 0xfa, 0xb1, 0x47, 0x2e, 0x2c,
-	0x0b, 0xeb, 0x08, 0x55, 0x61, 0x77, 0x6e, 0x5e, 0x19, 0x88, 0x6d, 0x6f, 0x0b, 0xd9, 0x85, 0x85,
-	0xdb, 0x35, 0x47, 0x04, 0x78, 0x41, 0xb6, 0x23, 0xb6, 0x3d, 0x97, 0x2d, 0x6f, 0xfb, 0x73, 0x84,
-	0x60, 0x23, 0x15, 0x95, 0x66, 0x0d, 0xeb, 0xbb, 0x68, 0x07, 0x36, 0x93, 0x1d, 0x24, 0x8a, 0xff,
-	0xca, 0xa3, 0x47, 0x80, 0xfa, 0x0e, 0xb6, 0x6a, 0x0d, 0xe1, 0x90, 0x99, 0xe0, 0xdf, 0xf9, 0xf3,
-	0x6c, 0x61, 0x4d, 0xcf, 0x98, 0xff, 0xcc, 0x40, 0x65, 0xa1, 0x2e, 0xd1, 0x3e, 0x14, 0x23, 0xf7,
-	0xda, 0xa7, 0x5c, 0x30, 0x87, 0x22, 0x95, 0x39, 0x20, 0xaf, 0xd1, 0x11, 0x75, 0x7d, 0xc5, 0x66,
-	0x8a, 0xf7, 0x8b, 0x12, 0x91, 0x5c, 0xb6, 0x07, 0xf9, 0xe4, 0xca, 0xce, 0xcc, 0xae, 0xec, 0xf5,
-	0x81, 0xba, 0xaa, 0xf7, 0xa1, 0x28, 0x28, 0x33, 0xe2, 0x74, 0x3c, 0x91, 0x25, 0x5e, 0xc1, 0x73,
-	0x00, 0x3d, 0x85, 0xca, 0x98, 0x45, 0x11, 0xbd, 0x66, 0x44, 0x95, 0x29, 0x48, 0x8d, 0x72, 0x0c,
-	0x36, 0x65, 0xb5, 0x3e, 0x85, 0x84, 0x36, 0x62, 0xa5, 0x9c, 0x52, 0x8a, 0x41, 0xa5, 0xb4, 0xcc,
-	0xd8, 0x9c, 0xc6, 0x6c, 0x90, 0x66, 0x6c, 0x4e, 0xd1, 0x0b, 0xd8, 0x52, 0x94, 0xe3, 0xfa, 0xee,
-	0x78, 0x3a, 0x56, 0xd4, 0x93, 0x97, 0xd4, 0xb3, 0x29, 0xa9, 0x47, 0xe1, 0x92, 0x81, 0x1e, 0x43,
-	0xe1, 0x92, 0x46, 0x4c, 0x5c, 0x16, 0x31, 0x35, 0xe4, 0xc5, 0xb8, 0xc9, 0x98, 0x10, 0x89, 0x2b,
-	0x24, 0x14, 0xa4, 0xa7, 0x18, 0x21, 0x7f, 0xc5, 0x18, 0x16, 0xbe, 0x9c, 0x59, 0xa0, 0x9f, 0xe6,
-	0x16, 0x4a, 0x29, 0x0b, 0x0a, 0x97, 0x16, 0x5e, 0xc0, 0x16, 0xfb, 0xc4, 0x43, 0x4a, 0x82, 0x09,
-	0xfd, 0x79, 0xca, 0xc8, 0x90, 0x72, 0x2a, 0x7b, 0xc0, 0x32, 0xde, 0x94, 0x82, 0x8e, 0xc4, 0x1b,
-	0x94, 0x53, 0x73, 0x1f, 0xaa, 0x98, 0x45, 0x8c, 0xb7, 0xdd, 0x28, 0x72, 0x03, 0xbf, 0x1e, 0xf8,
-	0x3c, 0x0c, 0xbc, 0xf8, 0xce, 0x31, 0x0f, 0x60, 0x6f, 0xa5, 0x54, 0x5d, 0x1a, 0x62, 0xf2, 0xbb,
-	0x29, 0x0b, 0x6f, 0x57, 0x4f, 0x7e, 0x07, 0x7b, 0x2b, 0xa5, 0xf1, 0x8d, 0xf3, 0x12, 0x72, 0x13,
-	0xea, 0x86, 0x91, 0xb1, 0x26, 0x6f, 0xed, 0xdd, 0x85, 0x26, 0xc1, 0x0d, 0xcf, 0xdc, 0x88, 0x07,
-	0xe1, 0x2d, 0x56, 0x4a, 0xe7, 0xd9, 0x82, 0xa6, 0xaf, 0x99, 0x7f, 0xd2, 0xa0, 0x94, 0x12, 0x8a,
-	0x3c, 0xf0, 0x83, 0x21, 0x23, 0x57, 0x61, 0x30, 0x4e, 0x32, 0x6c, 0x06, 0x20, 0x03, 0xf2, 0x72,
-	0xc0, 0x83, 0x38, 0xbd, 0x92, 0x21, 0xfa, 0x1a, 0xf2, 0x23, 0xb5, 0x84, 0x8c, 0x52, 0xe9, 0x74,
-	0x7b, 0xc9, 0xba, 0xf0, 0x0d, 0x4e, 0x74, 0xce, 0xb3, 0x85, 0x8c, 0x9e, 0x3d, 0xcf, 0x16, 0xb2,
-	0x7a, 0xee, 0x3c, 0x5b, 0xc8, 0xe9, 0xeb, 0xe7, 0xd9, 0xc2, 0xba, 0x9e, 0x37, 0xff, 0xa2, 0x41,
-	0x21, 0xd1, 0x5e, 0xcc, 0x49, 0xd5, 0x00, 0xa4, 0x72, 0xf2, 0x14, 0x76, 0xc6, 0xae, 0x4f, 0x26,
-	0xcc, 0xa7, 0x9e, 0xfb, 0x47, 0x46, 0x16, 0xfb, 0x8b, 0x95, 0x32, 0xf4, 0x1a, 0x1e, 0xc9, 0x86,
-	0x94, 0xaa, 0x26, 0x86, 0x44, 0xd3, 0xc1, 0x80, 0x45, 0xd1, 0xd5, 0xd4, 0x93, 0x25, 0x51, 0xc0,
-	0xf7, 0x89, 0xcd, 0x31, 0x3c, 0x92, 0xae, 0xbf, 0x08, 0x83, 0x4b, 0x7a, 0xe9, 0x7a, 0x2e, 0xbf,
-	0x4d, 0xda, 0x88, 0x7d, 0x28, 0x0a, 0xe7, 0x10, 0x3f, 0xb9, 0x97, 0xcb, 0x78, 0x0e, 0x08, 0x97,
-	0xf1, 0x40, 0xc9, 0x62, 0x97, 0xc5, 0x43, 0xd1, 0x20, 0xcc, 0xde, 0x13, 0x19, 0xb9, 0xe9, 0xd9,
-	0xd8, 0xbc, 0x01, 0xe3, 0xae, 0xb9, 0x38, 0xcc, 0x87, 0x50, 0x9a, 0xcc, 0x61, 0x69, 0x51, 0xc3,
-	0x69, 0x28, 0x1d, 0x8c, 0xb5, 0x5f, 0x0e, 0x86, 0xf9, 0x57, 0x0d, 0xb6, 0xde, 0x4c, 0x5d, 0x6f,
-	0xb8, 0xd0, 0x1d, 0xa5, 0x9f, 0x3b, 0xda, 0xe2, 0x73, 0x67, 0xd5, 0x5b, 0x66, 0x6d, 0xe5, 0x5b,
-	0x66, 0xd5, 0x7b, 0x21, 0x73, 0xef, 0x7b, 0xe1, 0x09, 0x94, 0xe6, 0x4f, 0x05, 0xd5, 0x7c, 0x96,
-	0x31, 0x8c, 0x92, 0x77, 0x42, 0x64, 0xbe, 0x06, 0x94, 0xde, 0x68, 0xec, 0x90, 0x59, 0x93, 0xa6,
-	0xdd, 0xdb, 0xa4, 0xbd, 0xf8, 0xb3, 0x06, 0xe5, 0x74, 0xa7, 0x8c, 0x2a, 0x50, 0xb4, 0x1d, 0xd2,
-	0x6c, 0xd9, 0xdf, 0x9f, 0xf5, 0xf4, 0xcf, 0xc4, 0xb0, 0xdb, 0xaf, 0xd7, 0x2d, 0xab, 0x61, 0x35,
-	0x74, 0x4d, 0x70, 0xb8, 0xa0, 0x63, 0xab, 0x41, 0x7a, 0x76, 0xdb, 0xea, 0xf4, 0xc5, 0xed, 0xbe,
-	0x0d, 0x9b, 0x31, 0xe6, 0x74, 0x08, 0xee, 0xf4, 0x7b, 0x96, 0x9e, 0x41, 0x3a, 0x94, 0x63, 0xd0,
-	0xc2, 0xb8, 0x83, 0xf5, 0xac, 0xb8, 0x92, 0x62, 0xe4, 0x6e, 0xa7, 0x90, 0x34, 0x12, 0xb9, 0xd3,
-	0x7f, 0xe4, 0x60, 0x5d, 0x6e, 0x30, 0x44, 0x67, 0x50, 0x4a, 0xbd, 0x47, 0xd0, 0xc1, 0x83, 0xef,
-	0x94, 0xaa, 0xb1, 0xba, 0xf5, 0x9f, 0x46, 0xaf, 0x34, 0x74, 0x0e, 0xe5, 0xf4, 0x8b, 0x03, 0xa5,
-	0xdb, 0xc3, 0x15, 0x4f, 0x91, 0x07, 0xd7, 0x7a, 0x0b, 0xba, 0x15, 0x71, 0x77, 0x2c, 0xda, 0xc1,
-	0xb8, 0x41, 0x47, 0xd5, 0x94, 0xfe, 0x52, 0xd7, 0x5f, 0xdd, 0x5b, 0x29, 0x8b, 0x23, 0xd4, 0x52,
-	0x47, 0x8c, 0x5b, 0xe4, 0x3b, 0x47, 0x5c, 0xec, 0xcb, 0xab, 0x5f, 0xdc, 0x27, 0x8e, 0x57, 0x1b,
-	0xc2, 0xf6, 0x0a, 0x0e, 0x45, 0xbf, 0x4a, 0xef, 0xe0, 0x5e, 0x06, 0xae, 0x3e, 0xff, 0x25, 0xb5,
-	0xb9, 0x95, 0x15, 0x64, 0xbb, 0x60, 0xe5, 0x7e, 0xaa, 0x5e, 0xb0, 0xf2, 0x10, 0x67, 0xff, 0x04,
-	0xfa, 0x72, 0xa1, 0x23, 0x73, 0x79, 0xee, 0x5d, 0xd2, 0xa9, 0x3e, 0x7d, 0x50, 0x27, 0x5e, 0xdc,
-	0x06, 0x98, 0x97, 0x0b, 0xda, 0x4f, 0x4d, 0xb9, 0x53, 0xee, 0xd5, 0x83, 0x7b, 0xa4, 0x6a, 0xa9,
-	0x37, 0xbf, 0xfe, 0xfd, 0xc9, 0xb5, 0xcb, 0x47, 0xd3, 0xcb, 0xe3, 0x41, 0x30, 0x3e, 0xf1, 0x44,
-	0x53, 0xed, 0xbb, 0xfe, 0xb5, 0xcf, 0xf8, 0x1f, 0x82, 0xf0, 0xe6, 0xc4, 0xf3, 0x87, 0x27, 0xb2,
-	0xea, 0x4e, 0x66, 0xab, 0x5c, 0xae, 0xcb, 0xff, 0x5c, 0x7e, 0xf3, 0xbf, 0x00, 0x00, 0x00, 0xff,
-	0xff, 0x78, 0xac, 0xbb, 0x04, 0xa3, 0x11, 0x00, 0x00,
+	// 2011 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x58, 0x5d, 0x73, 0x1a, 0xc9,
+	0xd5, 0xde, 0x11, 0x20, 0xe0, 0x00, 0x62, 0xd4, 0x92, 0x65, 0x8c, 0xac, 0xb5, 0x76, 0xec, 0xd7,
+	0xab, 0x72, 0x79, 0x25, 0xbf, 0x4a, 0xed, 0x96, 0x6b, 0x2f, 0x92, 0xc2, 0x30, 0xac, 0x46, 0x86,
+	0x41, 0x6e, 0xc0, 0xbb, 0xce, 0x5e, 0x74, 0xb5, 0xa0, 0x25, 0xa6, 0x34, 0x1f, 0xec, 0x4c, 0xe3,
+	0x58, 0xff, 0x21, 0xf9, 0x1d, 0xc9, 0x45, 0x72, 0x95, 0xff, 0x94, 0x54, 0xe5, 0x32, 0x55, 0xb9,
+	0x4f, 0x75, 0xf7, 0x0c, 0x0c, 0x08, 0x79, 0x73, 0xc5, 0xf4, 0x73, 0x9e, 0x3e, 0xa7, 0xbb, 0xcf,
+	0x47, 0x9f, 0x06, 0xf6, 0xc2, 0x60, 0xc6, 0x59, 0x18, 0x4e, 0x47, 0x27, 0xea, 0xeb, 0x78, 0x1a,
+	0x06, 0x3c, 0x40, 0xc5, 0x39, 0x5e, 0x2f, 0x86, 0xd3, 0x91, 0x42, 0x8d, 0x7f, 0x65, 0x01, 0xf5,
+	0x99, 0x3f, 0xbe, 0xa0, 0xb7, 0x1e, 0xf3, 0x39, 0x66, 0xbf, 0xcc, 0x58, 0xc4, 0x11, 0x82, 0xec,
+	0x98, 0x45, 0xbc, 0xa6, 0x1d, 0x6a, 0x47, 0x65, 0x2c, 0xbf, 0x91, 0x0e, 0x19, 0xea, 0xf1, 0xda,
+	0xc6, 0xa1, 0x76, 0x94, 0xc1, 0xe2, 0x13, 0x3d, 0x82, 0x02, 0xf5, 0x38, 0xf1, 0x22, 0xca, 0x6b,
+	0x65, 0x09, 0xe7, 0xa9, 0xc7, 0xbb, 0x11, 0xe5, 0xe8, 0x2b, 0x28, 0x4f, 0x95, 0x4a, 0x32, 0xa1,
+	0xd1, 0xa4, 0x96, 0x91, 0x8a, 0x4a, 0x31, 0x76, 0x46, 0xa3, 0x09, 0x3a, 0x02, 0xfd, 0xca, 0xf1,
+	0xa9, 0x4b, 0x46, 0x2e, 0xff, 0x48, 0xc6, 0xcc, 0xe5, 0xb4, 0x96, 0x3d, 0xd4, 0x8e, 0x72, 0x78,
+	0x4b, 0xe2, 0x4d, 0x97, 0x7f, 0x6c, 0x09, 0x14, 0x7d, 0x0d, 0xd5, 0x44, 0x59, 0xa8, 0x16, 0x58,
+	0xcb, 0x1d, 0x6a, 0x47, 0x45, 0xbc, 0x35, 0x5d, 0x5e, 0xf6, 0xd7, 0x50, 0xe5, 0x8e, 0xc7, 0x82,
+	0x19, 0x27, 0x11, 0x1b, 0x05, 0xfe, 0x38, 0xaa, 0x6d, 0x2a, 0x8d, 0x31, 0xdc, 0x57, 0x28, 0x32,
+	0xa0, 0x72, 0xc5, 0x18, 0x71, 0x1d, 0xcf, 0xe1, 0x44, 0x2c, 0x3f, 0x2f, 0x97, 0x5f, 0xba, 0x62,
+	0xac, 0x23, 0xb0, 0x3e, 0xe5, 0xe8, 0x19, 0x6c, 0x2d, 0x38, 0x72, 0x8f, 0x15, 0x49, 0x2a, 0x27,
+	0x24, 0xb9, 0xd1, 0x97, 0xa0, 0x07, 0x33, 0x7e, 0x1d, 0x38, 0xfe, 0x35, 0x19, 0x4d, 0xa8, 0x4f,
+	0x9c, 0x71, 0xad, 0x70, 0xa8, 0x1d, 0x65, 0xdf, 0x6c, 0xbc, 0xd2, 0xf0, 0x56, 0x22, 0x6b, 0x4e,
+	0xa8, 0x6f, 0x8d, 0xd1, 0x73, 0xa8, 0xba, 0x34, 0xe2, 0x64, 0x12, 0x4c, 0xc9, 0x74, 0x76, 0x79,
+	0xc3, 0x6e, 0x6b, 0x5b, 0xf2, 0x64, 0x2a, 0x02, 0x3e, 0x0b, 0xa6, 0x17, 0x12, 0x44, 0x07, 0x00,
+	0xf2, 0x54, 0xa4, 0xf1, 0x5a, 0x51, 0xee, 0xa1, 0x28, 0x10, 0x69, 0x18, 0x9d, 0x42, 0x49, 0x7a,
+	0x93, 0x4c, 0x1c, 0x9f, 0x47, 0x35, 0x38, 0xcc, 0x1c, 0x95, 0x4e, 0xf5, 0x63, 0xd7, 0x17, 0x8e,
+	0xc5, 0x42, 0x72, 0xe6, 0xf8, 0x1c, 0xa7, 0x49, 0xc8, 0x84, 0x82, 0x70, 0x23, 0xe1, 0xee, 0xc7,
+	0x5a, 0x49, 0x4e, 0x78, 0x71, 0x3c, 0x0f, 0x89, 0xe3, 0xbb, 0x31, 0x70, 0xdc, 0x62, 0x11, 0x1f,
+	0xb8, 0x1f, 0x4d, 0x9f, 0x87, 0xb7, 0x38, 0x3f, 0x56, 0xa3, 0xfa, 0xf7, 0x50, 0x4e, 0x0b, 0x44,
+	0x54, 0x88, 0x5d, 0x88, 0x40, 0xc9, 0x62, 0xf1, 0x89, 0x76, 0x21, 0xf7, 0x91, 0xba, 0x33, 0x26,
+	0x23, 0xa5, 0x8c, 0xd5, 0xe0, 0xfb, 0x8d, 0xd7, 0x9a, 0xf1, 0x1a, 0x76, 0x06, 0x21, 0x1d, 0xdd,
+	0xac, 0x04, 0xdb, 0x6a, 0xac, 0x68, 0x77, 0x62, 0xc5, 0xf8, 0x8b, 0x06, 0x95, 0x78, 0x56, 0x9f,
+	0x53, 0x3e, 0x8b, 0xd0, 0x37, 0x90, 0x8b, 0x38, 0xe5, 0x4c, 0xb2, 0xb7, 0x4e, 0x1f, 0xa6, 0xf6,
+	0x92, 0x22, 0x32, 0xac, 0x58, 0xa8, 0x0e, 0x85, 0x69, 0xc8, 0x1c, 0x8f, 0x5e, 0x27, 0xeb, 0x9a,
+	0x8f, 0x91, 0x01, 0x39, 0x39, 0x59, 0x06, 0x69, 0xe9, 0xb4, 0x9c, 0x3e, 0x47, 0xac, 0x44, 0xe8,
+	0x08, 0x72, 0x13, 0xee, 0x8e, 0xa2, 0x5a, 0x56, 0x1e, 0x1d, 0x8a, 0x39, 0x67, 0x83, 0x4e, 0xb3,
+	0xc1, 0x39, 0xf3, 0xa6, 0x1c, 0x2b, 0x82, 0xf1, 0x5b, 0xa8, 0xca, 0x99, 0x6d, 0xc6, 0x3e, 0x97,
+	0x4d, 0x0f, 0x41, 0xe4, 0x8a, 0x8c, 0x3d, 0x95, 0x51, 0x9b, 0xd4, 0x13, 0x61, 0x67, 0x8c, 0x41,
+	0x5f, 0xcc, 0x8f, 0xa6, 0x81, 0x1f, 0x09, 0xeb, 0xba, 0x58, 0x86, 0x88, 0x31, 0x11, 0x92, 0x32,
+	0x18, 0x35, 0x39, 0x6b, 0x2b, 0xc6, 0xdb, 0x8c, 0xc9, 0x70, 0x7c, 0xae, 0x32, 0x80, 0xb8, 0xc1,
+	0xe8, 0x46, 0xe4, 0x14, 0xbd, 0x8d, 0xd5, 0x57, 0x04, 0xdc, 0x09, 0x46, 0x37, 0x2d, 0x01, 0x1a,
+	0x3f, 0xab, 0xb4, 0x1f, 0x04, 0x6a, 0x97, 0xff, 0xb3, 0x27, 0x16, 0x87, 0xb5, 0x71, 0xef, 0x61,
+	0x19, 0x04, 0x76, 0x96, 0x94, 0xc7, 0xbb, 0x48, 0xfb, 0x40, 0x5b, 0xf1, 0xc1, 0x4b, 0xc8, 0x5f,
+	0x51, 0xc7, 0x9d, 0x85, 0x89, 0x62, 0x94, 0x72, 0x68, 0x5b, 0x49, 0x70, 0x42, 0x31, 0xfe, 0x93,
+	0x87, 0x7c, 0x0c, 0xa2, 0x53, 0xc8, 0x8e, 0x82, 0x71, 0x12, 0x07, 0x5f, 0xde, 0x9d, 0x96, 0xfc,
+	0x36, 0x83, 0x31, 0xc3, 0x92, 0x8b, 0x7e, 0x07, 0x5b, 0x22, 0x57, 0x7d, 0xe6, 0x92, 0xd9, 0x74,
+	0x4c, 0xe7, 0xae, 0xaf, 0xa5, 0x66, 0x37, 0x15, 0x61, 0x28, 0xe5, 0xb8, 0x32, 0x4a, 0x0f, 0xd1,
+	0x3e, 0x14, 0x85, 0xb7, 0x95, 0x27, 0xb2, 0x32, 0xf6, 0x0b, 0x02, 0x90, 0x3e, 0x30, 0xa0, 0x12,
+	0xf8, 0x4e, 0xe0, 0x93, 0x68, 0x42, 0xc9, 0xe9, 0xb7, 0xdf, 0xc9, 0x62, 0x55, 0xc6, 0x25, 0x09,
+	0xf6, 0x27, 0xf4, 0xf4, 0xdb, 0xef, 0xd0, 0x13, 0x28, 0xc9, 0x04, 0x67, 0x9f, 0xa6, 0x4e, 0x78,
+	0x2b, 0xab, 0x54, 0x05, 0xcb, 0x9c, 0x37, 0x25, 0x22, 0xb2, 0xe8, 0xca, 0xa5, 0xd7, 0x91, 0xac,
+	0x4c, 0x15, 0xac, 0x06, 0xe8, 0x15, 0xec, 0xc6, 0x67, 0x40, 0xa2, 0x60, 0x16, 0x8e, 0x18, 0x71,
+	0xfc, 0x31, 0xfb, 0x24, 0x2b, 0x4e, 0x05, 0xa3, 0x58, 0xd6, 0x97, 0x22, 0x4b, 0x48, 0xd0, 0x1e,
+	0x6c, 0x4e, 0x98, 0x73, 0x3d, 0x51, 0x55, 0xa4, 0x82, 0xe3, 0x91, 0xf1, 0xd7, 0x1c, 0x94, 0x52,
+	0x07, 0x83, 0xca, 0x50, 0xc0, 0x66, 0xdf, 0xc4, 0xef, 0xcd, 0x96, 0xfe, 0x05, 0x3a, 0x82, 0x67,
+	0x96, 0xdd, 0xec, 0x61, 0x6c, 0x36, 0x07, 0xa4, 0x87, 0xc9, 0xd0, 0x7e, 0x6b, 0xf7, 0x7e, 0xb4,
+	0xc9, 0x45, 0xe3, 0x43, 0xd7, 0xb4, 0x07, 0xa4, 0x65, 0x0e, 0x1a, 0x56, 0xa7, 0xaf, 0x6b, 0xe8,
+	0x31, 0xd4, 0x16, 0xcc, 0x44, 0xdc, 0xe8, 0xf6, 0x86, 0xf6, 0x40, 0xdf, 0x40, 0x4f, 0x60, 0xbf,
+	0x6d, 0xd9, 0x8d, 0x0e, 0x59, 0x70, 0x9a, 0x9d, 0xc1, 0x7b, 0x62, 0xfe, 0x74, 0x61, 0xe1, 0x0f,
+	0x7a, 0x66, 0x1d, 0x41, 0xe4, 0x54, 0xa2, 0x21, 0x8b, 0x1e, 0xc1, 0x03, 0x45, 0x50, 0x53, 0xc8,
+	0xa0, 0xd7, 0x23, 0xfd, 0x5e, 0xcf, 0xd6, 0x73, 0x68, 0x1b, 0x2a, 0x96, 0xfd, 0xbe, 0xd1, 0xb1,
+	0x5a, 0x04, 0x9b, 0x8d, 0x4e, 0x57, 0xdf, 0x44, 0x3b, 0x50, 0x5d, 0xe5, 0xe5, 0x85, 0x8a, 0x84,
+	0xd7, 0xb3, 0xad, 0x9e, 0x4d, 0xde, 0x9b, 0xb8, 0x6f, 0xf5, 0x6c, 0xbd, 0x80, 0xf6, 0x00, 0x2d,
+	0x8b, 0xce, 0xba, 0x8d, 0xa6, 0x5e, 0x44, 0x0f, 0x60, 0x7b, 0x19, 0x7f, 0x6b, 0x7e, 0xd0, 0x01,
+	0xd5, 0x60, 0x57, 0x2d, 0x8c, 0xbc, 0x31, 0x3b, 0xbd, 0x1f, 0x49, 0xd7, 0xb2, 0xad, 0xee, 0xb0,
+	0xab, 0x97, 0xd0, 0x2e, 0xe8, 0x6d, 0xd3, 0x24, 0x96, 0xdd, 0x1f, 0xb6, 0xdb, 0x56, 0xd3, 0x32,
+	0xed, 0x81, 0x5e, 0x56, 0x96, 0xd7, 0x6d, 0xbc, 0x22, 0x26, 0x34, 0xcf, 0x1a, 0xb6, 0x6d, 0x76,
+	0x48, 0xcb, 0xea, 0x37, 0xde, 0x74, 0xcc, 0x96, 0xbe, 0x85, 0x0e, 0xe0, 0xd1, 0xc0, 0xec, 0x5e,
+	0xf4, 0x70, 0x03, 0x7f, 0x20, 0x89, 0xbc, 0xdd, 0xb0, 0x3a, 0x43, 0x6c, 0xea, 0x55, 0xf4, 0x15,
+	0x1c, 0x60, 0xf3, 0xdd, 0xd0, 0xc2, 0x66, 0x8b, 0xd8, 0xbd, 0x96, 0x49, 0xda, 0x66, 0x63, 0x30,
+	0xc4, 0x26, 0xe9, 0x5a, 0xfd, 0xbe, 0x65, 0xff, 0xa0, 0xeb, 0xe8, 0x19, 0x1c, 0xce, 0x29, 0x73,
+	0x05, 0x2b, 0xac, 0x6d, 0xb1, 0xbf, 0xc4, 0xa5, 0xb6, 0xf9, 0xd3, 0x80, 0x5c, 0x98, 0x26, 0xd6,
+	0x11, 0xaa, 0xc3, 0xde, 0xc2, 0xbc, 0x32, 0x10, 0xdb, 0xde, 0x11, 0xb2, 0x0b, 0x13, 0x77, 0x1b,
+	0xb6, 0x70, 0xf0, 0x92, 0x6c, 0x57, 0x2c, 0x7b, 0x21, 0x5b, 0x5d, 0xf6, 0x03, 0x84, 0x60, 0x2b,
+	0xe5, 0x95, 0x76, 0x03, 0xeb, 0x7b, 0x68, 0x17, 0xaa, 0xc9, 0x0a, 0x12, 0xe2, 0x3f, 0xf2, 0xe8,
+	0x21, 0xa0, 0xa1, 0x8d, 0xcd, 0x46, 0x4b, 0x1c, 0xc8, 0x5c, 0xf0, 0xcf, 0xfc, 0x79, 0xb6, 0xb0,
+	0xa1, 0x67, 0x8c, 0xbf, 0x67, 0xa0, 0xb2, 0x94, 0x97, 0xe8, 0x31, 0x14, 0x23, 0xe7, 0xda, 0xa7,
+	0x5c, 0x54, 0x0e, 0x55, 0x54, 0x16, 0x80, 0xbc, 0x46, 0x27, 0xd4, 0xf1, 0x55, 0x35, 0x53, 0x75,
+	0xbf, 0x28, 0x11, 0x59, 0xcb, 0xf6, 0x21, 0x9f, 0x5c, 0xd9, 0x99, 0xf9, 0x95, 0xbd, 0x39, 0x52,
+	0x57, 0xf5, 0x63, 0x28, 0x8a, 0x92, 0x19, 0x71, 0xea, 0x4d, 0x65, 0x8a, 0x57, 0xf0, 0x02, 0x40,
+	0x4f, 0xa1, 0xe2, 0xb1, 0x28, 0xa2, 0xd7, 0x8c, 0xa8, 0x34, 0x05, 0xc9, 0x28, 0xc7, 0x60, 0x5b,
+	0x66, 0xeb, 0x53, 0x48, 0xca, 0x46, 0x4c, 0xca, 0x29, 0x52, 0x0c, 0x2a, 0xd2, 0x6a, 0xc5, 0xe6,
+	0x34, 0xae, 0x06, 0xe9, 0x8a, 0xcd, 0x29, 0x7a, 0x01, 0xdb, 0xaa, 0xe4, 0x38, 0xbe, 0xe3, 0xcd,
+	0x3c, 0x55, 0x7a, 0xf2, 0xb2, 0xf4, 0x54, 0x65, 0xe9, 0x51, 0xb8, 0xac, 0x40, 0x8f, 0xa0, 0x70,
+	0x49, 0x23, 0x26, 0x2e, 0x8b, 0xb8, 0x34, 0xe4, 0xc5, 0xb8, 0xcd, 0x98, 0x10, 0x89, 0x2b, 0x24,
+	0x14, 0x45, 0x4f, 0x55, 0x84, 0xfc, 0x15, 0x63, 0x58, 0x9c, 0xe5, 0xdc, 0x02, 0xfd, 0xb4, 0xb0,
+	0x50, 0x4a, 0x59, 0x50, 0xb8, 0xb4, 0xf0, 0x02, 0xb6, 0xd9, 0x27, 0x1e, 0x52, 0x12, 0x4c, 0xe9,
+	0x2f, 0x33, 0x46, 0xc6, 0x94, 0x53, 0xd9, 0x03, 0x96, 0x71, 0x55, 0x0a, 0x7a, 0x12, 0x6f, 0x51,
+	0x4e, 0x8d, 0xc7, 0x50, 0xc7, 0x2c, 0x62, 0xbc, 0xeb, 0x44, 0x91, 0x13, 0xf8, 0xcd, 0xc0, 0xe7,
+	0x61, 0xe0, 0xc6, 0x77, 0x8e, 0x71, 0x00, 0xfb, 0x6b, 0xa5, 0xea, 0xd2, 0x10, 0x93, 0xdf, 0xcd,
+	0x58, 0x78, 0xbb, 0x7e, 0xf2, 0x3b, 0xd8, 0x5f, 0x2b, 0x8d, 0x6f, 0x9c, 0x97, 0x90, 0x9b, 0x52,
+	0x27, 0x8c, 0x6a, 0x1b, 0xf2, 0xd6, 0xde, 0x5b, 0x6a, 0x12, 0x9c, 0xf0, 0xcc, 0x89, 0x78, 0x10,
+	0xde, 0x62, 0x45, 0x3a, 0xcf, 0x16, 0x34, 0x7d, 0xc3, 0xf8, 0xa3, 0x06, 0xa5, 0x94, 0x50, 0xc4,
+	0x81, 0x1f, 0x8c, 0x19, 0xb9, 0x0a, 0x03, 0x2f, 0x89, 0xb0, 0x39, 0x80, 0x6a, 0x90, 0x97, 0x03,
+	0x1e, 0xc4, 0xe1, 0x95, 0x0c, 0xd1, 0x37, 0x90, 0x9f, 0x28, 0x15, 0xd2, 0x4b, 0xa5, 0xd3, 0x9d,
+	0x15, 0xeb, 0xe2, 0x6c, 0x70, 0xc2, 0x39, 0xcf, 0x16, 0x32, 0x7a, 0xf6, 0x3c, 0x5b, 0xc8, 0xea,
+	0xb9, 0xf3, 0x6c, 0x21, 0xa7, 0x6f, 0x9e, 0x67, 0x0b, 0x9b, 0x7a, 0xde, 0xf8, 0xb7, 0x06, 0x85,
+	0x84, 0x2d, 0xd6, 0x22, 0x4a, 0x3c, 0x11, 0x91, 0x11, 0x37, 0x00, 0x0b, 0x00, 0x19, 0x50, 0x96,
+	0x83, 0xe5, 0xbe, 0x62, 0x09, 0x43, 0xcf, 0xa0, 0x32, 0x1f, 0xcf, 0x2f, 0xaf, 0x0c, 0x5e, 0x06,
+	0x85, 0xa6, 0x68, 0x36, 0x1a, 0xb1, 0x28, 0x52, 0xa6, 0x72, 0x4a, 0x53, 0x1a, 0x43, 0x47, 0x50,
+	0x4d, 0xc6, 0x89, 0xc1, 0x4d, 0x49, 0x5b, 0x85, 0xd1, 0x0b, 0xd0, 0xd3, 0x90, 0xb7, 0xe8, 0xb7,
+	0xef, 0xe0, 0xea, 0x18, 0x0c, 0x0f, 0x1e, 0x4a, 0xb7, 0x5e, 0x84, 0xc1, 0x25, 0xbd, 0x74, 0x5c,
+	0x87, 0xdf, 0x26, 0x2d, 0x8a, 0x38, 0x82, 0x30, 0xf0, 0x88, 0x9f, 0xdc, 0xf9, 0x65, 0xbc, 0x00,
+	0x84, 0x3b, 0x78, 0xa0, 0x64, 0xb1, 0x3b, 0xe2, 0xa1, 0x68, 0x3e, 0xe6, 0xc6, 0x33, 0xd2, 0xf8,
+	0x7c, 0x6c, 0xdc, 0x40, 0xed, 0xae, 0xb9, 0x38, 0x84, 0x0e, 0xa1, 0x34, 0x5d, 0xc0, 0xd2, 0xa2,
+	0x86, 0xd3, 0x50, 0xda, 0xd1, 0x1b, 0xbf, 0xee, 0x68, 0xe3, 0xcf, 0x1a, 0x6c, 0xbf, 0x99, 0x39,
+	0xee, 0x78, 0xa9, 0xf3, 0x4a, 0x3f, 0xa5, 0xb4, 0xe5, 0xa7, 0xd4, 0xba, 0x77, 0xd2, 0xc6, 0xda,
+	0x77, 0xd2, 0xba, 0xb7, 0x48, 0xe6, 0xde, 0xb7, 0xc8, 0x13, 0x28, 0x2d, 0x9e, 0x21, 0xaa, 0xb1,
+	0x2d, 0x63, 0x98, 0x24, 0x6f, 0x90, 0xc8, 0x78, 0x0d, 0x28, 0xbd, 0xd0, 0xf8, 0x40, 0xe6, 0x0d,
+	0xa0, 0x76, 0x6f, 0x03, 0xf8, 0xe2, 0x4f, 0x1a, 0x94, 0xd3, 0x5d, 0x38, 0xaa, 0x40, 0xd1, 0xb2,
+	0x49, 0xbb, 0x63, 0xfd, 0x70, 0x36, 0xd0, 0xbf, 0x10, 0xc3, 0xfe, 0xb0, 0xd9, 0x34, 0xcd, 0x96,
+	0xd9, 0xd2, 0x35, 0x71, 0x3f, 0x88, 0x52, 0x6f, 0xb6, 0xc8, 0xc0, 0xea, 0x9a, 0xbd, 0xa1, 0xe8,
+	0x1c, 0x76, 0xa0, 0x1a, 0x63, 0x76, 0x8f, 0xe0, 0xde, 0x70, 0x60, 0xea, 0x19, 0xa4, 0x43, 0x39,
+	0x06, 0x4d, 0x8c, 0x7b, 0x58, 0xcf, 0x8a, 0xeb, 0x2e, 0x46, 0xee, 0x76, 0x21, 0x49, 0x93, 0x92,
+	0x3b, 0xfd, 0x5b, 0x0e, 0x36, 0xe5, 0x02, 0x43, 0x74, 0x06, 0xa5, 0xd4, 0x5b, 0x07, 0x1d, 0x7c,
+	0xf6, 0x0d, 0x54, 0xaf, 0xad, 0x7f, 0x56, 0xcc, 0xa2, 0x57, 0x1a, 0x3a, 0x87, 0x72, 0xfa, 0x35,
+	0x83, 0xd2, 0xad, 0xe7, 0x9a, 0x67, 0xce, 0x67, 0x75, 0xbd, 0x05, 0xdd, 0x8c, 0xb8, 0xe3, 0x89,
+	0x56, 0x33, 0x6e, 0xfe, 0x51, 0x3d, 0xc5, 0x5f, 0x79, 0x51, 0xd4, 0xf7, 0xd7, 0xca, 0x62, 0x0f,
+	0x75, 0xd4, 0x16, 0xe3, 0xf6, 0xfb, 0xce, 0x16, 0x97, 0x7b, 0xfe, 0xfa, 0x97, 0xf7, 0x89, 0x63,
+	0x6d, 0x63, 0xd8, 0x59, 0x53, 0x9f, 0xd1, 0xff, 0xa5, 0x57, 0x70, 0x6f, 0x75, 0xaf, 0x3f, 0xff,
+	0x35, 0xda, 0xc2, 0xca, 0x9a, 0x42, 0xbe, 0x64, 0xe5, 0xfe, 0x6b, 0x60, 0xc9, 0xca, 0xe7, 0xee,
+	0x83, 0x9f, 0x41, 0x5f, 0x4d, 0x74, 0x64, 0xac, 0xce, 0xbd, 0x5b, 0x74, 0xea, 0x4f, 0x3f, 0xcb,
+	0x89, 0x95, 0x5b, 0x00, 0x8b, 0x74, 0x41, 0x8f, 0x53, 0x53, 0xee, 0xa4, 0x7b, 0xfd, 0xe0, 0x1e,
+	0xa9, 0x52, 0xf5, 0xe6, 0xff, 0x7f, 0x7f, 0x72, 0xed, 0xf0, 0xc9, 0xec, 0xf2, 0x78, 0x14, 0x78,
+	0x27, 0xae, 0x68, 0xd8, 0x7d, 0xc7, 0xbf, 0xf6, 0x19, 0xff, 0x43, 0x10, 0xde, 0x9c, 0xb8, 0xfe,
+	0xf8, 0x44, 0x66, 0xdd, 0xc9, 0x5c, 0xcb, 0xe5, 0xa6, 0xfc, 0x3f, 0xe7, 0x37, 0xff, 0x0d, 0x00,
+	0x00, 0xff, 0xff, 0x7d, 0xd4, 0x80, 0xa8, 0xff, 0x11, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
diff --git a/lnrpc/routerrpc/router.proto b/lnrpc/routerrpc/router.proto
index 167b8d7aa..8bc7de020 100644
--- a/lnrpc/routerrpc/router.proto
+++ b/lnrpc/routerrpc/router.proto
@@ -391,14 +391,31 @@ message PairHistory {
 }
 
 message PairData {
-    /// Time stamp of last result.
-    int64 timestamp = 1 [json_name = "timestamp"];
+    /// Time of last failure.
+    int64 fail_time = 1 [json_name = "fail_time"];
 
-    /// Minimum penalization amount (only applies to failed attempts).
-    int64 min_penalize_amt_sat = 2 [json_name = "min_penalize_amt_sat"];
+    /**
+    Lowest amount that failed to forward rounded to whole sats. This may be
+    set to zero if the failure is independent of amount.
+    */
+    int64 fail_amt_sat = 2 [json_name = "fail_amt_sat"];
+
+    /**
+    Lowest amount that failed to forward in millisats. This may be
+    set to zero if the failure is independent of amount.
+    */
+    int64 fail_amt_msat = 4 [json_name = "fail_amt_msat"];
+
+    reserved 3;
+
+    /// Time of last success.
+    int64 success_time = 5 [json_name = "success_time"];
+
+    /// Highest amount that we could successfully forward rounded to whole sats.
+    int64 success_amt_sat = 6 [json_name = "success_amt_sat"];
 
-    /// Whether the last payment attempt through this pair was successful.
-    bool last_attempt_successful = 3 [json_name = "last_attempt_successful"];
+    /// Highest amount that we could successfully forward in millisats.
+    int64 success_amt_msat = 7 [json_name = "success_amt_msat"];
 }
 
 message QueryProbabilityRequest{
diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go
index 3432ecd87..e815e78af 100644
--- a/lnrpc/routerrpc/router_server.go
+++ b/lnrpc/routerrpc/router_server.go
@@ -494,14 +494,18 @@ func (s *Server) QueryMissionControl(ctx context.Context,
 // toRPCPairData marshalls mission control pair data to the rpc struct.
 func toRPCPairData(data *routing.TimedPairResult) *PairData {
 	rpcData := PairData{
-		MinPenalizeAmtSat: int64(
-			data.MinPenalizeAmt.ToSatoshis(),
-		),
-		LastAttemptSuccessful: data.Success,
+		FailAmtSat:     int64(data.FailAmt.ToSatoshis()),
+		FailAmtMsat:    int64(data.FailAmt),
+		SuccessAmtSat:  int64(data.SuccessAmt.ToSatoshis()),
+		SuccessAmtMsat: int64(data.SuccessAmt),
 	}
 
-	if !data.Timestamp.IsZero() {
-		rpcData.Timestamp = data.Timestamp.Unix()
+	if !data.FailTime.IsZero() {
+		rpcData.FailTime = data.FailTime.Unix()
+	}
+
+	if !data.SuccessTime.IsZero() {
+		rpcData.SuccessTime = data.SuccessTime.Unix()
 	}
 
 	return &rpcData
diff --git a/routing/missioncontrol.go b/routing/missioncontrol.go
index 2d5deb508..c360953af 100644
--- a/routing/missioncontrol.go
+++ b/routing/missioncontrol.go
@@ -125,27 +125,22 @@ type MissionControlConfig struct {
 
 // TimedPairResult describes a timestamped pair result.
 type TimedPairResult struct {
-	// timestamp is the time when this result was obtained.
-	Timestamp time.Time
-
-	// minPenalizeAmt is the minimum amount for which a penalty should be
-	// applied based on this result. Only applies to fail results.
-	MinPenalizeAmt lnwire.MilliSatoshi
-
-	// success indicates whether the payment attempt was successful through
-	// this pair.
-	Success bool
-}
-
-// newTimedPairResult wraps a pair result with a timestamp.
-func newTimedPairResult(timestamp time.Time,
-	result pairResult) TimedPairResult {
-
-	return TimedPairResult{
-		Timestamp:      timestamp,
-		MinPenalizeAmt: result.minPenalizeAmt,
-		Success:        result.success,
-	}
+	// FailTime is the time of the last failure.
+	FailTime time.Time
+
+	// FailAmt is the amount of the last failure. This amount may be pushed
+	// up if a later success is higher than the last failed amount.
+	FailAmt lnwire.MilliSatoshi
+
+	// SuccessTime is the time of the last success.
+	SuccessTime time.Time
+
+	// SuccessAmt is the highest amount that successfully forwarded. This
+	// isn't necessarily the last success amount. The value of this field
+	// may also be pushed down if a later failure is lower than the highest
+	// success amount. Because of this, SuccessAmt may not match
+	// SuccessTime.
+	SuccessAmt lnwire.MilliSatoshi
 }
 
 // MissionControlSnapshot contains a snapshot of the current state of mission
@@ -273,8 +268,8 @@ func (m *MissionControl) GetProbability(fromNode, toNode route.Vertex,
 }
 
 // setLastPairResult stores a result for a node pair.
-func (m *MissionControl) setLastPairResult(fromNode,
-	toNode route.Vertex, result TimedPairResult) {
+func (m *MissionControl) setLastPairResult(fromNode, toNode route.Vertex,
+	timestamp time.Time, result *pairResult) {
 
 	nodePairs, ok := m.lastPairResult[fromNode]
 	if !ok {
@@ -282,7 +277,60 @@ func (m *MissionControl) setLastPairResult(fromNode,
 		m.lastPairResult[fromNode] = nodePairs
 	}
 
-	nodePairs[toNode] = result
+	current := nodePairs[toNode]
+
+	// Apply the new result to the existing data for this pair. If there is
+	// no existing data, apply it to the default values for TimedPairResult.
+	if result.success {
+		successAmt := result.amt
+		current.SuccessTime = timestamp
+
+		// Only update the success amount if this amount is higher. This
+		// prevents the success range from shrinking when there is no
+		// reason to do so. For example: small amount probes shouldn't
+		// affect a previous success for a much larger amount.
+		if successAmt > current.SuccessAmt {
+			current.SuccessAmt = successAmt
+		}
+
+		// If the success amount goes into the failure range, move the
+		// failure range up. Future attempts up to the success amount
+		// are likely to succeed. We don't want to clear the failure
+		// completely, because we haven't learnt much for amounts above
+		// the current success amount.
+		if !current.FailTime.IsZero() && successAmt >= current.FailAmt {
+			current.FailAmt = successAmt + 1
+		}
+	} else {
+		// For failures we always want to update both the amount and the
+		// time. Those need to relate to the same result, because the
+		// time is used to gradually diminish the penality for that
+		// specific result. Updating the timestamp but not the amount
+		// could cause a failure for a lower amount (a more severe
+		// condition) to be revived as if it just happened.
+		failAmt := result.amt
+		current.FailTime = timestamp
+		current.FailAmt = failAmt
+
+		switch {
+		// The failure amount is set to zero when the failure is
+		// amount-independent, meaning that the attempt would have
+		// failed regardless of the amount. This should also reset the
+		// success amount to zero.
+		case failAmt == 0:
+			current.SuccessAmt = 0
+
+		// If the failure range goes into the success range, move the
+		// success range down.
+		case failAmt <= current.SuccessAmt:
+			current.SuccessAmt = failAmt - 1
+		}
+	}
+
+	log.Debugf("Setting %v->%v range to [%v-%v]",
+		fromNode, toNode, current.SuccessAmt, current.FailAmt)
+
+	nodePairs[toNode] = current
 }
 
 // setAllFail stores a fail result for all known connection of the given node.
@@ -295,9 +343,9 @@ func (m *MissionControl) setAllFail(fromNode route.Vertex,
 	}
 
 	for connection := range nodePairs {
-		nodePairs[connection] = newTimedPairResult(
-			timestamp, failPairResult(0),
-		)
+		nodePairs[connection] = TimedPairResult{
+			FailTime: timestamp,
+		}
 	}
 }
 
@@ -492,21 +540,19 @@ func (m *MissionControl) applyPaymentResult(
 	}
 
 	for pair, pairResult := range i.pairResults {
+		pairResult := pairResult
+
 		if pairResult.success {
 			log.Debugf("Reporting pair success to Mission "+
 				"Control: pair=%v", pair)
 		} else {
 			log.Debugf("Reporting pair failure to Mission "+
-				"Control: pair=%v, minPenalizeAmt=%v",
-				pair, pairResult.minPenalizeAmt)
+				"Control: pair=%v, amt=%v",
+				pair, pairResult.amt)
 		}
 
 		m.setLastPairResult(
-			pair.From, pair.To,
-			newTimedPairResult(
-				result.timeReply,
-				pairResult,
-			),
+			pair.From, pair.To, result.timeReply, &pairResult,
 		)
 	}
 
diff --git a/routing/probability_estimator.go b/routing/probability_estimator.go
index 1e60608cb..238a765f1 100644
--- a/routing/probability_estimator.go
+++ b/routing/probability_estimator.go
@@ -80,19 +80,20 @@ func (p *probabilityEstimator) getNodeProbability(now time.Time,
 	totalWeight := aprioriFactor
 
 	for _, result := range results {
-		age := now.Sub(result.Timestamp)
-
 		switch {
+
 		// Weigh success with a constant high weight of 1. There is no
-		// decay.
-		case result.Success:
+		// decay. Amt is never zero, so this clause is never executed
+		// when result.SuccessAmt is zero.
+		case amt <= result.SuccessAmt:
 			totalWeight++
 			probabilitiesTotal += p.prevSuccessProbability
 
 		// Weigh failures in accordance with their age. The base
 		// probability of a failure is considered zero, so nothing needs
 		// to be added to probabilitiesTotal.
-		case amt >= result.MinPenalizeAmt:
+		case !result.FailTime.IsZero() && amt >= result.FailAmt:
+			age := now.Sub(result.FailTime)
 			totalWeight += p.getWeight(age)
 		}
 	}
@@ -155,9 +156,10 @@ func (p *probabilityEstimator) calculateProbability(
 		return nodeProbability
 	}
 
-	// For successes, we have a fixed (high) probability. Those pairs
-	// will be assumed good until proven otherwise.
-	if lastPairResult.Success {
+	// For successes, we have a fixed (high) probability. Those pairs will
+	// be assumed good until proven otherwise. Amt is never zero, so this
+	// clause is never executed when lastPairResult.SuccessAmt is zero.
+	if amt <= lastPairResult.SuccessAmt {
 		return p.prevSuccessProbability
 	}
 
@@ -166,11 +168,11 @@ func (p *probabilityEstimator) calculateProbability(
 	// penalization. If the current amount is smaller than the amount that
 	// previously triggered a failure, we act as if this is an untried
 	// channel.
-	if amt < lastPairResult.MinPenalizeAmt {
+	if lastPairResult.FailTime.IsZero() || amt < lastPairResult.FailAmt {
 		return nodeProbability
 	}
 
-	timeSinceLastFailure := now.Sub(lastPairResult.Timestamp)
+	timeSinceLastFailure := now.Sub(lastPairResult.FailTime)
 
 	// Calculate success probability based on the weight of the last
 	// failure. When the failure is fresh, its weight is 1 and we'll return
diff --git a/routing/result_interpretation.go b/routing/result_interpretation.go
index 03457619e..7b3d539af 100644
--- a/routing/result_interpretation.go
+++ b/routing/result_interpretation.go
@@ -17,9 +17,9 @@ var (
 // pairResult contains the result of the interpretation of a payment attempt for
 // a specific node pair.
 type pairResult struct {
-	// minPenalizeAmt is the minimum amount for which a penalty should be
-	// applied based on this result. Only applies to fail results.
-	minPenalizeAmt lnwire.MilliSatoshi
+	// amt is the amount that was forwarded for this pair. Can be set to
+	// zero for failures that are amount independent.
+	amt lnwire.MilliSatoshi
 
 	// success indicates whether the payment attempt was successful through
 	// this pair.
@@ -29,24 +29,28 @@ type pairResult struct {
 // failPairResult creates a new result struct for a failure.
 func failPairResult(minPenalizeAmt lnwire.MilliSatoshi) pairResult {
 	return pairResult{
-		minPenalizeAmt: minPenalizeAmt,
+		amt: minPenalizeAmt,
 	}
 }
 
-// successPairResult creates a new result struct for a success.
-func successPairResult() pairResult {
+// newSuccessPairResult creates a new result struct for a success.
+func successPairResult(successAmt lnwire.MilliSatoshi) pairResult {
 	return pairResult{
 		success: true,
+		amt:     successAmt,
 	}
 }
 
 // String returns the human-readable representation of a pair result.
 func (p pairResult) String() string {
+	var resultType string
 	if p.success {
-		return "success"
+		resultType = "success"
+	} else {
+		resultType = "failed"
 	}
 
-	return fmt.Sprintf("failed (minPenalizeAmt=%v)", p.minPenalizeAmt)
+	return fmt.Sprintf("%v (amt=%v)", resultType, p.amt)
 }
 
 // interpretedResult contains the result of the interpretation of a payment
@@ -458,9 +462,9 @@ func (i *interpretedResult) successPairRange(
 	rt *route.Route, fromIdx, toIdx int) {
 
 	for idx := fromIdx; idx <= toIdx; idx++ {
-		pair, _ := getPair(rt, idx)
+		pair, amt := getPair(rt, idx)
 
-		i.pairResults[pair] = successPairResult()
+		i.pairResults[pair] = successPairResult(amt)
 	}
 }
 


Test patch:
diff --git a/routing/missioncontrol_test.go b/routing/missioncontrol_test.go
index f7b2f33a0..f921b71de 100644
--- a/routing/missioncontrol_test.go
+++ b/routing/missioncontrol_test.go
@@ -204,12 +204,12 @@ func TestMissionControlChannelUpdate(t *testing.T) {
 	ctx.reportFailure(
 		0, lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate{}),
 	)
-	ctx.expectP(0, testAprioriHopProbability)
+	ctx.expectP(100, testAprioriHopProbability)
 
 	// Report another failure for the same channel. We expect it to be
 	// pruned.
 	ctx.reportFailure(
 		0, lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate{}),
 	)
-	ctx.expectP(0, 0)
+	ctx.expectP(100, 0)
 }
diff --git a/routing/probability_estimator_test.go b/routing/probability_estimator_test.go
index b2f159d1f..384b39b63 100644
--- a/routing/probability_estimator_test.go
+++ b/routing/probability_estimator_test.go
@@ -84,10 +84,9 @@ func TestProbabilityEstimatorOneSuccess(t *testing.T) {
 	ctx := newEstimatorTestContext(t)
 
 	ctx.results = map[int]TimedPairResult{
-		node1: newTimedPairResult(
-			testTime.Add(-time.Hour),
-			successPairResult(),
-		),
+		node1: {
+			SuccessAmt: lnwire.MilliSatoshi(1000),
+		},
 	}
 
 	// Because of the previous success, this channel keep reporting a high
@@ -108,10 +107,10 @@ func TestProbabilityEstimatorOneFailure(t *testing.T) {
 	ctx := newEstimatorTestContext(t)
 
 	ctx.results = map[int]TimedPairResult{
-		node1: newTimedPairResult(
-			testTime.Add(-time.Hour),
-			failPairResult(0),
-		),
+		node1: {
+			FailTime: testTime.Add(-time.Hour),
+			FailAmt:  lnwire.MilliSatoshi(50),
+		},
 	}
 
 	// For an untried node, we expected the node probability. The weight for
@@ -131,18 +130,17 @@ func TestProbabilityEstimatorMix(t *testing.T) {
 	ctx := newEstimatorTestContext(t)
 
 	ctx.results = map[int]TimedPairResult{
-		node1: newTimedPairResult(
-			testTime.Add(-time.Hour),
-			successPairResult(),
-		),
-		node2: newTimedPairResult(
-			testTime.Add(-2*time.Hour),
-			failPairResult(0),
-		),
-		node3: newTimedPairResult(
-			testTime.Add(-3*time.Hour),
-			failPairResult(0),
-		),
+		node1: {
+			SuccessAmt: lnwire.MilliSatoshi(1000),
+		},
+		node2: {
+			FailTime: testTime.Add(-2 * time.Hour),
+			FailAmt:  lnwire.MilliSatoshi(50),
+		},
+		node3: {
+			FailTime: testTime.Add(-3 * time.Hour),
+			FailAmt:  lnwire.MilliSatoshi(50),
+		},
 	}
 
 	// We expect the probability for a previously successful channel to
diff --git a/routing/result_interpretation_test.go b/routing/result_interpretation_test.go
index 4f3fd2508..42f3ec879 100644
--- a/routing/result_interpretation_test.go
+++ b/routing/result_interpretation_test.go
@@ -74,7 +74,7 @@ var resultTestCases = []resultTestCase{
 
 		expectedResult: &interpretedResult{
 			pairResults: map[DirectedNodePair]pairResult{
-				getTestPair(0, 1): successPairResult(),
+				getTestPair(0, 1): successPairResult(100),
 				getTestPair(1, 2): failPairResult(99),
 			},
 		},
@@ -109,8 +109,8 @@ var resultTestCases = []resultTestCase{
 
 		expectedResult: &interpretedResult{
 			pairResults: map[DirectedNodePair]pairResult{
-				getTestPair(0, 1): successPairResult(),
-				getTestPair(1, 2): successPairResult(),
+				getTestPair(0, 1): successPairResult(100),
+				getTestPair(1, 2): successPairResult(99),
 			},
 			finalFailureReason: &reasonIncorrectDetails,
 		},
@@ -124,7 +124,7 @@ var resultTestCases = []resultTestCase{
 
 		expectedResult: &interpretedResult{
 			pairResults: map[DirectedNodePair]pairResult{
-				getTestPair(0, 1): successPairResult(),
+				getTestPair(0, 1): successPairResult(100),
 			},
 		},
 	},
@@ -137,8 +137,8 @@ var resultTestCases = []resultTestCase{
 
 		expectedResult: &interpretedResult{
 			pairResults: map[DirectedNodePair]pairResult{
-				getTestPair(0, 1): successPairResult(),
-				getTestPair(1, 2): successPairResult(),
+				getTestPair(0, 1): successPairResult(100),
+				getTestPair(1, 2): successPairResult(99),
 			},
 		},
 	},
@@ -190,6 +190,7 @@ var resultTestCases = []resultTestCase{
 			pairResults: map[DirectedNodePair]pairResult{
 				getTestPair(0, 1): {
 					success: true,
+					amt:     100,
 				},
 				getTestPair(1, 2): {},
 				getTestPair(2, 1): {},
@@ -211,12 +212,15 @@ var resultTestCases = []resultTestCase{
 			pairResults: map[DirectedNodePair]pairResult{
 				getTestPair(0, 1): {
 					success: true,
+					amt:     100,
 				},
 				getTestPair(1, 2): {
 					success: true,
+					amt:     99,
 				},
 				getTestPair(2, 3): {
 					success: true,
+					amt:     97,
 				},
 				getTestPair(4, 3): {},
 			},
@@ -238,9 +242,11 @@ var resultTestCases = []resultTestCase{
 			pairResults: map[DirectedNodePair]pairResult{
 				getTestPair(0, 1): {
 					success: true,
+					amt:     100,
 				},
 				getTestPair(1, 2): {
 					success: true,
+					amt:     99,
 				},
 				getTestPair(3, 2): {},
 				getTestPair(3, 4): {},