[NOD-64] Remove subnetwork id supports all (#237)

* [NOD-64] Intermediate commit: need check tests on master

* [NOD-64] Commit before changing subnetwork IDS to new values

* [NOD-64] Fixed tests after changing subnetworks IDs constants

* [NOD-64] Extract duplicate code into functions

* [NOD-64] Renamed IsAllSubnetworks ==> IncludeAllSubnetworks
This commit is contained in:
Evgeny Khirin 2019-04-03 17:03:48 +03:00 committed by Svarog
parent 67358d1e85
commit 7c30bc4301
62 changed files with 686 additions and 484 deletions

View File

@ -34,23 +34,27 @@ type triedBucket [triedBucketCount]*list.List
// AddrManager provides a concurrency safe address manager for caching potential
// peers on the bitcoin network.
type AddrManager struct {
mtx sync.Mutex
peersFile string
lookupFunc func(string) ([]net.IP, error)
rand *rand.Rand
key [32]byte
addrIndex map[string]*KnownAddress // address key to ka for all addrs.
addrNew map[subnetworkid.SubnetworkID]*newBucket
addrTried map[subnetworkid.SubnetworkID]*triedBucket
started int32
shutdown int32
wg sync.WaitGroup
quit chan struct{}
nTried map[subnetworkid.SubnetworkID]int
nNew map[subnetworkid.SubnetworkID]int
lamtx sync.Mutex
localAddresses map[string]*localAddress
localSubnetworkID *subnetworkid.SubnetworkID
mtx sync.Mutex
peersFile string
lookupFunc func(string) ([]net.IP, error)
rand *rand.Rand
key [32]byte
addrIndex map[string]*KnownAddress // address key to ka for all addrs.
addrNew map[subnetworkid.SubnetworkID]*newBucket
addrNewFullNodes newBucket
addrTried map[subnetworkid.SubnetworkID]*triedBucket
addrTriedFullNodes triedBucket
started int32
shutdown int32
wg sync.WaitGroup
quit chan struct{}
nTried map[subnetworkid.SubnetworkID]int
nNew map[subnetworkid.SubnetworkID]int
nTriedFullNodes int
nNewFullNodes int
lamtx sync.Mutex
localAddresses map[string]*localAddress
localSubnetworkID *subnetworkid.SubnetworkID
}
type serializedKnownAddress struct {
@ -68,11 +72,13 @@ type serializedNewBucket [newBucketCount][]string
type serializedTriedBucket [triedBucketCount][]string
type serializedAddrManager struct {
Version int
Key [32]byte
Addresses []*serializedKnownAddress
NewBuckets map[string]*serializedNewBucket // string is NetAddressKey
TriedBuckets map[string]*serializedTriedBucket
Version int
Key [32]byte
Addresses []*serializedKnownAddress
NewBuckets map[string]*serializedNewBucket // string is Subnetwork ID
NewBucketFullNodes serializedNewBucket
TriedBuckets map[string]*serializedTriedBucket // string is Subnetwork ID
TriedBucketFullNodes serializedTriedBucket
}
type localAddress struct {
@ -218,34 +224,57 @@ func (a *AddrManager) updateAddress(netAddr, srcAddr *wire.NetAddress, subnetwor
netAddrCopy := *netAddr
ka = &KnownAddress{na: &netAddrCopy, srcAddr: srcAddr, subnetworkID: subnetworkID}
a.addrIndex[addr] = ka
a.nNew[*subnetworkID]++
if subnetworkID == nil {
a.nNewFullNodes++
} else {
a.nNew[*subnetworkID]++
}
// XXX time penalty?
}
bucket := a.getNewBucket(netAddr, srcAddr)
// Already exists?
if a.addrNew[*ka.subnetworkID] != nil {
if ka.subnetworkID == nil {
if _, ok := a.addrNewFullNodes[bucket][addr]; ok {
return
}
} else if a.addrNew[*ka.subnetworkID] != nil {
if _, ok := a.addrNew[*ka.subnetworkID][bucket][addr]; ok {
return
}
}
// Enforce max addresses.
if a.addrNew[*ka.subnetworkID] != nil && len(a.addrNew[*ka.subnetworkID][bucket]) > newBucketSize {
if ka.subnetworkID == nil {
if len(a.addrNewFullNodes[bucket]) > newBucketSize {
log.Tracef("new bucket of full nodes is full, expiring old")
a.expireNewFullNodes(bucket)
}
} else if a.addrNew[*ka.subnetworkID] != nil && len(a.addrNew[*ka.subnetworkID][bucket]) > newBucketSize {
log.Tracef("new bucket is full, expiring old")
a.expireNew(bucket)
a.expireNewBySubnetworkID(ka.subnetworkID, bucket)
}
// Add to new bucket.
ka.refs++
a.updateAddrNew(bucket, addr, ka)
log.Tracef("Added new address %s for a total of %d addresses", addr,
a.nTried[*ka.subnetworkID]+a.nNew[*ka.subnetworkID])
if ka.subnetworkID == nil {
log.Tracef("Added new full node address %s for a total of %d addresses", addr,
a.nTriedFullNodes+a.nNewFullNodes)
} else {
log.Tracef("Added new address %s for a total of %d addresses", addr,
a.nTried[*ka.subnetworkID]+a.nNew[*ka.subnetworkID])
}
}
func (a *AddrManager) updateAddrNew(bucket int, addr string, ka *KnownAddress) {
if ka.subnetworkID == nil {
a.addrNewFullNodes[bucket][addr] = ka
return
}
if _, ok := a.addrNew[*ka.subnetworkID]; !ok {
a.addrNew[*ka.subnetworkID] = &newBucket{}
for i := range a.addrNew[*ka.subnetworkID] {
@ -256,6 +285,11 @@ func (a *AddrManager) updateAddrNew(bucket int, addr string, ka *KnownAddress) {
}
func (a *AddrManager) updateAddrTried(bucket int, ka *KnownAddress) {
if ka.subnetworkID == nil {
a.addrTriedFullNodes[bucket].PushBack(ka)
return
}
if _, ok := a.addrTried[*ka.subnetworkID]; !ok {
a.addrTried[*ka.subnetworkID] = &triedBucket{}
for i := range a.addrTried[*ka.subnetworkID] {
@ -267,45 +301,54 @@ func (a *AddrManager) updateAddrTried(bucket int, ka *KnownAddress) {
// expireNew makes space in the new buckets by expiring the really bad entries.
// If no bad entries are available we look at a few and remove the oldest.
func (a *AddrManager) expireNew(bucket int) {
for subnetworkID := range a.addrNew {
// First see if there are any entries that are so bad we can just throw
// them away. otherwise we throw away the oldest entry in the cache.
// Bitcoind here chooses four random and just throws the oldest of
// those away, but we keep track of oldest in the initial traversal and
// use that information instead.
var oldest *KnownAddress
for k, v := range a.addrNew[subnetworkID][bucket] {
if v.isBad() {
log.Tracef("expiring bad address %s", k)
delete(a.addrNew[subnetworkID][bucket], k)
v.refs--
if v.refs == 0 {
a.nNew[subnetworkID]--
delete(a.addrIndex, k)
}
continue
}
if oldest == nil {
oldest = v
} else if !v.na.Timestamp.After(oldest.na.Timestamp) {
oldest = v
func (a *AddrManager) expireNew(bucket *newBucket, idx int, decrNewCounter func()) {
// First see if there are any entries that are so bad we can just throw
// them away. otherwise we throw away the oldest entry in the cache.
// Bitcoind here chooses four random and just throws the oldest of
// those away, but we keep track of oldest in the initial traversal and
// use that information instead.
var oldest *KnownAddress
for k, v := range bucket[idx] {
if v.isBad() {
log.Tracef("expiring bad address %s", k)
delete(bucket[idx], k)
v.refs--
if v.refs == 0 {
decrNewCounter()
delete(a.addrIndex, k)
}
continue
}
if oldest != nil {
key := NetAddressKey(oldest.na)
log.Tracef("expiring oldest address %s", key)
delete(a.addrNew[subnetworkID][bucket], key)
oldest.refs--
if oldest.refs == 0 {
a.nNew[subnetworkID]--
delete(a.addrIndex, key)
}
if oldest == nil {
oldest = v
} else if !v.na.Timestamp.After(oldest.na.Timestamp) {
oldest = v
}
}
if oldest != nil {
key := NetAddressKey(oldest.na)
log.Tracef("expiring oldest address %s", key)
delete(bucket[idx], key)
oldest.refs--
if oldest.refs == 0 {
decrNewCounter()
delete(a.addrIndex, key)
}
}
}
// expireNewBySubnetworkID makes space in the new buckets by expiring the really bad entries.
// If no bad entries are available we look at a few and remove the oldest.
func (a *AddrManager) expireNewBySubnetworkID(subnetworkID *subnetworkid.SubnetworkID, bucket int) {
a.expireNew(a.addrNew[*subnetworkID], bucket, func() { a.nNew[*subnetworkID]-- })
}
// expireNewFullNodes makes space in the new buckets by expiring the really bad entries.
// If no bad entries are available we look at a few and remove the oldest.
func (a *AddrManager) expireNewFullNodes(bucket int) {
a.expireNew(&a.addrNewFullNodes, bucket, func() { a.nNewFullNodes-- })
}
// pickTried selects an address from the tried bucket to be evicted.
@ -314,7 +357,13 @@ func (a *AddrManager) expireNew(bucket int) {
func (a *AddrManager) pickTried(subnetworkID *subnetworkid.SubnetworkID, bucket int) *list.Element {
var oldest *KnownAddress
var oldestElem *list.Element
for e := a.addrTried[*subnetworkID][bucket].Front(); e != nil; e = e.Next() {
var lst *list.List
if subnetworkID == nil {
lst = a.addrTriedFullNodes[bucket]
} else {
lst = a.addrTried[*subnetworkID][bucket]
}
for e := lst.Front(); e != nil; e = e.Next() {
ka := e.Value.(*KnownAddress)
if oldest == nil || oldest.na.Timestamp.After(ka.na.Timestamp) {
oldestElem = e
@ -404,7 +453,11 @@ func (a *AddrManager) savePeers() {
for k, v := range a.addrIndex {
ska := new(serializedKnownAddress)
ska.Addr = k
ska.SubnetworkID = v.subnetworkID.String()
if v.subnetworkID == nil {
ska.SubnetworkID = ""
} else {
ska.SubnetworkID = v.subnetworkID.String()
}
ska.TimeStamp = v.na.Timestamp.Unix()
ska.Src = NetAddressKey(v.srcAddr)
ska.Attempts = v.attempts
@ -431,6 +484,15 @@ func (a *AddrManager) savePeers() {
}
}
for i := range a.addrNewFullNodes {
sam.NewBucketFullNodes[i] = make([]string, len(a.addrNewFullNodes[i]))
j := 0
for k := range a.addrNewFullNodes[i] {
sam.NewBucketFullNodes[i][j] = k
j++
}
}
sam.TriedBuckets = make(map[string]*serializedTriedBucket)
for subnetworkID := range a.addrTried {
subnetworkIDStr := subnetworkID.String()
@ -447,6 +509,16 @@ func (a *AddrManager) savePeers() {
}
}
for i := range a.addrTriedFullNodes {
sam.TriedBucketFullNodes[i] = make([]string, a.addrTriedFullNodes[i].Len())
j := 0
for e := a.addrTriedFullNodes[i].Front(); e != nil; e = e.Next() {
ka := e.Value.(*KnownAddress)
sam.TriedBucketFullNodes[i][j] = NetAddressKey(ka.na)
j++
}
}
w, err := os.Create(a.peersFile)
if err != nil {
log.Errorf("Error opening file %s: %s", a.peersFile, err)
@ -482,7 +554,6 @@ func (a *AddrManager) loadPeers() {
}
func (a *AddrManager) deserializePeers(filePath string) error {
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
return nil
@ -518,10 +589,12 @@ func (a *AddrManager) deserializePeers(filePath string) error {
return fmt.Errorf("failed to deserialize netaddress "+
"%s: %s", v.Src, err)
}
ka.subnetworkID, err = subnetworkid.NewFromStr(v.SubnetworkID)
if err != nil {
return fmt.Errorf("failed to deserialize subnetwork id "+
"%s: %s", v.SubnetworkID, err)
if v.SubnetworkID != "" {
ka.subnetworkID, err = subnetworkid.NewFromStr(v.SubnetworkID)
if err != nil {
return fmt.Errorf("failed to deserialize subnetwork id "+
"%s: %s", v.SubnetworkID, err)
}
}
ka.attempts = v.Attempts
ka.lastattempt = time.Unix(v.LastAttempt, 0)
@ -550,6 +623,23 @@ func (a *AddrManager) deserializePeers(filePath string) error {
}
}
}
for i, newBucket := range sam.NewBucketFullNodes {
for _, val := range newBucket {
ka, ok := a.addrIndex[val]
if !ok {
return fmt.Errorf("full nodes newbucket contains %s but "+
"none in address list", val)
}
if ka.refs == 0 {
a.nNewFullNodes++
}
ka.refs++
a.updateAddrNew(i, val, ka)
}
}
for subnetworkIDStr := range sam.TriedBuckets {
subnetworkID, err := subnetworkid.NewFromStr(subnetworkIDStr)
if err != nil {
@ -559,7 +649,7 @@ func (a *AddrManager) deserializePeers(filePath string) error {
for _, val := range subnetworkTriedBucket {
ka, ok := a.addrIndex[val]
if !ok {
return fmt.Errorf("Newbucket contains %s but "+
return fmt.Errorf("Tried bucket contains %s but "+
"none in address list", val)
}
@ -570,6 +660,20 @@ func (a *AddrManager) deserializePeers(filePath string) error {
}
}
for i, triedBucket := range sam.TriedBucketFullNodes {
for _, val := range triedBucket {
ka, ok := a.addrIndex[val]
if !ok {
return fmt.Errorf("Full nodes tried bucket contains %s but "+
"none in address list", val)
}
ka.tried = true
a.nTriedFullNodes++
a.addrTriedFullNodes[i].PushBack(ka)
}
}
// Sanity checking.
for k, v := range a.addrIndex {
if v.refs == 0 && !v.tried {
@ -679,12 +783,15 @@ func (a *AddrManager) AddAddressByIP(addrIP string, subnetworkID *subnetworkid.S
// numAddresses returns the number of addresses that belongs to a specific subnetwork id
// which are known to the address manager.
func (a *AddrManager) numAddresses(subnetworkID *subnetworkid.SubnetworkID) int {
if subnetworkID == nil {
return a.nNewFullNodes + a.nTriedFullNodes
}
return a.nTried[*subnetworkID] + a.nNew[*subnetworkID]
}
// totalNumAddresses returns the number of addresses known to the address manager.
func (a *AddrManager) totalNumAddresses() int {
total := 0
total := a.nNewFullNodes + a.nTriedFullNodes
for _, numAddresses := range a.nTried {
total += numAddresses
}
@ -709,15 +816,15 @@ func (a *AddrManager) NeedMoreAddresses() bool {
defer a.mtx.Unlock()
allAddrs := a.numAddresses(a.localSubnetworkID)
if !a.localSubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
allAddrs += a.numAddresses(subnetworkid.SubnetworkIDSupportsAll)
if a.localSubnetworkID != nil {
allAddrs += a.numAddresses(nil)
}
return allAddrs < needAddressThreshold
}
// AddressCache returns the current address cache. It must be treated as
// read-only (but since it is a copy now, this is not as dangerous).
func (a *AddrManager) AddressCache(subnetworkID *subnetworkid.SubnetworkID) []*wire.NetAddress {
func (a *AddrManager) AddressCache(includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) []*wire.NetAddress {
a.mtx.Lock()
defer a.mtx.Unlock()
@ -728,7 +835,7 @@ func (a *AddrManager) AddressCache(subnetworkID *subnetworkid.SubnetworkID) []*w
allAddr := []*wire.NetAddress{}
// Iteration order is undefined here, but we randomise it anyway.
for _, v := range a.addrIndex {
if subnetworkID == nil || v.SubnetworkID().IsEqual(subnetworkID) {
if includeAllSubnetworks || v.SubnetworkID().IsEqual(subnetworkID) {
allAddr = append(allAddr, v.na)
}
}
@ -763,6 +870,15 @@ func (a *AddrManager) reset() {
a.nNew = make(map[subnetworkid.SubnetworkID]int)
a.nTried = make(map[subnetworkid.SubnetworkID]int)
for i := range a.addrNewFullNodes {
a.addrNewFullNodes[i] = make(map[string]*KnownAddress)
}
for i := range a.addrTriedFullNodes {
a.addrTriedFullNodes[i] = list.New()
}
a.nNewFullNodes = 0
a.nTriedFullNodes = 0
}
// HostToNetAddress returns a netaddress given a host address. If the address
@ -826,24 +942,35 @@ func (a *AddrManager) GetAddress() *KnownAddress {
a.mtx.Lock()
defer a.mtx.Unlock()
if a.localSubnetworkID == nil {
return a.getAddress(&a.addrTriedFullNodes, a.nTriedFullNodes,
&a.addrNewFullNodes, a.nNewFullNodes)
}
subnetworkID := *a.localSubnetworkID
return a.getAddress(a.addrTried[subnetworkID], a.nTried[subnetworkID],
a.addrNew[subnetworkID], a.nNew[subnetworkID])
}
// see GetAddress for details
func (a *AddrManager) getAddress(addrTried *triedBucket, nTried int, addrNew *newBucket, nNew int) *KnownAddress {
// Use a 50% chance for choosing between tried and new table entries.
if a.nTried[subnetworkID] > 0 && (a.nNew[subnetworkID] == 0 || a.rand.Intn(2) == 0) {
if nTried > 0 && (nNew == 0 || a.rand.Intn(2) == 0) {
// Tried entry.
large := 1 << 30
factor := 1.0
for {
// pick a random bucket.
bucket := a.rand.Intn(len(a.addrTried[subnetworkID]))
if a.addrTried[subnetworkID][bucket].Len() == 0 {
bucket := a.rand.Intn(len(addrTried))
if addrTried[bucket].Len() == 0 {
continue
}
// Pick a random entry in the list
e := a.addrTried[subnetworkID][bucket].Front()
e := addrTried[bucket].Front()
for i :=
a.rand.Int63n(int64(a.addrTried[subnetworkID][bucket].Len())); i > 0; i-- {
a.rand.Int63n(int64(addrTried[bucket].Len())); i > 0; i-- {
e = e.Next()
}
ka := e.Value.(*KnownAddress)
@ -855,21 +982,21 @@ func (a *AddrManager) GetAddress() *KnownAddress {
}
factor *= 1.2
}
} else if a.nNew[subnetworkID] > 0 {
} else if nNew > 0 {
// new node.
// XXX use a closure/function to avoid repeating this.
large := 1 << 30
factor := 1.0
for {
// Pick a random bucket.
bucket := a.rand.Intn(len(a.addrNew[subnetworkID]))
if len(a.addrNew[subnetworkID][bucket]) == 0 {
bucket := a.rand.Intn(len(addrNew))
if len(addrNew[bucket]) == 0 {
continue
}
// Then, a random entry in it.
var ka *KnownAddress
nth := a.rand.Intn(len(a.addrNew[subnetworkID][bucket]))
for _, value := range a.addrNew[subnetworkID][bucket] {
nth := a.rand.Intn(len(addrNew[bucket]))
for _, value := range addrNew[bucket] {
if nth == 0 {
ka = value
}
@ -978,17 +1105,31 @@ func (a *AddrManager) Good(addr *wire.NetAddress, subnetworkID *subnetworkid.Sub
// Record one of the buckets in question and call it the `first'
oldBucket := -1
if !ka.tried {
for i := range a.addrNew[*oldSubnetworkID] {
// we check for existence so we can record the first one
if _, ok := a.addrNew[*oldSubnetworkID][i][addrKey]; ok {
delete(a.addrNew[*oldSubnetworkID][i], addrKey)
ka.refs--
if oldBucket == -1 {
oldBucket = i
if oldSubnetworkID == nil {
for i := range a.addrNewFullNodes {
// we check for existence so we can record the first one
if _, ok := a.addrNewFullNodes[i][addrKey]; ok {
delete(a.addrNewFullNodes[i], addrKey)
ka.refs--
if oldBucket == -1 {
oldBucket = i
}
}
}
a.nNewFullNodes--
} else {
for i := range a.addrNew[*oldSubnetworkID] {
// we check for existence so we can record the first one
if _, ok := a.addrNew[*oldSubnetworkID][i][addrKey]; ok {
delete(a.addrNew[*oldSubnetworkID][i], addrKey)
ka.refs--
if oldBucket == -1 {
oldBucket = i
}
}
}
a.nNew[*oldSubnetworkID]--
}
a.nNew[*oldSubnetworkID]--
if oldBucket == -1 {
// What? wasn't in a bucket after all.... Panic?
@ -997,7 +1138,14 @@ func (a *AddrManager) Good(addr *wire.NetAddress, subnetworkID *subnetworkid.Sub
}
// Room in this tried bucket?
if a.nTried[*ka.subnetworkID] == 0 || a.addrTried[*ka.subnetworkID][triedBucketIndex].Len() < triedBucketSize {
if ka.subnetworkID == nil {
if a.nTriedFullNodes == 0 || a.addrTriedFullNodes[triedBucketIndex].Len() < triedBucketSize {
ka.tried = true
a.updateAddrTried(triedBucketIndex, ka)
a.nTriedFullNodes++
return
}
} else if a.nTried[*ka.subnetworkID] == 0 || a.addrTried[*ka.subnetworkID][triedBucketIndex].Len() < triedBucketSize {
ka.tried = true
a.updateAddrTried(triedBucketIndex, ka)
a.nTried[*ka.subnetworkID]++
@ -1013,18 +1161,35 @@ func (a *AddrManager) Good(addr *wire.NetAddress, subnetworkID *subnetworkid.Sub
// If no room in the original bucket, we put it in a bucket we just
// freed up a space in.
if len(a.addrNew[*ka.subnetworkID][newBucket]) >= newBucketSize {
if oldBucket == -1 {
// If addr was a tried bucket with updated subnetworkID - oldBucket will be equal to -1.
// In that case - find some non-full bucket.
// If no such bucket exists - throw rmka away
for newBucket := range a.addrNew[*ka.subnetworkID] {
if len(a.addrNew[*ka.subnetworkID][newBucket]) < newBucketSize {
break
if ka.subnetworkID == nil {
if len(a.addrNewFullNodes[newBucket]) >= newBucketSize {
if oldBucket == -1 {
// If addr was a tried bucket with updated subnetworkID - oldBucket will be equal to -1.
// In that case - find some non-full bucket.
// If no such bucket exists - throw rmka away
for newBucket := range a.addrNewFullNodes {
if len(a.addrNewFullNodes[newBucket]) < newBucketSize {
break
}
}
} else {
newBucket = oldBucket
}
}
} else if len(a.addrNew[*ka.subnetworkID][newBucket]) >= newBucketSize {
if len(a.addrNew[*ka.subnetworkID][newBucket]) >= newBucketSize {
if oldBucket == -1 {
// If addr was a tried bucket with updated subnetworkID - oldBucket will be equal to -1.
// In that case - find some non-full bucket.
// If no such bucket exists - throw rmka away
for newBucket := range a.addrNew[*ka.subnetworkID] {
if len(a.addrNew[*ka.subnetworkID][newBucket]) < newBucketSize {
break
}
}
} else {
newBucket = oldBucket
}
} else {
newBucket = oldBucket
}
}
@ -1038,13 +1203,21 @@ func (a *AddrManager) Good(addr *wire.NetAddress, subnetworkID *subnetworkid.Sub
// We don't touch a.nTried here since the number of tried stays the same
// but we decemented new above, raise it again since we're putting
// something back.
a.nNew[*ka.subnetworkID]++
if ka.subnetworkID == nil {
a.nNewFullNodes++
} else {
a.nNew[*ka.subnetworkID]++
}
rmkey := NetAddressKey(rmka.na)
log.Tracef("Replacing %s with %s in tried", rmkey, addrKey)
// We made sure there is space here just above.
a.addrNew[*ka.subnetworkID][newBucket][rmkey] = rmka
if ka.subnetworkID == nil {
a.addrNewFullNodes[newBucket][rmkey] = rmka
} else {
a.addrNew[*ka.subnetworkID][newBucket][rmkey] = rmka
}
}
// AddLocalAddress adds na to the list of known local addresses to advertise

View File

@ -104,7 +104,7 @@ func lookupFunc(host string) ([]net.IP, error) {
}
func TestStartStop(t *testing.T) {
n := New("teststartstop", lookupFunc, subnetworkid.SubnetworkIDSupportsAll)
n := New("teststartstop", lookupFunc, nil)
n.Start()
err := n.Stop()
if err != nil {
@ -137,9 +137,9 @@ func TestAddAddressByIP(t *testing.T) {
},
}
amgr := New("testaddressbyip", nil, subnetworkid.SubnetworkIDSupportsAll)
amgr := New("testaddressbyip", nil, nil)
for i, test := range tests {
err := amgr.AddAddressByIP(test.addrIP, subnetworkid.SubnetworkIDSupportsAll)
err := amgr.AddAddressByIP(test.addrIP, nil)
if test.err != nil && err == nil {
t.Errorf("TestGood test %d failed expected an error and got none", i)
continue
@ -193,7 +193,7 @@ func TestAddLocalAddress(t *testing.T) {
true,
},
}
amgr := New("testaddlocaladdress", nil, subnetworkid.SubnetworkIDSupportsAll)
amgr := New("testaddlocaladdress", nil, nil)
for x, test := range tests {
result := amgr.AddLocalAddress(&test.address, test.priority)
if result == nil && !test.valid {
@ -210,10 +210,10 @@ func TestAddLocalAddress(t *testing.T) {
}
func TestAttempt(t *testing.T) {
n := New("testattempt", lookupFunc, subnetworkid.SubnetworkIDSupportsAll)
n := New("testattempt", lookupFunc, nil)
// Add a new address and get it
err := n.AddAddressByIP(someIP+":8333", subnetworkid.SubnetworkIDSupportsAll)
err := n.AddAddressByIP(someIP+":8333", nil)
if err != nil {
t.Fatalf("Adding address failed: %v", err)
}
@ -232,10 +232,10 @@ func TestAttempt(t *testing.T) {
}
func TestConnected(t *testing.T) {
n := New("testconnected", lookupFunc, subnetworkid.SubnetworkIDSupportsAll)
n := New("testconnected", lookupFunc, nil)
// Add a new address and get it
err := n.AddAddressByIP(someIP+":8333", subnetworkid.SubnetworkIDSupportsAll)
err := n.AddAddressByIP(someIP+":8333", nil)
if err != nil {
t.Fatalf("Adding address failed: %v", err)
}
@ -252,7 +252,7 @@ func TestConnected(t *testing.T) {
}
func TestNeedMoreAddresses(t *testing.T) {
n := New("testneedmoreaddresses", lookupFunc, subnetworkid.SubnetworkIDSupportsAll)
n := New("testneedmoreaddresses", lookupFunc, nil)
addrsToAdd := 1500
b := n.NeedMoreAddresses()
if !b {
@ -271,7 +271,7 @@ func TestNeedMoreAddresses(t *testing.T) {
srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0)
n.AddAddresses(addrs, srcAddr, subnetworkid.SubnetworkIDSupportsAll)
n.AddAddresses(addrs, srcAddr, nil)
numAddrs := n.TotalNumAddresses()
if numAddrs > addrsToAdd {
t.Errorf("Number of addresses is too many %d vs %d", numAddrs, addrsToAdd)
@ -284,7 +284,7 @@ func TestNeedMoreAddresses(t *testing.T) {
}
func TestGood(t *testing.T) {
n := New("testgood", lookupFunc, subnetworkid.SubnetworkIDSupportsAll)
n := New("testgood", lookupFunc, nil)
addrsToAdd := 64 * 64
addrs := make([]*wire.NetAddress, addrsToAdd)
subnetworkCount := 32
@ -305,7 +305,7 @@ func TestGood(t *testing.T) {
srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0)
n.AddAddresses(addrs, srcAddr, subnetworkid.SubnetworkIDSupportsAll)
n.AddAddresses(addrs, srcAddr, nil)
for i, addr := range addrs {
n.Good(addr, subnetworkIDs[i%subnetworkCount])
}
@ -315,14 +315,14 @@ func TestGood(t *testing.T) {
t.Errorf("Number of addresses is too many: %d vs %d", numAddrs, addrsToAdd)
}
numCache := len(n.AddressCache(nil))
numCache := len(n.AddressCache(true, nil))
if numCache == 0 || numCache >= numAddrs/4 {
t.Errorf("Number of addresses in cache: got %d, want positive and less than %d",
numCache, numAddrs/4)
}
for i := 0; i < subnetworkCount; i++ {
numCache = len(n.AddressCache(subnetworkIDs[i]))
numCache = len(n.AddressCache(false, subnetworkIDs[i]))
if numCache == 0 || numCache >= numAddrs/subnetworkCount {
t.Errorf("Number of addresses in subnetwork cache: got %d, want positive and less than %d",
numCache, numAddrs/4/subnetworkCount)
@ -331,7 +331,7 @@ func TestGood(t *testing.T) {
}
func TestGoodChangeSubnetworkID(t *testing.T) {
n := New("test_good_change_subnetwork_id", lookupFunc, subnetworkid.SubnetworkIDSupportsAll)
n := New("test_good_change_subnetwork_id", lookupFunc, nil)
addr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0)
addrKey := NetAddressKey(addr)
srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0)
@ -423,7 +423,7 @@ func TestGetAddress(t *testing.T) {
n.Good(ka.NetAddress(), actualSubnetworkID)
ka = n.GetAddress()
if ka != nil {
t.Errorf("Didn't expect to get an address because there shouldn't be any address from subnetwork ID %s or %s", localSubnetworkID, subnetworkid.SubnetworkIDSupportsAll)
t.Errorf("Didn't expect to get an address because there shouldn't be any address from subnetwork ID %s or nil", localSubnetworkID)
}
// Checks that the total number of addresses incremented although the new address is not full node or a partial node of the same subnetwork as the local node.
@ -519,7 +519,7 @@ func TestGetBestLocalAddress(t *testing.T) {
*/
}
amgr := New("testgetbestlocaladdress", nil, subnetworkid.SubnetworkIDSupportsAll)
amgr := New("testgetbestlocaladdress", nil, nil)
// Test against default when there's no address
for x, test := range tests {

View File

@ -9,14 +9,12 @@ import (
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/database"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/subnetworkid"
)
func TestMaybeAcceptBlockErrors(t *testing.T) {
// Create a new database and DAG instance to run tests against.
dag, teardownFunc, err := DAGSetup("TestMaybeAcceptBlockErrors", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("TestMaybeAcceptBlockErrors: Failed to setup DAG instance: %v", err)

View File

@ -9,7 +9,6 @@ import (
"bou.ke/monkey"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/database"
"github.com/daglabs/btcd/util/subnetworkid"
)
func TestAncestorErrors(t *testing.T) {
@ -24,8 +23,7 @@ func TestAncestorErrors(t *testing.T) {
func TestFlushToDBErrors(t *testing.T) {
// Create a new database and DAG instance to run tests against.
dag, teardownFunc, err := DAGSetup("TestFlushToDBErrors", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("TestFlushToDBErrors: Failed to setup DAG instance: %s", err)

View File

@ -1597,9 +1597,6 @@ func New(config *Config) (*BlockDAG, error) {
if config.TimeSource == nil {
return nil, AssertError("BlockDAG.New timesource is nil")
}
if config.SubnetworkID == nil {
return nil, AssertError("BlockDAG.New subnetworkID is nil")
}
// Generate a checkpoint by height map from the provided checkpoints
// and assert the provided checkpoints are sorted by height as required.

View File

@ -49,8 +49,7 @@ func TestBlockCount(t *testing.T) {
// Create a new database and DAG instance to run tests against.
dag, teardownFunc, err := DAGSetup("TestBlockCount", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("Failed to setup DAG instance: %v", err)
@ -99,8 +98,7 @@ func TestHaveBlock(t *testing.T) {
// Create a new database and DAG instance to run tests against.
dag, teardownFunc, err := DAGSetup("haveblock", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("Failed to setup DAG instance: %v", err)
@ -194,10 +192,10 @@ func TestHaveBlock(t *testing.T) {
{hash: dagconfig.SimNetParams.GenesisHash.String(), want: true},
// Block 3b should be present (as a second child of Block 2).
{hash: "08a3f0182ac8ff0326497f592d2e28b8b3b2b7e3fd77c7cb6f31ca872536cf7b", want: true},
{hash: "040c43ca52ded708dacef2a9fa589f41e4f7565345f7f1e61f379dbf32bb6b48", want: true},
// Block 100000 should be present (as an orphan).
{hash: "25d5494f3e1f895774c58034f1bd50f7b279e75db6007514affec8573ace4389", want: true},
{hash: "3da8f9ec89820deee1a4d26ff0e69c53686166ea4fbc1895fa1e0b1ccb651374", want: true},
// Random hashes should not be available.
{hash: "123", want: false},
@ -782,8 +780,7 @@ func testErrorThroughPatching(t *testing.T, expectedErrorMessage string, targetF
// Create a new database and dag instance to run tests against.
dag, teardownFunc, err := DAGSetup("testErrorThroughPatching", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("Failed to setup dag instance: %v", err)
@ -841,11 +838,10 @@ func TestNew(t *testing.T) {
os.RemoveAll(testDbRoot)
}()
config := &Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DB: db,
TimeSource: NewMedianTime(),
SigCache: txscript.NewSigCache(1000),
DAGParams: &dagconfig.SimNetParams,
DB: db,
TimeSource: NewMedianTime(),
SigCache: txscript.NewSigCache(1000),
}
_, err = New(config)
if err != nil {
@ -855,9 +851,9 @@ func TestNew(t *testing.T) {
config.SubnetworkID = &subnetworkid.SubnetworkID{0xff}
_, err = New(config)
expectedErrorMessage := fmt.Sprintf("Cannot start btcd with subnetwork ID %s because"+
" its database is already built with subnetwork ID %s. If you"+
" its database is already built with subnetwork ID <nil>. If you"+
" want to switch to a new database, please reset the"+
" database by starting btcd with --reset-db flag", config.SubnetworkID, subnetworkid.SubnetworkIDSupportsAll)
" database by starting btcd with --reset-db flag", config.SubnetworkID)
if err.Error() != expectedErrorMessage {
t.Errorf("Unexpected error. Expected error '%s' but got '%s'", expectedErrorMessage, err)
}
@ -867,8 +863,7 @@ func TestValidateFeeTransaction(t *testing.T) {
params := dagconfig.SimNetParams
params.K = 1
dag, teardownFunc, err := DAGSetup("TestValidateFeeTransaction", Config{
DAGParams: &params,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &params,
})
if err != nil {
t.Fatalf("Failed to setup DAG instance: %v", err)

View File

@ -499,6 +499,9 @@ func (dag *BlockDAG) createDAGState() error {
}
func dbPutLocalSubnetworkID(dbTx database.Tx, subnetworkID *subnetworkid.SubnetworkID) error {
if subnetworkID == nil {
return dbTx.Metadata().Put(localSubnetworkKeyName, []byte{})
}
return dbTx.Metadata().Put(localSubnetworkKeyName, subnetworkID[:])
}
@ -512,9 +515,12 @@ func (dag *BlockDAG) initDAGState() error {
err := dag.db.View(func(dbTx database.Tx) error {
initialized = dbTx.Metadata().Get(dagStateKeyName) != nil
if initialized {
var localSubnetworkID *subnetworkid.SubnetworkID
localSubnetworkIDBytes := dbTx.Metadata().Get(localSubnetworkKeyName)
localSubnetworkID := &subnetworkid.SubnetworkID{}
localSubnetworkID.SetBytes(localSubnetworkIDBytes)
if len(localSubnetworkIDBytes) != 0 {
localSubnetworkID = &subnetworkid.SubnetworkID{}
localSubnetworkID.SetBytes(localSubnetworkIDBytes)
}
if !localSubnetworkID.IsEqual(dag.subnetworkID) {
return fmt.Errorf("Cannot start btcd with subnetwork ID %s because"+
" its database is already built with subnetwork ID %s. If you"+

View File

@ -14,7 +14,6 @@ import (
"github.com/daglabs/btcd/database"
_ "github.com/daglabs/btcd/database/ffldb"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/subnetworkid"
)
// This example demonstrates how to create a new chain instance and use
@ -46,10 +45,9 @@ func ExampleBlockDAG_ProcessBlock() {
// values obtained from other peers on the network so the local time is
// adjusted to be in agreement with other peers.
chain, err := blockdag.New(&blockdag.Config{
DB: db,
DAGParams: &dagconfig.MainNetParams,
TimeSource: blockdag.NewMedianTime(),
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DB: db,
DAGParams: &dagconfig.MainNetParams,
TimeSource: blockdag.NewMedianTime(),
})
if err != nil {
fmt.Printf("Failed to create chain instance: %v\n", err)
@ -69,5 +67,5 @@ func ExampleBlockDAG_ProcessBlock() {
fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
// Output:
// Failed to process block: already have block 4f0fbe497b98f0ab3dd92a3be968d5c7623cbaa844ff9f19e2b94756337eb0b8
// Failed to process block: already have block 6477863f190fac902e556da4671c7537da4fe367022b1f00fa5270e0d073cc08
}

View File

@ -38,8 +38,7 @@ func TestFinality(t *testing.T) {
params := dagconfig.SimNetParams
params.K = 1
dag, teardownFunc, err := blockdag.DAGSetup("TestFinality", blockdag.Config{
DAGParams: &params,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &params,
})
if err != nil {
t.Fatalf("Failed to setup DAG instance: %v", err)
@ -147,8 +146,7 @@ func TestSubnetworkRegistry(t *testing.T) {
params.K = 1
params.BlockRewardMaturity = 1
dag, teardownFunc, err := blockdag.DAGSetup("TestSubnetworkRegistry", blockdag.Config{
DAGParams: &params,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &params,
})
if err != nil {
t.Fatalf("Failed to setup DAG instance: %v", err)
@ -174,8 +172,7 @@ func TestChainedTransactions(t *testing.T) {
params.BlockRewardMaturity = 1
// Create a new database and dag instance to run tests against.
dag, teardownFunc, err := blockdag.DAGSetup("TestChainedTransactions", blockdag.Config{
DAGParams: &params,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &params,
})
if err != nil {
t.Fatalf("Failed to setup dag instance: %v", err)
@ -269,8 +266,7 @@ func TestGasLimit(t *testing.T) {
params.K = 1
params.BlockRewardMaturity = 1
dag, teardownFunc, err := blockdag.DAGSetup("TestSubnetworkRegistry", blockdag.Config{
DAGParams: &params,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &params,
})
if err != nil {
t.Fatalf("Failed to setup DAG instance: %v", err)

View File

@ -10,7 +10,6 @@ import (
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/mining"
"github.com/daglabs/btcd/util"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/daglabs/btcd/wire"
)
@ -41,7 +40,6 @@ func TestTxIndexConnectBlock(t *testing.T) {
config := blockdag.Config{
IndexManager: indexManager,
DAGParams: &params,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
}
dag, teardown, err := blockdag.DAGSetup("TestTxIndexConnectBlock", config)

View File

@ -8,7 +8,6 @@ import (
"testing"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/util/subnetworkid"
)
// TestNotifications ensures that notification callbacks are fired on events.
@ -20,8 +19,7 @@ func TestNotifications(t *testing.T) {
// Create a new database and dag instance to run tests against.
dag, teardownFunc, err := DAGSetup("notifications", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Fatalf("Failed to setup dag instance: %v", err)

View File

@ -88,10 +88,6 @@ func DAGSetup(dbName string, config Config) (*BlockDAG, func(), error) {
}
}
if config.SubnetworkID == nil {
config.SubnetworkID = subnetworkid.SubnetworkIDSupportsAll
}
config.TimeSource = NewMedianTime()
config.SigCache = txscript.NewSigCache(1000)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -272,7 +272,7 @@ func CheckTransactionSanity(tx *util.Tx, subnetworkID *subnetworkid.SubnetworkID
// If we are a partial node, only transactions on the Registry subnetwork
// or our own subnetwork may have a payload
isLocalNodeFull := subnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll)
isLocalNodeFull := subnetworkID == nil
shouldTxBeFull := msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDRegistry) ||
msgTx.SubnetworkID.IsEqual(subnetworkID)
if !isLocalNodeFull && !shouldTxBeFull && len(msgTx.Payload) > 0 {

View File

@ -69,8 +69,7 @@ func TestSequenceLocksActive(t *testing.T) {
func TestCheckConnectBlockTemplate(t *testing.T) {
// Create a new database and chain instance to run tests against.
dag, teardownFunc, err := DAGSetup("checkconnectblocktemplate", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Errorf("Failed to setup dag instance: %v", err)
@ -160,8 +159,7 @@ func TestCheckConnectBlockTemplate(t *testing.T) {
func TestCheckBlockSanity(t *testing.T) {
// Create a new database and dag instance to run tests against.
dag, teardownFunc, err := DAGSetup("TestCheckBlockSanity", Config{
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: &dagconfig.SimNetParams,
})
if err != nil {
t.Errorf("Failed to setup dag instance: %v", err)
@ -750,16 +748,16 @@ var Block100000 = wire.MsgBlock{
},
},
HashMerkleRoot: &daghash.Hash{ // Make go vet happy.
0xb6, 0xfb, 0xb8, 0xc1, 0xbe, 0x96, 0x5b, 0x22,
0xf8, 0x46, 0x05, 0x8b, 0x81, 0xc9, 0xb0, 0x94,
0x6c, 0x55, 0x06, 0xd9, 0x7f, 0xe0, 0x85, 0x7a,
0xaa, 0xce, 0x6a, 0x52, 0x4b, 0x69, 0x21, 0x3a,
0x30, 0xed, 0xf5, 0xbd, 0xd1, 0x4f, 0x8f, 0xb2,
0x0b, 0x6c, 0x92, 0xac, 0xd2, 0x47, 0xb7, 0xd6,
0x6f, 0x22, 0xfa, 0x60, 0x36, 0x80, 0x99, 0xc3,
0x6e, 0x39, 0x14, 0x9b, 0xcc, 0x1f, 0x31, 0xa9,
},
IDMerkleRoot: &daghash.Hash{ // Make go vet happy.
0x03, 0x10, 0x71, 0x0d, 0x36, 0xc5, 0x91, 0x03,
0x5f, 0x8f, 0x67, 0x08, 0x78, 0xe4, 0x31, 0xaf,
0x0d, 0xb2, 0x91, 0xe7, 0x80, 0x12, 0x5d, 0x76,
0x2b, 0x69, 0xe4, 0xc4, 0xc0, 0x67, 0xe7, 0xd1,
0x81, 0xb8, 0xa0, 0x68, 0x77, 0xc4, 0x02, 0x1e,
0x3c, 0xb1, 0x16, 0x8f, 0x5f, 0x6b, 0x45, 0x87,
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
0x5d, 0x4e, 0x2c, 0xc9, 0x57, 0x88, 0x30, 0x65,
},
Timestamp: time.Unix(0x5c404bc3, 0),
Bits: 0x207fffff,

View File

@ -159,7 +159,7 @@ func TestDAGSvrWsNtfns(t *testing.T) {
{
name: "txAcceptedVerbose",
newNtfn: func() (interface{}, error) {
return btcjson.NewCmd("txAcceptedVerbose", `{"hex":"001122","txid":"123","version":1,"locktime":4294967295,"subnetwork":"0000000000000000000000000000000000000001","gas":0,"payloadHash":"","payload":"","vin":null,"vout":null,"confirmations":0}`)
return btcjson.NewCmd("txAcceptedVerbose", `{"hex":"001122","txid":"123","version":1,"locktime":4294967295,"subnetwork":"0000000000000000000000000000000000000000","gas":0,"payloadHash":"","payload":"","vin":null,"vout":null,"confirmations":0}`)
},
staticNtfn: func() interface{} {
txResult := btcjson.TxRawResult{
@ -174,7 +174,7 @@ func TestDAGSvrWsNtfns(t *testing.T) {
}
return btcjson.NewTxAcceptedVerboseNtfn(txResult)
},
marshalled: `{"jsonrpc":"1.0","method":"txAcceptedVerbose","params":[{"hex":"001122","txId":"123","version":1,"lockTime":4294967295,"subnetwork":"0000000000000000000000000000000000000001","gas":0,"payloadHash":"","payload":"","vin":null,"vout":null,"acceptedBy":null}],"id":null}`,
marshalled: `{"jsonrpc":"1.0","method":"txAcceptedVerbose","params":[{"hex":"001122","txId":"123","version":1,"lockTime":4294967295,"subnetwork":"0000000000000000000000000000000000000000","gas":0,"payloadHash":"","payload":"","vin":null,"vout":null,"acceptedBy":null}],"id":null}`,
unmarshalled: &btcjson.TxAcceptedVerboseNtfn{
RawTx: btcjson.TxRawResult{
Hex: "001122",

View File

@ -10,6 +10,7 @@ import (
"math/big"
"time"
"github.com/daglabs/btcd/blockdag"
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/util"
@ -53,15 +54,38 @@ func solveGenesisBlock(block *wire.MsgBlock, powBits uint32, netName string) {
}
}
func validateGenesisBlock(genesisBlock *wire.MsgBlock, netName string) bool {
block := util.NewBlock(genesisBlock)
hashMerkleTree := blockdag.BuildHashMerkleTreeStore(block.Transactions())
calculatedHashMerkleRoot := hashMerkleTree.Root()
header := genesisBlock.Header
if !header.HashMerkleRoot.IsEqual(calculatedHashMerkleRoot) {
fmt.Printf("%s: genesis block hash merkle root is invalid - block "+
"header indicates %s, but calculated value is %s\n\n",
netName, hex.EncodeToString(header.HashMerkleRoot[:]),
hex.EncodeToString(calculatedHashMerkleRoot[:]))
return false
}
return true
}
func validateAndSolve(genesisBlock *wire.MsgBlock, powBits uint32, netName string) {
// Validate merkle root
if validateGenesisBlock(genesisBlock, netName) {
// Solve genesis block
solveGenesisBlock(genesisBlock, powBits, netName)
}
}
// main
func main() {
bigOne := big.NewInt(1)
// Solve mainnet genesis
solveGenesisBlock(dagconfig.MainNetParams.GenesisBlock,
util.BigToCompact(new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne)), "mainnet")
validateAndSolve(dagconfig.MainNetParams.GenesisBlock,
util.BigToCompact(new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne)),
"MainNet")
// Solve devnet genesis
solveGenesisBlock(dagconfig.DevNetParams.GenesisBlock,
util.BigToCompact(new(big.Int).Sub(new(big.Int).Lsh(bigOne, 239), bigOne)), "devnet")
validateAndSolve(dagconfig.DevNetParams.GenesisBlock,
util.BigToCompact(new(big.Int).Sub(new(big.Int).Lsh(bigOne, 239), bigOne)),
"DevNet")
}

View File

@ -167,7 +167,7 @@ type configFlags struct {
DropAddrIndex bool `long:"dropaddrindex" description:"Deletes the address-based transaction index from the database on start up and then exits."`
RelayNonStd bool `long:"relaynonstd" description:"Relay non-standard transactions regardless of the default settings for the active network."`
RejectNonStd bool `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."`
Subnetwork string `long:"subnetwork" description:"If subnetwork ID != 0, than node will request and process only payloads from specified subnetwork. And if subnetwork ID is 0, than payloads of all subnetworks are processed. Subnetworks with IDs 3 through 255 are reserved for future use and are currently not allowed."`
Subnetwork string `long:"subnetwork" description:"If subnetwork ID is specified, than node will request and process only payloads from specified subnetwork. And if subnetwork ID is ommited, than payloads of all subnetworks are processed. Subnetworks with IDs 2 through 255 are reserved for future use and are currently not allowed."`
ResetDatabase bool `long:"reset-db" description:"Reset database before starting node. It's needed when switching between subnetworks."`
}
@ -183,7 +183,7 @@ type Config struct {
MiningAddrs []util.Address
MinRelayTxFee util.Amount
Whitelists []*net.IPNet
SubnetworkID *subnetworkid.SubnetworkID
SubnetworkID *subnetworkid.SubnetworkID // nil in full nodes
}
// serviceOptions defines the configuration options for the daemon as a service on
@ -765,11 +765,11 @@ func loadConfig() (*Config, []string, error) {
return nil, nil, err
}
} else {
cfg.SubnetworkID = subnetworkid.SubnetworkIDSupportsAll
cfg.SubnetworkID = nil
}
// Check that 'generate' and 'subnetwork' flags do not conflict
if cfg.Generate && !cfg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if cfg.Generate && cfg.SubnetworkID != nil {
str := "%s: both generate flag and subnetwork filtering are set "
err := fmt.Errorf(str, funcName)
fmt.Fprintln(os.Stderr, err)

View File

@ -76,7 +76,11 @@ func TestCreateDefaultConfigFile(t *testing.T) {
// TestConstants makes sure that all constants hard-coded into the help text were not modified.
func TestConstants(t *testing.T) {
zero := subnetworkid.SubnetworkID{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
if *subnetworkid.SubnetworkIDSupportsAll != zero {
t.Errorf("subnetworkid.SubnetworkIDSupportsAll value was changed from 0, therefore you probably need to update the help text for SubnetworkID")
if *subnetworkid.SubnetworkIDNative != zero {
t.Errorf("subnetworkid.SubnetworkIDNative value was changed from 0, therefore you probably need to update the help text for SubnetworkID")
}
one := subnetworkid.SubnetworkID{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
if *subnetworkid.SubnetworkIDRegistry != one {
t.Errorf("subnetworkid.SubnetworkIDRegistry value was changed from 1, therefore you probably need to update the help text for SubnetworkID")
}
}

View File

@ -38,8 +38,8 @@ type OnSeed func(addrs []*wire.NetAddress)
type LookupFunc func(string) ([]net.IP, error)
// SeedFromDNS uses DNS seeding to populate the address manager with peers.
func SeedFromDNS(dagParams *dagconfig.Params, reqServices wire.ServiceFlag, subnetworkID *subnetworkid.SubnetworkID,
lookupFn LookupFunc, seedFn OnSeed) {
func SeedFromDNS(dagParams *dagconfig.Params, reqServices wire.ServiceFlag, includeAllSubnetworks bool,
subnetworkID *subnetworkid.SubnetworkID, lookupFn LookupFunc, seedFn OnSeed) {
for _, dnsseed := range dagParams.DNSSeeds {
var host string
@ -49,8 +49,12 @@ func SeedFromDNS(dagParams *dagconfig.Params, reqServices wire.ServiceFlag, subn
host = fmt.Sprintf("%c%x.%s", ServiceFlagPrefixChar, uint64(reqServices), dnsseed)
}
if !subnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
host = fmt.Sprintf("%c%s.%s", SubnetworkIDPrefixChar, subnetworkID, host)
if !includeAllSubnetworks {
if subnetworkID != nil {
host = fmt.Sprintf("%c%s.%s", SubnetworkIDPrefixChar, subnetworkID, host)
} else {
host = fmt.Sprintf("%c.%s", SubnetworkIDPrefixChar, host)
}
}
go func(host string) {

View File

@ -41,19 +41,19 @@ var genesisCoinbaseTx = wire.NewNativeMsgTx(1, genesisTxIns, genesisTxOuts)
// genesisHash is the hash of the first block in the block chain for the main
// network (genesis block).
var genesisHash = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
0xb8, 0xb0, 0x7e, 0x33, 0x56, 0x47, 0xb9, 0xe2,
0x19, 0x9f, 0xff, 0x44, 0xa8, 0xba, 0x3c, 0x62,
0xc7, 0xd5, 0x68, 0xe9, 0x3b, 0x2a, 0xd9, 0x3d,
0xab, 0xf0, 0x98, 0x7b, 0x49, 0xbe, 0x0f, 0x4f,
0x08, 0xcc, 0x73, 0xd0, 0xe0, 0x70, 0x52, 0xfa,
0x00, 0x1f, 0x2b, 0x02, 0x67, 0xe3, 0x4f, 0xda,
0x37, 0x75, 0x1c, 0x67, 0xa4, 0x6d, 0x55, 0x2e,
0x90, 0xac, 0x0f, 0x19, 0x3f, 0x86, 0x77, 0x64,
})
// genesisMerkleRoot is the hash of the first transaction in the genesis block
// for the main network.
var genesisMerkleRoot = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
0x76, 0x2b, 0x33, 0xa9, 0x4c, 0xd4, 0x36, 0x13,
0x29, 0x5e, 0x9b, 0x68, 0xb7, 0xad, 0x2b, 0x16,
0x7c, 0x63, 0x89, 0xc3, 0x54, 0xc9, 0xa7, 0x06,
0x8c, 0x23, 0x24, 0x3c, 0x53, 0x6d, 0x56, 0x23,
0xd4, 0xdc, 0x8b, 0xb8, 0x76, 0x57, 0x9d, 0x7d,
0xe9, 0x9d, 0xae, 0xdb, 0xf8, 0x22, 0xd2, 0x0d,
0xa2, 0xe0, 0xbb, 0xbe, 0xed, 0xb0, 0xdb, 0xba,
0xeb, 0x18, 0x4d, 0x42, 0x01, 0xff, 0xed, 0x9d,
})
// genesisBlock defines the genesis block of the block chain which serves as the
@ -64,9 +64,9 @@ var genesisBlock = wire.MsgBlock{
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: &genesisMerkleRoot,
IDMerkleRoot: &genesisMerkleRoot,
Timestamp: time.Unix(0x5c3cafec, 0),
Timestamp: time.Unix(0x5ca09ba1, 0),
Bits: 0x207fffff,
Nonce: 0,
Nonce: 0x6,
},
Transactions: []*wire.MsgTx{genesisCoinbaseTx},
}
@ -117,10 +117,10 @@ var devNetGenesisCoinbaseTx = genesisCoinbaseTx
// devGenesisHash is the hash of the first block in the block chain for the development
// network (genesis block).
var devNetGenesisHash = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
0x4d, 0x6a, 0xc5, 0x8c, 0xfd, 0x73, 0xff, 0x60,
0x5e, 0x0b, 0x03, 0x4f, 0x05, 0xcf, 0x8b, 0xa2,
0x21, 0x50, 0x05, 0xf4, 0x16, 0xd2, 0xa6, 0x75,
0x11, 0x36, 0xa9, 0xa3, 0x21, 0x3f, 0x00, 0x00,
0xe8, 0xf0, 0x59, 0x4b, 0x54, 0xe7, 0xa1, 0xba,
0x1b, 0xe0, 0x6c, 0x72, 0xf8, 0x3d, 0x75, 0x5d,
0xa3, 0x3c, 0xc5, 0x71, 0x43, 0x94, 0x81, 0xbf,
0x32, 0x82, 0x5e, 0xfa, 0x6a, 0x0d, 0x00, 0x00,
})
// devNetGenesisMerkleRoot is the hash of the first transaction in the genesis block
@ -135,9 +135,9 @@ var devNetGenesisBlock = wire.MsgBlock{
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: &devNetGenesisMerkleRoot,
IDMerkleRoot: &devNetGenesisMerkleRoot,
Timestamp: time.Unix(0x5c922d07, 0),
Timestamp: time.Unix(0x5ca09ba1, 0),
Bits: 0x1e7fffff,
Nonce: 0x2633,
Nonce: 0x155d9,
},
Transactions: []*wire.MsgTx{devNetGenesisCoinbaseTx},
}

View File

@ -121,17 +121,17 @@ func TestSimNetGenesisBlock(t *testing.T) {
// genesisBlockBytes are the wire encoded bytes for the genesis block of the
// main network as of protocol version 60002.
var genesisBlockBytes = []byte{
0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0x2b, 0x33,
0xa9, 0x4c, 0xd4, 0x36, 0x13, 0x29, 0x5e, 0x9b,
0x68, 0xb7, 0xad, 0x2b, 0x16, 0x7c, 0x63, 0x89,
0xc3, 0x54, 0xc9, 0xa7, 0x06, 0x8c, 0x23, 0x24,
0x3c, 0x53, 0x6d, 0x56, 0x23, 0x76, 0x2b, 0x33,
0xa9, 0x4c, 0xd4, 0x36, 0x13, 0x29, 0x5e, 0x9b,
0x68, 0xb7, 0xad, 0x2b, 0x16, 0x7c, 0x63, 0x89,
0xc3, 0x54, 0xc9, 0xa7, 0x06, 0x8c, 0x23, 0x24,
0x3c, 0x53, 0x6d, 0x56, 0x23, 0xec, 0xaf, 0x3c,
0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xdc, 0x8b,
0xb8, 0x76, 0x57, 0x9d, 0x7d, 0xe9, 0x9d, 0xae,
0xdb, 0xf8, 0x22, 0xd2, 0x0d, 0xa2, 0xe0, 0xbb,
0xbe, 0xed, 0xb0, 0xdb, 0xba, 0xeb, 0x18, 0x4d,
0x42, 0x01, 0xff, 0xed, 0x9d, 0xd4, 0xdc, 0x8b,
0xb8, 0x76, 0x57, 0x9d, 0x7d, 0xe9, 0x9d, 0xae,
0xdb, 0xf8, 0x22, 0xd2, 0x0d, 0xa2, 0xe0, 0xbb,
0xbe, 0xed, 0xb0, 0xdb, 0xba, 0xeb, 0x18, 0x4d,
0x42, 0x01, 0xff, 0xed, 0x9d, 0xa1, 0x9b, 0xa0,
0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -142,7 +142,7 @@ var genesisBlockBytes = []byte{
0x64, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, 0x2a, 0x01,
0x00, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,

Binary file not shown.

View File

@ -51,7 +51,7 @@ func generateBlock(parent *wire.MsgBlock) *wire.MsgBlock {
Bits: 0x2e00ffff, // 503382015 [000000ffff000000000000000000000000000000000000000000000000000000]
Nonce: 0xc0192550, // 2148484547
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
Transactions: []*wire.MsgTx{genesisCoinbaseTx},
}
}
@ -140,7 +140,7 @@ var genesisCoinbaseTxOuts = []*wire.TxOut{
},
},
}
var genesisCoinbaseTx = wire.NewMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseTxOuts, nil, 0, nil)
var genesisCoinbaseTx = wire.NewNativeMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseTxOuts)
var genesisMerkleRoot = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,

View File

@ -95,21 +95,25 @@ func NewDNSServer(hostname, nameserver, listen string) *DNSServer {
}
}
func (d *DNSServer) extractServicesSubnetworkID(addr *net.UDPAddr, domainName string) (wire.ServiceFlag, *subnetworkid.SubnetworkID, error) {
func (d *DNSServer) extractServicesSubnetworkID(addr *net.UDPAddr, domainName string) (wire.ServiceFlag, *subnetworkid.SubnetworkID, bool, error) {
// Domain name may be in following format:
// [nsubnetwork.][xservice.]hostname
// [n[subnetwork].][xservice.]hostname
// where connmgr.SubnetworkIDPrefixChar and connmgr.ServiceFlagPrefixChar are prefexes
wantedSF := wire.SFNodeNetwork
subnetworkID := subnetworkid.SubnetworkIDSupportsAll
var subnetworkID *subnetworkid.SubnetworkID
includeAllSubnetworks := true
if d.hostname != domainName {
idx := 0
labels := dns.SplitDomainName(domainName)
if labels[0][0] == connmgr.SubnetworkIDPrefixChar && len(labels[0]) > 1 {
idx = 1
subnetworkID, err := subnetworkid.NewFromStr(labels[0][1:])
if err != nil {
log.Printf("%s: subnetworkid.NewFromStr: %v", addr, err)
return wantedSF, subnetworkID, err
if labels[0][0] == connmgr.SubnetworkIDPrefixChar {
includeAllSubnetworks = false
if len(labels[0]) > 1 {
idx = 1
subnetworkID, err := subnetworkid.NewFromStr(labels[0][1:])
if err != nil {
log.Printf("%s: subnetworkid.NewFromStr: %v", addr, err)
return wantedSF, subnetworkID, includeAllSubnetworks, err
}
}
}
if labels[idx][0] == connmgr.ServiceFlagPrefixChar && len(labels[idx]) > 1 {
@ -117,12 +121,12 @@ func (d *DNSServer) extractServicesSubnetworkID(addr *net.UDPAddr, domainName st
u, err := strconv.ParseUint(wantedSFStr, 10, 64)
if err != nil {
log.Printf("%s: ParseUint: %v", addr, err)
return wantedSF, subnetworkID, err
return wantedSF, subnetworkID, includeAllSubnetworks, err
}
wantedSF = wire.ServiceFlag(u)
}
}
return wantedSF, subnetworkID, nil
return wantedSF, subnetworkID, includeAllSubnetworks, nil
}
func (d *DNSServer) validateDNSRequest(addr *net.UDPAddr, b []byte) (dnsMsg *dns.Msg, domainName string, atype string, err error) {
@ -167,7 +171,7 @@ func translateDNSQuestion(addr *net.UDPAddr, dnsMsg *dns.Msg) (string, error) {
}
func (d *DNSServer) buildDNSResponse(addr *net.UDPAddr, authority dns.RR, dnsMsg *dns.Msg,
wantedSF wire.ServiceFlag, subnetworkID *subnetworkid.SubnetworkID, atype string) ([]byte, error) {
wantedSF wire.ServiceFlag, includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID, atype string) ([]byte, error) {
respMsg := dnsMsg.Copy()
respMsg.Authoritative = true
respMsg.Response = true
@ -175,7 +179,7 @@ func (d *DNSServer) buildDNSResponse(addr *net.UDPAddr, authority dns.RR, dnsMsg
qtype := dnsMsg.Question[0].Qtype
if qtype != dns.TypeNS {
respMsg.Ns = append(respMsg.Ns, authority)
addrs := amgr.GoodAddresses(qtype, wantedSF, subnetworkID)
addrs := amgr.GoodAddresses(qtype, wantedSF, includeAllSubnetworks, subnetworkID)
for _, a := range addrs {
rr := fmt.Sprintf("%s 30 IN %s %s", dnsMsg.Question[0].Name, atype, a.IP.String())
newRR, err := dns.NewRR(rr)
@ -213,7 +217,7 @@ func (d *DNSServer) handleDNSRequest(addr *net.UDPAddr, authority dns.RR, udpLis
return
}
wantedSF, subnetworkID, err := d.extractServicesSubnetworkID(addr, domainName)
wantedSF, subnetworkID, includeAllSubnetworks, err := d.extractServicesSubnetworkID(addr, domainName)
if err != nil {
return
}
@ -221,7 +225,7 @@ func (d *DNSServer) handleDNSRequest(addr *net.UDPAddr, authority dns.RR, udpLis
log.Printf("%s: query %d for services %v, subnetwork ID %v",
addr, dnsMsg.Question[0].Qtype, wantedSF, subnetworkID)
sendBytes, err := d.buildDNSResponse(addr, authority, dnsMsg, wantedSF, subnetworkID, atype)
sendBytes, err := d.buildDNSResponse(addr, authority, dnsMsg, wantedSF, includeAllSubnetworks, subnetworkID, atype)
if err != nil {
return
}

View File

@ -17,7 +17,6 @@ import (
"github.com/daglabs/btcd/connmgr"
"github.com/daglabs/btcd/peer"
"github.com/daglabs/btcd/signal"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/daglabs/btcd/wire"
)
@ -71,14 +70,13 @@ func creep() {
log.Printf("Adding peer %v with services %v and subnetword ID %v",
p.NA().IP.String(), msg.Services, msg.SubnetworkID)
// Mark this peer as a good node.
amgr.Good(p.NA().IP, msg.Services, &msg.SubnetworkID)
amgr.Good(p.NA().IP, msg.Services, msg.SubnetworkID)
// Ask peer for some addresses.
p.QueueMessage(wire.NewMsgGetAddr(nil), nil)
p.QueueMessage(wire.NewMsgGetAddr(true, nil), nil)
// notify that version is received and Peer's subnetwork ID is updated
onVersion <- struct{}{}
},
},
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
}
var wgCreep sync.WaitGroup
@ -86,7 +84,7 @@ func creep() {
peers := amgr.Addresses()
if len(peers) == 0 && amgr.AddressCount() == 0 {
// Add peers discovered through DNS to the address manager.
connmgr.SeedFromDNS(activeNetParams, requiredServices, subnetworkid.SubnetworkIDSupportsAll, hostLookup, func(addrs []*wire.NetAddress) {
connmgr.SeedFromDNS(activeNetParams, requiredServices, true, nil, hostLookup, func(addrs []*wire.NetAddress) {
amgr.AddAddresses(addrs)
})
peers = amgr.Addresses()

View File

@ -200,7 +200,7 @@ func (m *Manager) AddressCount() int {
// GoodAddresses returns good working IPs that match both the
// passed DNS query type and have the requested services.
func (m *Manager) GoodAddresses(qtype uint16, services wire.ServiceFlag, subnetworkID *subnetworkid.SubnetworkID) []*wire.NetAddress {
func (m *Manager) GoodAddresses(qtype uint16, services wire.ServiceFlag, includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) []*wire.NetAddress {
addrs := make([]*wire.NetAddress, 0, defaultMaxAddresses)
i := defaultMaxAddresses
@ -219,7 +219,7 @@ func (m *Manager) GoodAddresses(qtype uint16, services wire.ServiceFlag, subnetw
continue
}
if node.SubnetworkID == nil || !node.SubnetworkID.IsEqual(subnetworkID) {
if !includeAllSubnetworks && !node.SubnetworkID.IsEqual(subnetworkID) {
continue
}

View File

@ -735,7 +735,8 @@ func (mp *TxPool) maybeAcceptTransaction(tx *util.Tx, isNew, rateLimit, rejectDu
// Don't accept the transaction if it's from an incompatible subnetwork.
subnetworkID := mp.cfg.DAG.SubnetworkID()
if !tx.MsgTx().IsSubnetworkCompatible(subnetworkID) {
str := fmt.Sprintf("tx %s belongs to an invalid subnetwork", tx.ID())
str := fmt.Sprintf("tx %s belongs to an invalid subnetwork %s, DAG subnetwork %s", tx.ID(),
tx.MsgTx().SubnetworkID, subnetworkID)
return nil, nil, txRuleError(wire.RejectInvalid, str)
}
@ -752,9 +753,7 @@ func (mp *TxPool) maybeAcceptTransaction(tx *util.Tx, isNew, rateLimit, rejectDu
// Check that transaction does not overuse GAS
msgTx := tx.MsgTx()
if msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
return nil, nil, txRuleError(wire.RejectInvalid, "SubnetworkIDSupportsAll is not permited in transaction")
} else if !msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) {
if !msgTx.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) {
gasLimit, err := mp.cfg.DAG.SubnetworkStore.GasLimit(&msgTx.SubnetworkID)
if err != nil {
return nil, nil, err

View File

@ -288,8 +288,7 @@ func newPoolHarness(dagParams *dagconfig.Params, numOutputs uint32, dbName strin
// Create a new database and chain instance to run tests against.
dag, teardownFunc, err := blockdag.DAGSetup(dbName, blockdag.Config{
DAGParams: dagParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
DAGParams: dagParams,
})
if err != nil {
return nil, nil, nil, fmt.Errorf("Failed to setup DAG instance: %v", err)

View File

@ -11,7 +11,6 @@ import (
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/peer"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/daglabs/btcd/wire"
)
@ -24,7 +23,6 @@ func mockRemotePeer() error {
UserAgentName: "peer", // User agent name to advertise.
UserAgentVersion: "1.0.0", // User agent version to advertise.
DAGParams: &dagconfig.SimNetParams,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
SelectedTip: fakeSelectedTipFn,
}
@ -80,8 +78,7 @@ func Example_newOutboundPeer() {
verack <- struct{}{}
},
},
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
SelectedTip: fakeSelectedTipFn,
SelectedTip: fakeSelectedTipFn,
}
p, err := peer.NewOutboundPeer(peerCfg, "127.0.0.1:18555")
if err != nil {

View File

@ -271,6 +271,7 @@ type Config struct {
Listeners MessageListeners
// SubnetworkID specifies which subnetwork the peer is associated with.
// It is nil in full nodes.
SubnetworkID *subnetworkid.SubnetworkID
}
@ -837,7 +838,7 @@ func (p *Peer) PushAddrMsg(addresses []*wire.NetAddress, subnetworkID *subnetwor
return nil, nil
}
msg := wire.NewMsgAddr(subnetworkID)
msg := wire.NewMsgAddr(false, subnetworkID)
msg.AddrList = make([]*wire.NetAddress, addressCount)
copy(msg.AddrList, addresses)
@ -1000,8 +1001,8 @@ func (p *Peer) handleRemoteVersionMsg(msg *wire.MsgVersion) error {
// Disconnect if:
// - we are a full node and the outbound connection we've initiated is a partial node
// - the remote node is partial and our subnetwork doesn't match their subnetwork
isLocalNodeFull := p.cfg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll)
isRemoteNodeFull := msg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll)
isLocalNodeFull := p.cfg.SubnetworkID == nil
isRemoteNodeFull := msg.SubnetworkID == nil
if (isLocalNodeFull && !isRemoteNodeFull && !p.inbound) ||
(!isLocalNodeFull && !isRemoteNodeFull && !msg.SubnetworkID.IsEqual(p.cfg.SubnetworkID)) {

View File

@ -16,7 +16,6 @@ import (
"github.com/daglabs/btcd/dagconfig"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/peer"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/daglabs/btcd/wire"
)
@ -218,7 +217,6 @@ func TestPeerConnection(t *testing.T) {
DAGParams: &dagconfig.MainNetParams,
ProtocolVersion: wire.ProtocolVersion, // Configure with older version
Services: 0,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
SelectedTip: fakeSelectedTipFn,
}
peer2Cfg := &peer.Config{
@ -229,7 +227,6 @@ func TestPeerConnection(t *testing.T) {
DAGParams: &dagconfig.MainNetParams,
ProtocolVersion: wire.ProtocolVersion + 1,
Services: wire.SFNodeNetwork,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
SelectedTip: fakeSelectedTipFn,
}
@ -244,8 +241,8 @@ func TestPeerConnection(t *testing.T) {
wantLastPingNonce: uint64(0),
wantLastPingMicros: int64(0),
wantTimeOffset: int64(0),
wantBytesSent: 215, // 191 version + 24 verack
wantBytesReceived: 215,
wantBytesSent: 196, // 172 version + 24 verack
wantBytesReceived: 196,
}
wantStats2 := peerStats{
wantUserAgent: wire.DefaultUserAgent + "peer:1.0(comment)/",
@ -258,8 +255,8 @@ func TestPeerConnection(t *testing.T) {
wantLastPingNonce: uint64(0),
wantLastPingMicros: int64(0),
wantTimeOffset: int64(0),
wantBytesSent: 215, // 191 version + 24 verack
wantBytesReceived: 215,
wantBytesSent: 196, // 172 version + 24 verack
wantBytesReceived: 196,
}
tests := []struct {
@ -432,7 +429,6 @@ func TestPeerListeners(t *testing.T) {
UserAgentComments: []string{"comment"},
DAGParams: &dagconfig.MainNetParams,
Services: wire.SFNodeBloom,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
SelectedTip: fakeSelectedTipFn,
}
inConn, outConn := pipe(
@ -469,11 +465,11 @@ func TestPeerListeners(t *testing.T) {
}{
{
"OnGetAddr",
wire.NewMsgGetAddr(nil),
wire.NewMsgGetAddr(false, nil),
},
{
"OnAddr",
wire.NewMsgAddr(nil),
wire.NewMsgAddr(false, nil),
},
{
"OnPing",
@ -603,7 +599,6 @@ func TestOutboundPeer(t *testing.T) {
UserAgentComments: []string{"comment"},
DAGParams: &dagconfig.MainNetParams,
Services: 0,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
}
r, w := io.Pipe()
@ -695,7 +690,7 @@ func TestOutboundPeer(t *testing.T) {
p2.PushRejectMsg("block", wire.RejectInvalid, "invalid", nil, false)
// Test Queue Messages
p2.QueueMessage(wire.NewMsgGetAddr(nil), nil)
p2.QueueMessage(wire.NewMsgGetAddr(false, nil), nil)
p2.QueueMessage(wire.NewMsgPing(1), nil)
p2.QueueMessage(wire.NewMsgMemPool(), nil)
p2.QueueMessage(wire.NewMsgGetData(), nil)
@ -714,7 +709,6 @@ func TestUnsupportedVersionPeer(t *testing.T) {
UserAgentComments: []string{"comment"},
DAGParams: &dagconfig.MainNetParams,
Services: 0,
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
SelectedTip: fakeSelectedTipFn,
}
@ -772,7 +766,7 @@ func TestUnsupportedVersionPeer(t *testing.T) {
}
// Remote peer writes version message advertising invalid protocol version 0
invalidVersionMsg := wire.NewMsgVersion(remoteNA, localNA, 0, &daghash.ZeroHash, subnetworkid.SubnetworkIDSupportsAll)
invalidVersionMsg := wire.NewMsgVersion(remoteNA, localNA, 0, &daghash.ZeroHash, nil)
invalidVersionMsg.ProtocolVersion = 0
_, err = wire.WriteMessageN(

View File

@ -454,15 +454,15 @@ func (sp *Peer) OnVersion(_ *peer.Peer, msg *wire.MsgVersion) {
// Request known addresses if the server address manager needs
// more.
if addrManager.NeedMoreAddresses() {
sp.QueueMessage(wire.NewMsgGetAddr(sp.SubnetworkID()), nil)
sp.QueueMessage(wire.NewMsgGetAddr(false, sp.SubnetworkID()), nil)
if !sp.SubnetworkID().IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
sp.QueueMessage(wire.NewMsgGetAddr(subnetworkid.SubnetworkIDSupportsAll), nil)
if sp.SubnetworkID() != nil {
sp.QueueMessage(wire.NewMsgGetAddr(false, nil), nil)
}
}
// Mark the address as a known good address.
addrManager.Good(sp.NA(), &msg.SubnetworkID)
addrManager.Good(sp.NA(), msg.SubnetworkID)
}
}
@ -1115,7 +1115,7 @@ func (sp *Peer) OnGetAddr(_ *peer.Peer, msg *wire.MsgGetAddr) {
sp.sentAddrs = true
// Get the current known addresses from the address manager.
addrCache := sp.server.addrManager.AddressCache(msg.SubnetworkID)
addrCache := sp.server.addrManager.AddressCache(msg.IncludeAllSubnetworks, msg.SubnetworkID)
// Push the addresses.
sp.pushAddrMsg(addrCache, sp.SubnetworkID())
@ -1140,9 +1140,14 @@ func (sp *Peer) OnAddr(_ *peer.Peer, msg *wire.MsgAddr) {
return
}
if msg.SubnetworkID == nil || (!msg.SubnetworkID.IsEqual(config.MainConfig().SubnetworkID) && !msg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll)) {
peerLog.Errorf("Only %s and %s subnetwork IDs are allowed in [%s] command, but got subnetwork ID %s from %s",
subnetworkid.SubnetworkIDSupportsAll, config.MainConfig().SubnetworkID, msg.Command(), msg.SubnetworkID, sp.Peer)
if msg.IncludeAllSubnetworks {
peerLog.Errorf("Got unexpected IncludeAllSubnetworks=true in [%s] command from %s",
msg.Command(), sp.Peer)
sp.Disconnect()
return
} else if !msg.SubnetworkID.IsEqual(config.MainConfig().SubnetworkID) && msg.SubnetworkID != nil {
peerLog.Errorf("Only full nodes and %s subnetwork IDs are allowed in [%s] command, but got subnetwork ID %s from %s",
config.MainConfig().SubnetworkID, msg.Command(), msg.SubnetworkID, sp.Peer)
sp.Disconnect()
return
}
@ -1302,8 +1307,8 @@ func (s *Server) pushBlockMsg(sp *Peer, hash *daghash.Hash, doneChan chan<- stru
// the block to a partial block.
nodeSubnetworkID := s.DAG.SubnetworkID()
peerSubnetworkID := sp.Peer.SubnetworkID()
isNodeFull := nodeSubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll)
isPeerFull := peerSubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll)
isNodeFull := nodeSubnetworkID == nil
isPeerFull := peerSubnetworkID == nil
if isNodeFull && !isPeerFull {
msgBlock.ConvertToPartial(peerSubnetworkID)
}
@ -1921,7 +1926,7 @@ func (s *Server) peerHandler() {
if !config.MainConfig().DisableDNSSeed {
seedFromSubNetwork := func(subnetworkID *subnetworkid.SubnetworkID) {
connmgr.SeedFromDNS(config.ActiveNetParams(), defaultRequiredServices,
subnetworkid.SubnetworkIDSupportsAll, serverutils.BTCDLookup, func(addrs []*wire.NetAddress) {
false, subnetworkID, serverutils.BTCDLookup, func(addrs []*wire.NetAddress) {
// Bitcoind uses a lookup of the dns seeder here. Since seeder returns
// IPs of nodes and not its own IP, we can not know real IP of
// source. So we'll take first returned address as source.
@ -1930,9 +1935,9 @@ func (s *Server) peerHandler() {
}
// Add full nodes discovered through DNS to the address manager.
seedFromSubNetwork(subnetworkid.SubnetworkIDSupportsAll)
seedFromSubNetwork(nil)
if !config.MainConfig().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if config.MainConfig().SubnetworkID != nil {
// Node is partial - fetch nodes with same subnetwork
seedFromSubNetwork(config.MainConfig().SubnetworkID)
}

View File

@ -902,7 +902,7 @@ func handleGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
}
}
if !config.MainConfig().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if config.MainConfig().SubnetworkID != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidRequest.Code,
Message: "`generate` is not supported on partial nodes.",
@ -1131,8 +1131,8 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
}
nodeSubnetworkID := config.MainConfig().SubnetworkID
if !requestSubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if !nodeSubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if requestSubnetworkID != nil {
if nodeSubnetworkID != nil {
if !nodeSubnetworkID.IsEqual(requestSubnetworkID) {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidRequest.Code,
@ -2279,7 +2279,7 @@ func handleGetGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (i
// handleGetHashesPerSec implements the getHashesPerSec command.
func handleGetHashesPerSec(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
if !config.MainConfig().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if config.MainConfig().SubnetworkID != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidRequest.Code,
Message: "`getHashesPerSec` is not supported on partial nodes.",
@ -2369,7 +2369,7 @@ func handleGetMempoolInfo(s *Server, cmd interface{}, closeChan <-chan struct{})
// handleGetMiningInfo implements the getMiningInfo command. We only return the
// fields that are not related to wallet functionality.
func handleGetMiningInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
if !config.MainConfig().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if config.MainConfig().SubnetworkID != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidRequest.Code,
Message: "`getMiningInfo` is not supported on partial nodes.",
@ -2432,7 +2432,7 @@ func handleGetNetTotals(s *Server, cmd interface{}, closeChan <-chan struct{}) (
// This command had been (possibly temporarily) dropped.
// Originally it relied on height, which no longer makes sense.
func handleGetNetworkHashPS(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
if !config.MainConfig().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if config.MainConfig().SubnetworkID != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidRequest.Code,
Message: "`getNetworkHashPS` is not supported on partial nodes.",
@ -3336,7 +3336,7 @@ func handleSendRawTransaction(s *Server, cmd interface{}, closeChan <-chan struc
// handleSetGenerate implements the setGenerate command.
func handleSetGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
if !config.MainConfig().SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
if config.MainConfig().SubnetworkID != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidRequest.Code,
Message: "`setGenerate` is not supported on partial nodes.",

View File

@ -1854,7 +1854,7 @@ func handleNotifyNewTransactions(wsc *wsClient, icmd interface{}) (interface{},
Code: btcjson.ErrRPCInvalidParameter,
Message: "Subnetwork switch is disabled when node is in Native subnetwork",
}
} else if !nodeSubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
} else if nodeSubnetworkID != nil {
if subnetworkID == nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCInvalidParameter,

View File

@ -55,10 +55,10 @@ func TestBlock(t *testing.T) {
// Hashes for the transactions in Block100000.
wantTxHashes := []string{
"171090dd8ab478a2c4499858abd5d9b10e173b659bab5d5acca68c7dcb4c519e",
"fc9100986f2a188ccffe206a4c013aaa0c7442898b2f58d474f0b4f534600e0b",
"42ef8bcc302b4a92d479c02c4bf6cb154f26ad9915433da7fb102f6fd135b5c3",
"c8eeef60be812de9982d066be027fee93f2c226c840670424a413fbd66ad36dd",
"9bdfb2c83f82ab919e2e87cba505392bdfd9fa987864cbf59879c7dedf6da2cf",
"7fdc7d604ea88d81b284db97b09817869a8adae7efc8a1e43d7d4b11965c526e",
"de28b21c894897598f8377c3a84a5a746266d6a929f7ae2054b820c2f77f01b1",
"6ef923e08c5b6cee1e70488f282c11eeb9c67f12a684a4900e5731ac53510d06",
}
// Create a new block to nuke all cached data.

View File

@ -278,7 +278,7 @@ func TestFilterBloomMatch(t *testing.T) {
0x29, 0x65, 0x54, 0x76, 0x08, 0xb9, 0xe1, 0x5d,
0x90, 0x32, 0xa7, 0xb9, 0xd6, 0x4f, 0xa4, 0x31,
0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
@ -288,11 +288,11 @@ func TestFilterBloomMatch(t *testing.T) {
return
}
spendingTxBytes := []byte{
0x01, 0x00, 0x00, 0x00, 0x01, 0x4c, 0x55, 0x7d,
0x38, 0xc1, 0xde, 0x01, 0x1d, 0x08, 0x0d, 0x54,
0x16, 0xd4, 0x8f, 0x67, 0xdb, 0xbd, 0x20, 0xf2,
0x60, 0x68, 0x4a, 0x1b, 0x58, 0xb8, 0xbb, 0x9e,
0x8c, 0x65, 0x1c, 0xf0, 0xcb, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x95, 0x7c, 0x1d,
0xfd, 0x07, 0x87, 0xc3, 0x2b, 0xb7, 0x67, 0xbb,
0xa9, 0x4d, 0x29, 0x0e, 0x64, 0xdc, 0x3d, 0x12,
0x19, 0xbf, 0x53, 0xe6, 0x15, 0x01, 0xef, 0xb3,
0xfc, 0x5d, 0xc0, 0xf9, 0x81, 0x00, 0x00, 0x00,
0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00,
0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06,
0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1,
@ -321,7 +321,7 @@ func TestFilterBloomMatch(t *testing.T) {
0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe,
0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43,
0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
@ -333,7 +333,7 @@ func TestFilterBloomMatch(t *testing.T) {
}
f := bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
inputStr := "cbf01c658c9ebbb8581b4a6860f220bddb678fd416540d081d01dec1387d554c" // byte-reversed tx id
inputStr := "81f9c05dfcb3ef0115e653bf19123ddc640e294da9bb67b72bc38707fd1d7c95" // byte-reversed tx id
hash, err := daghash.NewHashFromStr(inputStr)
if err != nil {
t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", err)
@ -341,11 +341,11 @@ func TestFilterBloomMatch(t *testing.T) {
}
f.AddHash(hash)
if !f.MatchTxAndUpdate(tx) {
t.Errorf("TestFilterBloomMatch didn't match hash %s", inputStr)
t.Errorf("TestFilterBloomMatch didn't match ID, want %s, got %s", inputStr, tx.ID())
}
f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
inputStr = "4c557d38c1de011d080d5416d48f67dbbd20f260684a1b58b8bb9e8c651cf0cb" // non-reversed tx id
inputStr = "957c1dfd0787c32bb767bba94d290e64dc3d1219bf53e61501efb3fc5dc0f981" // non-reversed tx id
hashBytes, err := hex.DecodeString(inputStr)
if err != nil {
t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", err)
@ -354,7 +354,8 @@ func TestFilterBloomMatch(t *testing.T) {
f.Add(hashBytes)
if !f.MatchTxAndUpdate(tx) {
t.Errorf("TestFilterBloomMatch didn't match hash %s", inputStr)
t.Errorf("TestFilterBloomMatch didn't match ID, want %s, got %s", inputStr,
hex.EncodeToString(tx.ID()[:]))
}
f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
@ -555,7 +556,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x1E, 0xC0, 0xF0, 0xDD, 0x5B, 0x2E, 0x86, 0xE7, 0x16, 0x8C, 0xEF,
0xE0, 0xD8, 0x11, 0x13, 0xC3, 0x80, 0x74, 0x20, 0xCE, 0x13, 0xAD,
0x13, 0x57, 0x23, 0x1A, 0x22, 0x52, 0x24, 0x7D, 0x97, 0xA4, 0x6A,
0x91, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x91, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -577,7 +578,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x00, 0x19, 0x76, 0xA9, 0x14, 0x1B, 0x8D, 0xD1, 0x3B, 0x99, 0x4B,
0xCF, 0xC7, 0x87, 0xB3, 0x2A, 0xEA, 0xDF, 0x58, 0xCC, 0xB3, 0x61,
0x5C, 0xBD, 0x54, 0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x03, 0xFD, 0xAC, 0xF9, 0xB3, 0xEB, 0x07, // Txs[2]
0x74, 0x12, 0xE7, 0xA9, 0x68, 0xD2, 0xE4, 0xF1, 0x1B, 0x9A, 0x9D,
@ -621,7 +622,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x44, 0x60, 0x03, 0x00, 0x00, 0x00, 0x19, 0x76, 0xA9, 0x14, 0xC7,
0xB5, 0x51, 0x41, 0xD0, 0x97, 0xEA, 0x5D, 0xF7, 0xA0, 0xED, 0x33,
0x0C, 0xF7, 0x94, 0x37, 0x6E, 0x53, 0xEC, 0x8D, 0x88, 0xAC, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x5B, 0xF0, 0xE2, 0x14, 0xAA, 0x40, // Txs[3]
@ -695,7 +696,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x17, 0xA8, 0x04, 0x00, 0x00, 0x00, 0x19, 0x76, 0xA9, 0x14, 0xB6,
0xEF, 0xD8, 0x0D, 0x99, 0x17, 0x9F, 0x4F, 0x4F, 0xF6, 0xF4, 0xDD,
0x0A, 0x00, 0x7D, 0x01, 0x8C, 0x38, 0x5D, 0x21,
0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x83, 0x45, 0x37, 0xB2, 0xF1, 0xCE, // Txs[4]
@ -722,7 +723,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x00, 0x19, 0x76, 0xA9, 0x14, 0xA8, 0x4E, 0x27, 0x29, 0x33, 0xAA,
0xF8, 0x7E, 0x17, 0x15, 0xD7, 0x78, 0x6C, 0x51, 0xDF, 0xAE, 0xB5,
0xB6, 0x5A, 0x6F, 0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x43, 0xAC, 0x81, 0xC8, 0xE6, 0xF6, // Txs[5]
0xEF, 0x30, 0x7D, 0xFE, 0x17, 0xF3, 0xD9, 0x06, 0xD9, 0x99, 0xE2,
@ -748,7 +749,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x00, 0x00, 0x19, 0x76, 0xA9, 0x14, 0x64, 0x8D, 0x04, 0x34, 0x1D,
0x00, 0xD7, 0x96, 0x8B, 0x34, 0x05, 0xC0, 0x34, 0xAD, 0xC3, 0x8D,
0x4D, 0x8F, 0xB9, 0xBD, 0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x48, 0xCC, 0x91, 0x75, 0x01, 0xEA, // Txs[6]
@ -789,7 +790,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xA9, 0x14, 0x8E, 0xDB, 0x68,
0x82, 0x2F, 0x1A, 0xD5, 0x80, 0xB0, 0x43, 0xC7, 0xB3, 0xDF, 0x2E,
0x40, 0x0F, 0x86, 0x99, 0xEB, 0x48, 0x88, 0xAC, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
}
@ -825,7 +826,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
_, _ = bloom.NewMerkleBlock(block, f)
// We should match the generation pubkey
inputStr = "042aaac8c54b07f1e729e01d38b1fb26c6d595ed5920b856faf4070db79ce933" //0st tx hash
inputStr = "5f8261e729a931a6258f291d88ad62c1657c444f41acb829843b4cbdd7018944" //0st tx ID
txID, err := daghash.NewTxIDFromStr(inputStr)
if err != nil {
t.Errorf("TestMerkleBlockP2PubKeyOnly NewHashFromStr failed: %v", err)

View File

@ -44,7 +44,7 @@ func TestMerkleBlock3(t *testing.T) {
0x5F, 0x64, 0x86, 0x81, 0x37, 0xA1, 0x8C, 0xDD, 0x85, 0xCB, 0xBB,
0x4C, 0x74, 0xFB, 0xCC, 0xFD, 0x4F, 0x49, 0x63, 0x9C, 0xF1, 0xBD,
0xC9, 0x4A, 0x56, 0x72, 0xBB, 0x15, 0xAD, 0x5D, 0x4C, 0xAC, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
}
@ -84,11 +84,11 @@ func TestMerkleBlock3(t *testing.T) {
0xfd, 0xd0, 0xd9, 0x72, 0x87, 0x67, 0x29, 0x1b,
0x4d, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x86, 0x04,
0x1b, 0x8f, 0xa4, 0x5d, 0x63, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0xb0,
0x08, 0x73, 0xd7, 0xde, 0x86, 0xf3, 0x9e, 0x37,
0x06, 0x03, 0xb4, 0x75, 0xb4, 0xac, 0xb4, 0x67,
0xd3, 0x98, 0x3d, 0x2b, 0x9e, 0xe5, 0x35, 0x83,
0x1a, 0xa4, 0xec, 0xd5, 0x76, 0x18, 0x01, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xe2, 0x03,
0xc3, 0xca, 0x45, 0x44, 0x5e, 0xcd, 0xbc, 0x90,
0xdf, 0x49, 0xa2, 0x91, 0x41, 0xdf, 0x31, 0x92,
0xee, 0xdb, 0x9d, 0x42, 0x33, 0xf5, 0x22, 0xff,
0x26, 0xca, 0x44, 0xde, 0x3e, 0x9e, 0x01, 0x00,
}
t.Log(spew.Sdump(want))
if err != nil {

View File

@ -227,7 +227,7 @@ func TestMinPrioritySelector(t *testing.T) {
var (
// should be two outpoints, with 1st one having 0.035BTC value.
testSimpleCoinNumConfs = int64(1)
testSimpleCoinTxHash = "8b6cefebd8a9b3ec28e9195b852edc306bc7d6b582bd5c8b74b602bbed4124b8"
testSimpleCoinTxHash = "c9e1a2b492e1d76872df50ddae62662f7d40f853b6d5aa85522ed915bbd96be7"
testSimpleCoinTxHex = "0100000001A214A110F79E4ABE073865EA5B3745C6E82C91" +
"3BAD44BE70652804A5E4003B0A010000008C493046022100" +
"EDD18A69664EFA57264BE207100C203E6CADE1888CBB88A0" +
@ -239,7 +239,7 @@ var (
"673500000000001976A914686DD149A79B4A559D561FBC39" +
"6D3E3C6628B98D88ACE86EF102000000001976A914AC3F99" +
"5655E81B875B38B64351D6F896DDBFC68588AC0000000000" +
"000000010000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000"
testSimpleCoinTxValue0 = util.Amount(3500000)
testSimpleCoinTxValueAge0 = int64(testSimpleCoinTxValue0) * testSimpleCoinNumConfs
testSimpleCoinTxPkScript0Hex = "76a914686dd149a79b4a559d561fbc396d3e3c6628b98d88ac"

View File

@ -28,14 +28,11 @@ var ErrIDStrSize = fmt.Errorf("max ID string length is %d bytes", MaxStringSize)
type SubnetworkID [IDLength]byte
var (
// SubnetworkIDSupportsAll is the subnetwork ID that is used to signal to peers that you support all subnetworks
SubnetworkIDSupportsAll = &SubnetworkID{}
// SubnetworkIDNative is the default subnetwork ID which is used for transactions without related payload data
SubnetworkIDNative = &SubnetworkID{1}
SubnetworkIDNative = &SubnetworkID{}
// SubnetworkIDRegistry is the subnetwork ID which is used for adding new sub networks to the registry
SubnetworkIDRegistry = &SubnetworkID{2}
SubnetworkIDRegistry = &SubnetworkID{1}
)
// String returns the SubnetworkID as the hexadecimal string of the byte-reversed

View File

@ -37,7 +37,7 @@ func TestTx(t *testing.T) {
}
// Hash for block 100,000 transaction 0.
wantHashStr := "171090dd8ab478a2c4499858abd5d9b10e173b659bab5d5acca68c7dcb4c519e"
wantHashStr := "9bdfb2c83f82ab919e2e87cba505392bdfd9fa987864cbf59879c7dedf6da2cf"
wantHash, err := daghash.NewHashFromStr(wantHashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
@ -53,7 +53,7 @@ func TestTx(t *testing.T) {
}
// ID for block 100,000 transaction 1.
wantIDStr := "1742649144632997855e06650c1df5fd27cad915419a8f14f2f1b5a652257342"
wantIDStr := "011f7009d8e5a99c4cf2f7216a3eb6044a7017a98732a8fb6390fbbb668e84d8"
wantID, err := daghash.NewTxIDFromStr(wantIDStr)
// Request the ID multiple times to test generation and caching.
for i := 0; i < 2; i++ {

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000100000000000000000000000000000000000000
010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000000000000000000000000000000000000000000

View File

@ -1 +1 @@
0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000100000000000000000000000000000000000000
0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000000000000000000000000000000000000000000

View File

@ -1 +1 @@
01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000100000000000000000000000000000000000000
01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000000000000000000000000000000000000000000

View File

@ -1 +1 @@
01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000100000000000000000000000000000000000000
01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000000000000000000000000000000000000000000

View File

@ -28,36 +28,36 @@ func TestSort(t *testing.T) {
name: "first test case from BIP 69 - sorts inputs only, based on hash",
hexFile: "bip69-1.hex",
isSorted: false,
unsortedHash: "6b178242e9b6c1d448e2fa7d52fb7ec8dcea289c7852f1184880aabaef4da412",
sortedHash: "ab07dbc63d1376cfb4f122722748a9f1487adb66fbbb682c593da602723f22c3",
unsortedHash: "942436554228bcff3af7825cc733f58df686166943da87347f1dfd77ace0f8cf",
sortedHash: "a730bfdb5efc611dbf6b1cf10b16477f60be647ac95009d9b655f59f09fbe7cb",
},
{
name: "second test case from BIP 69 - already sorted",
hexFile: "bip69-2.hex",
isSorted: true,
unsortedHash: "ef51200d830bf2bc77b50e3b92f878d82f6f8d29d7e0d031782f24e2af023601",
sortedHash: "ef51200d830bf2bc77b50e3b92f878d82f6f8d29d7e0d031782f24e2af023601",
unsortedHash: "81812ee14ff0e57582eb1520630812838d8fbf2a278517b7ff89e82463f6a558",
sortedHash: "81812ee14ff0e57582eb1520630812838d8fbf2a278517b7ff89e82463f6a558",
},
{
name: "block 100001 tx[1] - sorts outputs only, based on amount",
hexFile: "bip69-3.hex",
isSorted: false,
unsortedHash: "36e32ff592786843a4b80dc1029129530e93c885a1cbeb9ef2bed309b336b92e",
sortedHash: "f971eb5dd57cc6848c0b903440c175a2fe0d93004099b1582e201de8d60ef6dc",
unsortedHash: "73d990869a7e3095ba06cc2c6718b4f210f72f6099643d2c6fe4dd93d32a49cf",
sortedHash: "5c2b807e2fff4dadea373e2f2a41a6d4808675bc478a3448f76bbbeec6fae310",
},
{
name: "block 100001 tx[2] - sorts both inputs and outputs",
hexFile: "bip69-4.hex",
isSorted: false,
unsortedHash: "355b28a1b5e05c937755182169cbb6cfd58c9c50122ce430efb83c650c9aadef",
sortedHash: "4f0f023e7fc32a893fa156ca3001d1be4f1ff86f6d7b69d36f76fa0f427e765a",
unsortedHash: "cefbcc2b6513392c9296a866e8ca9e3fc832355b454c6897aedbf2159f958fd3",
sortedHash: "4e3573d75a3aa02aeb3508f8203c52f0154d19ecb0cb0ef2e00ec3fa803baa5d",
},
{
name: "block 100998 tx[6] - sorts outputs only, based on output script",
hexFile: "bip69-5.hex",
isSorted: false,
unsortedHash: "f1d10b059664f8711d7a0960ce7763a89a89c697a74b8b5db4dbf850c0973fd6",
sortedHash: "76405dc7da88f622481b5e9d6894a45a45f7c376d1f95a390b8a494b7767ff71",
unsortedHash: "f79ed295b9d8a3c9813cc2b207d267753755503258bc9ac887f2d5495e8b6140",
sortedHash: "a90123db6e884f821d3228da70e7a810d4797d43379d40b71c8e214c7104c59a",
},
}

View File

@ -481,7 +481,7 @@ func BenchmarkDecodeAddr(b *testing.B) {
// Create a message with the maximum number of addresses.
pver := ProtocolVersion
ip := net.ParseIP("127.0.0.1")
ma := NewMsgAddr(nil)
ma := NewMsgAddr(false, nil)
for port := uint16(0); port < MaxAddrPerMsg; port++ {
ma.AddAddress(NewNetAddressIPPort(ip, port, SFNodeNetwork))
}

View File

@ -14,7 +14,6 @@ import (
"time"
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/davecgh/go-spew/spew"
)
@ -47,11 +46,11 @@ func TestMessage(t *testing.T) {
addrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333}
me := NewNetAddress(addrMe, SFNodeNetwork)
me.Timestamp = time.Time{} // Version message has zero value timestamp.
msgVersion := NewMsgVersion(me, you, 123123, &daghash.ZeroHash, subnetworkid.SubnetworkIDSupportsAll)
msgVersion := NewMsgVersion(me, you, 123123, &daghash.ZeroHash, nil)
msgVerack := NewMsgVerAck()
msgGetAddr := NewMsgGetAddr(nil)
msgAddr := NewMsgAddr(nil)
msgGetAddr := NewMsgGetAddr(false, nil)
msgAddr := NewMsgAddr(false, nil)
msgGetBlocks := NewMsgGetBlocks(&daghash.Hash{})
msgBlock := &blockOne
msgInv := NewMsgInv()
@ -87,10 +86,10 @@ func TestMessage(t *testing.T) {
btcnet BitcoinNet // Network to use for wire encoding
bytes int // Expected num bytes read/written
}{
{msgVersion, msgVersion, pver, MainNet, 173},
{msgVersion, msgVersion, pver, MainNet, 154},
{msgVerack, msgVerack, pver, MainNet, 24},
{msgGetAddr, msgGetAddr, pver, MainNet, 25},
{msgAddr, msgAddr, pver, MainNet, 26},
{msgGetAddr, msgGetAddr, pver, MainNet, 26},
{msgAddr, msgAddr, pver, MainNet, 27},
{msgGetBlocks, msgGetBlocks, pver, MainNet, 61},
{msgBlock, msgBlock, pver, MainNet, 340},
{msgInv, msgInv, pver, MainNet, 25},
@ -222,7 +221,7 @@ func TestReadMessageWireErrors(t *testing.T) {
// Wire encoded bytes for a message which exceeds the max payload for
// a specific message type.
exceedTypePayloadBytes := makeHeader(btcnet, "getaddr", 22, 0)
exceedTypePayloadBytes := makeHeader(btcnet, "getaddr", 23, 0)
// Wire encoded bytes for a message which does not deliver the full
// payload according to the header length.

View File

@ -26,8 +26,9 @@ const MaxAddrPerMsg = 1000
// Use the AddAddress function to build up the list of known addresses when
// sending an addr message to another peer.
type MsgAddr struct {
SubnetworkID *subnetworkid.SubnetworkID
AddrList []*NetAddress
IncludeAllSubnetworks bool
SubnetworkID *subnetworkid.SubnetworkID
AddrList []*NetAddress
}
// AddAddress adds a known active peer to the message.
@ -61,21 +62,27 @@ func (msg *MsgAddr) ClearAddresses() {
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error {
// Read subnetwork
var isAllSubnetworks bool
err := readElement(r, &isAllSubnetworks)
msg.SubnetworkID = nil
err := readElement(r, &msg.IncludeAllSubnetworks)
if err != nil {
return err
}
if isAllSubnetworks {
msg.SubnetworkID = nil
} else {
var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID)
if !msg.IncludeAllSubnetworks {
var isFullNode bool
err := readElement(r, &isFullNode)
if err != nil {
return err
}
msg.SubnetworkID = &subnetworkID
if !isFullNode {
var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID)
if err != nil {
return err
}
msg.SubnetworkID = &subnetworkID
}
}
// Read addresses array
@ -114,17 +121,24 @@ func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error {
return messageError("MsgAddr.BtcEncode", str)
}
// Write subnetwork ID
isAllSubnetworks := msg.SubnetworkID == nil
err := writeElement(w, isAllSubnetworks)
err := writeElement(w, msg.IncludeAllSubnetworks)
if err != nil {
return err
}
if !isAllSubnetworks {
err = writeElement(w, msg.SubnetworkID)
if !msg.IncludeAllSubnetworks {
// Write subnetwork ID
isFullNode := msg.SubnetworkID == nil
err = writeElement(w, isFullNode)
if err != nil {
return err
}
if !isFullNode {
err = writeElement(w, msg.SubnetworkID)
if err != nil {
return err
}
}
}
err = WriteVarInt(w, pver, uint64(count))
@ -151,15 +165,16 @@ func (msg *MsgAddr) Command() string {
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgAddr) MaxPayloadLength(pver uint32) uint32 {
// IsAllSubnetworks flag 1 byte + SubnetworkID length + Num addresses (varInt) + max allowed addresses.
return 1 + subnetworkid.IDLength + MaxVarIntPayload + (MaxAddrPerMsg * maxNetAddressPayload(pver))
// IncludeAllSubnetworks flag 1 byte + isFullNode 1 byte + SubnetworkID length + Num addresses (varInt) + max allowed addresses.
return 1 + 1 + subnetworkid.IDLength + MaxVarIntPayload + (MaxAddrPerMsg * maxNetAddressPayload(pver))
}
// NewMsgAddr returns a new bitcoin addr message that conforms to the
// Message interface. See MsgAddr for details.
func NewMsgAddr(subnetworkID *subnetworkid.SubnetworkID) *MsgAddr {
func NewMsgAddr(includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) *MsgAddr {
return &MsgAddr{
SubnetworkID: subnetworkID,
AddrList: make([]*NetAddress, 0, MaxAddrPerMsg),
IncludeAllSubnetworks: includeAllSubnetworks,
SubnetworkID: subnetworkID,
AddrList: make([]*NetAddress, 0, MaxAddrPerMsg),
}
}

View File

@ -22,7 +22,7 @@ func TestAddr(t *testing.T) {
// Ensure the command is expected value.
wantCmd := "addr"
msg := NewMsgAddr(nil)
msg := NewMsgAddr(false, nil)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgAddr: wrong command - got %v want %v",
cmd, wantCmd)
@ -30,7 +30,7 @@ func TestAddr(t *testing.T) {
// Ensure max payload is expected value for latest protocol version.
// Num addresses (varInt) + max allowed addresses.
wantPayload := uint32(34030)
wantPayload := uint32(34031)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
@ -92,14 +92,15 @@ func TestAddrWire(t *testing.T) {
}
// Empty address message.
noAddr := NewMsgAddr(nil)
noAddr := NewMsgAddr(false, nil)
noAddrEncoded := []byte{
0x01, // All subnetworks
0x00, // All subnetworks
0x01, // Is full node
0x00, // Varint for number of addresses
}
// Address message with multiple addresses.
multiAddr := NewMsgAddr(nil)
multiAddr := NewMsgAddr(true, nil)
multiAddr.AddAddresses(na, na2)
multiAddrEncoded := []byte{
0x01, // All subnetworks
@ -117,11 +118,12 @@ func TestAddrWire(t *testing.T) {
}
// Address message with multiple addresses and subnetworkID.
multiAddrSubnet := NewMsgAddr(subnetworkid.SubnetworkIDNative)
multiAddrSubnet := NewMsgAddr(false, subnetworkid.SubnetworkIDNative)
multiAddrSubnet.AddAddresses(na, na2)
multiAddrSubnetEncoded := []byte{
0x00, // All subnetworks
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Subnetwork ID
0x00, // Is full node
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Subnetwork ID
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x02, // Varint for number of addresses
@ -220,7 +222,7 @@ func TestAddrWireErrors(t *testing.T) {
}
// Address message with multiple addresses.
baseAddr := NewMsgAddr(nil)
baseAddr := NewMsgAddr(false, nil)
baseAddr.AddAddresses(na, na2)
baseAddrEncoded := []byte{
0x01, // All subnetworks
@ -239,7 +241,7 @@ func TestAddrWireErrors(t *testing.T) {
// Message that forces an error by having more than the max allowed
// addresses.
maxAddr := NewMsgAddr(nil)
maxAddr := NewMsgAddr(false, nil)
for i := 0; i < MaxAddrPerMsg; i++ {
maxAddr.AddAddress(na)
}

View File

@ -586,7 +586,7 @@ var blockOneBytes = []byte{
0xee, // 65-byte uncompressed public key
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // SubnetworkID
}

View File

@ -17,45 +17,67 @@ import (
//
// This message has no payload.
type MsgGetAddr struct {
SubnetworkID *subnetworkid.SubnetworkID
IncludeAllSubnetworks bool
SubnetworkID *subnetworkid.SubnetworkID
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
var isAllSubnetworks bool
err := readElement(r, &isAllSubnetworks)
msg.SubnetworkID = nil
err := readElement(r, &msg.IncludeAllSubnetworks)
if err != nil {
return err
}
if isAllSubnetworks {
msg.SubnetworkID = nil
} else {
var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID)
if err != nil {
return err
}
msg.SubnetworkID = &subnetworkID
if msg.IncludeAllSubnetworks {
return nil
}
var isFullNode bool
err = readElement(r, &isFullNode)
if err != nil {
return err
}
if isFullNode {
return nil
}
var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID)
if err != nil {
return err
}
msg.SubnetworkID = &subnetworkID
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error {
isAllSubnetworks := msg.SubnetworkID == nil
err := writeElement(w, isAllSubnetworks)
err := writeElement(w, msg.IncludeAllSubnetworks)
if err != nil {
return err
}
if !isAllSubnetworks {
if msg.IncludeAllSubnetworks {
return nil
}
isFullNode := msg.SubnetworkID == nil
err = writeElement(w, isFullNode)
if err != nil {
return err
}
if !isFullNode {
err = writeElement(w, msg.SubnetworkID)
if err != nil {
return err
}
}
return nil
}
@ -68,13 +90,15 @@ func (msg *MsgGetAddr) Command() string {
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetAddr) MaxPayloadLength(pver uint32) uint32 {
return subnetworkid.IDLength + 1
// SubnetworkID length + IncludeAllSubnetworks (1) + isFullNode (1)
return subnetworkid.IDLength + 2
}
// NewMsgGetAddr returns a new bitcoin getaddr message that conforms to the
// Message interface. See MsgGetAddr for details.
func NewMsgGetAddr(subnetworkID *subnetworkid.SubnetworkID) *MsgGetAddr {
func NewMsgGetAddr(includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) *MsgGetAddr {
return &MsgGetAddr{
SubnetworkID: subnetworkID,
IncludeAllSubnetworks: includeAllSubnetworks,
SubnetworkID: subnetworkID,
}
}

View File

@ -19,7 +19,7 @@ func TestGetAddr(t *testing.T) {
// Ensure the command is expected value.
wantCmd := "getaddr"
msg := NewMsgGetAddr(nil)
msg := NewMsgGetAddr(false, nil)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgGetAddr: wrong command - got %v want %v",
cmd, wantCmd)
@ -27,7 +27,7 @@ func TestGetAddr(t *testing.T) {
// Ensure max payload is expected value for latest protocol version.
// Num addresses (varInt) + max allowed addresses.
wantPayload := uint32(21)
wantPayload := uint32(22)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
@ -40,16 +40,18 @@ func TestGetAddr(t *testing.T) {
// protocol versions.
func TestGetAddrWire(t *testing.T) {
// With all subnetworks
msgGetAddr := NewMsgGetAddr(nil)
msgGetAddr := NewMsgGetAddr(false, nil)
msgGetAddrEncoded := []byte{
0x01, // All subnetworks
0x00, // All subnetworks
0x01, // Get full nodes
}
// With specific subnetwork
msgGetAddrSubnet := NewMsgGetAddr(subnetworkid.SubnetworkIDNative)
msgGetAddrSubnet := NewMsgGetAddr(false, subnetworkid.SubnetworkIDNative)
msgGetAddrSubnetEncoded := []byte{
0x00, // All subnetworks
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Subnetwork ID
0x00, // Is all subnetworks
0x00, // Is full node
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Subnetwork ID
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
}

View File

@ -534,11 +534,6 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
return err
}
if msg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) {
str := fmt.Sprintf("%s is a reserved sub network and cannot be used as part of a transaction", msg.SubnetworkID)
return messageError("MsgTx.BtcDecode", str)
}
if !msg.SubnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) {
msg.Gas, err = binaryserializer.Uint64(r, littleEndian)
if err != nil {
@ -843,7 +838,7 @@ func (msg *MsgTx) PkScriptLocs() []int {
// 2. The native subnetwork
// 3. The transaction's subnetwork
func (msg *MsgTx) IsSubnetworkCompatible(subnetworkID *subnetworkid.SubnetworkID) bool {
return subnetworkID.IsEqual(subnetworkid.SubnetworkIDSupportsAll) ||
return subnetworkID == nil ||
subnetworkID.IsEqual(subnetworkid.SubnetworkIDNative) ||
subnetworkID.IsEqual(&msg.SubnetworkID)
}

View File

@ -129,7 +129,7 @@ func TestTx(t *testing.T) {
// TestTxHash tests the ability to generate the hash of a transaction accurately.
func TestTxHashAndID(t *testing.T) {
txID1Str := "2d0dd1e05410fe76afbd90f577f615d603ca00b2fa53f963e6375ce742343faa"
txID1Str := "5b92e6ed52bc78745905e0d104069e46407f62ea8d7d2bce78cd13f80ce220dc"
wantTxID1, err := daghash.NewTxIDFromStr(txID1Str)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
@ -263,7 +263,7 @@ func TestTxWire(t *testing.T) {
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
}
@ -392,7 +392,7 @@ func TestTxSerialize(t *testing.T) {
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
}
@ -403,7 +403,7 @@ func TestTxSerialize(t *testing.T) {
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
@ -617,29 +617,6 @@ func TestTxSerializeErrors(t *testing.T) {
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err)
}
zeroSubnetworkTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
0x08, // Payload length varint
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Payload / Gas limit
}
r := bytes.NewReader(zeroSubnetworkTxEncoded)
var tx MsgTx
err = tx.Deserialize(r)
str = fmt.Sprintf("%v is a reserved sub network and cannot be used as part of a transaction", subnetworkid.SubnetworkIDSupportsAll)
expectedErr = messageError("MsgTx.BtcDecode", str)
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err)
}
}
// TestTxOverflowErrors performs tests to ensure deserializing transactions
@ -770,11 +747,6 @@ func TestIsSubnetworkCompatible(t *testing.T) {
subnetworkID *subnetworkid.SubnetworkID
expectedResult bool
}{
{
name: "SupportsAll subnetwork",
subnetworkID: subnetworkid.SubnetworkIDSupportsAll,
expectedResult: true,
},
{
name: "Native subnetwork",
subnetworkID: subnetworkid.SubnetworkIDNative,
@ -960,7 +932,7 @@ var multiTxEncoded = []byte{
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
}

View File

@ -59,8 +59,8 @@ type MsgVersion struct {
// Don't announce transactions to peer.
DisableRelayTx bool
// The subnetwork of the generator of the version message.
SubnetworkID subnetworkid.SubnetworkID
// The subnetwork of the generator of the version message. Should be nil in full nodes
SubnetworkID *subnetworkid.SubnetworkID
}
// HasService returns whether the specified service is supported by the peer
@ -95,10 +95,22 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
return err
}
err = readElement(buf, &msg.SubnetworkID)
// Read subnetwork ID
var isFullNode bool
err = readElement(r, &isFullNode)
if err != nil {
return err
}
if isFullNode {
msg.SubnetworkID = nil
} else {
var subnetworkID subnetworkid.SubnetworkID
err = readElement(r, &subnetworkID)
if err != nil {
return err
}
msg.SubnetworkID = &subnetworkID
}
err = readNetAddress(buf, pver, &msg.AddrYou, false)
if err != nil {
@ -153,10 +165,18 @@ func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
return err
}
err = writeElement(w, msg.SubnetworkID)
// Write subnetwork ID
isFullNode := msg.SubnetworkID == nil
err = writeElement(w, isFullNode)
if err != nil {
return err
}
if !isFullNode {
err = writeElement(w, msg.SubnetworkID)
if err != nil {
return err
}
}
err = writeNetAddress(w, pver, &msg.AddrYou, false)
if err != nil {
@ -229,7 +249,7 @@ func NewMsgVersion(me *NetAddress, you *NetAddress, nonce uint64,
UserAgent: DefaultUserAgent,
SelectedTip: selectedTip,
DisableRelayTx: false,
SubnetworkID: *subnetworkID,
SubnetworkID: subnetworkID,
}
}

View File

@ -15,7 +15,6 @@ import (
"github.com/daglabs/btcd/dagconfig/daghash"
"github.com/daglabs/btcd/util/random"
"github.com/daglabs/btcd/util/subnetworkid"
"github.com/davecgh/go-spew/spew"
)
@ -35,7 +34,7 @@ func TestVersion(t *testing.T) {
}
// Ensure we get the correct data back out.
msg := NewMsgVersion(me, you, nonce, selectedTip, subnetworkid.SubnetworkIDSupportsAll)
msg := NewMsgVersion(me, you, nonce, selectedTip, nil)
if msg.ProtocolVersion != int32(pver) {
t.Errorf("NewMsgVersion: wrong protocol version - got %v, want %v",
msg.ProtocolVersion, pver)
@ -225,10 +224,10 @@ func TestVersionWireErrors(t *testing.T) {
newLen := len(baseVersionEncoded) - len(baseVersion.UserAgent)
newLen = newLen + len(newUAVarIntBuf.Bytes()) - 1 + len(newUA)
exceedUAVerEncoded := make([]byte, newLen)
copy(exceedUAVerEncoded, baseVersionEncoded[0:100])
copy(exceedUAVerEncoded[100:], newUAVarIntBuf.Bytes())
copy(exceedUAVerEncoded[103:], []byte(newUA))
copy(exceedUAVerEncoded[103+len(newUA):], baseVersionEncoded[117:120])
copy(exceedUAVerEncoded, baseVersionEncoded[0:81])
copy(exceedUAVerEncoded[81:], newUAVarIntBuf.Bytes())
copy(exceedUAVerEncoded[84:], []byte(newUA))
copy(exceedUAVerEncoded[84+len(newUA):], baseVersionEncoded[98:101])
tests := []struct {
in *MsgVersion // Value to encode
@ -247,17 +246,17 @@ func TestVersionWireErrors(t *testing.T) {
// Force error in subnetworkID.
{baseVersion, baseVersionEncoded, pver, 20, io.ErrShortWrite, io.EOF},
// Force error in remote address.
{baseVersion, baseVersionEncoded, pver, 40, io.ErrShortWrite, io.EOF},
{baseVersion, baseVersionEncoded, pver, 21, io.ErrShortWrite, io.EOF},
// Force error in local address.
{baseVersion, baseVersionEncoded, pver, 67, io.ErrShortWrite, io.ErrUnexpectedEOF},
{baseVersion, baseVersionEncoded, pver, 48, io.ErrShortWrite, io.ErrUnexpectedEOF},
// Force error in nonce.
{baseVersion, baseVersionEncoded, pver, 93, io.ErrShortWrite, io.ErrUnexpectedEOF},
{baseVersion, baseVersionEncoded, pver, 74, io.ErrShortWrite, io.ErrUnexpectedEOF},
// Force error in user agent length.
{baseVersion, baseVersionEncoded, pver, 101, io.ErrShortWrite, io.EOF},
{baseVersion, baseVersionEncoded, pver, 82, io.ErrShortWrite, io.EOF},
// Force error in user agent.
{baseVersion, baseVersionEncoded, pver, 102, io.ErrShortWrite, io.ErrUnexpectedEOF},
{baseVersion, baseVersionEncoded, pver, 83, io.ErrShortWrite, io.ErrUnexpectedEOF},
// Force error in last block.
{baseVersion, baseVersionEncoded, pver, 118, io.ErrShortWrite, io.ErrUnexpectedEOF},
{baseVersion, baseVersionEncoded, pver, 99, io.ErrShortWrite, io.ErrUnexpectedEOF},
// Force error due to user agent too big
{exceedUAVer, exceedUAVerEncoded, pver, newLen, wireErr, wireErr},
}
@ -333,9 +332,7 @@ var baseVersionEncoded = []byte{
0x62, 0xea, 0x00, 0x00, // Protocol version 60002
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // SubnetworkIDSupportsAll
0x01, // is full node
// AddrYou -- No timestamp for NetAddress in version message
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -384,9 +381,7 @@ var baseVersionWithRelayTxEncoded = []byte{
0x71, 0x11, 0x01, 0x00, // Protocol version 70001
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // SubnetworkIDSupportsAll
0x01, // is full node
// AddrYou -- No timestamp for NetAddress in version message
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,