dcrd/chaincfg/init_test.go
2020-12-24 13:46:38 -06:00

451 lines
10 KiB
Go

// Copyright (c) 2017-2020 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package chaincfg
import (
"errors"
"testing"
"github.com/decred/dcrd/wire"
)
var (
consecMask = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0xa, // 0b1010 XXX not consecutive mask
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: false,
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
},
}
tooManyChoices = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: false,
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
{
Id: "Maybe",
Description: "Vote for Pedro",
Bits: 0x6, // 0b0110
IsAbstain: false,
IsNo: false,
},
// XXX here we go out of mask bounds
{
Id: "Hmmmm",
Description: "Vote for Pedro",
Bits: 0x6, // 0b0110 XXX invalid bits too
IsAbstain: false,
IsNo: false,
},
},
}
notConsec = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: false,
},
// XXX not consecutive
{
Id: "Maybe",
Description: "Vote for Pedro",
Bits: 0x6, // 0b0110
IsAbstain: false,
IsNo: false,
},
},
}
invalidAbstain = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: false, // XXX this is the invalid bit
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: false,
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
},
}
invalidVoteBits = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: false,
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0xc, // 0b1100 XXX invalid bits
IsAbstain: false,
IsNo: true,
},
},
}
twoIsAbstain = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: true, // XXX this is the invalid choice
IsNo: false,
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
},
}
twoIsNo = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: true, // XXX this is the invalid choice
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
},
}
bothFlags = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: true, // XXX this is the invalid choice
IsNo: true, // XXX this is the invalid choice
},
{
Id: "No",
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
},
}
dupChoice = Vote{
Id: "voteforpedro",
Description: "You should always vote for Pedro",
Mask: 0x6, // 0b0110
Choices: []Choice{
{
Id: "Abstain",
Description: "Abstain voting for Pedro",
Bits: 0x0, // 0b0000
IsAbstain: true,
IsNo: false,
},
{
Id: "Yes",
Description: "Vote for Pedro",
Bits: 0x2, // 0b0010
IsAbstain: false,
IsNo: false,
},
{
Id: "Yes", // XXX this is the invalid ID
Description: "Dont vote for Pedro",
Bits: 0x4, // 0b0100
IsAbstain: false,
IsNo: true,
},
},
}
)
func TestChoices(t *testing.T) {
tests := []struct {
name string
vote Vote
expected error
}{
{
name: "consecutive mask",
vote: consecMask,
expected: errInvalidMask,
},
{
name: "not consecutive choices",
vote: notConsec,
expected: errNotConsecutive,
},
{
name: "too many choices",
vote: tooManyChoices,
expected: errTooManyChoices,
},
{
name: "invalid ignore",
vote: invalidAbstain,
expected: errInvalidAbstain,
},
{
name: "invalid vote bits",
vote: invalidVoteBits,
expected: errInvalidBits,
},
{
name: "2 IsAbstain",
vote: twoIsAbstain,
expected: errInvalidIsAbstain,
},
{
name: "2 IsNo",
vote: twoIsNo,
expected: errInvalidIsNo,
},
{
name: "both IsAbstain IsNo",
vote: bothFlags,
expected: errInvalidBothFlags,
},
{
name: "duplicate choice id",
vote: dupChoice,
expected: errDuplicateChoiceId,
},
}
for _, test := range tests {
t.Logf("running: %v", test.name)
err := validateAgenda(test.vote)
if !errors.Is(err, test.expected) {
t.Fatalf("%v: got '%v' expected '%v'", test.name, err,
test.expected)
}
}
}
var (
dupVote = []ConsensusDeployment{
{Vote: Vote{Id: "moo"}},
{Vote: Vote{Id: "moo"}},
}
)
func TestDeployments(t *testing.T) {
tests := []struct {
name string
deployments []ConsensusDeployment
expected error
}{
{
name: "duplicate vote id",
deployments: dupVote,
expected: errDuplicateVoteId,
},
}
for _, test := range tests {
t.Logf("running: %v", test.name)
_, err := validateDeployments(test.deployments)
if !errors.Is(err, test.expected) {
t.Fatalf("%v: got '%v' expected '%v'", test.name, err,
test.expected)
}
}
}
// allDefaultNetParams returns the parameters for all of the default networks
// for use in the tests.
func allDefaultNetParams() []*Params {
return []*Params{MainNetParams(), TestNet3Params(), SimNetParams(),
RegNetParams()}
}
// TestRequiredUnique ensures that the network parameter fields that are
// required to be unique are in fact unique for all of the provided default
// parameters.
func TestRequiredUnique(t *testing.T) {
var (
netMagics = make(map[wire.CurrencyNet]struct{})
netPrefixes = make(map[string]struct{})
pubKeyAddrIDs = make(map[[2]byte]struct{})
pubKeyHashAddrIDs = make(map[[2]byte]struct{})
pkhEdwardsAddrIDs = make(map[[2]byte]struct{})
pkhSchnorrAddrIDs = make(map[[2]byte]struct{})
scriptHashAddrIDs = make(map[[2]byte]struct{})
)
for _, params := range allDefaultNetParams() {
if _, ok := netMagics[params.Net]; ok {
t.Fatalf("%q: duplicate network magic %x", params.Name,
params.Net)
}
netMagics[params.Net] = struct{}{}
if _, ok := netPrefixes[params.NetworkAddressPrefix]; ok {
t.Fatalf("%q: duplicate network address prefix %s", params.Name,
params.NetworkAddressPrefix)
}
netPrefixes[params.Name] = struct{}{}
if _, ok := pubKeyAddrIDs[params.PubKeyAddrID]; ok {
t.Fatalf("%q: duplicate pubkey addr ID %x", params.Name,
params.PubKeyAddrID)
}
pubKeyAddrIDs[params.PubKeyAddrID] = struct{}{}
if _, ok := pubKeyHashAddrIDs[params.PubKeyHashAddrID]; ok {
t.Fatalf("%q: duplicate pubkey hash addr ID %x", params.Name,
params.PubKeyHashAddrID)
}
pubKeyHashAddrIDs[params.PubKeyHashAddrID] = struct{}{}
if _, ok := pkhEdwardsAddrIDs[params.PKHEdwardsAddrID]; ok {
t.Fatalf("%q: duplicate edwards pubkey hash addr ID %x",
params.Name, params.PKHEdwardsAddrID)
}
pkhEdwardsAddrIDs[params.PKHEdwardsAddrID] = struct{}{}
if _, ok := pkhSchnorrAddrIDs[params.PKHSchnorrAddrID]; ok {
t.Fatalf("%q: duplicate schnorr pubkey hash addr ID %x",
params.Name, params.PKHSchnorrAddrID)
}
pkhSchnorrAddrIDs[params.PKHSchnorrAddrID] = struct{}{}
if _, ok := scriptHashAddrIDs[params.ScriptHashAddrID]; ok {
t.Fatalf("%q: duplicate script hash addr ID %x", params.Name,
params.ScriptHashAddrID)
}
scriptHashAddrIDs[params.ScriptHashAddrID] = struct{}{}
}
}