Commit Graph

42 Commits

Author SHA1 Message Date
Sander van Grieken 36efae3875 imports, whitespace 2025-02-10 14:22:50 +01:00
SomberNight 2f1095510c bitcoin.py/transaction.py: API changes: rm most hex usage
Instead of some functions operating with hex strings,
and others using bytes, this consolidates most things to use bytes.

This mainly focuses on bitcoin.py and transaction.py,
and then adapts the API usages in other files.

Notably,
- scripts,
- pubkeys,
- signatures
should be bytes in almost all places now.
2024-04-29 17:10:26 +00:00
JeremyRand a7f0c90c8a Add pow_hash_header abstraction (#7592)
There is no reason why the hash function for identifying a block and the
hash function used to instantiate Hashcash must be the same; it's only a
coincidence that Bitcoin happens to use the same hash for both use
cases.  Reflecting this fact by adding this abstraction makes the code
more flexible.

Co-authored-by: Jeremy Rand <jeremyrand@danwin1210.de>
2023-10-31 14:02:20 +00:00
Sander van Grieken 1e725b6baa break the cyclic dependency 2023-06-28 16:49:28 +02:00
SomberNight 612d3493df fix flake8-bugbear B017
B017 `assertRaises(Exception)` and `pytest.raises(Exception)` should be considered evil. They can lead to your test passing even if the code being tested is never executed due to a typo. Assert for a more specific exception (builtin or custom), or use `assertRaisesRegex` (if using `assertRaises`), or add the `match` keyword argument (if using `pytest.raises`), or use the context manager form with a target.
2023-04-24 12:58:30 +00:00
SomberNight 312f2641e7 don't use bare except
use "except Exception", or if really needed explicitly "except BaseException"
2023-04-24 12:58:01 +00:00
SomberNight 373db76ac9 util: kill bh2u
no longer useful, and the name is so confusing...
2023-02-17 11:43:11 +00:00
SomberNight 7e2d9c48d1 blockchain: fix bugs in bits_to_target and target_to_bits
This fixes three bugs:
- too large targets: the fixme in target_to_bits, which meant that we could
  not handle targets where the first bit was non-zero. This however cannot
  happen due to these being over MAX_TARGET. (difficulty 1)
- too small targets: in bits_to_target, very small targets were not handled well:
  ```
  >>> Blockchain.bits_to_target(0x03008000)
  32768
  ```
  We could not process headers with targets smaller than the above value.
  (note that these small targets would only occur at astronomically high mining difficulty)
- non-canonically encoded targets:
  we would not accept headers that had targets encoded in compact form (nBits) in a non-canonical way.
  I think this bug could actually be triggered by mining such a header.
  E.g. consider the target "1167130406913723784571467005534932607254396928"
  ```
  Blockchain.target_to_bits(1167130406913723784571467005534932607254396928).to_bytes(4, "big").hex()
  '13345600'
  ```
  Bitcoin Core when used to e.g. mine a block would encode this target as 0x13345600 in compact form.
  However, AFAICT, when validating Bitcoin Core would equally accept 0x14003456 which decodes to the
  same target. We were however rejecting such non-canonical compact nBits.
  ```
  >>> from electrum.blockchain import Blockchain
  >>> Blockchain.bits_to_target(0x14003456)
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/home/user/wspace/electrum/electrum/blockchain.py", line 548, in bits_to_target
      raise Exception("Second part of bits should be in [0x8000, 0x7fffff]")
  Exception: Second part of bits should be in [0x8000, 0x7fffff]
  >>> Blockchain.bits_to_target(0x13345600)
  1167130406913723784571467005534932607254396928
  ```
2021-11-13 04:31:08 +01:00
SomberNight ee10e8e4d3 blockchain: bits_to_target: small clean-up
note: why is the first byte cut unconditionally? what if it's non-zero?
Maybe the intention of cutting the first two chars in the hex case intended to
cut a "0x" prefix?? But there was no such prefix with the given format string...
2021-11-13 03:07:36 +01:00
SomberNight 6033471853 blockchain: clarify MAX_TARGET by referencing bitcoin core source
change is no-op as the compact nBits form of both values are equal, that is:
```
>>> from electrum.blockchain import Blockchain
>>> MAX_TARGET1 = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
>>> MAX_TARGET2 = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
>>> Blockchain.bits_to_target(Blockchain.target_to_bits(MAX_TARGET2)) == Blockchain.bits_to_target(Blockchain.target_to_bits(MAX_TARGET1))
True
```
2021-11-13 03:02:31 +01:00
bitromortac 63308f94a0 reorganize with_lock decorator 2021-04-02 09:38:39 +02:00
SomberNight 4acf884790 blockchain.py: maybe fix rare deadlock
Saw a deadlock near a swap_with_parent(), could not reproduce.
get_branch_size() and get_parent_heights() could have been the culprits as
they take locks in differing orders and are called from gui/network threads.
2020-08-25 20:29:08 +02:00
SomberNight 2eec7e1600 network: smarter switch_unwanted_fork_interface
Previously this function would not switch to a different chain if the
current chain contained the preferred block. This was not the intended
behaviour: if there is a *stronger* chain that *also* contains the
preferred block, we should jump to that.

Note that with this commit there will now always be a preferred block
(defaults to genesis). Previously, it might seem that often there was none,
but actually in practice if the user used the GUI context menu to switch
servers even once, there was one (usually genesis).

Hence, with the old code, if an attacker mined a single header which
then got reorged, auto_connect clients which were connected to the
attacker's server would never switch servers (jump chains) even
without the user explicitly configuring preference for the stale branch.
2020-06-21 11:31:54 +02:00
SomberNight 54e1520ee4 ln: check if chain tip is stale when receiving HTLC
if so, don't release preimage / don't forward HTLC
2020-04-13 17:04:27 +02:00
SomberNight ce81957d25 blockchain: move init_headers_file from network.py to blockchain.py
and don't run it every time the network restarts
2020-02-27 20:45:29 +01:00
SomberNight 9d2629c5c3 blockchain.fork: better exception if datadir was deleted while running 2020-02-04 19:04:38 +01:00
SomberNight 3385a94753 logging: basics 2019-05-02 15:19:03 +02:00
SomberNight bca6ad5241 verifier: fix logic bug. after reorg, some verifs were not undone
after a reorg, in a many fork/orphan chains scenario,
we would sometimes not undo SPV for enough blocks

functions in blockchain.py somewhat based on kyuupichan/bitcoinX@5126bd15ef
2019-03-26 21:01:43 +01:00
SomberNight 9a71120090 blockchain: fix bug when swapping chain with parent
chain might become the parent of some of its former siblings
2019-03-26 20:55:27 +01:00
ghost43 dc19cf1fa1 wallet: randomise locktime of transactions a bit. also check if stale. (#4967) 2019-01-16 18:51:59 +01:00
SomberNight 73e2b09ba8 blockchain: check best chain on disk is consistent with checkpoints
had a corrupted mainnet datadir that had testnet blockchain_headers file
(I had probably corrupted it myself but electrum could not recover from it)
2018-11-30 16:36:37 +01:00
SomberNight bddea809ec storage/blockchain: use os.replace 2018-11-30 04:08:02 +01:00
ThomasV d062548e41 Merge pull request #4861 from SomberNight/blockchain_fork_ids
blockchain: generalise fork handling and follow most work chain
2018-11-28 12:54:57 +01:00
SomberNight d7c5949365 prefer int.from_bytes over int('0x'+hex, 16) 2018-11-26 01:16:26 +01:00
SomberNight 65ce3deeaa blockchain: chain hierarchy based on most work, not length 2018-11-22 17:13:43 +01:00
SomberNight 141ff99580 blockchain.py: generalise fork ids to get rid of conflicts 2018-11-22 16:57:22 +01:00
SomberNight a8e6eaa247 blockchain: fix difficulty retarget
"target" is a 256 bit int, but the "bits" field in the block headers
that is used to represent target is only 32 bits.
We were checking PoW against the untruncated target value, which is a
slightly larger value than the one that can actually be represented,
and hence we would have accepted a slightly lower difficulty chain
than what the consensus requires.
2018-11-22 16:52:51 +01:00
SomberNight e37da62a1c fix most "scripts"
related: #4754
2018-11-02 20:14:59 +01:00
SomberNight 082a83dd85 rename crypto.Hash to sha256d 2018-10-25 22:28:24 +02:00
SomberNight 81cc20039e more type annotations in core lib 2018-10-22 16:41:25 +02:00
SomberNight 37206ec08e network: auto-switch servers to preferred fork (or longest chain)
If auto_connect is enabled, allow jumping between forks too.
(Previously auto_connect was only switching servers on a given fork,
not across forks)
If there is a preferred fork set, jump to that (and stay);
if there isn't, always jump to the longest fork.
2018-10-11 20:07:19 +02:00
SomberNight 4360a785ad blockchain: blockchains_lock needed to write/iterate global dict 2018-09-16 18:26:40 +02:00
SomberNight 1635bc8cb3 blockchain: use HEADER_SIZE named constant instead of magic numbers 2018-09-16 03:06:21 +02:00
SomberNight 8cd08cc0fa network: rm dead code; simplify 2018-09-12 01:40:54 +02:00
SomberNight a5b3f809ce blockchain.py: add type annotations 2018-09-11 22:14:57 +02:00
SomberNight cdca74aa39 move max_checkpoint from network to constants 2018-09-09 05:00:09 +02:00
SomberNight 3f0d79f07d blockchain.py: better handling of missing headers. more restrictive verify_chunk. 2018-09-06 14:17:42 +02:00
Janus e9ceeb85af async block headers 2018-09-06 14:17:41 +02:00
SomberNight 2a9f5db576 blockchain.py: fix: chunks in checkpoint region were not getting saved if we were on a fork 2018-08-03 19:06:23 +02:00
SomberNight 531cdeffa9 blockchain.py: rename 'checkpoint' to 'forkpoint' 2018-08-03 18:25:53 +02:00
SomberNight b44aca1654 network: disconnect from server on incorrect header length
fix #4522
2018-07-13 18:11:48 +02:00
Janus 097ac144d9 file reorganization with top-level module 2018-07-13 14:01:37 +02:00