This reverts to the correct upstream majority version code which
properly detects when certain thresholds of the network have been
updated in order to determine when to start rejecting old version
blocks and enforcing the rules in the new version block.
I misunderstood an old dcrd comment and thought that all stake
transactions were notified irrespective of whether they were actually
relevant to the wallet or not. Fix this by only including those that
pass the tx filter for block connected notifications. Rescanned
blocks already handled this correctly by only including the relevant
stake txs.
Change the block connected and disconnected notifications to include
the entire block header.
Do not notify the previous block's regular tree transactions if the
newly attached block voted to approve them. Instead, notify the
regular transactions from the newly attached block. It is up to the
client to check the vote bits in the header to decide how to handle
the previous block's regular transactions.
Every websocket client now has an associated transaction filter that
is used to determine whether or not a processed transaction is (or
might be) relevant to the client. A new RPC, loadtxfilter, has been
added to load, reload, or add to this filter.
Redo the entire rescan RPC to scan over previously-processed blocks
using the same transaction filter (rather than specifying which
addresses and outpoints to watch for in the rescan request).
Fixes#433.
Bump block version and add stake version to wire. Currently
StakeVersions are unused and once the enforcement logic goes in the
versions will bump again.
This fixes#435
* Fraudulent transaction due to invalid index
* Transaction with no inputs
* Transaction with no outputs
* Transaction output with negative vlaue
* Transaction output with too large value
* Block with multiple transactions that sum to too large value
* Stakebase script too small and too large
* Input transactions with null outpoints
* Blocks with duplicate tx inputs
* Test no proof-of-work subsidy output in the coinbase
* Test invalid script type in the coinbase block commitment output
* Test too few bytes for the coinbase height commitment
* Test invalid block height in the coinbase commitment
* Test block with sbits underflow
* Test stake transaction pos limit
* Test stakebase script len checks
* Test stakebase unknown signature script
* Test stake transaction in regular tx tree
* Vote with null ticket reference
* Regular tx in the stake tree
* Too many votes
* Too few votes
* Specified number of votes in header does not match included votes
This adds a full-blown testing infrastructure in order to test consensus
validation rules. It is built around the idea of dynamically generating
full blocks that link together to form a block chain. In order to
properly test the rules, each test instance starts with a valid block
that is then modified to be invalid in the specific way needed to test a
specific rule.
Since the intent of this framework is to be able to detect any
regressions and/or otherwise inadvertent changes to the consensus rules,
it intentionally does not rely on any logic from the blockchain package
and instead has local implementations of everything necessary to build
valid blocks including things such as the initial premine block,
proof-of-work and proof-of-stake difficulty calculations, purchasing
stake tickets, and calculating lottery winners and casting the
appropriate votes.
In addition, blocks which exercise following rules have been added as an
initial starting point. These are not exhaustive by any means, but they
serve to show how the framework is used and pave the way for more
exhaustive tests to be added over time.
* Invalid premine block
* Valid premine block
* Enough valid blocks to reach ticket maturity
* Enough valid blocks to reach stake enabled height
* Enough valid blocks to reach stake validation height
* Enough valid block to have a stable base of mature coinbases to spend
for futher tests
* Basic forking and chain reorganization
* Double spend in regular transaction tree
* Too much proof-of-work coinbase (extending main chain, in block that
forces a reorg, and in a valid fork)
* Too much dev-org coinbase (same scenarios as pow coinbase above)
* Max and too many signature operations via various combinations of
OP_CHECKSIG, OP_MULTISIG, OP_CHECKSIGVERIFY, and OP_MULTISIGVERIFY
* Too many signature operations with offending sigop after invalid data
push
* Attempt to spend tx created on a different forks
* Attempt to spend immature coinbase (on main chain and fork)
* Max size block and block that exceeds the max size
* Children of rejected blocks are either orphans or rejected
* Coinbase script too small and too large
* Max length coinbase script
* Attempt to spend tx in blocks that failed to connect
* Valid non-coinbase tx in place of coinbase
* Block with no transactions
* Invalid proof-of-work
* Block with a timestamp too far in the future
* Invalid regular tree merkle root
* Invalid proof-of-work limit (Bits header field)
* Two coinbase transactions
* Duplicate txns in the regular tree
* Timestamp exactly at and one second after the median time
* Spend from transaction index that is out of range
* Transaction that spends more that its inputs provide
* Non-final coinbase
* Spend from transaction earlier in same block
* Spend from transaction later in same block
* Double spend transaction from earlier in same block
* Coinbase that pays more than subsidy + fees
* Coinbase that includes subsidy + fees
* Spend from transaction that does not exist
This RPC is essentially a reimplementation of the wire protocol
getheaders and headers messages and is planned on being used by the
wallet to fetch block headers during startup sync.
Copy hash_test.go from btcd. This file contains tests for encoding
and decoding of hashes to and from strings, and does not rely on the
hash algorithm.
The dcrwallet command to set multiple tickets vote bits fields at
the same time has been added. Functions to encode/decode relevant
hex strings (as passed over JSON) were also added, along with tests.
The blockchain pruning functions would run at every newly inserted
block node, causing performance degradation. Now the blockchain will
only prune nodes to return the memory to the garbage collector at
prespecified (5 minute) intervals, resulting in much less overhead
when syncing the blockchain.
Sidechain and orphan blocks were given in previous version of the
software in response to the RPC command getblock, in line with
bitcoind. Insight relied on this functionality. It has been
restored in 0.5.0. Fixes#406.
If the transaction index was run and never synced before, the first
time run will cause an OOM failure on machines with low RAM. This was
due to the GC never collecting blocks and freeing them after they were
used, because there were references to the block pointers or internal
pointers to the transaction hashes in the database updates. The
pointers to hashes have all been replaced with values to save memory
and allow the GC to free the blocks/transactions as the indexer runs.
The dumpblockchain function used to serialize a map of block
into gob serialized format, which was used for testing but which
was incompatible with the addblock tool. The function now dumps
a flat file the the same format required by the addblock tool.
A couple shutdown assertions were added as well, to prevent
potential panics if pointers were nil. The duration of time
it took to sync the blockchain with addblock is now
reported.
Profiling indicated that significant time was being spent validating
coinbase outputs, ensuring that they paid to the development
organization's P2SH tax address. This check was more inefficient than
necessary for a couple of reasons:
* The tax address was always decoded from a string to a dcrutil.Address.
* The actual script being validated was always parsed for addresses to
check if they matched the tax address.
Neither of these are needed. To optimize the algorithm, only the
equality of the output script and script version are checked.
This corrects the the hash256 deterministic prng generator to properly
rollover and avoid repeating values when it has been invoked more than
2^35 + 8 times.
While here, it also removes the unnecessary 'seedState' struct field in
favor of storing the seed as a chainhash.Hash directly and just updating
it on rollover.
Finally, it also refactors the seed const to a package level constant to
avoid generating a new byte slice (and hence extra garbage) every time a
new generator is created.
It should be noted that this does not affect Decred consensus at all
because it's impossible to invoke the generator more than 2^35 + 8 times
due to other constraints.
A bug in the restoration of stake nodes from the disk would prevent the
blockchain from reloading if there was an immediate reorganization
required on start up. This correctly disconnects the block.
A bug when updating the chain state during forced reorganizations
was fixed. An assertion was added into the mining code so that it
now errors out if the blockchain and chainState of the block
manager are inconsistent.
The blockchain function to fetch the latest block header was
renamed for consistency and now returns a copy of the block header
instead of the pointer itself.
The legacy ticket database, which was GOB serialized and stored on
shut down, has been removed. Ticket state information is now held in
a stake node, which acts as a modularized "black box" to contain all
information about the state of the stake system. Stake nodes are now
a component of the blockchain blockNode struct, and are updated with
them.
Stake nodes, like their internal treap primitives, are immutable
objects that are created with their connect and disconnect node
functions. The blockchain database now stores all information about
the stake state of the best node in the block database. The blockchain
makes the assumption that the stake state of the best node is known at
any given time. If the states of former blocks or sidechains must be
evaluated, this can be achieved by iterating backwards along the
blockchain from the best node, and then connecting stake nodes
iteratively if necessary.
Performance improvements with this new module are dramatic. The long
delays on start up and shut down are removed. Blockchain
synchronization time is improved approximately 5-10x on the mainnet
chain. The state of the database is atomic, so unexpected shut downs
should no longer have the ability to disrupt the chain state.
An upgrade path has been added for version 1 blockchain databases.
Users with this blockchain database will automatically update when
they start their clients.