mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-19 13:18:26 +02:00
Add received payments table and get it in rpc method (#443)
This commit is contained in:
parent
f7c5fabe43
commit
0dde62bf46
10 changed files with 181 additions and 0 deletions
38
alembic/versions/387dd872e766_add_received_payment_table.py
Normal file
38
alembic/versions/387dd872e766_add_received_payment_table.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
"""Add received_payment table
|
||||
|
||||
Revision ID: 387dd872e766
|
||||
Revises: ccc641c2ce52
|
||||
Create Date: 2020-11-11 01:24:10.148710
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '387dd872e766'
|
||||
down_revision = 'ccc641c2ce52'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('received_payment',
|
||||
sa.Column('received_payment_id', sa.Integer(), nullable=False),
|
||||
sa.Column('created', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
||||
sa.Column('squeak_hash', sa.String(length=64), nullable=False),
|
||||
sa.Column('preimage_hash', sa.String(length=64), nullable=False),
|
||||
sa.Column('price_msat', sa.Integer(), nullable=False),
|
||||
sa.Column('is_paid', sa.Boolean(), nullable=False),
|
||||
sa.Column('payment_time', sa.DateTime(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('received_payment_id'),
|
||||
sa.UniqueConstraint('preimage_hash')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('received_payment')
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -913,6 +913,13 @@ def test_connect_other_node(server_stub, admin_stub, other_server_stub, other_ad
|
|||
assert sent_payment_time > datetime.datetime.now() - five_minutes
|
||||
assert sent_payment_time < datetime.datetime.now()
|
||||
|
||||
# Get the received payment from the seller node
|
||||
get_received_payments_response = admin_stub.GetReceivedPayments(
|
||||
squeak_admin_pb2.GetReceivedPaymentsRequest(),
|
||||
)
|
||||
squeak_hashes = [received_payment.squeak_hash for received_payment in get_received_payments_response.received_payments]
|
||||
assert saved_squeak_hash in squeak_hashes
|
||||
|
||||
|
||||
def test_download_single_squeak(server_stub, admin_stub, other_server_stub, other_admin_stub, lightning_client, signing_profile_id, saved_squeak_hash):
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,10 @@ service SqueakAdmin {
|
|||
*/
|
||||
rpc GetSqueakDetails (GetSqueakDetailsRequest) returns (GetSqueakDetailsReply) {}
|
||||
|
||||
/** sqkadmin: `getreceivedpayments`
|
||||
*/
|
||||
rpc GetReceivedPayments (GetReceivedPaymentsRequest) returns (GetReceivedPaymentsReply) {}
|
||||
|
||||
}
|
||||
|
||||
message CreateSigningProfileRequest {
|
||||
|
|
@ -645,3 +649,31 @@ message SqueakDetailEntry {
|
|||
/// The seriallized squeak in hex encoding
|
||||
string serialized_squeak_hex = 1;
|
||||
}
|
||||
|
||||
message GetReceivedPaymentsRequest {
|
||||
}
|
||||
|
||||
message GetReceivedPaymentsReply {
|
||||
/// The received payments
|
||||
repeated ReceivedPayment received_payments = 1;
|
||||
}
|
||||
|
||||
message ReceivedPayment {
|
||||
/// The received payment id
|
||||
int32 received_payment_id = 1;
|
||||
|
||||
/// The squeak hash
|
||||
string squeak_hash = 2;
|
||||
|
||||
/// The preimage hash
|
||||
string preimage_hash = 3;
|
||||
|
||||
/// The price_msat
|
||||
int64 price_msat = 4;
|
||||
|
||||
/// Is the payment paid
|
||||
bool is_paid = 5;
|
||||
|
||||
/// Time of payment
|
||||
int64 payment_time_ms = 6;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from squeaknode.admin.util import offer_entry_to_message
|
|||
from squeaknode.admin.util import sent_payment_with_peer_to_message
|
||||
from squeaknode.admin.util import sync_result_to_message
|
||||
from squeaknode.admin.util import squeak_entry_to_detail_message
|
||||
from squeaknode.admin.util import received_payment_to_message
|
||||
|
||||
from proto import squeak_admin_pb2, squeak_admin_pb2_grpc
|
||||
|
||||
|
|
@ -415,3 +416,12 @@ class SqueakAdminServerHandler(object):
|
|||
return squeak_admin_pb2.GetSqueakDetailsReply(
|
||||
squeak_detail_entry=detail_message
|
||||
)
|
||||
|
||||
def handle_get_received_payments(self, request):
|
||||
logger.info("Handle get received payments")
|
||||
received_payments = self.squeak_node.get_received_payments()
|
||||
logger.info("Received payments: {}".format(received_payments))
|
||||
received_payment_msgs = [received_payment_to_message(received_payment) for received_payment in received_payments]
|
||||
return squeak_admin_pb2.GetReceivedPaymentsReply(
|
||||
received_payments=received_payment_msgs,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -154,6 +154,9 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
|
|||
def GetSqueakDetails(self, request, context):
|
||||
return self.handler.handle_get_squeak_details(request)
|
||||
|
||||
def GetReceivedPayments(self, request, context):
|
||||
return self.handler.handle_get_received_payments(request)
|
||||
|
||||
def serve(self):
|
||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||
squeak_admin_pb2_grpc.add_SqueakAdminServicer_to_server(self, server)
|
||||
|
|
|
|||
|
|
@ -120,3 +120,17 @@ def squeak_entry_to_detail_message(squeak_entry_with_profile):
|
|||
return squeak_admin_pb2.SqueakDetailEntry(
|
||||
serialized_squeak_hex=serialized_squeak.hex(),
|
||||
)
|
||||
|
||||
def received_payment_to_message(received_payment):
|
||||
if received_payment is None:
|
||||
return None
|
||||
return squeak_admin_pb2.ReceivedPayment(
|
||||
received_payment_id=received_payment.received_payment_id,
|
||||
squeak_hash=received_payment.squeak_hash,
|
||||
preimage_hash=received_payment.preimage_hash,
|
||||
price_msat=received_payment.price_msat,
|
||||
is_paid=received_payment.is_paid,
|
||||
payment_time_ms=int(received_payment.payment_time.timestamp()) * 1000
|
||||
if received_payment.payment_time
|
||||
else None,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -108,3 +108,15 @@ class Models:
|
|||
Column("node_pubkey", String(66), nullable=False),
|
||||
Column("preimage_is_valid", Boolean, nullable=False),
|
||||
)
|
||||
|
||||
self.received_payments = Table(
|
||||
"received_payment",
|
||||
self.metadata,
|
||||
Column("received_payment_id", Integer, primary_key=True),
|
||||
Column("created", DateTime, server_default=func.now(), nullable=False),
|
||||
Column("squeak_hash", String(64), nullable=False),
|
||||
Column("preimage_hash", String(64), unique=True, nullable=False),
|
||||
Column("price_msat", Integer, nullable=False, default=0),
|
||||
Column("is_paid", Boolean, nullable=False),
|
||||
Column("payment_time", DateTime, nullable=True),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ from squeaknode.core.squeak_entry_with_profile import SqueakEntryWithProfile
|
|||
from squeaknode.server.squeak_peer import SqueakPeer
|
||||
from squeaknode.server.squeak_profile import SqueakProfile
|
||||
from squeaknode.server.sent_payment import SentPayment
|
||||
from squeaknode.server.received_payment import ReceivedPayment
|
||||
from squeaknode.server.util import get_hash
|
||||
from squeaknode.db.models import Models
|
||||
from squeaknode.db.migrations import run_migrations
|
||||
|
|
@ -80,6 +81,10 @@ class SqueakDb:
|
|||
def sent_payments(self):
|
||||
return self.models.sent_payments
|
||||
|
||||
@property
|
||||
def received_payments(self):
|
||||
return self.models.received_payments
|
||||
|
||||
def insert_squeak(self, squeak):
|
||||
""" Insert a new squeak. """
|
||||
vch_decryption_key = squeak.GetDecryptionKey().get_bytes() if squeak.HasDecryptionKey() else None
|
||||
|
|
@ -927,6 +932,33 @@ class SqueakDb:
|
|||
row = result.fetchone()
|
||||
return self._parse_sent_payment_with_peer(row)
|
||||
|
||||
def insert_received_payment(self, received_payment):
|
||||
""" Insert a new received payment. """
|
||||
ins = self.received_payments.insert().values(
|
||||
squeak_hash=received_payment.squeak_hash,
|
||||
preimage_hash=received_payment.preimage_hash,
|
||||
price_msat=received_payment.price_msat,
|
||||
is_paid=received_payment.is_paid,
|
||||
)
|
||||
with self.get_connection() as connection:
|
||||
res = connection.execute(ins)
|
||||
received_payment_id = res.inserted_primary_key[0]
|
||||
return received_payment_id
|
||||
|
||||
def get_received_payments(self):
|
||||
""" Get all received payments. """
|
||||
s = (
|
||||
select([self.received_payments])
|
||||
.order_by(
|
||||
self.received_payments.c.created.desc(),
|
||||
)
|
||||
)
|
||||
with self.get_connection() as connection:
|
||||
result = connection.execute(s)
|
||||
rows = result.fetchall()
|
||||
received_payments = [self._parse_received_payment(row) for row in rows]
|
||||
return received_payments
|
||||
|
||||
def _parse_squeak_entry(self, row):
|
||||
if row is None:
|
||||
return None
|
||||
|
|
@ -1037,3 +1069,15 @@ class SqueakDb:
|
|||
sent_payment=sent_payment,
|
||||
peer=peer,
|
||||
)
|
||||
|
||||
def _parse_received_payment(self, row):
|
||||
if row is None:
|
||||
return None
|
||||
return ReceivedPayment(
|
||||
received_payment_id=row["received_payment_id"],
|
||||
squeak_hash=row["squeak_hash"],
|
||||
preimage_hash=row["preimage_hash"],
|
||||
price_msat=row["price_msat"],
|
||||
is_paid=row["is_paid"],
|
||||
payment_time=row["payment_time"],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from squeaknode.node.squeak_store import SqueakStore
|
|||
from squeaknode.node.squeak_sync_status import SqueakSyncController
|
||||
from squeaknode.node.squeak_whitelist import SqueakWhitelist
|
||||
from squeaknode.server.buy_offer import BuyOffer
|
||||
from squeaknode.server.received_payment import ReceivedPayment
|
||||
from squeaknode.server.squeak_peer import SqueakPeer
|
||||
from squeaknode.server.squeak_profile import SqueakProfile
|
||||
from squeaknode.server.sent_payment import SentPayment
|
||||
|
|
@ -131,6 +132,17 @@ class SqueakNode:
|
|||
# Get the lightning network node pubkey
|
||||
get_info_response = self.lightning_client.get_info()
|
||||
pubkey = get_info_response.identity_pubkey
|
||||
# Save the incoming potential payment in the databse.
|
||||
self.squeak_db.insert_received_payment(
|
||||
ReceivedPayment(
|
||||
received_payment_id=None,
|
||||
squeak_hash=squeak_hash,
|
||||
preimage_hash=preimage_hash.hex(),
|
||||
price_msat=self.price_msat,
|
||||
is_paid=False,
|
||||
payment_time=None,
|
||||
)
|
||||
)
|
||||
# Return the buy offer
|
||||
return BuyOffer(
|
||||
squeak_hash,
|
||||
|
|
@ -336,3 +348,6 @@ class SqueakNode:
|
|||
|
||||
def get_sent_payment(self, sent_payment_id):
|
||||
return self.squeak_db.get_sent_payment(sent_payment_id)
|
||||
|
||||
def get_received_payments(self):
|
||||
return self.squeak_db.get_received_payments()
|
||||
|
|
|
|||
6
squeaknode/server/received_payment.py
Normal file
6
squeaknode/server/received_payment.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
from collections import namedtuple
|
||||
|
||||
ReceivedPayment = namedtuple(
|
||||
"ReceivedPayment",
|
||||
"received_payment_id, squeak_hash, preimage_hash, price_msat, is_paid, payment_time",
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue