def mock_fork(self, bad_header): forkpoint = bad_header['block_height'] b = blockchain.Blockchain(config=self.config, forkpoint=forkpoint, parent=None, forkpoint_hash=bh2u(sha256(str(forkpoint))), prev_hash=bh2u(sha256(str(forkpoint - 1)))) return b
def test_mnemonic_to_seed(self): for test_name, test in SEED_TEST_CASES.items(): if test.words_hex is not None: self.assertEqual(test.words_hex, bh2u(test.words.encode('utf8')), msg=test_name) self.assertTrue(is_new_seed(test.words, prefix=test.seed_version), msg=test_name) m = mnemonic.Mnemonic(lang=test.lang) if test.entropy is not None: self.assertEqual(test.entropy, m.mnemonic_decode(test.words), msg=test_name) if test.passphrase_hex is not None: self.assertEqual(test.passphrase_hex, bh2u(test.passphrase.encode('utf8')), msg=test_name) seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=test.words, passphrase=test.passphrase) self.assertEqual(test.bip32_seed, bh2u(seed), msg=test_name)
def gen_random_versioned_seed(cls): version = cls.LATEST_VERSION hex_seed = bh2u(os.urandom(16)) checksum = cls.code_hashid(version + hex_seed) return VersionedSeed(version=version.upper(), seed=hex_seed.upper(), checksum=checksum.upper())
def update(self, window: 'ElectrumSysWindow'): wallet = window.wallet if type(wallet) != Multisig_Wallet: return assert isinstance(wallet, Multisig_Wallet) # only here for type-hints in IDE if self.listener is None: self.logger.info("starting listener") self.listener = Listener(self) self.listener.start() elif self.listener: self.logger.info("shutting down listener") self.listener.stop() self.listener = None self.keys = [] self.cosigner_list = [] for key, keystore in wallet.keystores.items(): xpub = keystore.get_master_public_key() # type: str pubkey = BIP32Node.from_xkey(xpub).eckey.get_public_key_bytes(compressed=True) _hash = bh2u(crypto.sha256d(pubkey)) if not keystore.is_watching_only(): self.keys.append((key, _hash, window)) else: self.cosigner_list.append((window, xpub, pubkey, _hash)) if self.listener: self.listener.set_keyhashes([t[1] for t in self.keys])
def update(features): self.features = features set_label_enabled() bl_hash = bh2u(features.bootloader_hash) bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]]) noyes = [_("No"), _("Yes")] endis = [_("Enable Passphrases"), _("Disable Passphrases")] disen = [_("Disabled"), _("Enabled")] setchange = [_("Set a PIN"), _("Change PIN")] version = "%d.%d.%d" % (features.major_version, features.minor_version, features.patch_version) coins = ", ".join(coin.coin_name for coin in features.coins) device_label.setText(features.label) pin_set_label.setText(noyes[features.pin_protection]) passphrases_label.setText(disen[features.passphrase_protection]) bl_hash_label.setText(bl_hash) label_edit.setText(features.label) device_id_label.setText(features.device_id) initialized_label.setText(noyes[features.initialized]) version_label.setText(version) coins_label.setText(coins) clear_pin_button.setVisible(features.pin_protection) clear_pin_warning.setVisible(features.pin_protection) pin_button.setText(setchange[features.pin_protection]) pin_msg.setVisible(not features.pin_protection) passphrase_button.setText(endis[features.passphrase_protection]) language_label.setText(features.language)
def on_suggest(): self.parent.wallet.network.start_gossip() nodeid = bh2u(lnworker.suggest_peer() or b'') if not nodeid: remote_nodeid.setText("") remote_nodeid.setPlaceholderText( "Please wait until the graph is synchronized to 30%, and then try again.") else: remote_nodeid.setText(nodeid) remote_nodeid.repaint() # macOS hack for #6269
def open(self, *args, **kwargs): super(LightningOpenChannelDialog, self).open(*args, **kwargs) if self.lnaddr: fee = self.app.electrumsys_config.fee_per_kb() if not fee: fee = config.FEERATE_FALLBACK_STATIC_FEE self.amount = self.app.format_amount_and_units(self.lnaddr.amount * COIN + fee * 2) # FIXME magic number?! self.pubkey = bh2u(self.lnaddr.pubkey.serialize()) if self.msg: self.app.show_info(self.msg)
def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx): self.prev_tx = prev_tx client = self.get_client(keystore) inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore) outputs = self.tx_outputs(tx, keystore=keystore) signatures = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime, version=tx.version)[0] signatures = [(bh2u(x) + '01') for x in signatures] tx.update_signatures(signatures)
def make_htlc_item(self, i: UpdateAddHtlc, direction: Direction) -> HTLCItem: it = HTLCItem( _('Sent HTLC with ID {}' if Direction.SENT == direction else 'Received HTLC with ID {}').format(i.htlc_id)) it.appendRow( [HTLCItem(_('Amount')), HTLCItem(self.format_msat(i.amount_msat))]) it.appendRow( [HTLCItem(_('CLTV expiry')), HTLCItem(str(i.cltv_expiry))]) it.appendRow( [HTLCItem(_('Payment hash')), HTLCItem(bh2u(i.payment_hash))]) return it
def __init__(self, chan: Channel, app: 'ElectrumSysWindow', **kwargs): Popup.__init__(self, **kwargs) Logger.__init__(self) self.is_closed = chan.is_closed() self.can_be_deleted = chan.can_be_deleted() self.app = app self.chan = chan self.title = _('Channel details') self.node_id = bh2u(chan.node_id) self.channel_id = bh2u(chan.channel_id) self.funding_txid = chan.funding_outpoint.txid self.short_id = format_short_channel_id(chan.short_channel_id) self.capacity = self.app.format_amount_and_units(chan.get_capacity()) self.state = chan.get_state_for_GUI() self.local_ctn = chan.get_latest_ctn(LOCAL) self.remote_ctn = chan.get_latest_ctn(REMOTE) self.local_csv = chan.config[LOCAL].to_self_delay self.remote_csv = chan.config[REMOTE].to_self_delay self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote' feerate_kw = chan.get_latest_feerate(LOCAL) self.feerate = str( quantize_feerate(Transaction.satperbyte_from_satperkw(feerate_kw))) self.can_send = self.app.format_amount_and_units( chan.available_to_spend(LOCAL) // 1000) self.can_receive = self.app.format_amount_and_units( chan.available_to_spend(REMOTE) // 1000) self.is_open = chan.is_open() closed = chan.get_closing_height() if closed: self.closing_txid, closing_height, closing_timestamp = closed msg = messages.MSG_NON_TRAMPOLINE_CHANNEL_FROZEN_WITHOUT_GOSSIP self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer( chan.node_id) else _('Warning') + ': ' + msg self.is_frozen_for_sending = chan.is_frozen_for_sending() self.is_frozen_for_receiving = chan.is_frozen_for_receiving() self.update_action_dropdown()
def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx): prev_tx = { bfh(txhash): self.electrumsys_tx_to_txtype(tx) for txhash, tx in prev_tx.items() } client = self.get_client(keystore) inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore) outputs = self.tx_outputs(tx, keystore=keystore) signatures, _ = client.sign_tx( self.get_coin_name(), inputs, outputs, lock_time=tx.locktime, version=tx.version, amount_unit=self.get_trezor_amount_unit(), prev_txes=prev_tx) signatures = [(bh2u(x) + '01') for x in signatures] tx.update_signatures(signatures)
def sign_transaction( self, keystore: Hardware_KeyStore, tx: PartialTransaction, wallet: Deterministic_Wallet, ): if tx.is_complete(): return if self.bitbox02_device is None: raise Exception( "Need to setup communication first before attempting any BitBox02 calls" ) coin = self._get_coin() tx_script_type = None # Build BTCInputType list inputs = [] for txin in tx.inputs(): my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin) if full_path is None: raise Exception( "A wallet owned pubkey was not found in the transaction input to be signed" ) prev_tx = txin.utxo if prev_tx is None: raise UserFacingException(_('Missing previous tx.')) prev_inputs: List[bitbox02.BTCPrevTxInputType] = [] prev_outputs: List[bitbox02.BTCPrevTxOutputType] = [] for prev_txin in prev_tx.inputs(): prev_inputs.append({ "prev_out_hash": prev_txin.prevout.txid[::-1], "prev_out_index": prev_txin.prevout.out_idx, "signature_script": prev_txin.script_sig, "sequence": prev_txin.nsequence, }) for prev_txout in prev_tx.outputs(): prev_outputs.append({ "value": prev_txout.value, "pubkey_script": prev_txout.scriptpubkey, }) inputs.append({ "prev_out_hash": txin.prevout.txid[::-1], "prev_out_index": txin.prevout.out_idx, "prev_out_value": txin.value_sats(), "sequence": txin.nsequence, "keypath": full_path, "script_config_index": 0, "prev_tx": { "version": prev_tx.version, "locktime": prev_tx.locktime, "inputs": prev_inputs, "outputs": prev_outputs, }, }) if tx_script_type == None: tx_script_type = txin.script_type elif tx_script_type != txin.script_type: raise Exception("Cannot mix different input script types") if tx_script_type == "p2wpkh": tx_script_type = bitbox02.btc.BTCScriptConfig( simple_type=bitbox02.btc.BTCScriptConfig.P2WPKH) elif tx_script_type == "p2wpkh-p2sh": tx_script_type = bitbox02.btc.BTCScriptConfig( simple_type=bitbox02.btc.BTCScriptConfig.P2WPKH_P2SH) elif tx_script_type in ("p2wsh-p2sh", "p2wsh"): if type(wallet) is Multisig_Wallet: tx_script_type = self.btc_multisig_config( coin, full_path, wallet, tx_script_type) else: raise Exception( "Can only use p2wsh-p2sh or p2wsh with multisig wallets") else: raise UserFacingException( "invalid input script type: {} is not supported by the BitBox02" .format(tx_script_type)) # Build BTCOutputType list outputs = [] for txout in tx.outputs(): assert txout.address # check for change if txout.is_change: my_pubkey, change_pubkey_path = keystore.find_my_pubkey_in_txinout( txout) outputs.append( bitbox02.BTCOutputInternal( keypath=change_pubkey_path, value=txout.value, script_config_index=0, )) else: addrtype, pubkey_hash = syscoin.address_to_hash(txout.address) if addrtype == OnchainOutputType.P2PKH: output_type = bitbox02.btc.P2PKH elif addrtype == OnchainOutputType.P2SH: output_type = bitbox02.btc.P2SH elif addrtype == OnchainOutputType.WITVER0_P2WPKH: output_type = bitbox02.btc.P2WPKH elif addrtype == OnchainOutputType.WITVER0_P2WSH: output_type = bitbox02.btc.P2WSH else: raise UserFacingException( "Received unsupported output type during transaction signing: {} is not supported by the BitBox02" .format(addrtype)) outputs.append( bitbox02.BTCOutputExternal( output_type=output_type, output_hash=pubkey_hash, value=txout.value, )) keypath_account = full_path[:-2] sigs = self.bitbox02_device.btc_sign( coin, [ bitbox02.btc.BTCScriptConfigWithKeypath( script_config=tx_script_type, keypath=keypath_account, ) ], inputs=inputs, outputs=outputs, locktime=tx.locktime, version=tx.version, ) # Fill signatures if len(sigs) != len(tx.inputs()): raise Exception( "Incorrect number of inputs signed.") # Should never occur signatures = [ bh2u(ecc.der_sig_from_sig_string(x[1])) + "01" for x in sigs ] tx.update_signatures(signatures)
def test_mnemonic_to_seed_basic(self): # note: not a valid electrumsys seed seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic='foobar', passphrase='none') self.assertEqual('741b72fd15effece6bfe5a26a52184f66811bd2be363190e07a42cca442b1a5bb22b3ad0eb338197287e6d314866c7fba863ac65d3f156087a5052ebc7157fce', bh2u(seed))
def __init__(self, window: 'ElectrumSysWindow', chan_id: bytes): super().__init__(window) # initialize instance fields self.window = window self.wallet = window.wallet chan = self.chan = window.wallet.lnworker.channels[chan_id] self.format_msat = lambda msat: window.format_amount_and_units(msat / 1000) # connect signals with slots self.htlc_fulfilled.connect(self.on_htlc_fulfilled) self.htlc_failed.connect(self.on_htlc_failed) self.state_changed.connect(self.do_state_changed) self.htlc_added.connect(self.on_htlc_added) # register callbacks for updating util.register_callback(self.htlc_fulfilled.emit, ['htlc_fulfilled']) util.register_callback(self.htlc_failed.emit, ['htlc_failed']) util.register_callback(self.htlc_added.emit, ['htlc_added']) util.register_callback(self.state_changed.emit, ['channel']) # set attributes of QDialog self.setWindowTitle(_('Channel Details')) self.setMinimumSize(800, 400) # add layouts vbox = QtWidgets.QVBoxLayout(self) vbox.addWidget(QLabel(_('Remote Node ID:'))) remote_id_e = ButtonsLineEdit(bh2u(chan.node_id)) remote_id_e.addCopyButton(self.window.app) remote_id_e.setReadOnly(True) vbox.addWidget(remote_id_e) funding_label_text = f'<a href=click_destination>{chan.funding_outpoint.txid}</a>:{chan.funding_outpoint.output_index}' vbox.addWidget(QLabel(_('Funding Outpoint:'))) vbox.addWidget(LinkedLabel(funding_label_text, self.show_tx)) form_layout = QtWidgets.QFormLayout(None) # add form content form_layout.addRow( _('Channel ID:'), SelectableLabel( f"{chan.channel_id.hex()} (Short: {chan.short_channel_id})")) form_layout.addRow(_('State:'), SelectableLabel(chan.get_state_for_GUI())) self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote' form_layout.addRow(_('Initiator:'), SelectableLabel(self.initiator)) self.capacity = self.window.format_amount_and_units( chan.get_capacity()) form_layout.addRow(_('Capacity:'), SelectableLabel(self.capacity)) self.can_send_label = SelectableLabel() self.can_receive_label = SelectableLabel() form_layout.addRow(_('Can send:'), self.can_send_label) form_layout.addRow(_('Can receive:'), self.can_receive_label) self.received_label = SelectableLabel() form_layout.addRow(_('Received:'), self.received_label) self.sent_label = SelectableLabel() form_layout.addRow(_('Sent:'), self.sent_label) #self.htlc_minimum_msat = SelectableLabel(str(chan.config[REMOTE].htlc_minimum_msat)) #form_layout.addRow(_('Minimum HTLC value accepted by peer (mSAT):'), self.htlc_minimum_msat) #self.max_htlcs = SelectableLabel(str(chan.config[REMOTE].max_accepted_htlcs)) #form_layout.addRow(_('Maximum number of concurrent HTLCs accepted by peer:'), self.max_htlcs) #self.max_htlc_value = SelectableLabel(self.window.format_amount_and_units(chan.config[REMOTE].max_htlc_value_in_flight_msat / 1000)) #form_layout.addRow(_('Maximum value of in-flight HTLCs accepted by peer:'), self.max_htlc_value) self.dust_limit = SelectableLabel( self.window.format_amount_and_units( chan.config[REMOTE].dust_limit_sat)) form_layout.addRow(_('Remote dust limit:'), self.dust_limit) self.remote_reserve = self.window.format_amount_and_units( chan.config[REMOTE].reserve_sat) form_layout.addRow(_('Remote reserve:'), SelectableLabel(self.remote_reserve)) vbox.addLayout(form_layout) # add htlc tree view to vbox (wouldn't scale correctly in QFormLayout) vbox.addWidget(QLabel(_('Payments (HTLCs):'))) w = QtWidgets.QTreeView(self) htlc_dict = chan.get_payments() htlc_list = [] for rhash, plist in htlc_dict.items(): for htlc_with_status in plist: htlc_list.append(htlc_with_status) w.setModel(self.make_model(htlc_list)) w.header().setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents) vbox.addWidget(w) vbox.addLayout(Buttons(CloseButton(self))) # initialize sent/received fields self.update()