kaspad/util/testtools/testtools.go
Ori Newman f7f44995d6 [NOD-215] implement difficulty adjustment algorithm (#331)
* [NOD-215] Implement difficulty adjustment algorithm

* [NOD-215] Handle blocks with genesis parent, and fix adjustment factor calculation

* [NOD-215] Fix tests

* [NOD-215] fix calcNextRequiredDifficulty

* [NOD-215] Add TestDifficulty

* [NOD-215] Fix delay to be positive, and add tests for delayed blocks

* [NOD-215] Split calcBlockWindowMinMaxAndMedianTimestamps to two functions

* [NOD-215] Make explicit loop for padding blue block window with genesis

* [NOD-215] Name return values

* [NOD-215] Fix delay != 0 error messages

* [NOD-215] Fix comments

* [NOD-215] Fix blueBlockWindow

* [NOD-215] Add TestBlueBlockWindow

* [NOD-215] Rename PowLimit -> PowMax

* [NOD-215] Fix delay != 0 error messages

* [NOD-215] Move PowMaxBits to BlockDAG

* [NOD-215] Make blockWindow type

* [NOD-215] Make blueBlockWindow always pad with genesis

* [NOD-215] Remove redundant line in checkWindowIDs

* [NOD-215] Make medianTimestamp return error for empty window
2019-06-26 15:47:39 +03:00

98 lines
2.8 KiB
Go

package testtools
import (
"fmt"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/mining"
"github.com/daglabs/btcd/util/daghash"
"github.com/daglabs/btcd/blockdag"
"github.com/daglabs/btcd/txscript"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/daglabs/btcd/wire"
)
// RegisterSubnetworkForTest is used to register network on DAG with specified gas limit
func RegisterSubnetworkForTest(dag *blockdag.BlockDAG, params *dagconfig.Params, gasLimit uint64) (*subnetworkid.SubnetworkID, error) {
buildNextBlock := func(parentHashes []*daghash.Hash, txs []*wire.MsgTx) (*util.Block, error) {
msgBlock, err := mining.PrepareBlockForTest(dag, params, parentHashes, txs, false)
if err != nil {
return nil, err
}
return util.NewBlock(msgBlock), nil
}
addBlockToDAG := func(block *util.Block) error {
isOrphan, delay, err := dag.ProcessBlock(block, blockdag.BFNoPoWCheck)
if err != nil {
return err
}
if delay != 0 {
return fmt.Errorf("ProcessBlock: block is is too far in the future")
}
if isOrphan {
return fmt.Errorf("ProcessBlock: unexpected returned orphan block")
}
return nil
}
// Create a block in order to fund later transactions
fundsBlock, err := buildNextBlock(dag.TipHashes(), []*wire.MsgTx{})
if err != nil {
return nil, fmt.Errorf("could not build funds block: %s", err)
}
err = addBlockToDAG(fundsBlock)
if err != nil {
return nil, fmt.Errorf("could not add funds block to DAG: %s", err)
}
fundsBlockCbTx := fundsBlock.Transactions()[0].MsgTx()
// Create a block with a valid subnetwork registry transaction
signatureScript, err := txscript.PayToScriptHashSignatureScript(blockdag.OpTrueScript, nil)
if err != nil {
return nil, fmt.Errorf("Failed to build signature script: %s", err)
}
txIn := &wire.TxIn{
PreviousOutpoint: *wire.NewOutpoint(fundsBlockCbTx.TxID(), 0),
Sequence: wire.MaxTxInSequenceNum,
SignatureScript: signatureScript,
}
pkScript, err := txscript.PayToScriptHashScript(blockdag.OpTrueScript)
if err != nil {
return nil, err
}
txOut := &wire.TxOut{
PkScript: pkScript,
Value: fundsBlockCbTx.TxOut[0].Value,
}
registryTx := wire.NewRegistryMsgTx(1, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}, gasLimit)
// Add it to the DAG
registryBlock, err := buildNextBlock([]*daghash.Hash{fundsBlock.Hash()}, []*wire.MsgTx{registryTx})
if err != nil {
return nil, fmt.Errorf("could not build registry block: %s", err)
}
err = addBlockToDAG(registryBlock)
if err != nil {
return nil, fmt.Errorf("could not add registry block to DAG: %s", err)
}
// Build a subnetwork ID from the registry transaction
subnetworkID, err := blockdag.TxToSubnetworkID(registryTx)
if err != nil {
return nil, fmt.Errorf("could not build subnetwork ID: %s", err)
}
return subnetworkID, nil
}