From 52427c8276c4879349d3d08f5b423515828edc59 Mon Sep 17 00:00:00 2001 From: Prathamesh Musale Date: Wed, 11 Oct 2023 11:31:41 +0530 Subject: [PATCH] Implement payment authentication --- pkg/payments/payments_manager.go | 65 ++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/pkg/payments/payments_manager.go b/pkg/payments/payments_manager.go index 1547846e..bce32616 100644 --- a/pkg/payments/payments_manager.go +++ b/pkg/payments/payments_manager.go @@ -17,6 +17,7 @@ package payments import ( + "errors" "math/big" "sync" "time" @@ -41,6 +42,14 @@ const ( DEFAULT_LRU_CACHE_VOUCHER_TTL = 5 * 60 // 5mins DEFAULT_LRU_CACHE_MAX_PAYMENT_CHANNELS = 10000 DEFAULT_LRU_CACHE_PAYMENT_CHANNEL_TTL = DEFAULT_LRU_CACHE_ACCOUNT_TTL + + DEFAULT_VOUCHER_CHECK_INTERVAL = 2 + DEFAULT_VOUCHER_CHECK_ATTEMPTS = 5 +) + +var ( + ERR_PAYMENT_NOT_RECEIVED = errors.New("Payment not received") + ERR_AMOUNT_INSUFFICIENT = errors.New("Payment amount insufficient") ) type Payment struct { @@ -48,11 +57,6 @@ type Payment struct { amount *big.Int } -type paymentVoucher struct { - payer common.Address - voucherHash common.Hash -} - // Struct representing payments manager // Maintains either an in-process Nitro node or communication with an out-of-process Nitro node type PaymentsManager struct { @@ -66,14 +70,11 @@ type PaymentsManager struct { paidSoFarOnChannel *expirable.LRU[nitroTypes.Destination, *big.Int] - paymentListeners []chan paymentVoucher - // Used to signal shutdown of the service quitChan chan bool } func NewPaymentsManager(runInProcessNitroNode bool) (PaymentsManager, error) { - // TODO: Implement var err error pm := PaymentsManager{runInProcessNitroNode: runInProcessNitroNode} @@ -130,6 +131,50 @@ func (pm *PaymentsManager) Stop() error { return nil } +func (pm *PaymentsManager) AuthenticatePayment(voucherHash common.Hash, signerAddress common.Address, value *big.Int) error { + // Check the payments map for required voucher + var isPaymentReceived, isOfSufficientValue bool + for i := 0; i < DEFAULT_VOUCHER_CHECK_ATTEMPTS; i++ { + isPaymentReceived, isOfSufficientValue = pm.acceptReceivedPayment(voucherHash, signerAddress, value) + + if isPaymentReceived { + if !isOfSufficientValue { + return ERR_AMOUNT_INSUFFICIENT + } + + return nil + } + + // Retry after an interval if voucher not found + log.Debugf("Payment from %s not found, retrying after %d sec...", signerAddress, DEFAULT_VOUCHER_CHECK_INTERVAL) + time.Sleep(DEFAULT_VOUCHER_CHECK_INTERVAL * time.Second) + } + + return ERR_PAYMENT_NOT_RECEIVED +} + +// Check for a given payment voucher in LRU cache map +// Returns whether the voucher was found, whether it was of sufficient value +func (pm *PaymentsManager) acceptReceivedPayment(voucherHash common.Hash, signerAddress common.Address, minRequiredValue *big.Int) (bool, bool) { + paymentsMap, ok := pm.receivedPayments.Get(signerAddress) + if !ok { + return false, false + } + + receivedPayment, ok := paymentsMap.Get(voucherHash) + if !ok { + return false, false + } + + if receivedPayment.amount.Cmp(minRequiredValue) < 0 { + return true, false + } + + // Delete the voucher from map after consuming it + paymentsMap.Remove(voucherHash) + return true, true +} + func (pm *PaymentsManager) run(receivedVouchers <-chan payments.Voucher) { log.Info("starting voucher subscription...") for { @@ -168,10 +213,6 @@ func (pm *PaymentsManager) run(receivedVouchers <-chan payments.Voucher) { } paymentsMap.Add(voucherHash, Payment{voucher: voucher, amount: paymentAmount}) - - for _, listener := range pm.paymentListeners { - listener <- paymentVoucher{payer: payer, voucherHash: voucherHash} - } case <-pm.quitChan: log.Info("stopping voucher subscription loop") // TODO: stop the nitro node if that means anything