This fixes the behavior of expanding ~ on Windows and macOS, as well
as adding support for ~otheruser to expand to the home directory of
otheruser.
Modify the default sample config to reflect the change in the meaning
of ~ on Windows, and the unintended meaning of ~ on macOS. Include
defaults for all 3 of the major operating system classes since
uncommenting the default Unix option on macOS or Windows would change
the blockchain data directory to a non-default location.
This adds code to migrate the existing block index in ffldb to the new
format managed by the blockchain package and updates the code to use the
new infrastructure.
This adds a new field to the block node struct named status that
consists of bit flags for keeping tracking of the validation state of
each block. The status is only stored in memory as of this commit, but
it will be stored as a part of the block index in the upcoming block
index migration code.
Since the field will be updated after node creation, this also
introduces some new functions for interacting with the status field in a
concurrent-safe fashion.
This is largely based on upstream commits 2492af0 and fb0d13c; however,
it does not include some of the logic in the reorganization paths those
commits include as that approach doesn't match the intended direction
this package is moving towards.
This adds infrastructure necessary for blockchain to independently
manage and persist a full block index in a bucket. Note that the
new infrastructure is not used yet as it will be integrated in future
commits after migrating existing databases has been done.
The purpose of this infrastructure is to significantly speed up startup
time which currently has to load a bunch of the most recent blocks in
order to rebuild the stake state and also to pave the way towards being
able to have the full block index in memory allows for a lot of
optimizations and greatly simplified code.
This also includes a full suite of tests to ensure proper serialization
and deserialization functionality.
This simplifies and consolidates the logic for adding and removing nodes
to and from the block index by moving the initial add into
maybeAcceptBlock just after the node is created, adding the child
connection logic to the AddNode function, and introducing a RemoveNode
function that is called in dry run mode which undoes the aforementioned
changes.
In addition to being simpler logic to follow, it helps make it clear
that all blocks which are written to the database end up with a block
index entry, even if they ultimately fail to connect.
This adds missing error entries to the tests and also adds an additional
check to ensure that all possibilities are tested to prevent drift in the
future.
This provides a function to calculate the lottery initialization vector
for a node on demand versus calculating it at node creation time and
storing the result.
This is being done because it saves an additional 32 bytes in the block
node structure and the ultimate goal is to move towards having all block
nodes in memory to greatly simplify and optimize the code. Since there
will be a lot of nodes in memory, these extra bytes can add up to
significant savings.
This replaces the ErrDoubleSpend and ErrMissingTx error codes with a
single error code named ErrMissingTxOut and updates the relevant errors
and expected test results accordingly.
Once upon a time, the code relied on a transaction index, so it was able
to definitively differentiate between a transaction output that
legitimately did not exist and one that had already been spent.
However, since the code now uses a pruned utxoset, it is no longer
possible to reliably differentiate since once all outputs of a
transaction are spent, it is removed from the utxoset completely.
Consequently, a missing transaction could be either because the
transaction never existed or because it is fully spent.
Also, while here, consistently use the LookupEntry function on the
UtxoView instead of directly accessing the internal map as intended.
this adds a collection of summary total fields to the GetBalanceResult
struct which allows providing a summary of totals for all wallet
accounts when using `getbalance "*"`.
This modifies the newBlockNode function to accept the parent as an
argument to automatically connect the newly created node. When it is
not nil, the work sum will automatically be summed and the parent of the
new node will be set accordingly.
This simplifies the block node construction a bit and allows some
redundant code to be removed. It also paves the way for easier simpler
full block index construction in the future.
This separates the logic for populating the stake information in a block
node from the construction of the node in order to better delineate the
difference between the two and to pave the way for that information to
be stored separately in the database versus needing to load full blocks
to retrieve it.
This modifies the code in maybeAcceptBlock to return an error if there
is no previous entry in the block index for a given block indicating it
is either an orphan or the genesis block.
The function should never be called in either circumstance since the
genesis block is valid by definition and orphans are handled prior to
calling the function.
This removes the legacy version details from the database to ensure that
loading older versions of the software after the database has been
upgraded fails as desired.
This is important because otherwise, the database could actually be
using a new version that has been upgraded via the new scheme, but old
software would still see this old information and believe the database
was still on that older version.
This propagates the interrupt channel through to blockchain and the
indexers so that it is possible to interrupt long-running operations
such as catching up indexes.
This modifies the database upgrade logic to avoid needing the chain and
moves it earlier in the initialization process just after the initial
database creation (if needed), but prior the final struct instance
population from the database.
It is much simpler logic to have an already upgraded database prior to
populating the initial chain state so all of the initial setup happens
in one place.
This modifies the database versioning to use separate keys within the
version bucket for each component in order to simplify upgrade logic.
Having a single key for the various versions of the database components
makes it difficult to use because the version isn't known until the data
is read, however, modifying the format necessarily means the version is
needed before that point to know which format to read.
While here, it uses a uint64 to store the date instead of a uint32 so
the timestamp continues to work past 2106.
Also, it removes the upgrade started logic since it should be possible
to stop in the middle of an upgrade and resume later. Forcing a
completely new database to be created because an upgrade was stopped in
the middle is not ideal.
Prior to this commit, the chain data structures were initialized in two
separate places depending on whether or not the database state had
already been created.
This simplifies that logic so that the initialization of the data
structures happens in a single place.
In order to accomplish this, the logic has been split into three phases:
1) Query to determine the current state of the database
2) Optionally initialize the database by creating all buckets and
populating it with the genesis block and associated state if it
has not already been done
3) Initialize the data structures using the data loaded from the
database
This modifies the blockchain code to store all blocks that have passed
proof-of-work and contextual validity tests in the database even if they
may ultimately fail to connect.
This eliminates the need to store those blocks in memory, allows them to
be available as orphans later even if they were never part of the main
chain, and helps pave the way toward being able to separate the download
logic from the connection logic.
Note that it also updates the blockExists function since the code base
is currently in the process of changing over to decouple download and
connection logic, but not all of the necessary parts are updated yet,
to ensure blocks that are in the database, but do not have an associated
main chain block index entry, are treated as if they do not exist for
the purposes of chain connection and selection logic.
This renames the fields dealing with the hashes of tickets that have
been voted on from ticketsSpent to ticketsVoted to more accurately
differentiate them from revocations which also technically spend
tickets.
This moves the test for validating the revocations in the block are
actually eligible to be revoked per the results of the ticket lottery
into the checkBlockContext function where it more naturally belongs
since it is only dependent on the block and its contextual position
within the chain.
While here, it also refactors the check into a separate function named
checkAllowedRevocations to improve readability. Also, since this was
the final check in the CheckBlockStakeSanity function, that entire
function has been removed along with its call site.
This moves the test for validating the votes in the block are eligible
votes per the results of the ticket lottery into the checkBlockContext
function where it more naturally belongs since it is only dependent on
the block and its contextual position within the chain.
While here, it also refactors the check into a separate function named
checkAllowedVotes to improve readability.
This moves the check for validating that only ticket purchases, votes,
and revocations are included in the stake tree to the checkBlockSanity
function where it more naturally belongs since it does not require
access to any previous chain context.
This moves the check for validating that the number of revocations does
not exceed the maximum allowed to the checkBlockSanity function where it
more naturally belongs since it does not require access to any previous
chain context.
It should be noted that this check previously used math.MaxUint8 and was
rather implicitly limited by the fact the header uses a uint8 for the
field, so this makes the requirement more explicit by defining a
constant.
This moves the test for validating the final state specified by the
header matches the calculated final state into the
checkBlockHeaderContext function where it more naturally belongs since
it is only dependent on the header and its contextual position within
the chain.
This modifies the checkBlockHeaderSanity function to include an
additional check which ensures the final state is zero prior to stake
validation height.
It should be noted that this is technically a hard fork since before
this change it was possible to use any value for the final state prior
to stake validation height. However, no blocks on mainnet nor testnet
ever used non-zero final states for blocks in that range and they are
buried behind checkpoints in the minimum required version of the
software due to the previous consensus votes, so it isn't possible to
trigger a reorg that would fork old nodes off the network anyways, so it
is safe to retroactively apply this check.
This moves the checks for validating that votes commit to the parent of
the block they are contained in and the vote bits specified by the
header match the result of the actual votes included in the block to the
checkBlockSanity function where they more naturally belong since they do
not require access to any previous chain context.
This modifies the NextBlock function to account for changes made to the
block height or previous block hash in munge functions and update the
commitments in all votes accordingly.
This moves the test for validating the pool size specified by the header
matches the calculated size into the checkBlockHeaderContext function
where it more naturally belongs since it is only dependent on the header
and its contextual position within the chain.
This modifies the exported CheckConnectBlock function to call the
checkBlockSanity and checkBlockContext functions to ensure all
validation rules are enforced from the mining code.
Since both the mining code and tests typically work with unsolved
blocks, this also introduces a new parameter on CheckConnectBlock to
pass behavior flags which allows the caller to skip the proof of work
check.
It also modifies forceHeadReorganization to call checkBlockContext for
the same reason.
Finally, all tests and call sites are updated with the appropriate
flags and various tests are updated for the changes accordingly.
This renames the mempool.Config.RelayNonStd option to AcceptNonStd which
more accurately describes its behavior since the mempool was refactored
into a separate package.
The reasoning for this change is that the mempool is not responsible for
relaying transactions (nor should it be). Its job is to maintain a pool
of unmined transactions that are validated according to consensus and
policy configuration options which are then used to provide a source of
transactions that need to be mined.
Instead, it is the server that is responsible for relaying transactions.
While it is true that the current server code currently only relays txns
that were accepted to the mempool, this does not necessarily have to
be the case. It would be entirely possible (and perhaps even a good
idea as something do in the future), to separate the relay policy from
the mempool acceptance policy (and thus indirectly the mining policy).