forked from LBRYCommunity/lbry-sdk
progress on deterministic channel keys
This commit is contained in:
parent
5eb95d7dd4
commit
f741b00768
5 changed files with 40 additions and 8 deletions
|
@ -2704,12 +2704,13 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
name, claim, amount, claim_address, funding_accounts, funding_accounts[0]
|
||||
)
|
||||
txo = tx.outputs[0]
|
||||
await txo.generate_channel_private_key()
|
||||
txo.set_channel_private_key(
|
||||
await funding_accounts[0].generate_channel_private_key()
|
||||
)
|
||||
|
||||
await tx.sign(funding_accounts)
|
||||
|
||||
if not preview:
|
||||
account.add_channel_private_key(txo.private_key)
|
||||
wallet.save()
|
||||
await self.broadcast_or_release(tx, blocking)
|
||||
self.component_manager.loop.create_task(self.storage.save_claims([self._old_get_temp_claim_info(
|
||||
|
|
|
@ -34,6 +34,22 @@ def validate_claim_id(claim_id):
|
|||
raise Exception("Claim id is not hex encoded")
|
||||
|
||||
|
||||
class DeterministicChannelKeyManager:
|
||||
|
||||
def __init__(self, account):
|
||||
self.account = account
|
||||
self.public_key = account.public_key.child(2)
|
||||
self.private_key = account.private_key.child(2) if account.private_key else None
|
||||
|
||||
def generate_next_key(self):
|
||||
db = self.account.ledger.db
|
||||
i = 0
|
||||
while True:
|
||||
next_key = self.private_key.child(i)
|
||||
if not await db.is_channel_key_used(self.account, next_key.address):
|
||||
return next_key
|
||||
|
||||
|
||||
class AddressManager:
|
||||
|
||||
name: str
|
||||
|
@ -252,6 +268,7 @@ class Account:
|
|||
self.receiving, self.change = self.address_generator.from_dict(self, address_generator)
|
||||
self.address_managers = {am.chain_number: am for am in (self.receiving, self.change)}
|
||||
self.channel_keys = channel_keys
|
||||
self.deterministic_channel_keys = DeterministicChannelKeyManager(self)
|
||||
ledger.add_account(self)
|
||||
wallet.add_account(self)
|
||||
|
||||
|
@ -520,6 +537,11 @@ class Account:
|
|||
|
||||
return tx
|
||||
|
||||
async def generate_channel_private_key(self):
|
||||
key = self.deterministic_channel_keys.generate_next_key()
|
||||
self.add_channel_private_key(key)
|
||||
return key
|
||||
|
||||
def add_channel_private_key(self, private_key):
|
||||
public_key_bytes = private_key.get_verifying_key().to_der()
|
||||
channel_pubkey_hash = self.ledger.public_key_to_address(public_key_bytes)
|
||||
|
|
|
@ -1241,6 +1241,12 @@ class Database(SQLiteMixin):
|
|||
async def set_address_history(self, address, history):
|
||||
await self._set_address_history(address, history)
|
||||
|
||||
async def is_channel_key_used(self, account, address):
|
||||
for channel in await self.get_channels(accounts=[account]):
|
||||
if channel.private_key.address == address:
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def constrain_purchases(constraints):
|
||||
accounts = constraints.pop('accounts', None)
|
||||
|
|
|
@ -469,13 +469,11 @@ class Output(InputOutput):
|
|||
self.channel = None
|
||||
self.signable.clear_signature()
|
||||
|
||||
async def generate_channel_private_key(self):
|
||||
self.private_key = await asyncio.get_event_loop().run_in_executor(
|
||||
None, ecdsa.SigningKey.generate, ecdsa.SECP256k1, None, hashlib.sha256
|
||||
)
|
||||
self.claim.channel.public_key_bytes = self.private_key.get_verifying_key().to_der()
|
||||
def set_channel_private_key(self, private_key):
|
||||
self.private_key = private_key
|
||||
self.claim.channel.public_key_bytes = private_key.get_verifying_key().to_der()
|
||||
self.script.generate()
|
||||
return self.private_key
|
||||
return private_key
|
||||
|
||||
def is_channel_private_key(self, private_key):
|
||||
return self.claim.channel.public_key_bytes == private_key.get_verifying_key().to_der()
|
||||
|
|
|
@ -174,3 +174,8 @@ class AccountManagement(CommandTestCase):
|
|||
bad_address = address[0:20] + '9999999' + address[27:]
|
||||
with self.assertRaisesRegex(Exception, f"'{bad_address}' is not a valid address"):
|
||||
await self.daemon.jsonrpc_account_send('0.1', addresses=[bad_address])
|
||||
|
||||
async def test_deterministic_channel_keys(self):
|
||||
seed = self.account.seed
|
||||
await self.channel_create('@foo1')
|
||||
self.daemon2 = await self.add_daemon(seed=seed)
|
||||
|
|
Loading…
Add table
Reference in a new issue