mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-05 21:56:50 +00:00
[DEV-68] Revert block version to 1 everywhere
* revert block version to 1 * [DEV-68] remove dersig flag * [DEV-68] get rid of vbLegacyBlockVersion * [DEV-68] remove isBIP0030Node
This commit is contained in:
parent
56fb7f09c1
commit
d9abfa0fd3
@ -84,7 +84,7 @@ func TestHaveBlock(t *testing.T) {
|
||||
{hash: dagconfig.MainNetParams.GenesisHash.String(), want: true},
|
||||
|
||||
// Block 3b should be present (as a second child of Block 2).
|
||||
{hash: "00000033119c0f74eff8b4711fce3769ea33e8a69670d9c0366179a9a5b8aec3", want: true},
|
||||
{hash: "000000bce70562ed076f269c5c4e39c590abb29428c573c02ab970e17931f8a4", want: true},
|
||||
|
||||
// Block 100000 should be present (as an orphan).
|
||||
{hash: "000000824dca82828b9a18ac09ed7c93292f6a042fae580c1192c8cd086fd990", want: true},
|
||||
@ -120,7 +120,7 @@ func TestHaveBlock(t *testing.T) {
|
||||
func TestCalcSequenceLock(t *testing.T) {
|
||||
netParams := &dagconfig.SimNetParams
|
||||
|
||||
blockVersion := int32(0x20000000)
|
||||
blockVersion := int32(0x10000000)
|
||||
|
||||
// Generate enough synthetic blocks for the rest of the test
|
||||
chain := newTestDAG(netParams)
|
||||
|
@ -105,8 +105,6 @@ var regressionNetParams = &dagconfig.Params{
|
||||
PowLimit: regressionPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
CoinbaseMaturity: 100,
|
||||
BIP0034Height: 100000000, // Not active - Permit ver 1 blocks
|
||||
BIP0066Height: 1251, // Used by regression tests
|
||||
SubsidyReductionInterval: 150,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
TargetTimePerBlock: time.Minute * 10, // 10 minutes
|
||||
|
@ -31,7 +31,7 @@ type hashIDPair struct {
|
||||
func TestPhantom(t *testing.T) {
|
||||
netParams := dagconfig.SimNetParams
|
||||
|
||||
blockVersion := int32(0x20000000)
|
||||
blockVersion := int32(0x10000000)
|
||||
|
||||
tests := []struct {
|
||||
k uint32
|
||||
@ -40,7 +40,7 @@ func TestPhantom(t *testing.T) {
|
||||
expectedReds []string
|
||||
}{
|
||||
{
|
||||
//Block hash order:DEBHICAKGJF
|
||||
//Block hash order:AKJIHGFEDCB
|
||||
k: 1,
|
||||
virtualBlockID: "K",
|
||||
expectedReds: []string{"D"},
|
||||
@ -98,8 +98,8 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"E", "G"},
|
||||
id: "I",
|
||||
expectedScore: 5,
|
||||
expectedSelectedParent: "G",
|
||||
expectedBlues: []string{"G"},
|
||||
expectedSelectedParent: "E",
|
||||
expectedBlues: []string{"G", "D", "E"},
|
||||
},
|
||||
{
|
||||
parents: []string{"F"},
|
||||
@ -113,12 +113,12 @@ func TestPhantom(t *testing.T) {
|
||||
id: "K",
|
||||
expectedScore: 9,
|
||||
expectedSelectedParent: "H",
|
||||
expectedBlues: []string{"I", "G", "J", "F", "H"},
|
||||
expectedBlues: []string{"I", "J", "G", "F", "H"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
//block hash order:DQKRLHOEBSIGUJNPCMTAFV
|
||||
//block hash order:AVUTSRQPONMLKJIHGFEDCB
|
||||
k: 2,
|
||||
virtualBlockID: "V",
|
||||
expectedReds: []string{"D", "J", "P"},
|
||||
@ -205,7 +205,7 @@ func TestPhantom(t *testing.T) {
|
||||
id: "M",
|
||||
expectedScore: 10,
|
||||
expectedSelectedParent: "F",
|
||||
expectedBlues: []string{"L", "K", "H", "I", "E", "G", "B", "F"},
|
||||
expectedBlues: []string{"L", "K", "I", "H", "G", "E", "B", "F"},
|
||||
},
|
||||
{
|
||||
parents: []string{"G", "K"},
|
||||
@ -233,7 +233,7 @@ func TestPhantom(t *testing.T) {
|
||||
id: "Q",
|
||||
expectedScore: 10,
|
||||
expectedSelectedParent: "P",
|
||||
expectedBlues: []string{"O", "N", "K", "I", "J", "E", "P"},
|
||||
expectedBlues: []string{"O", "N", "K", "J", "I", "E", "P"},
|
||||
},
|
||||
{
|
||||
parents: []string{"L", "Q"},
|
||||
@ -273,7 +273,7 @@ func TestPhantom(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
//Block hash order:NRSHBUXJTFGPDVCKEQIOWLMA
|
||||
//Block hash order:AXWVUTSRQPONMLKJIHGFEDCB
|
||||
k: 1,
|
||||
virtualBlockID: "X",
|
||||
expectedReds: []string{"D", "F", "G", "H", "J", "K", "L", "N", "O", "Q", "R", "S", "U", "V"},
|
||||
@ -373,15 +373,15 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"F", "G", "J"},
|
||||
id: "O",
|
||||
expectedScore: 5,
|
||||
expectedSelectedParent: "G",
|
||||
expectedBlues: []string{"J", "F", "G"},
|
||||
expectedSelectedParent: "F",
|
||||
expectedBlues: []string{"J", "G", "F"},
|
||||
},
|
||||
{
|
||||
parents: []string{"B", "M", "I"},
|
||||
id: "P",
|
||||
expectedScore: 6,
|
||||
expectedSelectedParent: "B",
|
||||
expectedBlues: []string{"I", "M", "C", "E", "B"},
|
||||
expectedBlues: []string{"M", "I", "E", "C", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"K", "E"},
|
||||
@ -415,15 +415,15 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"K", "L"},
|
||||
id: "U",
|
||||
expectedScore: 4,
|
||||
expectedSelectedParent: "L",
|
||||
expectedBlues: []string{"K", "L"},
|
||||
expectedSelectedParent: "K",
|
||||
expectedBlues: []string{"L", "K"},
|
||||
},
|
||||
{
|
||||
parents: []string{"U", "R"},
|
||||
id: "V",
|
||||
expectedScore: 6,
|
||||
expectedSelectedParent: "U",
|
||||
expectedBlues: []string{"R", "U"},
|
||||
expectedScore: 5,
|
||||
expectedSelectedParent: "R",
|
||||
expectedBlues: []string{"U", "R"},
|
||||
},
|
||||
{
|
||||
parents: []string{"S", "U", "T"},
|
||||
@ -449,10 +449,10 @@ func TestPhantom(t *testing.T) {
|
||||
//you to point to all the parents that you know, and
|
||||
//propagate your block as soon as it's mined
|
||||
|
||||
//Block hash order: HRTGMKQBXDWSICYFONUPLEAJZ
|
||||
//Block hash order:AYXWVUTSRQPONMLKJIHGFEDCB
|
||||
k: 1,
|
||||
virtualBlockID: "Y",
|
||||
expectedReds: []string{"B", "C", "D", "E", "F", "G"},
|
||||
expectedReds: []string{"B", "C", "D", "E", "F", "G", "L"},
|
||||
dagData: []*testBlockData{
|
||||
{
|
||||
parents: []string{"A"},
|
||||
@ -514,15 +514,15 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"H", "I"},
|
||||
id: "J",
|
||||
expectedScore: 3,
|
||||
expectedSelectedParent: "I",
|
||||
expectedBlues: []string{"H", "I"},
|
||||
expectedSelectedParent: "H",
|
||||
expectedBlues: []string{"I", "H"},
|
||||
},
|
||||
{
|
||||
parents: []string{"H", "I"},
|
||||
id: "K",
|
||||
expectedScore: 3,
|
||||
expectedSelectedParent: "I",
|
||||
expectedBlues: []string{"H", "I"},
|
||||
expectedSelectedParent: "H",
|
||||
expectedBlues: []string{"I", "H"},
|
||||
},
|
||||
{
|
||||
parents: []string{"I"},
|
||||
@ -534,105 +534,105 @@ func TestPhantom(t *testing.T) {
|
||||
{
|
||||
parents: []string{"J", "K", "L"},
|
||||
id: "M",
|
||||
expectedScore: 6,
|
||||
expectedScore: 5,
|
||||
expectedSelectedParent: "J",
|
||||
expectedBlues: []string{"K", "L", "J"},
|
||||
expectedBlues: []string{"K", "J"},
|
||||
},
|
||||
{
|
||||
parents: []string{"J", "K", "L"},
|
||||
id: "N",
|
||||
expectedScore: 6,
|
||||
expectedScore: 5,
|
||||
expectedSelectedParent: "J",
|
||||
expectedBlues: []string{"K", "L", "J"},
|
||||
expectedBlues: []string{"K", "J"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N", "M"},
|
||||
id: "O",
|
||||
expectedScore: 8,
|
||||
expectedSelectedParent: "N",
|
||||
expectedBlues: []string{"M", "N"},
|
||||
expectedScore: 7,
|
||||
expectedSelectedParent: "M",
|
||||
expectedBlues: []string{"N", "M"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N", "M"},
|
||||
id: "P",
|
||||
expectedScore: 8,
|
||||
expectedSelectedParent: "N",
|
||||
expectedBlues: []string{"M", "N"},
|
||||
expectedScore: 7,
|
||||
expectedSelectedParent: "M",
|
||||
expectedBlues: []string{"N", "M"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N", "M"},
|
||||
id: "Q",
|
||||
expectedScore: 8,
|
||||
expectedSelectedParent: "N",
|
||||
expectedBlues: []string{"M", "N"},
|
||||
expectedScore: 7,
|
||||
expectedSelectedParent: "M",
|
||||
expectedBlues: []string{"N", "M"},
|
||||
},
|
||||
{
|
||||
parents: []string{"O", "P", "Q"},
|
||||
id: "R",
|
||||
expectedScore: 11,
|
||||
expectedSelectedParent: "P",
|
||||
expectedBlues: []string{"Q", "O", "P"},
|
||||
expectedScore: 10,
|
||||
expectedSelectedParent: "O",
|
||||
expectedBlues: []string{"Q", "P", "O"},
|
||||
},
|
||||
{
|
||||
parents: []string{"O", "P", "Q"},
|
||||
id: "S",
|
||||
expectedScore: 11,
|
||||
expectedSelectedParent: "P",
|
||||
expectedBlues: []string{"Q", "O", "P"},
|
||||
expectedScore: 10,
|
||||
expectedSelectedParent: "O",
|
||||
expectedBlues: []string{"Q", "P", "O"},
|
||||
},
|
||||
{
|
||||
parents: []string{"G", "S", "R"},
|
||||
id: "T",
|
||||
expectedScore: 13,
|
||||
expectedSelectedParent: "S",
|
||||
expectedBlues: []string{"R", "S"},
|
||||
expectedScore: 12,
|
||||
expectedSelectedParent: "R",
|
||||
expectedBlues: []string{"S", "R"},
|
||||
},
|
||||
{
|
||||
parents: []string{"S", "R"},
|
||||
id: "U",
|
||||
expectedScore: 13,
|
||||
expectedSelectedParent: "S",
|
||||
expectedBlues: []string{"R", "S"},
|
||||
expectedScore: 12,
|
||||
expectedSelectedParent: "R",
|
||||
expectedBlues: []string{"S", "R"},
|
||||
},
|
||||
{
|
||||
parents: []string{"T", "U"},
|
||||
id: "V",
|
||||
expectedScore: 15,
|
||||
expectedSelectedParent: "U",
|
||||
expectedBlues: []string{"T", "U"},
|
||||
expectedScore: 14,
|
||||
expectedSelectedParent: "T",
|
||||
expectedBlues: []string{"U", "T"},
|
||||
},
|
||||
{
|
||||
parents: []string{"T", "U"},
|
||||
id: "W",
|
||||
expectedScore: 15,
|
||||
expectedSelectedParent: "U",
|
||||
expectedBlues: []string{"T", "U"},
|
||||
expectedScore: 14,
|
||||
expectedSelectedParent: "T",
|
||||
expectedBlues: []string{"U", "T"},
|
||||
},
|
||||
{
|
||||
parents: []string{"T", "U"},
|
||||
parents: []string{"U", "T"},
|
||||
id: "X",
|
||||
expectedScore: 15,
|
||||
expectedSelectedParent: "U",
|
||||
expectedBlues: []string{"T", "U"},
|
||||
expectedScore: 14,
|
||||
expectedSelectedParent: "T",
|
||||
expectedBlues: []string{"U", "T"},
|
||||
},
|
||||
{
|
||||
parents: []string{"V", "W", "X"},
|
||||
id: "Y",
|
||||
expectedScore: 18,
|
||||
expectedSelectedParent: "X",
|
||||
expectedBlues: []string{"W", "V", "X"},
|
||||
expectedScore: 17,
|
||||
expectedSelectedParent: "V",
|
||||
expectedBlues: []string{"X", "W", "V"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
//Censorship mining attack: The attacker is mining blocks B,C,D,E,F,G in secret without propagating them,
|
||||
//so all blocks except B should be red, because they don't follow the rules of
|
||||
//so all blocks except B and C should be red, because they don't follow the rules of
|
||||
//PHANTOM that require you to point to all the parents that you know
|
||||
|
||||
//Block hash order:WZHOGBJMDSICRUYKTFQLEAPXN
|
||||
//Block hash order:AYXWVUTSRQPONMLKJIHGFEDCB
|
||||
k: 1,
|
||||
virtualBlockID: "Y",
|
||||
expectedReds: []string{"C", "D", "E", "F", "G"},
|
||||
expectedReds: []string{"D", "E", "F", "G", "L"},
|
||||
dagData: []*testBlockData{
|
||||
{
|
||||
parents: []string{"A"},
|
||||
@ -694,15 +694,15 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"H", "I", "B"},
|
||||
id: "J",
|
||||
expectedScore: 4,
|
||||
expectedSelectedParent: "I",
|
||||
expectedBlues: []string{"H", "B", "I"},
|
||||
expectedSelectedParent: "B",
|
||||
expectedBlues: []string{"I", "H", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"H", "I", "B"},
|
||||
id: "K",
|
||||
expectedScore: 4,
|
||||
expectedSelectedParent: "I",
|
||||
expectedBlues: []string{"H", "B", "I"},
|
||||
expectedSelectedParent: "B",
|
||||
expectedBlues: []string{"I", "H", "B"},
|
||||
},
|
||||
{
|
||||
parents: []string{"I"},
|
||||
@ -715,50 +715,50 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"J", "K", "L", "C"},
|
||||
id: "M",
|
||||
expectedScore: 7,
|
||||
expectedSelectedParent: "K",
|
||||
expectedBlues: []string{"J", "L", "K"},
|
||||
expectedSelectedParent: "J",
|
||||
expectedBlues: []string{"K", "C", "J"},
|
||||
},
|
||||
{
|
||||
parents: []string{"J", "K", "L", "C"},
|
||||
id: "N",
|
||||
expectedScore: 7,
|
||||
expectedSelectedParent: "K",
|
||||
expectedBlues: []string{"J", "L", "K"},
|
||||
expectedSelectedParent: "J",
|
||||
expectedBlues: []string{"K", "C", "J"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N", "M", "D"},
|
||||
id: "O",
|
||||
expectedScore: 9,
|
||||
expectedSelectedParent: "N",
|
||||
expectedBlues: []string{"M", "N"},
|
||||
expectedSelectedParent: "M",
|
||||
expectedBlues: []string{"N", "M"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N", "M", "D"},
|
||||
id: "P",
|
||||
expectedScore: 9,
|
||||
expectedSelectedParent: "N",
|
||||
expectedBlues: []string{"M", "N"},
|
||||
expectedSelectedParent: "M",
|
||||
expectedBlues: []string{"N", "M"},
|
||||
},
|
||||
{
|
||||
parents: []string{"N", "M", "D"},
|
||||
id: "Q",
|
||||
expectedScore: 9,
|
||||
expectedSelectedParent: "N",
|
||||
expectedBlues: []string{"M", "N"},
|
||||
expectedSelectedParent: "M",
|
||||
expectedBlues: []string{"N", "M"},
|
||||
},
|
||||
{
|
||||
parents: []string{"O", "P", "Q", "E"},
|
||||
id: "R",
|
||||
expectedScore: 12,
|
||||
expectedSelectedParent: "P",
|
||||
expectedBlues: []string{"O", "Q", "P"},
|
||||
expectedSelectedParent: "O",
|
||||
expectedBlues: []string{"Q", "P", "O"},
|
||||
},
|
||||
{
|
||||
parents: []string{"O", "P", "Q", "E"},
|
||||
id: "S",
|
||||
expectedScore: 12,
|
||||
expectedSelectedParent: "P",
|
||||
expectedBlues: []string{"O", "Q", "P"},
|
||||
expectedSelectedParent: "O",
|
||||
expectedBlues: []string{"Q", "P", "O"},
|
||||
},
|
||||
{
|
||||
parents: []string{"G", "S", "R"},
|
||||
@ -799,8 +799,8 @@ func TestPhantom(t *testing.T) {
|
||||
parents: []string{"V", "W", "X"},
|
||||
id: "Y",
|
||||
expectedScore: 19,
|
||||
expectedSelectedParent: "W",
|
||||
expectedBlues: []string{"V", "X", "W"},
|
||||
expectedSelectedParent: "V",
|
||||
expectedBlues: []string{"X", "W", "V"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -825,6 +825,10 @@ func TestPhantom(t *testing.T) {
|
||||
parents.add(parent)
|
||||
}
|
||||
node := newTestNode(parents, blockVersion, 0, blockTime, test.k)
|
||||
node.hash = daghash.Hash{} //It helps to predict hash order
|
||||
for i, char := range blockData.id {
|
||||
node.hash[i] = byte(char)
|
||||
}
|
||||
|
||||
blockDAG.index.AddNode(node)
|
||||
blockByIDMap[blockData.id] = node
|
||||
|
BIN
blockdag/testdata/blk_0_to_4.dat
vendored
BIN
blockdag/testdata/blk_0_to_4.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3A.dat
vendored
BIN
blockdag/testdata/blk_3A.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3B.dat
vendored
BIN
blockdag/testdata/blk_3B.dat
vendored
Binary file not shown.
@ -38,10 +38,6 @@ const (
|
||||
// used to calculate the median time used to validate block timestamps.
|
||||
medianTimeBlocks = 11
|
||||
|
||||
// serializedHeightVersion is the block version which changed block
|
||||
// coinbases to start with the serialized block height.
|
||||
serializedHeightVersion = 2
|
||||
|
||||
// baseSubsidy is the starting subsidy amount for mined blocks. This
|
||||
// value is halved every SubsidyHalvingInterval blocks.
|
||||
baseSubsidy = 50 * btcutil.SatoshiPerBitcoin
|
||||
@ -77,15 +73,6 @@ func isNullOutpoint(outpoint *wire.OutPoint) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ShouldHaveSerializedBlockHeight determines if a block should have a
|
||||
// serialized block height embedded within the scriptSig of its
|
||||
// coinbase transaction. Judgement is based on the block version in the block
|
||||
// header. Blocks with version 2 and above satisfy this criteria. See BIP0034
|
||||
// for further information.
|
||||
func ShouldHaveSerializedBlockHeight(header *wire.BlockHeader) bool {
|
||||
return header.Version >= serializedHeightVersion
|
||||
}
|
||||
|
||||
// IsCoinBaseTx determines whether or not a transaction is a coinbase. A coinbase
|
||||
// is a special transaction created by miners that has no inputs. This is
|
||||
// represented in the block chain by a transaction with a single input that has
|
||||
@ -174,21 +161,6 @@ func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int32, blockTime time.Ti
|
||||
return true
|
||||
}
|
||||
|
||||
// isBIP0030Node returns whether or not the passed node represents one of the
|
||||
// two blocks that violate the BIP0030 rule which prevents transactions from
|
||||
// overwriting old ones.
|
||||
func isBIP0030Node(node *blockNode) bool {
|
||||
if node.height == 91842 && node.hash.IsEqual(block91842Hash) {
|
||||
return true
|
||||
}
|
||||
|
||||
if node.height == 91880 && node.hash.IsEqual(block91880Hash) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// CalcBlockSubsidy returns the subsidy amount a block at the provided height
|
||||
// should have. This is mainly used for determining how much the coinbase for
|
||||
// newly generated blocks awards as well as validating the coinbase for blocks
|
||||
@ -584,20 +556,19 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource Median
|
||||
}
|
||||
|
||||
// ExtractCoinbaseHeight attempts to extract the height of the block from the
|
||||
// scriptSig of a coinbase transaction. Coinbase heights are only present in
|
||||
// blocks of version 2 or later. This was added as part of BIP0034.
|
||||
// scriptSig of a coinbase transaction.
|
||||
func ExtractCoinbaseHeight(coinbaseTx *btcutil.Tx) (int32, error) {
|
||||
sigScript := coinbaseTx.MsgTx().TxIn[0].SignatureScript
|
||||
if len(sigScript) < 1 {
|
||||
str := "the coinbase signature script for blocks of " +
|
||||
"version %d or greater must start with the " +
|
||||
str := "the coinbase signature script" +
|
||||
"must start with the " +
|
||||
"length of the serialized block height"
|
||||
str = fmt.Sprintf(str, serializedHeightVersion)
|
||||
str = fmt.Sprintf(str)
|
||||
return 0, ruleError(ErrMissingCoinbaseHeight, str)
|
||||
}
|
||||
|
||||
// Detect the case when the block height is a small integer encoded with
|
||||
// as single byte.
|
||||
// a single byte.
|
||||
opcode := int(sigScript[0])
|
||||
if opcode == txscript.Op0 {
|
||||
return 0, nil
|
||||
@ -610,8 +581,8 @@ func ExtractCoinbaseHeight(coinbaseTx *btcutil.Tx) (int32, error) {
|
||||
// encode in the block height.
|
||||
serializedLen := int(sigScript[0])
|
||||
if len(sigScript[1:]) < serializedLen {
|
||||
str := "the coinbase signature script for blocks of " +
|
||||
"version %d or greater must start with the " +
|
||||
str := "the coinbase signature script " +
|
||||
"must start with the " +
|
||||
"serialized block height"
|
||||
str = fmt.Sprintf(str, serializedLen)
|
||||
return 0, ruleError(ErrMissingCoinbaseHeight, str)
|
||||
@ -704,18 +675,6 @@ func (dag *BlockDAG) checkBlockHeaderContext(header *wire.BlockHeader, selectedP
|
||||
return ruleError(ErrForkTooOld, str)
|
||||
}
|
||||
|
||||
// Reject outdated block versions once a majority of the network
|
||||
// has upgraded. These were originally voted on by BIP0034,
|
||||
// BIP0065, and BIP0066.
|
||||
params := dag.dagParams
|
||||
if header.Version < 2 && blockHeight >= params.BIP0034Height ||
|
||||
header.Version < 3 && blockHeight >= params.BIP0066Height {
|
||||
|
||||
str := "new blocks with version %d are no longer valid"
|
||||
str = fmt.Sprintf(str, header.Version)
|
||||
return ruleError(ErrBlockVersionTooOld, str)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -757,25 +716,20 @@ func (dag *BlockDAG) checkBlockContext(block *btcutil.Block, selectedParent *blo
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure coinbase starts with serialized block heights for
|
||||
// blocks whose version is the serializedHeightVersion or newer
|
||||
// once a majority of the network has upgraded. This is part of
|
||||
// BIP0034.
|
||||
if ShouldHaveSerializedBlockHeight(header) &&
|
||||
blockHeight >= dag.dagParams.BIP0034Height {
|
||||
// Ensure coinbase starts with serialized block heights
|
||||
|
||||
coinbaseTx := block.Transactions()[0]
|
||||
err := checkSerializedHeight(coinbaseTx, blockHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
coinbaseTx := block.Transactions()[0]
|
||||
err := checkSerializedHeight(coinbaseTx, blockHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkBIP0030 ensures blocks do not contain duplicate transactions which
|
||||
// ensureNoDuplicateTx ensures blocks do not contain duplicate transactions which
|
||||
// 'overwrite' older transactions that are not fully spent. This prevents an
|
||||
// attack where a coinbase and all of its dependent transactions could be
|
||||
// duplicated to effectively revert the overwritten transactions to a single
|
||||
@ -786,7 +740,7 @@ func (dag *BlockDAG) checkBlockContext(block *btcutil.Block, selectedParent *blo
|
||||
// http://r6.ca/blog/20120206T005236Z.html.
|
||||
//
|
||||
// This function MUST be called with the chain state lock held (for reads).
|
||||
func (dag *BlockDAG) checkBIP0030(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error {
|
||||
func (dag *BlockDAG) ensureNoDuplicateTx(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error {
|
||||
// Fetch utxos for all of the transaction ouputs in this block.
|
||||
// Typically, there will not be any utxos for any of the outputs.
|
||||
fetchSet := make(map[wire.OutPoint]struct{})
|
||||
@ -965,27 +919,9 @@ func (dag *BlockDAG) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
|
||||
"of expected %v", view.Tips(), parentHashes))
|
||||
}
|
||||
|
||||
// BIP0030 added a rule to prevent blocks which contain duplicate
|
||||
// transactions that 'overwrite' older transactions which are not fully
|
||||
// spent. See the documentation for checkBIP0030 for more details.
|
||||
//
|
||||
// There are two blocks in the chain which violate this rule, so the
|
||||
// check must be skipped for those blocks. The isBIP0030Node function
|
||||
// is used to determine if this block is one of the two blocks that must
|
||||
// be skipped.
|
||||
//
|
||||
// In addition, as of BIP0034, duplicate coinbases are no longer
|
||||
// possible due to its requirement for including the block height in the
|
||||
// coinbase and thus it is no longer possible to create transactions
|
||||
// that 'overwrite' older ones. Therefore, only enforce the rule if
|
||||
// BIP0034 is not yet active. This is a useful optimization because the
|
||||
// BIP0030 check is expensive since it involves a ton of cache misses in
|
||||
// the utxoset.
|
||||
if !isBIP0030Node(node) && (node.height < dag.dagParams.BIP0034Height) {
|
||||
err := dag.checkBIP0030(node, block, view)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err := dag.ensureNoDuplicateTx(node, block, view)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Load all of the utxos referenced by the inputs for all transactions
|
||||
@ -993,7 +929,7 @@ func (dag *BlockDAG) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
|
||||
//
|
||||
// These utxo entries are needed for verification of things such as
|
||||
// transaction inputs, counting pay-to-script-hashes, and scripts.
|
||||
err := view.fetchInputUtxos(dag.db, block)
|
||||
err = view.fetchInputUtxos(dag.db, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1115,13 +1051,6 @@ func (dag *BlockDAG) checkConnectBlock(node *blockNode, block *btcutil.Block, vi
|
||||
scriptFlags |= txscript.ScriptBip16
|
||||
}
|
||||
|
||||
// Enforce DER signatures for block versions 3+ once the historical
|
||||
// activation threshold has been reached. This is part of BIP0066.
|
||||
blockHeader := &block.MsgBlock().Header
|
||||
if blockHeader.Version >= 3 && node.height >= dag.dagParams.BIP0066Height {
|
||||
scriptFlags |= txscript.ScriptVerifyDERSignatures
|
||||
}
|
||||
|
||||
// We obtain the MTP of the *previous* block in order to
|
||||
// determine if transactions in the current block are final.
|
||||
medianTime := node.selectedParent.CalcPastMedianTime()
|
||||
|
@ -11,9 +11,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// vbLegacyBlockVersion is the highest legacy block version before the
|
||||
// version bits scheme became active.
|
||||
vbLegacyBlockVersion = 4
|
||||
|
||||
// vbTopBits defines the bits to set in the version to signal that the
|
||||
// version bits scheme is being used.
|
||||
@ -282,8 +279,7 @@ func (dag *BlockDAG) warnUnknownVersions(node *blockNode) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if expectedVersion > vbLegacyBlockVersion &&
|
||||
(node.version & ^expectedVersion) != 0 {
|
||||
if (node.version & ^expectedVersion) != 0 {
|
||||
|
||||
numUpgraded++
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
{
|
||||
name: "getblocktemplate optional - template request with tweaks",
|
||||
newCmd: func() (interface{}, error) {
|
||||
return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}`)
|
||||
return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":1}`)
|
||||
},
|
||||
staticCmd: func() interface{} {
|
||||
template := btcjson.TemplateRequest{
|
||||
@ -277,25 +277,25 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
Capabilities: []string{"longpoll", "coinbasetxn"},
|
||||
SigOpLimit: 500,
|
||||
SizeLimit: 100000000,
|
||||
MaxVersion: 2,
|
||||
MaxVersion: 1,
|
||||
}
|
||||
return btcjson.NewGetBlockTemplateCmd(&template)
|
||||
},
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}],"id":1}`,
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":1}],"id":1}`,
|
||||
unmarshalled: &btcjson.GetBlockTemplateCmd{
|
||||
Request: &btcjson.TemplateRequest{
|
||||
Mode: "template",
|
||||
Capabilities: []string{"longpoll", "coinbasetxn"},
|
||||
SigOpLimit: int64(500),
|
||||
SizeLimit: int64(100000000),
|
||||
MaxVersion: 2,
|
||||
MaxVersion: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "getblocktemplate optional - template request with tweaks 2",
|
||||
newCmd: func() (interface{}, error) {
|
||||
return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}`)
|
||||
return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":1}`)
|
||||
},
|
||||
staticCmd: func() interface{} {
|
||||
template := btcjson.TemplateRequest{
|
||||
@ -303,18 +303,18 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
Capabilities: []string{"longpoll", "coinbasetxn"},
|
||||
SigOpLimit: true,
|
||||
SizeLimit: 100000000,
|
||||
MaxVersion: 2,
|
||||
MaxVersion: 1,
|
||||
}
|
||||
return btcjson.NewGetBlockTemplateCmd(&template)
|
||||
},
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}],"id":1}`,
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":1}],"id":1}`,
|
||||
unmarshalled: &btcjson.GetBlockTemplateCmd{
|
||||
Request: &btcjson.TemplateRequest{
|
||||
Mode: "template",
|
||||
Capabilities: []string{"longpoll", "coinbasetxn"},
|
||||
SigOpLimit: true,
|
||||
SizeLimit: int64(100000000),
|
||||
MaxVersion: 2,
|
||||
MaxVersion: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -183,11 +183,6 @@ type Params struct {
|
||||
// block in compact form.
|
||||
PowLimitBits uint32
|
||||
|
||||
// These fields define the block heights at which the specified softfork
|
||||
// BIP became active.
|
||||
BIP0034Height int32
|
||||
BIP0066Height int32
|
||||
|
||||
// CoinbaseMaturity is the number of blocks required before newly mined
|
||||
// coins (coinbase transactions) can be spent.
|
||||
CoinbaseMaturity uint16
|
||||
@ -285,8 +280,6 @@ var MainNetParams = Params{
|
||||
GenesisHash: &genesisHash,
|
||||
PowLimit: mainPowLimit,
|
||||
PowLimitBits: 0x1d00ffff,
|
||||
BIP0034Height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8
|
||||
BIP0066Height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 210000,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
@ -367,8 +360,6 @@ var RegressionNetParams = Params{
|
||||
PowLimit: regressionPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
CoinbaseMaturity: 100,
|
||||
BIP0034Height: 100000000, // Not active - Permit ver 1 blocks
|
||||
BIP0066Height: 1251, // Used by regression tests
|
||||
SubsidyReductionInterval: 150,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
TargetTimePerBlock: time.Minute * 10, // 10 minutes
|
||||
@ -433,8 +424,6 @@ var TestNet3Params = Params{
|
||||
GenesisHash: &testNet3GenesisHash,
|
||||
PowLimit: testNet3PowLimit,
|
||||
PowLimitBits: 0x1d00ffff,
|
||||
BIP0034Height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8
|
||||
BIP0066Height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 210000,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
@ -511,8 +500,6 @@ var SimNetParams = Params{
|
||||
GenesisHash: &simNetGenesisHash,
|
||||
PowLimit: simNetPowLimit,
|
||||
PowLimitBits: 0x207fffff,
|
||||
BIP0034Height: 0, // Always active on simnet
|
||||
BIP0066Height: 0, // Always active on simnet
|
||||
CoinbaseMaturity: 100,
|
||||
SubsidyReductionInterval: 210000,
|
||||
TargetTimespan: time.Hour * 24 * 14, // 14 days
|
||||
|
@ -33,7 +33,7 @@ const (
|
||||
|
||||
// BlockVersion is the default block version used when generating
|
||||
// blocks.
|
||||
BlockVersion = 4
|
||||
BlockVersion = 1
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -588,19 +588,16 @@ func (sm *SyncManager) handleBlockMsg(bmsg *blockMsg) {
|
||||
// block height from the scriptSig of the coinbase transaction.
|
||||
// Extraction is only attempted if the block's version is
|
||||
// high enough (ver 2+).
|
||||
header := &bmsg.block.MsgBlock().Header
|
||||
if blockdag.ShouldHaveSerializedBlockHeight(header) {
|
||||
coinbaseTx := bmsg.block.Transactions()[0]
|
||||
cbHeight, err := blockdag.ExtractCoinbaseHeight(coinbaseTx)
|
||||
if err != nil {
|
||||
log.Warnf("Unable to extract height from "+
|
||||
"coinbase tx: %v", err)
|
||||
} else {
|
||||
log.Debugf("Extracted height of %v from "+
|
||||
"orphan block", cbHeight)
|
||||
heightUpdate = cbHeight
|
||||
blkHashUpdate = blockHash
|
||||
}
|
||||
coinbaseTx := bmsg.block.Transactions()[0]
|
||||
cbHeight, err := blockdag.ExtractCoinbaseHeight(coinbaseTx)
|
||||
if err != nil {
|
||||
log.Warnf("Unable to extract height from "+
|
||||
"coinbase tx: %v", err)
|
||||
} else {
|
||||
log.Debugf("Extracted height of %v from "+
|
||||
"orphan block", cbHeight)
|
||||
heightUpdate = cbHeight
|
||||
blkHashUpdate = blockHash
|
||||
}
|
||||
|
||||
orphanRoot := sm.dag.GetOrphanRoot(blockHash)
|
||||
|
@ -1182,31 +1182,6 @@ func handleGetBlockDAGInfo(s *Server, cmd interface{}, closeChan <-chan struct{}
|
||||
Bip9SoftForks: make(map[string]*btcjson.Bip9SoftForkDescription),
|
||||
}
|
||||
|
||||
// Next, populate the response with information describing the current
|
||||
// status of soft-forks deployed via the super-majority block
|
||||
// signalling mechanism.
|
||||
height := dagState.SelectedTip.Height
|
||||
chainInfo.SoftForks = []*btcjson.SoftForkDescription{
|
||||
{
|
||||
ID: "bip34",
|
||||
Version: 2,
|
||||
Reject: struct {
|
||||
Status bool `json:"status"`
|
||||
}{
|
||||
Status: height >= params.BIP0034Height,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "bip66",
|
||||
Version: 3,
|
||||
Reject: struct {
|
||||
Status bool `json:"status"`
|
||||
}{
|
||||
Status: height >= params.BIP0066Height,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Finally, query the BIP0009 version bits state for all currently
|
||||
// defined BIP0009 soft-fork deployments.
|
||||
for deployment, deploymentDetails := range params.Deployments {
|
||||
|
@ -687,16 +687,6 @@
|
||||
"STRICTENC", "OK",
|
||||
"2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature."
|
||||
],
|
||||
|
||||
["Increase test coverage for DERSIG"],
|
||||
["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "OK", "Overly long signature is correctly encoded"],
|
||||
["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "OK", "Missing S is correctly encoded"],
|
||||
["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "S with invalid S length is correctly encoded"],
|
||||
["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Non-integer R is correctly encoded"],
|
||||
["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Non-integer S is correctly encoded"],
|
||||
["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Zero-length R is correctly encoded"],
|
||||
["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "OK", "Zero-length S is correctly encoded for DERSIG"],
|
||||
["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Negative S is correctly encoded"],
|
||||
|
||||
["TRUE 2147483648", "CHECKSEQUENCEVERIFY", "", "OK", "CSV passes if stack top bit 1 << 31 is set"],
|
||||
|
||||
@ -1077,7 +1067,6 @@
|
||||
["", "1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"],
|
||||
["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "SIG_COUNT", "CHECKMULTISIG must error when the specified number of signatures is negative"],
|
||||
["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "INVALID_STACK_OPERATION", "CHECKMULTISIG must error when there are not enough signatures on the stack"],
|
||||
["", "'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "EVAL_FALSE", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"],
|
||||
|
||||
["",
|
||||
"0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG",
|
||||
@ -1233,14 +1222,14 @@
|
||||
],
|
||||
|
||||
["Increase DERSIG test coverage"],
|
||||
["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Overly long signature is incorrectly encoded for DERSIG"],
|
||||
["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Missing S is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "S with invalid S length is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer R is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Non-integer S is incorrectly encoded for DERSIG"],
|
||||
["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length R is incorrectly encoded for DERSIG"],
|
||||
["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"],
|
||||
["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "SIG_DER", "Overly long signature is incorrectly encoded for DERSIG"],
|
||||
["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "SIG_DER", "Missing S is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "SIG_DER", "S with invalid S length is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "SIG_DER", "Non-integer R is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "SIG_DER", "Non-integer S is incorrectly encoded for DERSIG"],
|
||||
["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "SIG_DER", "Zero-length R is incorrectly encoded for DERSIG"],
|
||||
["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "SIG_DER", "Zero-length S is incorrectly encoded for DERSIG"],
|
||||
["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "SIG_DER", "Negative S is incorrectly encoded for DERSIG"],
|
||||
|
||||
["CHECKSEQUENCEVERIFY tests"],
|
||||
["", "CHECKSEQUENCEVERIFY", "", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"],
|
||||
@ -1251,12 +1240,12 @@
|
||||
"CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"],
|
||||
|
||||
["NULLFAIL should cover all signatures and signatures only"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "", "OK", "BIP66 and NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "", "OK", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "", "OK", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
["0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"],
|
||||
|
||||
["The End"]
|
||||
]
|
||||
|
@ -35,10 +35,6 @@ const (
|
||||
// This flag should never be used without the ScriptBip16 flag.
|
||||
ScriptVerifyCleanStack
|
||||
|
||||
// ScriptVerifyDERSignatures defines that signatures are required
|
||||
// to compily with the DER format.
|
||||
ScriptVerifyDERSignatures
|
||||
|
||||
// ScriptVerifyLowS defines that signtures are required to comply with
|
||||
// the DER format and whose S value is <= order / 2. This is rule 5
|
||||
// of BIP0062.
|
||||
@ -420,12 +416,6 @@ func (vm *Engine) checkPubKeyEncoding(pubKey []byte) error {
|
||||
// checkSignatureEncoding returns whether or not the passed signature adheres to
|
||||
// the strict encoding requirements if enabled.
|
||||
func (vm *Engine) checkSignatureEncoding(sig []byte) error {
|
||||
if !vm.hasFlag(ScriptVerifyDERSignatures) &&
|
||||
!vm.hasFlag(ScriptVerifyLowS) &&
|
||||
!vm.hasFlag(ScriptVerifyStrictEncoding) {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// The format of a DER encoded signature is as follows:
|
||||
//
|
||||
|
@ -162,7 +162,7 @@ func ExampleSignTxOutput() {
|
||||
|
||||
// Prove that the transaction has been validly signed by executing the
|
||||
// script pair.
|
||||
flags := txscript.ScriptBip16 | txscript.ScriptVerifyDERSignatures |
|
||||
flags := txscript.ScriptBip16 |
|
||||
txscript.ScriptDiscourageUpgradableNops
|
||||
vm, err := txscript.NewEngine(originTx.TxOut[0].PkScript, redeemTx, 0, flags, nil)
|
||||
if err != nil {
|
||||
|
@ -2023,14 +2023,7 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var signature *btcec.Signature
|
||||
if vm.hasFlag(ScriptVerifyStrictEncoding) ||
|
||||
vm.hasFlag(ScriptVerifyDERSignatures) {
|
||||
|
||||
signature, err = btcec.ParseDERSignature(sigBytes, btcec.S256())
|
||||
} else {
|
||||
signature, err = btcec.ParseSignature(sigBytes, btcec.S256())
|
||||
}
|
||||
signature, err := btcec.ParseDERSignature(sigBytes, btcec.S256())
|
||||
if err != nil {
|
||||
vm.dstack.PushBool(false)
|
||||
return nil
|
||||
@ -2200,15 +2193,9 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||
|
||||
// Parse the signature.
|
||||
var err error
|
||||
if vm.hasFlag(ScriptVerifyStrictEncoding) ||
|
||||
vm.hasFlag(ScriptVerifyDERSignatures) {
|
||||
parsedSig, err = btcec.ParseDERSignature(signature,
|
||||
btcec.S256())
|
||||
|
||||
parsedSig, err = btcec.ParseDERSignature(signature,
|
||||
btcec.S256())
|
||||
} else {
|
||||
parsedSig, err = btcec.ParseSignature(signature,
|
||||
btcec.S256())
|
||||
}
|
||||
sigInfo.parsed = true
|
||||
if err != nil {
|
||||
continue
|
||||
|
@ -135,8 +135,6 @@ func parseScriptFlags(flagStr string) (ScriptFlags, error) {
|
||||
// Nothing.
|
||||
case "CLEANSTACK":
|
||||
flags |= ScriptVerifyCleanStack
|
||||
case "DERSIG":
|
||||
flags |= ScriptVerifyDERSignatures
|
||||
case "DISCOURAGE_UPGRADABLE_NOPS":
|
||||
flags |= ScriptDiscourageUpgradableNops
|
||||
case "LOW_S":
|
||||
|
@ -56,7 +56,7 @@ func mkGetScript(scripts map[string][]byte) ScriptDB {
|
||||
func checkScripts(msg string, tx *wire.MsgTx, idx int, sigScript, pkScript []byte) error {
|
||||
tx.TxIn[idx].SignatureScript = sigScript
|
||||
vm, err := NewEngine(pkScript, tx, idx,
|
||||
ScriptBip16|ScriptVerifyDERSignatures, nil)
|
||||
ScriptBip16, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to make script engine for %s: %v",
|
||||
msg, err)
|
||||
@ -1658,7 +1658,7 @@ nexttest:
|
||||
}
|
||||
|
||||
// Validate tx input scripts
|
||||
scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures
|
||||
scriptFlags := ScriptBip16
|
||||
for j := range tx.TxIn {
|
||||
vm, err := NewEngine(sigScriptTests[i].
|
||||
inputs[j].txout.PkScript, tx, j, scriptFlags, nil)
|
||||
|
@ -27,7 +27,6 @@ const (
|
||||
// TODO: This definition does not belong here. It belongs in a policy
|
||||
// package.
|
||||
StandardVerifyFlags = ScriptBip16 |
|
||||
ScriptVerifyDERSignatures |
|
||||
ScriptVerifyStrictEncoding |
|
||||
ScriptVerifyMinimalData |
|
||||
ScriptDiscourageUpgradableNops |
|
||||
|
Loading…
x
Reference in New Issue
Block a user