This commit adds a new type, BlockLocator, and supporting infrastructure
to support generating block locators from a provided hash and getting
a full block locator for the latest known block. This will likely be
expanded in the future to provide the opposite functionality as well.
That is to say the ability to lookup a block using a block locator.
This commit modifies the GenerateInitialIndex function to update the best
chain with each node as it is loaded. This allows the best chain to be
set immediately upon generating the initial index which is a slight
performance optimization.
This commit provides a new exported function, HaveInventory, which can
be used to determine if the already has the item referenced by passed
inventory vector. Currently it only provides support for blocks and
cursory support for transactions in the main chain. Types that are
unrecognized are returned as if they unknown as expected.
This commit provides a new exported function, IsKnownOrphan, which can
be used to determine if the passed hash is currently already known to the
chain as an orphan.
This commit exposes GetOrphanRoot to callers. It also modifies the code
to allow the function to be called in a concurrent safe manner. This
allows the information to be safely obtained from multiple goroutines.
It is not safe to remove elements from a slice while iterating them with
the range statement since it does not reevaluate the slice on each
iteration nor does it adjust the index for the modified slice. This
commit modifies the code to use a for loop with an index (which does
reevaluate on every iteration) and manually adjusts the index when
elements are removed from the slice.
This commit updates the calls into btcutil, btcscript, and btcwire for the
latest API changes which remove the need for the protocol version for
serialization and deserialization of blocks and transactions.
This commit adds a new optional function named GenerateInitialIndex. It
generates the required number of initial block nodes in an optimized
fashion. Since the memory block index is sparse and previous nodes are
dynamically loaded as needed, this function is not stricty needed.
However, during initial startup (when there are no nodes in memory yet),
dynamically loading all of the required nodes on the fly in the usual way
is much slower than preloading them.
The recent pruning code made the parent hash for a node available directly
as a field in the node. Make use of this in the getPrevNodeFromNode
function to avoid having to load the full block data associated with the
node to get the parent hash.
This commit implements pruning for the block nodes that form the memory
chain which are no longer needed. The validation of a block only requires
information from a set number of previous nodes. The initial code did not
prune old nodes as they were no longer needed, but the vast majority of
the infrastructure to support it was already in place as that was always
the goal. This commit finishes implementing the missing bits to make it
a reality.
Previously, the code was using big rational numbers for work values which
resulted in carrying way too much precision around (and ultimately a lot
of extra memory and computation to carry that precision). This commit
converts the work values to big integers and calculates them with integer
division. This is acceptable because the numerator is multiplied by 2^256
which is higher than the maximum possible proof of work. Therefore
anything after the decimal is superfluous precision for the purposes of
chain selection.
Also, add a check for negative difficulty values when calculating the work
value. Negative values won't occur in practice with valid blocks, but
it's possible an invalid block could trigger the code path, so be safe and
check for it.
Previously the main network checkpoints were being used for unrecognized
networks. This commit changes the code so that no checkpoints are used in
that scenario.
Rather than converting the proof of work limit to its compact
representation multiple times during operation, do it once at package
initialization time and export it via the chain parameters.
This commit adds info level log statements when a block causes a chain
fork, extends a side chain (fork), or causes a reorganize. When a reorg
happens, the new and old chain heads along with the fork point are logged.
Even though the code currently makes heavy use of nodes which will have
the appropriate height, blocks which did not come from the database will
not have a height set. As a result, this could possibly result in a
height of 0 being used when unintended. By setting the block height in
the block as soon as its known (regardless of the source), we can future
proof against bugs that would likely be hard to track down.
The btcscript API for GetSigOpCount and GetPreciseSigOpCount
recently changed to no longer return an error. This change was necessary
to mirror the behavior of bitcoind signature operations counting. This
commit modifies the code accordingly to use the new API.
It is acceptable for a transaction input in a block to reference the
output of another transaction in the same block only if the referenced
transaction comes before the transaction referencing it.
This commit modifies the double spend detection to handle double spends
within the same block as well as side chains when doing the checks before
reorganizing the chain.
In addition to returning errors to the caller, log the error with a prefix
in a few key places that helps identify the origin for errors. In some
cases, the underlying error comes from a different subsystem such as the
SQL database driver and the error messages can be fairly generic.
This commit modifies the code to use params based on the active network
which paves the way for supporting the special rules and different genesis
blocks used by the test networks.
After discussing the criteria used by the core developers on #btc-dev IRC
channel, gmaxwell indicated they like to see at least 2016 blocks. This
commit updates the checkpoint confirmations accordingly.