Commit graph

278 commits

Author SHA1 Message Date
Calvin Kim
9093243d8b fullblocktests, testhelper: move uniqueOpReturnScript to testhelper
uniqueOpReturnScript is moved to testhelper and is exported so that the
code and be reused in package blockchain without introducing import
cycles.  The test code for invalidateblock and reconsiderblock that are
gonna be added in later commits uses the functions.
2024-04-23 02:48:28 +09:00
Calvin Kim
62790ac065 fullblocktests, testhelper: move opTrueScript and lowFee to testhelper
The variables are moved to testhelper so that they can be reused in the
blockchain package without introducing an import cycle.  The testing
code for invalidateblock and reconsiderblock that will be added in later
commits will be using these variables.
2024-04-23 02:48:28 +09:00
Calvin Kim
d4644dff10 fullblocktests, testhelper: move solveBlock to testhelper
solveBlock is moved to testhelper and is exported.  This is done so that
the code can be reused without introducing import cycles.  The testing
code to be added in alter commits for invalidateblock and reconsider
block will use SolveBlock.
2024-04-23 02:48:19 +09:00
Calvin Kim
337d7f6be8 fullblocktests, testhelper: refactor out spendableOut
spendableOut and the functions related to it are is moved to package
testhelper and are exported.  This is done to make the code reusable
without introducing an import cycle when the testing code for
invalidateblock and reconsiderblock are added in follow up commits.
2024-04-23 02:42:35 +09:00
Calvin Kim
597b68c79e blockchain, workmath: refactor functions to workmath package
Some of the functions in difficulty.go are not dependent on any external
functions and they are needed to introduce testing code for the
invalidateblock and reconsiderblock methods that are to be added on in
later commits. Having the workmath package let's us reuse the code and
avoid dependency cycles.

The existing functions that were exported already (HashToBig,
CompactToBig, BigToCompact, CalcWork) are still kept in difficulty.go
to avoid breaking external code that depends on those exported
functions.
2024-04-23 02:35:36 +09:00
Calvin Kim
bc6396ddfd blockchain: Add IsAncestor method to blockNode
IsAncestor() provides functionality for testing if a block node is
an ancestor of anther block node.
2024-04-08 17:47:26 +09:00
Calvin Kim
c9c8795160 blockchain: add Equals method to blockNode
Helper function for the added IsAncestor in the follow up commit.
Returns true if all the fields (except for parent and ancestor) are
equal.
2024-04-08 17:47:08 +09:00
xiaoxiangxianzi
95330bc1bb
chore: fix some comments (#2146)
Signed-off-by: xiaoxiangxianzi <zhaoyizheng@outlook.com>
2024-03-27 09:45:48 -04:00
mattn
3cb9f602e8
fix typos (#2100) 2024-03-25 09:44:25 -04:00
Olaoluwa Osuntokun
f0ec9fbcce
Merge pull request #2128 from kcalvinalvin/2024-02-27-no-panic-for-subscription-callback-errors
blockchain: always relock chainLock for subscription callbacks
2024-03-08 17:56:14 -08:00
Olaoluwa Osuntokun
8ed234b9f5
Merge pull request #2134 from kcalvinalvin/2024-03-07-make-duplicate-entries-on-mapslice-impossible
blockchain: fix a bug where a duplicate entry is possible in the mapslice
2024-03-08 17:54:08 -08:00
Olaoluwa Osuntokun
e63bf03d2a
Merge pull request #2123 from kcalvinalvin/2024-02-15-no-utxocache-loading-on-reorgs
blockchain: fix inconsistent utxocache and database on reorg
2024-03-08 17:52:57 -08:00
Calvin Kim
078815bcbc blockchain: remove utxoview from the argument in connectBlock
Since no code is now depending on accepting new blocks without the
cache, we get rid of the option to do so.
2024-03-07 15:43:48 +09:00
Calvin Kim
059a668e88 blockchain: check all the maps first before adding an entry
When attempting to insert an entry to the mapslice, we check all the
underlying maps to ensure that the entry doesn't exist.
2024-03-07 15:27:44 +09:00
Calvin Kim
8d1aa01c69 blockchain: add another mapslice duplicate entry case
Duplicate entries are currently possible in the following scenario:

1: Add entries to the mapslice.
2: 1st map is full. Move onto the 2nd map.
3: Delete any entry in the first map.
4: Attempt to add an entry in the 2nd map.

When attempting (4), the entry should just be overwritten but a
duplicate gets added.
2024-03-07 15:24:00 +09:00
Calvin Kim
99846b0805 blockchain: remove unused fetchUtxosMain() 2024-03-06 02:44:51 +09:00
Calvin Kim
78b158dc56 blockchain: get rid of database as an argument in fetchInputUtxos
Allowing the caller to fetch from either the database or the cache
resulted in inconsistencies if the cache were ever to be dirty.
Removing this option eliminates this problem.
2024-03-06 02:42:33 +09:00
Calvin Kim
a254998bc5 blockchain: change reorg utxo cache behavior
The assumption in the previous code was incorrect in that we were
assuming that the chainLock is held throughout the entire chain reorg.
This is not the case since the chainLock is let go of during the
callback to the subscribers.

Because of this, we need to ensure that the utxo set is consistent on
each block disconnect. To achieve this, additional flushes are added
during block disconnects.

Also the utxocache is no longer avoided during block connects and when
we're checking for the validity of the block connects and disconnects as
we can just use the cache instead of trying to avoid it.
2024-03-06 02:40:24 +09:00
Calvin Kim
f2caa8fadc blockchain: don't rely on BlockHeightByHash for prune height
calculations

Since BlockHeightByHash only returns the heights for blocks that are in
the main chain, when a block that is stale gets pruned, this will cause
an error in the block height lookup and cause an error in block
processing.

Look up the node directly from the index and if the node isn't found,
just skip that node. For utxoCache.lastFlushHash, if that isn't found,
just force a flush.
2024-03-06 02:15:39 +09:00
Calvin Kim
3d1150a1a8 blockchain: always relock chainLock for subscription callbacks
For various b.sendNotifcation() callbacks, if a runtime panic happens,
we don't get any useful debugging information since the error that
happens first is the "unlock of unlocked mutex" error.

This is because we temporarily unlock the chainLock for callbacks and
then relock them.  However, since the relocking code is executed after
the completion of the callback, if an error happens during that
callback, we never relock the chainLock.

Switching to an anonymous function and having the unlock code as a
defer will ensure that the lock always relocks.
2024-02-27 14:32:42 +09:00
Calvin Kim
5a91ea23ca blockchain_test, fullblocktests: add test to check for utxo
existance/non-existance

New test instance BlockDisconnectExpectUTXO tests that a utxo
exists/doesn't exist after a specific block has been disconnected.
2024-02-21 19:09:03 +09:00
Calvin Kim
a0c9e3b384 blockchain: add case for pruning stale blocks
Pruning stale blocks will make the block validation fail for the block
that the prune was triggered on as BlockHeightByHash will not return the
height for blocks that are not in the main chain.

We add a test case to ensure that the test fails in the above case.
2024-02-16 16:17:04 +09:00
Calvin Kim
8836219a02 blockchain: return error in db.View instead of t.Fatal
Calling t.Fatal inside db.View makes the test hang on failures.  Return
the error and call t.Fatal outside of db.View avoids this.
2024-02-16 16:17:04 +09:00
Olaoluwa Osuntokun
13152b35e1
Merge pull request #2089 from kcalvinalvin/2024-01-03-add-last-flush-time-on-initconsistentstate
blockchain: set the lastflushtime when setting the lastflushhash
2024-01-23 20:25:55 -08:00
yyforyongyu
ef54c49df4
multi: map btcd mempool acceptance errors to bitcoind's testmempoolaccept
This commit creates a `RejectReasonMap` to map the errors returned from
`btcd` to bitcoind's `testmempoolaccept` so the `RejectReason` is
unified at the RPC level. To make sure the map keys are unique, the
error strings are modified in `btcd`.
2024-01-15 17:22:41 +08:00
Thabokani
a4df044cfd
Fix some typos (#2085)
* Dockerfile: fix typo

* blockchain: fix typos

* sample-btcd.conf: fix typos

* server: fix typos

* txscript: fix typos
2024-01-03 16:36:49 -05:00
Calvin Kim
e307ad122f blockchain: set the lastflushtime when setting the lastflushhash
On startup when the headers-first mode is off, when receiving the first
block, the periodic flush will trigger.  The lastflushtime wasn't set
which resulted in the flush being triggered on the first block on
restart.
2024-01-03 14:24:36 +09:00
Oliver Gugger
7644d14078
blockchain: fix compilation issues with 32bit systems 2023-12-22 10:14:43 +01:00
Olaoluwa Osuntokun
c3c3545f9b
multi: update main package to chainhash/v1.1.0, use optimized dsha256
In this commit, we update the top-level btcd package to use the latest
version of btcutil and also the chainhash package. With this version
bump, we can now use the new optimized dsha256 routine where applicable.

With this commit, I've covered most of the areas we'll hash an entire
transaction/block/header, but we may want to optimize some other areas
further, in particular, the witness sighash calc.
2023-12-19 15:01:55 -08:00
Calvin Kim
87a81f14fc blockchain: address nit comments 2023-12-16 16:53:17 +09:00
Calvin Kim
26b2e9d9de blockchain: add test for InitConsistentState 2023-12-16 16:53:17 +09:00
Calvin Kim
ebc93a34ce blockchain: flush the utxo cache on prune if needed
If the prune will delete block past the last flush hash of the
utxocache, the cache will need to be flushed first to avoid a case
where the utxocache is irrecoverable.  The newly added code adds this
flush logic to connectBlock.
2023-12-16 16:53:17 +09:00
Calvin Kim
dd37dfa80b blockchain: add flushNeededAfterPrune
flushNeededAfterPrune returns true if the utxocache needs to be flushed
after the pruning of the given slice of block hashes.  For the utxo
cache to be recoverable while pruning is enabled, we need to make sure
that there exists blocks since the last utxo cache flush.  If there are
blocks that are deleted after the last utxo cache flush, the utxo set is
irrecoverable.  The added method provides a way to tell if a flush is
needed.
2023-12-16 16:53:17 +09:00
Calvin Kim
16cd44f0e6 blockchain, netsync, main, cmd/addblock: Use utxocache
This change is part of the effort to add utxocache support to btcd.

utxo cache is now used by the BlockChain struct.  By default it's used
and the minimum cache is set to 250MiB.  The change made helps speed up
block/tx validation as the cache allows for much faster lookup of utxos.
The initial block download in particular is improved as the db i/o
bottleneck is remedied by the cache.
2023-12-16 16:53:17 +09:00
Calvin Kim
3c11e48dd2 blockchain: Add utxocache
The implemented utxocache implements connectTransactions just like
utxoviewpoint and can be used as a drop in replacement for
connectTransactions.

One thing to note is that unlike the utxoViewpoint, the utxocache
immediately deletes the spent entry from the cache.  This means that the
utxocache is unfit for functions like checkConnectBlock where you expect
the entry to still exist but be marked as spent.

disconnectTransactions is purposely not implemented as using the cache
during reorganizations may leave the utxo state inconsistent if there is
an unexpected shutdown.  The utxoViewpoint will still have to be used
for reorganizations.
2023-12-16 16:53:04 +09:00
Calvin Kim
053ef330f2 blockchain: Refactor fetchInputUtxos
This change is part of the effort to add utxocache support to btcd.

fetchInputUtxos had mainly 2 functions:
1: Figure out which outpoints to fetch
2: Call fetchUtxosMain to fetch those outpoints

Functionality for (1) is refactored out to fetchInputsToFetch.  This is
done to allow fetchInputUtxos to use the cache to fetch the outpoints
as well in a later commit.
2023-12-16 16:36:45 +09:00
Calvin Kim
bcd8f547fe blockchain: Require utxoBucket in dbFetchUtxoEntry
This change is part of the effort to add utxocache support to btcd.

Require the caller to pass in the utxoBucket as the caller may be
fetching many utxos in one loop.  Having the caller pass it in removes
the need for dbFetchUtxoEntry to grab the bucket on every single fetch.
2023-12-16 16:36:45 +09:00
Calvin Kim
953d62afa7 blockchain: Return early on nil utxo view in dbPutUtxoView
This change is part of the effort to add utxocache support to btcd.

connectBlock may have an empty utxoviewpoint as the block verification
process may be using the utxo cache directly.  In that case, a nil utxo
viewpoint will be passed in.  Just return early on a nil utxoviewpoint.
2023-12-16 16:36:45 +09:00
Calvin Kim
d86e79eb79 blockchain: Refactor dbPutUtxoView
This change is part of the effort to add utxocache support to btcd.

dbPutUtxoView handled putting and deleting new/spent utxos from the
database.  These two functinalities are refactored to their own
functions: dbDeleteUtxoEntry and dbPutUtxoEntry.

Refactoring these out allows the cache to call these two functions
directly instead of having to create a view and saving that view to
disk.
2023-12-16 16:36:45 +09:00
Calvin Kim
fc65744134 blockchain: Add utxoStateConsistency read and write functions
This change is part of the effort to add utxocache support to btcd.

The utxoStateConsistency indicates what the last block that the utxo
cache got flush at.  This is useful for recovery purposes as if the node
is unexpectdly shut down, we know which block to start rebuilding the
utxo state from.
2023-12-16 16:36:45 +09:00
Calvin Kim
27cf70216f blockchain: Add memoryUsage() method on UtxoEntry
This change is part of the effort to add utxocache support to btcd.

Getting the memory usage of an entry is very useful for the utxo cache
as we need to know how much memory all the cached entries are using to
guarantee a cache usage limit for the end user.
2023-12-16 16:36:45 +09:00
Calvin Kim
35c42688d9 blockchain: Add tfFresh to txoFlags
This change is part of the effort to add utxocache support to btcd.

The fresh flag indicates that the entry is fresh and that the parent
view (the database) hasn't yet seen the entry.  This is very useful as
a performance optimization for the utxo cache as if a fresh entry is
spent, we can simply remove it from the cache and don't bother trying to
delete it from the database.
2023-12-16 16:36:45 +09:00
Calvin Kim
1f2dfa2d6e blockchain: Add mapslice
This change is part of the effort to add utxocache support to btcd.

mapslice allows the caller to allocate a fixed amount of memory for the
utxo cache maps without the mapslice going over that fixed amount of
memory.  This is useful as we can have variable sizes (1GB, 1.1GB, 2.3GB,
etc) while guaranteeing a memory limit.
2023-12-16 16:36:43 +09:00
Calvin Kim
e318551538 blockchain: Add sizehelper
This change is part of the effort to add utxocache support to btcd.

sizehelper introduces code for 2 main things:
    1: Calculating how many entries to allocate for a map given a size
       in bytes.
    2: Calculating how much a map takes up in memory given the entries
       were allocated for the map.

These functionality are useful for allocating maps so that they'll be
allocating below a certain number of bytes.  Since go maps will always
allocate in powers of B (where B is the bucket size for the given map),
it may allocate too much memory.  For example, for a map that can store
8GB of entries, the map will grow to be 16GB once the map is full and
the caller puts an extra entry onto the map.

If we want to give a memory guarantee to the user, we can either:
    1: Limit the cache size to fixed sizes (4GB, 8GB, ...).
    2: Allocate a slice of maps.

The sizehelper code helps with (2).
2023-12-13 23:48:54 +09:00
Olaoluwa Osuntokun
ac068e7f61
Merge pull request #1688 from kcalvinalvin/add-blockindex-parentskips
blockchain: Add ancestor optimization to finding Ancestor
2023-12-06 16:27:05 -08:00
xiaolou86
4171854739 Fix typos 2023-11-20 12:04:31 -05:00
Calvin Kim
f396b3d3d9 blockchain: better Ancestor with skiplists
On startup, Ancestor call was taking a lot of time when the node was
loading the blockindex onto memory. This change speeds up the Ancestor
function significantly and speeds up the node during startup.

On testnet3 at blockheight ~2,500,000, the startup was around 30seconds
on current main and was 5 seconds with this change. Below is a benchstat
result showing the significant speedup.

goos: darwin
goarch: arm64
pkg: github.com/utreexo/utreexod/blockchain
           │     old.txt      │               new.txt                │
           │      sec/op      │    sec/op     vs base                │
Ancestor-8   120819.301µ ± 5%   7.013µ ± 19%  -99.99% (p=0.000 n=10)

           │  old.txt   │            new.txt             │
           │    B/op    │    B/op     vs base            │
Ancestor-8   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

           │  old.txt   │            new.txt             │
           │ allocs/op  │ allocs/op   vs base            │
Ancestor-8   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal
2023-11-17 16:55:58 +09:00
Olaoluwa Osuntokun
f7e9fba086
Merge pull request #1918 from kcalvinalvin/2022-11-06-implement-getchaintips
blockchain, btcjson: Implement getchaintips rpc call
2023-11-14 17:16:15 -08:00
eugene
1a615550b7
blockchain: export CheckSerializedHeight, reduce allocs for cb height
parsing

Some callers only want to check the coinbase height rather than be given
the height.
2023-10-30 12:06:10 -04:00
Olaoluwa Osuntokun
ec401d00a1
Merge pull request #1971 from kcalvinalvin/add-pruning
main, wire, blockchain, indexers, ffldb: Add pruning
2023-08-23 15:59:37 -07:00