This commit provides a new interface, MedianTimeSource, along with a
concrete implementation which allows improved accuracy of time by making
use of the median network time as calculated from multiple time samples.
The time samples are to be provided by callers and are intended to come
from remote clients.
The calculations performed in this implementation exactly mirror those in
Bitcoin Core because time calculations are part of the consensus rules and
hence need to match exactly.
This commit splits the two rule validation errors related to the timestamp
being too old into two distince errors rather than grouping them under the
same one. Thus there is now a new ErrCheckpointTimeTooNew in addition to
the existing ErrTimeTooNew error.
This allows the caller to detect the when a block is rejected due to a
time-related checkpoint failure whereas before the combined error did not.
Since the underlying database driver can now return an error when looking
up if blocks and transactions exist, the HaveBlock function now includes
an error return to allow any underlying errors to be exposed.
This commit adds a new behavior flag, BFDryRun which allows the caller
to indicate all checks should be performed against the block as normal
except it will not modify any state. This is useful to test that a block
is valid without actually modifying the current chain or memory state.
This commit also adds a few additional checks which were elided before
since they are implicitly handled by btcwire. However, with the ability
to propose blocks which didn't necessarily come through the btcwire path,
these checks need to be enforced in the chain code as well.
As a part of adding the checks, three new error codes named
ErrBlockTooBig, ErrTooManyTransactions, and ErrTxTooBig have been
introduced.
Closes#5.
This commit adds a new behavior flag, BFNoPoWCheck which allows the caller
to indicate the check which ensures a block hashes to a value less than
required target should not be performed.
This commit change the ProcessBlock function to accept a new type named
BehaviorFlags in place of the current fastAdd parameter.
This has been done to pave the way for adding more control over the checks
that are performed such as avoiding the proof of work checks which will be
in an upcoming commit. A bitmask was chosen because it will allow the
ProcessBlock API to remain a little more stable since new flag additions
that change the behavior are only likely to be used by new code because
adding flags does not change the existing behavior.
ok @jrick
This commit changes the way that orphan blocks are identified by adding a
new boolean return value on ProcessBlock and removing the notification for
NTOrphanBlock.
This allows the calling code to identify orphan blocks immediately instead
of having to setup a seperate callback handler and implementing some type
of state tracking. This, in turn, allows cleaner code for handling them.
In addition, the tests have been updated for the new function signature
and also now check that each block is or is not an orphan as expected
which makes the tests more robust.
ok @jrick
This commit changes the RuleError type to a struct which consists of an
error code and human-readable description.
From a usage perspective, existing code should not break since type
asserting an error to a RuleError still works in the same manner. The
difference is the caller can now take that type asserted RuleError and
access the .ErrorCode field on it to programmatically identify the
specific rule that was violated.
ok @jrick
This commit refactors the code to make use of the btcnet package for
network-specific parameters instead of switching on the specific network.
For example, the percentage of the network that needs to run version 2
blocks is different between testnet and mainnet. Previously the code was
using a switch to choose these values. With this refactor, those
parameters are part of the network parameters provided when creating a new
chain instance.
Another example is checkpoints, which have been moved to btcnet so they
can be specified by the caller instead of hard coded into this package.
As a result, the checkpoints for the standard networks are now specified
in the btcnet package.
This makes it easier to add new networks such as a testnet4 should it
become needed. It also allows callers to define their own custom network
parameters without having to modify the code of the package to add new
switch cases for the custom network.
The name findLatestKnownCheckpoint is confusing and doesn't really convey
the fact the purpose of the function is to the find the checkpoint prior
to the current known block.
Therefore, rename the function to findPreviousCheckpoint for clarity.
Also, update some comments to follow suit.
This commit adds an additional check to the block acceptance rules which
prevents new blocks that fork the main chain before the previous known
good checkpoint. This prevents storage of new, otherwise valid, blocks
from building off of old blocks which are likely at a much easier
difficulty and therefore could be used to waste cache and disk space.
Note this is slightly different than the other existing check which
prevents blocks with a timestamp before the timestamp of the latest known
good checkpoint since that check effectively prevents old side chain
blocks that already existed (per the claimed timestamp).
ok drahn@
This commit modifies local variables that are used for more convenient
access to a block's header to use pointers. This avoids copying the
header multiple times.
It is not necessary to do all of the transaction validation on
blocks if they have been confirmed to be in the block chain leading
up to the final checkpoint in a given blockschain.
This algorithm fetches block headers from the peer, then once it has
established the full blockchain connection, it requests blocks.
Any blocks before the final checkpoint pass true for fastAdd on
btcchain operation, which causes it to do less valiation on the block.
Rather than defining CheckBlockSanity as a member of a BlockChain
instance, define it at the root level so it is truly context free as
intended. In order to make it context free, the proof of work limit is
now a required parameter.
This commit modifies the main processing loop for orphan dependencies
(orphans that are processed due to their parents showing up) to use an
index based for loop over range. Since the Go range statement does not
reevaluate on every iteration, it was previously possible under certain
circumstances for the slice to be changed out from under the range
statement while processing the orphan blocks.
This commit modifies the code to choose sane defaults for the backing
arrays for slices that involve a lot of appends such block locators, hash
processing, and needed transactions. This is an optimization to avoid
the overhead of growing the backing arrays and copying the data multiple
times in the most common case. This also prevents a leak in Go GC which
will likely ultimatley be fixed, but the efficiecy gains alone are worth
the change.
Rather than sending the root of the an orphan chain when sending an orphan
notification, send the hash of the orphan block itself. The caller can
then call the GetOrphanRoot function with the hash to get the root of the
orphan chain as needed. This is being changed since it's cleaner and more
detministic sending the hash for the orphan block that was just processed
rather than sending a possibly different hash depending on whether there
is an orphan chain or not.
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.
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.