Skip to content

Store more payment info for sent payments#1048

Closed
araspitzu wants to merge 11 commits intomasterfrom
save_payment_info
Closed

Store more payment info for sent payments#1048
araspitzu wants to merge 11 commits intomasterfrom
save_payment_info

Conversation

@araspitzu
Copy link
Contributor

@araspitzu araspitzu commented Jun 25, 2019

Summary of changes

Rationale

For various reasons the mobile app is getting rid of its own database and we need to store some extra info in the eclair-core database. This PR adds to each sent payment record the recipient node id, the payment request that is being paid and the deserialized description from the payment request. The description is stored in deserialized form to avoid potentlially costly operations on mobile.

Database layer changes

The sent_payments table in 'payment' DB has been altered to include three new optional columns where we store the payment request that was being paid ( as payment_request), the deserialized description and the node id of the recipient, all fields are nullable. The sent_payments table is now migrated to version 3.

Implementation details

The new feature is only exposed through eclair's internal API send and is not exposed via HTTP APIs.

@araspitzu araspitzu force-pushed the save_payment_info branch from fbf4c86 to 198d307 Compare June 25, 2019 14:53
@codecov-io
Copy link

codecov-io commented Jun 25, 2019

Codecov Report

Merging #1048 into master will increase coverage by 0.31%.
The diff coverage is 96.42%.

@@            Coverage Diff             @@
##           master    #1048      +/-   ##
==========================================
+ Coverage   81.93%   82.25%   +0.31%     
==========================================
  Files          97       97              
  Lines        7480     7783     +303     
  Branches      298      313      +15     
==========================================
+ Hits         6129     6402     +273     
- Misses       1351     1381      +30
Impacted Files Coverage Δ
...src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala 100% <ø> (ø) ⬆️
...main/scala/fr/acinq/eclair/payment/Autoprobe.scala 0% <0%> (ø) ⬆️
...ala/fr/acinq/eclair/payment/PaymentLifecycle.scala 88.49% <100%> (ø) ⬆️
...r-core/src/main/scala/fr/acinq/eclair/Eclair.scala 51.66% <100%> (-1.96%) ⬇️
...a/fr/acinq/eclair/db/sqlite/SqlitePaymentsDb.scala 99.27% <100%> (+0.15%) ⬆️
.../scala/fr/acinq/eclair/db/sqlite/SqliteUtils.scala 100% <100%> (ø) ⬆️
...e/src/main/scala/fr/acinq/eclair/api/Service.scala 69.75% <66.66%> (+0.76%) ⬆️
...c/main/scala/fr/acinq/eclair/payment/Relayer.scala 87.67% <0%> (-0.21%) ⬇️
...-core/src/main/scala/fr/acinq/eclair/io/Peer.scala 74.45% <0%> (+0.31%) ⬆️
... and 5 more

@araspitzu araspitzu marked this pull request as ready for review June 26, 2019 14:42
@araspitzu araspitzu requested review from dpad85 and pm47 June 26, 2019 14:42
Use description from the invoice in paymentDB.sent_payments,
use datatype BLOB to store descriptions
* @param targetNodeId the recipient of this payment
*/
case class OutgoingPayment(id: UUID, paymentHash: ByteVector32, preimage:Option[ByteVector32], amountMsat: Long, createdAt: Long, completedAt: Option[Long], status: OutgoingPaymentStatus.Value)
case class OutgoingPayment(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is a bit weird, it should be:

case class OutgoingPayment(id: UUID,
                           paymentHash: ByteVector32,
                           preimage: Option[ByteVector32],
                           amountMsat: Long,
                           createdAt: Long,
                           completedAt: Option[Long],
                           status: OutgoingPaymentStatus.Value,
                           paymentRequest_opt: Option[PaymentRequest] = None,
                           description_opt: Option[String] = None,
                           targetNodeId: PublicKey)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7c2e8c9


def getByteVector32Nullable(columnLabel: String): Option[ByteVector32] = getByteVectorNullable(columnLabel).map(ByteVector32(_))

def getStringNullable(columnLabel: String): Option[String] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is getStringNullable not alongside getNullableLong (see above)?

We should move getNullableLong into ExtendedResultSet for consistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, done in 7c2e8c9

case Event(c: SendPayment, WaitingForRequest) =>
router ! RouteRequest(nodeParams.nodeId, c.targetNodeId, c.amountMsat, c.assistedRoutes, routeParams = c.routeParams)
paymentsDb.addOutgoingPayment(OutgoingPayment(id, c.paymentHash, None, c.amountMsat, Platform.currentTime, None, OutgoingPaymentStatus.PENDING))
// val desc: Option[String] = c.paymentRequest_opt.map(_.description.fold(_ => _, _.toHex))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment should be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 7c2e8c9

statement.executeUpdate("ALTER TABLE sent_payments ADD payment_request TEXT")
statement.executeUpdate("ALTER TABLE sent_payments ADD description BLOB")
statement.executeUpdate(s"ALTER TABLE sent_payments ADD target_node_id BLOB DEFAULT '03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f' NOT NULL")
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a default node id for the payment destination does not sound right. I think we should either make this field nullable, meaning that OutgoingPayment.targetNodeId would be optional, or have a "" or "unknown"default value for the target_node_id column.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, i've made a fix in 6c71ea2 where the targetNodeId becomes optional (and there is no default for migrated records)

maxAttempts: Int,
routeParams: Option[RouteParams] = None) extends GenericSendPayment {
routeParams: Option[RouteParams] = None,
paymentRequest_opt: Option[PaymentRequest] = None) extends GenericSendPayment {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the paymentRequest_opt attribute should be moved upward in the constructor arguments list, so that it's alongside paymentHash, targetNodeId, and not alongside payment parameters arguments.

case class SendPayment(amountMsat: Long,
                         paymentHash: ByteVector32,
                         targetNodeId: PublicKey,
                         paymentRequest_opt: Option[PaymentRequest] = None,
                         assistedRoutes: Seq[Seq[ExtraHop]] = Nil,
                         finalCltvExpiry: Long = Channel.MIN_CLTV_EXPIRY,
                         maxAttempts: Int,
                         routeParams: Option[RouteParams] = None) extends ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, reorganized in 7c2e8c9

@t-bast
Copy link
Member

t-bast commented Sep 20, 2019

Superceded by #1130 🎉

@t-bast t-bast closed this Sep 20, 2019
@araspitzu araspitzu deleted the save_payment_info branch November 18, 2019 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants