Rename received offer (#606)

* Rename received_offer db table

* Rename core struct to ReceivedOffer

* Rename received_offer_id field

* Move received offer with peer module
This commit is contained in:
Jonathan Zernik 2021-01-11 16:33:56 -08:00 committed by GitHub
parent 96b3adb5a2
commit ccc7b66c40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 125 deletions

View file

@ -7,7 +7,7 @@ Alembic is used for database migrations.
To change any database model, follow these steps.
- Make sure that you have an up-to-date squeaknode with a sqlite database.
- Make a note of the path to the ".db" sqlite database file. (Usually `~/.sqk/data/testnet/data.db` by default)
- Make a note of the path to the ".db" sqlite database file. (Usually `~/.sqk/data/testnet/data.db` by default). If this is an initial migration, then create an empty file at this location.
- Make the changes to database models in `squeaknode/db/models.py`
- Update the `alembic.ini` file to point to the sqlite file from before:
```
@ -15,7 +15,7 @@ To change any database model, follow these steps.
```
- Run the command to generate a new alembic migration:
```
$ virtuelenv venv
$ virtualenv venv
$ pip install -r requirements.txt
$ pip install -e .
$ alembic -c squeaknode/db/alembic.ini revision --autogenerate -m "<YOUR_MESSAGE>"

View file

@ -595,32 +595,29 @@ message SentPayment {
/// The sent payment id
int32 sent_payment_id = 1;
/// The offer id
int32 offer_id = 2;
/// The peer id
int32 peer_id = 3;
int32 peer_id = 2;
/// The peer name
string peer_name = 4;
string peer_name = 3;
/// The squeak hash
string squeak_hash = 5;
string squeak_hash = 4;
/// The payment hash
string payment_hash = 6;
string payment_hash = 5;
/// The secret key
string secret_key = 7;
string secret_key = 6;
/// The price_msat
int64 price_msat = 8;
int64 price_msat = 7;
/// The seller node pubkey
string node_pubkey = 9;
string node_pubkey = 8;
/// time_ms
int64 time_ms = 10;
int64 time_ms = 9;
}
message SyncSqueakRequest {

View file

@ -1,6 +1,7 @@
import logging
from proto import squeak_admin_pb2
from squeaknode.core.received_offer_with_peer import ReceivedOfferWithPeer
from squeaknode.core.util import get_hash
from squeaknode.core.util import get_replyto
@ -63,21 +64,21 @@ def squeak_peer_to_message(squeak_peer):
)
def offer_entry_to_message(offer_entry):
if offer_entry is None:
def offer_entry_to_message(received_offer_entry: ReceivedOfferWithPeer):
if received_offer_entry is None:
return None
offer = offer_entry.offer
peer = squeak_peer_to_message(offer_entry.peer)
received_offer = received_offer_entry.received_offer
peer = squeak_peer_to_message(received_offer_entry.peer)
return squeak_admin_pb2.OfferDisplayEntry(
offer_id=offer.offer_id,
squeak_hash=offer.squeak_hash.hex(),
price_msat=offer.price_msat,
node_pubkey=offer.destination,
node_host=offer.node_host,
node_port=offer.node_port,
offer_id=received_offer.received_offer_id,
squeak_hash=received_offer.squeak_hash.hex(),
price_msat=received_offer.price_msat,
node_pubkey=received_offer.destination,
node_host=received_offer.node_host,
node_port=received_offer.node_port,
peer=peer,
invoice_timestamp=offer.invoice_timestamp,
invoice_expiry=offer.invoice_expiry,
invoice_timestamp=received_offer.invoice_timestamp,
invoice_expiry=received_offer.invoice_expiry,
)
@ -88,7 +89,6 @@ def sent_payment_with_peer_to_message(sent_payment_with_peer):
peer = sent_payment_with_peer.peer
return squeak_admin_pb2.SentPayment(
sent_payment_id=sent_payment.sent_payment_id,
offer_id=sent_payment.offer_id,
peer_id=sent_payment.peer_id,
peer_name=peer.peer_name,
squeak_hash=sent_payment.squeak_hash.hex(),

View file

@ -2,9 +2,9 @@ from typing import NamedTuple
from typing import Optional
class Offer(NamedTuple):
class ReceivedOffer(NamedTuple):
"""Class for saving an offer from a remote peer."""
offer_id: Optional[int]
received_offer_id: Optional[int]
squeak_hash: bytes
price_msat: int
payment_hash: bytes

View file

@ -1,10 +1,10 @@
from typing import NamedTuple
from squeaknode.core.offer import Offer
from squeaknode.core.received_offer import ReceivedOffer
from squeaknode.core.squeak_peer import SqueakPeer
class OfferWithPeer(NamedTuple):
class ReceivedOfferWithPeer(NamedTuple):
"""Class for saving an offer from a remote peer."""
offer: Offer
received_offer: ReceivedOffer
peer: SqueakPeer

View file

@ -6,7 +6,6 @@ from typing import Optional
class SentPayment(NamedTuple):
sent_payment_id: Optional[int]
created: Optional[datetime]
offer_id: int
peer_id: int
squeak_hash: bytes
payment_hash: bytes

View file

@ -8,7 +8,7 @@ from squeak.core.signing import CSigningKey
from squeak.core.signing import CSqueakAddress
from proto import squeak_server_pb2
from squeaknode.core.offer import Offer
from squeaknode.core.received_offer import ReceivedOffer
from squeaknode.core.sent_offer import SentOffer
from squeaknode.core.squeak_address_validator import SqueakAddressValidator
from squeaknode.core.squeak_peer import SqueakPeer
@ -203,24 +203,25 @@ class SqueakController:
def get_buy_offer_with_peer(self, offer_id: int):
return self.squeak_db.get_offer_with_peer(offer_id)
def pay_offer(self, offer_id: int) -> int:
def pay_offer(self, received_offer_id: int) -> int:
# Get the offer from the database
offer_with_peer = self.squeak_db.get_offer_with_peer(offer_id)
offer = offer_with_peer.offer
logger.info("Paying offer: {}".format(offer))
sent_payment = self.squeak_core.pay_offer(offer)
offer_with_peer = self.squeak_db.get_offer_with_peer(received_offer_id)
received_offer = offer_with_peer.received_offer
logger.info("Paying received offer: {}".format(received_offer))
sent_payment = self.squeak_core.pay_offer(received_offer)
sent_payment_id = self.squeak_db.insert_sent_payment(sent_payment)
# Delete the offer
# Delete the received offer
self.squeak_db.delete_offer(sent_payment.payment_hash)
secret_key = sent_payment.secret_key
squeak_entry = self.squeak_db.get_squeak_entry(offer.squeak_hash)
squeak_entry = self.squeak_db.get_squeak_entry(
received_offer.squeak_hash)
squeak = squeak_entry.squeak
# Check the decryption key
squeak.SetDecryptionKey(secret_key)
CheckSqueak(squeak)
# Set the decryption key in the database
self.unlock_squeak(
offer.squeak_hash,
received_offer.squeak_hash,
secret_key,
)
return sent_payment_id
@ -296,7 +297,7 @@ class SqueakController:
def get_network(self):
return self.config.core.network
def get_offer(self, squeak: CSqueak, offer_msg: squeak_server_pb2.SqueakBuyOffer, peer: SqueakPeer) -> Offer:
def get_offer(self, squeak: CSqueak, offer_msg: squeak_server_pb2.SqueakBuyOffer, peer: SqueakPeer) -> ReceivedOffer:
return self.squeak_core.get_offer(squeak, offer_msg, peer)
def get_squeak_entry_with_profile(self, squeak_hash: bytes):
@ -342,9 +343,9 @@ class SqueakController:
peer_id,
)
def save_offer(self, offer: Offer):
logger.info("Saving offer: {}".format(offer))
self.squeak_db.insert_offer(offer)
def save_offer(self, received_offer: ReceivedOffer):
logger.info("Saving received offer: {}".format(received_offer))
self.squeak_db.insert_offer(received_offer)
def get_followed_addresses(self):
followed_profiles = self.squeak_db.get_following_profiles()

View file

@ -8,7 +8,7 @@ from squeak.core import MakeSqueakFromStr
from squeak.core.signing import CSigningKey
from squeaknode.core.buy_offer import BuyOffer
from squeaknode.core.offer import Offer
from squeaknode.core.received_offer import ReceivedOffer
from squeaknode.core.received_payment import ReceivedPayment
from squeaknode.core.sent_offer import SentOffer
from squeaknode.core.sent_payment import SentPayment
@ -117,31 +117,31 @@ class SqueakCore:
port=lnd_port,
)
def pay_offer(self, offer: Offer) -> SentPayment:
if offer.offer_id is None:
raise Exception("Offer must have a non-null offer_id.")
def pay_offer(self, received_offer: ReceivedOffer) -> SentPayment:
if received_offer.received_offer_id is None:
raise Exception("Received offer must have a non-null offer_id.")
# Pay the invoice
payment = self.lightning_client.pay_invoice_sync(offer.payment_request)
payment = self.lightning_client.pay_invoice_sync(
received_offer.payment_request)
preimage = payment.payment_preimage
if not preimage:
raise Exception(
"Payment failed with error: {}".format(payment.payment_error)
)
# Calculate the secret key
nonce = offer.nonce
nonce = received_offer.nonce
# secret_key = bxor(nonce, preimage)
secret_key = subtract_tweak(preimage, nonce)
# Save the preimage of the sent payment
return SentPayment(
sent_payment_id=None,
created=None,
offer_id=offer.offer_id,
peer_id=offer.peer_id,
squeak_hash=offer.squeak_hash,
payment_hash=offer.payment_hash,
peer_id=received_offer.peer_id,
squeak_hash=received_offer.squeak_hash,
payment_hash=received_offer.payment_hash,
secret_key=secret_key,
price_msat=offer.price_msat,
node_pubkey=offer.destination,
price_msat=received_offer.price_msat,
node_pubkey=received_offer.destination,
)
def get_received_payments(self, get_sent_offer_fn, latest_settle_index) -> Iterator[ReceivedPayment]:
@ -163,7 +163,7 @@ class SqueakCore:
)
yield received_payment
def get_offer(self, squeak: CSqueak, offer: BuyOffer, peer: SqueakPeer) -> Offer:
def get_offer(self, squeak: CSqueak, offer: BuyOffer, peer: SqueakPeer) -> ReceivedOffer:
if peer.peer_id is None:
raise Exception("Peer must have a non-null peer_id.")
# Get the squeak hash
@ -184,8 +184,8 @@ class SqueakCore:
invoice_expiry = pay_req.expiry
node_host = offer.host or peer.host
node_port = offer.port
decoded_offer = Offer(
offer_id=None,
decoded_offer = ReceivedOffer(
received_offer_id=None,
squeak_hash=squeak_hash,
price_msat=price_msat,
payment_hash=payment_hash,

View file

@ -1,8 +1,8 @@
"""Initialize all
Revision ID: 82c409b96c66
Revision ID: afb1f38de2cb
Revises:
Create Date: 2020-12-28 15:35:10.195043
Create Date: 2021-01-11 16:10:46.633311
"""
import sqlalchemy as sa
@ -10,7 +10,7 @@ from alembic import op
# revision identifiers, used by Alembic.
revision = '82c409b96c66'
revision = 'afb1f38de2cb'
down_revision = None
branch_labels = None
depends_on = None
@ -18,29 +18,6 @@ depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('offer',
sa.Column('offer_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('payment_hash', sa.String(
length=64), nullable=False),
sa.Column('nonce', sa.String(length=64), nullable=False),
sa.Column('payment_point', sa.String(
length=66), nullable=False),
sa.Column('invoice_timestamp',
sa.Integer(), nullable=False),
sa.Column('invoice_expiry', sa.Integer(), nullable=False),
sa.Column('price_msat', sa.Integer(), nullable=False),
sa.Column('payment_request', sa.String(), nullable=False),
sa.Column('destination', sa.String(
length=66), nullable=False),
sa.Column('node_host', sa.String(), nullable=False),
sa.Column('node_port', sa.Integer(), nullable=False),
sa.Column('peer_id', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('offer_id')
)
op.create_table('peer',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created', sa.DateTime(), server_default=sa.text(
@ -65,6 +42,30 @@ def upgrade():
sa.UniqueConstraint('address'),
sa.UniqueConstraint('profile_name')
)
op.create_table('received_offer',
sa.Column('received_offer_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('payment_hash', sa.String(
length=64), nullable=False),
sa.Column('nonce', sa.String(length=64), nullable=False),
sa.Column('payment_point', sa.String(
length=66), nullable=False),
sa.Column('invoice_timestamp',
sa.Integer(), nullable=False),
sa.Column('invoice_expiry', sa.Integer(), nullable=False),
sa.Column('price_msat', sa.Integer(), nullable=False),
sa.Column('payment_request', sa.String(), nullable=False),
sa.Column('destination', sa.String(
length=66), nullable=False),
sa.Column('node_host', sa.String(), nullable=False),
sa.Column('node_port', sa.Integer(), nullable=False),
sa.Column('peer_id', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('received_offer_id')
)
op.create_table('received_payment',
sa.Column('received_payment_id',
sa.Integer(), nullable=False),
@ -106,7 +107,6 @@ def upgrade():
sa.Column('sent_payment_id', sa.Integer(), nullable=False),
sa.Column('created', sa.DateTime(), server_default=sa.text(
'(CURRENT_TIMESTAMP)'), nullable=False),
sa.Column('offer_id', sa.Integer(), nullable=False),
sa.Column('peer_id', sa.Integer(), nullable=False),
sa.Column('squeak_hash', sa.String(
length=64), nullable=False),
@ -153,7 +153,7 @@ def downgrade():
op.drop_table('sent_payment')
op.drop_table('sent_offer')
op.drop_table('received_payment')
op.drop_table('received_offer')
op.drop_table('profile')
op.drop_table('peer')
op.drop_table('offer')
# ### end Alembic commands ###

View file

@ -80,10 +80,10 @@ class Models:
Column("downloading", Boolean, nullable=False),
)
self.offers = Table(
"offer",
self.received_offers = Table(
"received_offer",
self.metadata,
Column("offer_id", Integer, primary_key=True),
Column("received_offer_id", Integer, primary_key=True),
Column("created", TZDateTime,
server_default=func.now(), nullable=False),
Column("squeak_hash", String(64), nullable=False),
@ -106,7 +106,6 @@ class Models:
Column("sent_payment_id", Integer, primary_key=True),
Column("created", TZDateTime,
server_default=func.now(), nullable=False),
Column("offer_id", Integer, nullable=False),
Column("peer_id", Integer, nullable=False),
Column("squeak_hash", String(64), nullable=False),
Column("payment_hash", String(64), nullable=False),

View file

@ -13,8 +13,8 @@ from sqlalchemy.sql import select
from squeak.core import CSqueak
from squeaknode.bitcoin.util import parse_block_header
from squeaknode.core.offer import Offer
from squeaknode.core.offer_with_peer import OfferWithPeer
from squeaknode.core.received_offer import ReceivedOffer
from squeaknode.core.received_offer_with_peer import ReceivedOfferWithPeer
from squeaknode.core.received_payment import ReceivedPayment
from squeaknode.core.sent_offer import SentOffer
from squeaknode.core.sent_payment import SentPayment
@ -59,8 +59,8 @@ class SqueakDb:
return self.models.peers
@property
def offers(self):
return self.models.offers
def received_offers(self):
return self.models.received_offers
@property
def sent_payments(self):
@ -369,10 +369,10 @@ class SqueakDb:
select([self.squeaks.c.hash])
.select_from(
self.squeaks.outerjoin(
self.offers,
self.received_offers,
and_(
self.offers.c.squeak_hash == self.squeaks.c.hash,
self.offers.c.peer_id == peer_id,
self.received_offers.c.squeak_hash == self.squeaks.c.hash,
self.received_offers.c.peer_id == peer_id,
),
)
)
@ -386,7 +386,7 @@ class SqueakDb:
include_unverified,
)
)
.where(self.offers.c.squeak_hash == None) # noqa: E711
.where(self.received_offers.c.squeak_hash == None) # noqa: E711
)
with self.get_connection() as connection:
result = connection.execute(s)
@ -730,7 +730,7 @@ class SqueakDb:
def insert_offer(self, offer):
""" Insert a new offer. """
ins = self.offers.insert().values(
ins = self.received_offers.insert().values(
squeak_hash=offer.squeak_hash.hex(),
payment_hash=offer.payment_hash.hex(),
nonce=offer.nonce.hex(),
@ -746,8 +746,8 @@ class SqueakDb:
)
with self.get_connection() as connection:
res = connection.execute(ins)
offer_id = res.inserted_primary_key[0]
return offer_id
received_offer_id = res.inserted_primary_key[0]
return received_offer_id
# sql = """
# INSERT INTO offer(squeak_hash, key_cipher, iv, price_msat, payment_hash, invoice_timestamp, invoice_expiry, payment_request, destination, node_host, node_port, peer_id)
@ -779,8 +779,8 @@ class SqueakDb:
def get_offers(self, squeak_hash: bytes):
""" Get offers for a squeak hash. """
s = select([self.offers]).where(
self.offers.c.squeak_hash == squeak_hash.hex())
s = select([self.received_offers]).where(
self.received_offers.c.squeak_hash == squeak_hash.hex())
with self.get_connection() as connection:
result = connection.execute(s)
rows = result.fetchall()
@ -800,14 +800,14 @@ class SqueakDb:
def get_offers_with_peer(self, squeak_hash: bytes):
""" Get offers with peer for a squeak hash. """
s = (
select([self.offers, self.peers])
select([self.received_offers, self.peers])
.select_from(
self.offers.outerjoin(
self.received_offers.outerjoin(
self.peers,
self.peers.c.id == self.offers.c.peer_id,
self.peers.c.id == self.received_offers.c.peer_id,
)
)
.where(self.offers.c.squeak_hash == squeak_hash.hex())
.where(self.received_offers.c.squeak_hash == squeak_hash.hex())
)
with self.get_connection() as connection:
result = connection.execute(s)
@ -828,17 +828,17 @@ class SqueakDb:
# offers_with_peer = [self._parse_offer_with_peer(row) for row in rows]
# return offers_with_peer
def get_offer_with_peer(self, offer_id):
def get_offer_with_peer(self, received_offer_id):
""" Get offer with peer for an offer id. """
s = (
select([self.offers, self.peers])
select([self.received_offers, self.peers])
.select_from(
self.offers.outerjoin(
self.received_offers.outerjoin(
self.peers,
self.peers.c.id == self.offers.c.peer_id,
self.peers.c.id == self.received_offers.c.peer_id,
)
)
.where(self.offers.c.offer_id == offer_id)
.where(self.received_offers.c.received_offer_id == received_offer_id)
)
with self.get_connection() as connection:
result = connection.execute(s)
@ -848,9 +848,9 @@ class SqueakDb:
def delete_expired_offers(self):
""" Delete all expired offers. """
s = self.offers.delete().where(
s = self.received_offers.delete().where(
datetime.now(timezone.utc).timestamp(
) > self.offers.c.invoice_timestamp + self.offers.c.invoice_expiry
) > self.received_offers.c.invoice_timestamp + self.received_offers.c.invoice_expiry
)
with self.get_connection() as connection:
res = connection.execute(s)
@ -869,7 +869,8 @@ class SqueakDb:
def delete_offers_for_squeak(self, squeak_hash: bytes):
""" Delete all offers for a squeak hash. """
s = self.offers.delete().where(self.offers.c.squeak_hash == squeak_hash.hex())
s = self.received_offers.delete().where(
self.received_offers.c.squeak_hash == squeak_hash.hex())
with self.get_connection() as connection:
res = connection.execute(s)
deleted_offers = res.rowcount
@ -877,8 +878,8 @@ class SqueakDb:
def delete_offer(self, payment_hash: bytes):
""" Delete a received offer by payment hash. """
s = self.offers.delete().where(
self.offers.c.payment_hash == payment_hash.hex()
s = self.received_offers.delete().where(
self.received_offers.c.payment_hash == payment_hash.hex()
)
with self.get_connection() as connection:
connection.execute(s)
@ -886,7 +887,6 @@ class SqueakDb:
def insert_sent_payment(self, sent_payment):
""" Insert a new sent payment. """
ins = self.sent_payments.insert().values(
offer_id=sent_payment.offer_id,
peer_id=sent_payment.peer_id,
squeak_hash=sent_payment.squeak_hash.hex(),
payment_hash=sent_payment.payment_hash.hex(),
@ -1121,8 +1121,8 @@ class SqueakDb:
def _parse_offer(self, row):
if row is None:
return None
return Offer(
offer_id=row["offer_id"],
return ReceivedOffer(
received_offer_id=row["received_offer_id"],
squeak_hash=bytes.fromhex(row["squeak_hash"]),
payment_hash=bytes.fromhex(row["payment_hash"]),
nonce=bytes.fromhex(row["nonce"]),
@ -1142,8 +1142,8 @@ class SqueakDb:
return None
offer = self._parse_offer(row)
peer = self._parse_squeak_peer(row)
return OfferWithPeer(
offer=offer,
return ReceivedOfferWithPeer(
received_offer=offer,
peer=peer,
)
@ -1153,7 +1153,6 @@ class SqueakDb:
return SentPayment(
sent_payment_id=row["sent_payment_id"],
created=row[self.sent_payments.c.created],
offer_id=row["offer_id"],
peer_id=row["peer_id"],
squeak_hash=bytes.fromhex(row["squeak_hash"]),
payment_hash=bytes.fromhex(row["payment_hash"]),