From 7c30bc4301357619bfd2580f0f980535a6626a8a Mon Sep 17 00:00:00 2001 From: Evgeny Khirin <32414982+evgeny-khirin@users.noreply.github.com> Date: Wed, 3 Apr 2019 17:03:48 +0300 Subject: [PATCH] [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 --- addrmgr/addrmanager.go | 385 ++++++++++++++++++++++-------- addrmgr/addrmanager_test.go | 34 +-- blockdag/accept_test.go | 4 +- blockdag/blockindex_test.go | 4 +- blockdag/dag.go | 3 - blockdag/dag_test.go | 29 +-- blockdag/dagio.go | 10 +- blockdag/example_test.go | 10 +- blockdag/external_dag_test.go | 12 +- blockdag/indexers/txindex_test.go | 2 - blockdag/notifications_test.go | 4 +- blockdag/test_utils.go | 4 - blockdag/testdata/blk_0_to_4.dat | Bin 1788 -> 1788 bytes blockdag/testdata/blk_3A.dat | Bin 425 -> 425 bytes blockdag/testdata/blk_3B.dat | Bin 312 -> 312 bytes blockdag/testdata/blk_3C.dat | Bin 344 -> 344 bytes blockdag/testdata/blk_3D.dat | Bin 470 -> 470 bytes blockdag/validate.go | 2 +- blockdag/validate_test.go | 22 +- btcjson/dagsvrwsntfns_test.go | 4 +- cmd/genesis/genesis.go | 36 ++- config/config.go | 8 +- config/config_test.go | 8 +- connmgr/seed.go | 12 +- dagconfig/genesis.go | 32 +-- dagconfig/genesis_test.go | 22 +- database/testdata/blocks1-256.bz2 | Bin 9964 -> 9924 bytes database/testdata/generator.go | 4 +- dnsseeder/dns.go | 34 +-- dnsseeder/dnsseed.go | 8 +- dnsseeder/manager.go | 4 +- mempool/mempool.go | 7 +- mempool/mempool_test.go | 3 +- peer/example_test.go | 5 +- peer/peer.go | 7 +- peer/peer_test.go | 22 +- server/p2p/p2p.go | 31 ++- server/rpc/rpcserver.go | 14 +- server/rpc/rpcwebsocket.go | 2 +- util/block_test.go | 8 +- util/bloom/filter_test.go | 39 +-- util/bloom/merkleblock_test.go | 12 +- util/coinset/coins_test.go | 4 +- util/subnetworkid/subnetworkid.go | 7 +- util/tx_test.go | 4 +- util/txsort/testdata/bip69-1.hex | 2 +- util/txsort/testdata/bip69-2.hex | 2 +- util/txsort/testdata/bip69-3.hex | 2 +- util/txsort/testdata/bip69-4.hex | 2 +- util/txsort/testdata/bip69-5.hex | 2 +- util/txsort/txsort_test.go | 20 +- wire/bench_test.go | 2 +- wire/message_test.go | 15 +- wire/msgaddr.go | 57 +++-- wire/msgaddr_test.go | 20 +- wire/msgblock_test.go | 2 +- wire/msggetaddr.go | 60 +++-- wire/msggetaddr_test.go | 16 +- wire/msgtx.go | 7 +- wire/msgtx_test.go | 38 +-- wire/msgversion.go | 30 ++- wire/msgversion_test.go | 31 +-- 62 files changed, 686 insertions(+), 484 deletions(-) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index 22bb8f971..2e523843a 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -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 diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index 4a9f90480..84e97cfb6 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -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 { diff --git a/blockdag/accept_test.go b/blockdag/accept_test.go index d9c9d12b3..5fa153f92 100644 --- a/blockdag/accept_test.go +++ b/blockdag/accept_test.go @@ -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) diff --git a/blockdag/blockindex_test.go b/blockdag/blockindex_test.go index cd7c7df38..63e14b31b 100644 --- a/blockdag/blockindex_test.go +++ b/blockdag/blockindex_test.go @@ -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) diff --git a/blockdag/dag.go b/blockdag/dag.go index ddd2aa00a..93f3955bd 100644 --- a/blockdag/dag.go +++ b/blockdag/dag.go @@ -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. diff --git a/blockdag/dag_test.go b/blockdag/dag_test.go index cddb97a4c..a9492c601 100644 --- a/blockdag/dag_test.go +++ b/blockdag/dag_test.go @@ -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 . 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: ¶ms, - SubnetworkID: subnetworkid.SubnetworkIDSupportsAll, + DAGParams: ¶ms, }) if err != nil { t.Fatalf("Failed to setup DAG instance: %v", err) diff --git a/blockdag/dagio.go b/blockdag/dagio.go index c78074ba7..bfe47baf8 100644 --- a/blockdag/dagio.go +++ b/blockdag/dagio.go @@ -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"+ diff --git a/blockdag/example_test.go b/blockdag/example_test.go index 335b526e0..b38277fbc 100644 --- a/blockdag/example_test.go +++ b/blockdag/example_test.go @@ -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 } diff --git a/blockdag/external_dag_test.go b/blockdag/external_dag_test.go index 3d5030dc5..c465928b3 100644 --- a/blockdag/external_dag_test.go +++ b/blockdag/external_dag_test.go @@ -38,8 +38,7 @@ func TestFinality(t *testing.T) { params := dagconfig.SimNetParams params.K = 1 dag, teardownFunc, err := blockdag.DAGSetup("TestFinality", blockdag.Config{ - DAGParams: ¶ms, - SubnetworkID: subnetworkid.SubnetworkIDSupportsAll, + DAGParams: ¶ms, }) 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: ¶ms, - SubnetworkID: subnetworkid.SubnetworkIDSupportsAll, + DAGParams: ¶ms, }) 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: ¶ms, - SubnetworkID: subnetworkid.SubnetworkIDSupportsAll, + DAGParams: ¶ms, }) 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: ¶ms, - SubnetworkID: subnetworkid.SubnetworkIDSupportsAll, + DAGParams: ¶ms, }) if err != nil { t.Fatalf("Failed to setup DAG instance: %v", err) diff --git a/blockdag/indexers/txindex_test.go b/blockdag/indexers/txindex_test.go index 97fa21269..f6fed8f8b 100644 --- a/blockdag/indexers/txindex_test.go +++ b/blockdag/indexers/txindex_test.go @@ -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: ¶ms, - SubnetworkID: subnetworkid.SubnetworkIDSupportsAll, } dag, teardown, err := blockdag.DAGSetup("TestTxIndexConnectBlock", config) diff --git a/blockdag/notifications_test.go b/blockdag/notifications_test.go index 279ebf094..111b0b538 100644 --- a/blockdag/notifications_test.go +++ b/blockdag/notifications_test.go @@ -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) diff --git a/blockdag/test_utils.go b/blockdag/test_utils.go index b2e68fc54..e6a9280ff 100644 --- a/blockdag/test_utils.go +++ b/blockdag/test_utils.go @@ -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) diff --git a/blockdag/testdata/blk_0_to_4.dat b/blockdag/testdata/blk_0_to_4.dat index 1c7af6f107fdbee9d085314b91d65179aad31549..89de5696fa04c55e26eecf82df8b92a6d7338caa 100644 GIT binary patch literal 1788 zcmeylZ_CYt3=9m6K+JIEPWO(o@VT`w=dQc`L+KLlq6fS8z1?to*J}x1C&vG8=Ms`% zID0`1$ejQG>lN5Q3?N_xnG7}^%*8?c2Le6@25$WTqhJsHq>|(meUK0cFfx2%)dCw5 zh(j}2_$SaK1`vA$7&*=qUwBXu^ov1Wn<@RV|1I-Une-*Op?VY6@Jrgam8aM%Wvs9% zbJ_Ci(mzqfgRzHr))z8Q-a1YFP-TJODRFB@Lh_4{Jjw)h6%+9u4Gg5fqhMv(KuFYk0<0U`OtNZ|%^6*KYS78FEjxDoOoD8Psd zH?XVcwyrt;x@)1mn%?=7LACFv_cYIQ%S^h!_KIM_2BD0R|oa3$kD@FU_md>3ox9;e4Gt~$CR^1{bzXU0wAc=#4 zfrN+(4yH7s2zijih`P>^ZJxGzE*q!Bx%`;T7hWA%`tq+1Kfm>qI|~xDW&~}ZSwxjb z&kl{&4+y?Er!-@;HFH=|>JruLJwnr(g`8_71vQu%-OpxeiAFqe6q3kD@_PA7otMLO zri`TC70%mtXWTqVP<|;=M6p1V4G9qy5<+Q25%M635w*;);`5%rYV&`p@o+I3)=ye~ Wq^{c0F6!8B&Vb|<>)z^6Gok?QkTh}t literal 1788 zcmeylZ_CYt3=9m6K+I64ZM@RwikYxx-0Y0)YqiB{k~U0s51_8-}y*#{(qMhyKIt}z(I!IjZ?Slk3G7Cg6LHZXAMphSQs7arHH16} zvIZCp5CC@zu5eoj3peK78$O@i+!$Er|8c^_NX3wC+J!dqomYxH^$b6#7QgqMW5l)p zWB0s`0!63q^oH}k584q>Ba`{_qn3O75|t{ILPGNIkire-7-q1C;BLgh0QrP3D2UQ< zBjiDlHN=G**wtwdE;jATKYJ(n{<&B4ET8QA_vG8|mmbG{ebcT^Sm~D82=)xfOb~!4 zWXZCXBDU|`3-fG#h2M7-G$~$YsJCz3XTgp&Fweun2F3@`pac$&sL6rTqP1=@PoEbi z$n|%}-V*lTcQ)$KP^%$ z=k7R^NJ#!YWf2t|Old?B@*pTcNr))1#|7dEe_J+QP1&XS#5K_HV$^dP^{oCAYzu4F zFrF;g1P*ABnIJ&Th&ngr`or1fXL9OW@0Ur~*qm+P6*wWWaoWUdKl+30ojI-keJ*H; zpLQ=v`PcrpEvx_V8MA+VqHJo@>*~Yu-RP!i1tIwlltolX2&EB4$b+B&B_X1sg5!dG k)|X_h-*m*ZbYZg0rJea_%4+#f2YoA#xMX^>l$sF*0M=YV6951J diff --git a/blockdag/testdata/blk_3A.dat b/blockdag/testdata/blk_3A.dat index e8ea33276fc978c5e7ec48cd7192dc37d1d82115..1e5fc5fab04e70bb20ea83a318893eab5a54157d 100644 GIT binary patch literal 425 zcmeylZ_CYvj0_+k!058TY3;EqZszZsl$;;kEIOlbM|1aY`IqTB=i(}wn(x*t{7PS= zJ=6dCd4^+Jb5_`_aX)RvKH-?crwiI;2Ip>GkWK&p*DHW%5MTyb4sigO zkDd4r1bo4v-1-4V!5;caCCMrJAR!Q7Wcb9Y1vVrQyIzPWSOp;ug3JTD4g&C*26i#y zb&hQFwAFLjI3>>I$85gv>d4ZUe|7lzt*6{skf1dqXam>;m~n7-N|vn@v3=)Wm}m1V W{JyK8N%1m6y?yIG3wEr*XCnX+xQv_t literal 425 zcmeylZ_CYvj0_+kz&JT@TC~euEPQ>e zBj>;;Po<`!rxhmLk$#Kj@l4Y>vh8n`(GIOGGYQGRUvCowvg!Z-dIb;-0?Z)GAr1iZ zu@nD+fG;?dTR*@k*h4?5BsoPNBm@GC44+uFz=j0E^kOp(tb&jSLFNHn2LUkCu(}Rx zoY><6@r1uE8?UD9(tP3?Xm~N|xr};N{|UB*HES48mTUr>05cBmPRX*BBDU|`3-fG# Zh2M7-G$~$YsJCz3XTgp&FdMPC9{}KIi^u=~ diff --git a/blockdag/testdata/blk_3B.dat b/blockdag/testdata/blk_3B.dat index b19494ee26eee7705af8453bc8cf33d6dd45a618..2943601ace52054e685603385a04a8b7de156bba 100644 GIT binary patch literal 312 zcmeylZ_7;sMg|ZNV02mFwD#B)H}m&RO3sgN7M)SJqq+OH{L6Hmb8!_-&3Ee+*ZcAM z{ulS!o>#r+wL<26?wy~eO{xl58KjXmAjmwR>mUH1X$$~K C(quXS literal 312 zcmeylZ_7;sMg|ZNV4NH{En4dq^YnRPf?R)h>@D#xDJ)o6u=V|ie>L&4C+`J1s3mM& zw%p_AiS0Rmq!~BMiK#4#+m>{x(_T;ZKv+)6dqVQ>*W1K^Z2JGdUI9dd029b^hy%cU z?8JW{;0q4p)(*A&tgZt9 D8JT4G diff --git a/blockdag/testdata/blk_3C.dat b/blockdag/testdata/blk_3C.dat index bb0c2bd9769a3b23c2ee76ee36f5a089c88a063b..9fae07493a5c7186987124b3f306bb057b4a6997 100644 GIT binary patch literal 344 zcmeylZ_CX9Mg|ZNU^2ZE=6FCWcC+B8VBt-T^E1sJ*&i!@u`$zn2B!nlp9L{43!K&- zyW(d4zDddX(aoYW3U@Sj|CWE5u5&J~qN(|A{ojHdmK-WP4KGPTgSQ2^E literal 344 zcmeylZ_CX9Mg|ZNU}E0A;q%$eje&LkA17RlR1DdsU1%fUd8Nox&+vn4@q6FNfzzV3 zZZS`v7beK{cgNlm|B}Ljg#}yRfB07uFMIM{pvvY89ge9w#Ze04m6{fgJ!*$k&OKye z5pp&DoBjS()i*-&@7LSJfL!wbf4u@LhyeslAjd%*2bY diff --git a/blockdag/testdata/blk_3D.dat b/blockdag/testdata/blk_3D.dat index afc7a6d9bccfff93d09f04e9f985a234314e5297..437ae05b194bb8cc29fe951b3b77d0ea0f31ba58 100644 GIT binary patch literal 470 zcmeylZ_CYdj0_+k!058TY3;EqZszZsl$;;kEIOlbM|1aY`IqTB=i(}wn(x-%&{_3f zne+463YXk}!fz*?vW{LF%Q`zL?&IF=+s<;e*b$OnGJ8P`$fp1Q>lHvW2rz>zhd2Pt z$4>kQ0>0n~Zv6nGU=RJIlH?S9kPrwkGJImy0vi&DT`xowtb&jSLFNHn2Lbp@1G|{% zI!Cs7+UmJ%oD%2qV>VxSb!6$wzdHQ<)>G~*NYI)Qv;k}a%s7%1!#yQgwo=6QoqJ)P Y&9CtLu7W1T%MA7Qt@|w4u?C;>0367r(EtDd literal 470 zcmeylZ_CYdj0_+kz&JT@TC~f>9sfrE zj1AWp-uBMYY4yLXelwNMxFEMPt@z3%*~Yo1cL~YAUvCowvg!Z-dIgA`3=GU528;ue z#0vfc0bg(gw|;<8u!nw9NpgxlNC*TN89uRUfei_SX~kw7SOp;ug3JTD4gz4NVRaqI zI3}^j1>y;RTQ*)z*`@i!HPG;4)N>j2to{>h3v1Reo-Ek}HUVZFNs8f~k}O*(V*Ad$ dFwf>!_h diff --git a/blockdag/validate.go b/blockdag/validate.go index 37c5bacc5..e699e1bc9 100644 --- a/blockdag/validate.go +++ b/blockdag/validate.go @@ -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 { diff --git a/blockdag/validate_test.go b/blockdag/validate_test.go index 35e6a7f5e..5beeffbcc 100644 --- a/blockdag/validate_test.go +++ b/blockdag/validate_test.go @@ -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, diff --git a/btcjson/dagsvrwsntfns_test.go b/btcjson/dagsvrwsntfns_test.go index c4514f9e7..5899f007d 100644 --- a/btcjson/dagsvrwsntfns_test.go +++ b/btcjson/dagsvrwsntfns_test.go @@ -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", diff --git a/cmd/genesis/genesis.go b/cmd/genesis/genesis.go index 3c9010069..c8d63fa0c 100644 --- a/cmd/genesis/genesis.go +++ b/cmd/genesis/genesis.go @@ -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") } diff --git a/config/config.go b/config/config.go index d5a6d905f..00da90755 100644 --- a/config/config.go +++ b/config/config.go @@ -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) diff --git a/config/config_test.go b/config/config_test.go index 34cdddec1..f08571e0c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -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") } } diff --git a/connmgr/seed.go b/connmgr/seed.go index b80abca9f..d112fe84b 100644 --- a/connmgr/seed.go +++ b/connmgr/seed.go @@ -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) { diff --git a/dagconfig/genesis.go b/dagconfig/genesis.go index c9ddac904..396d63c0c 100644 --- a/dagconfig/genesis.go +++ b/dagconfig/genesis.go @@ -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}, } diff --git a/dagconfig/genesis_test.go b/dagconfig/genesis_test.go index a4fbe2b31..184d0c35b 100644 --- a/dagconfig/genesis_test.go +++ b/dagconfig/genesis_test.go @@ -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, diff --git a/database/testdata/blocks1-256.bz2 b/database/testdata/blocks1-256.bz2 index 32c41683f35901e959766d9c21ea4bd7f5e33140..9f05e5bbf1b24c0fa321ff5c23327c09d9841101 100644 GIT binary patch literal 9924 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 K^a-Ut=>GuZWRU6r diff --git a/database/testdata/generator.go b/database/testdata/generator.go index 41d52688b..86879c20e 100644 --- a/database/testdata/generator.go +++ b/database/testdata/generator.go @@ -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, diff --git a/dnsseeder/dns.go b/dnsseeder/dns.go index 455458315..ad6af2ea9 100644 --- a/dnsseeder/dns.go +++ b/dnsseeder/dns.go @@ -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 } diff --git a/dnsseeder/dnsseed.go b/dnsseeder/dnsseed.go index bc3028c23..381f92b98 100644 --- a/dnsseeder/dnsseed.go +++ b/dnsseeder/dnsseed.go @@ -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() diff --git a/dnsseeder/manager.go b/dnsseeder/manager.go index a58ed5e70..68f269402 100644 --- a/dnsseeder/manager.go +++ b/dnsseeder/manager.go @@ -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 } diff --git a/mempool/mempool.go b/mempool/mempool.go index ca0e2a1d9..80ac698c7 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -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 diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index c410db42c..f5f1764ae 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -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) diff --git a/peer/example_test.go b/peer/example_test.go index ae2e0ad08..35c7ef427 100644 --- a/peer/example_test.go +++ b/peer/example_test.go @@ -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 { diff --git a/peer/peer.go b/peer/peer.go index 31fbe8529..c1ac7a282 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -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)) { diff --git a/peer/peer_test.go b/peer/peer_test.go index cf9d7b6f1..ca0b8f639 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -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( diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index a3b8f6aec..ee9518759 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -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) } diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index d0d19df1b..aeaf817ba 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -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.", diff --git a/server/rpc/rpcwebsocket.go b/server/rpc/rpcwebsocket.go index a034bda66..57caba709 100644 --- a/server/rpc/rpcwebsocket.go +++ b/server/rpc/rpcwebsocket.go @@ -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, diff --git a/util/block_test.go b/util/block_test.go index 6e767fd1c..2ce205c8b 100644 --- a/util/block_test.go +++ b/util/block_test.go @@ -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. diff --git a/util/bloom/filter_test.go b/util/bloom/filter_test.go index 34f8c33a6..6b5da3a19 100644 --- a/util/bloom/filter_test.go +++ b/util/bloom/filter_test.go @@ -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) diff --git a/util/bloom/merkleblock_test.go b/util/bloom/merkleblock_test.go index d848847c9..2a0db1a32 100644 --- a/util/bloom/merkleblock_test.go +++ b/util/bloom/merkleblock_test.go @@ -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 { diff --git a/util/coinset/coins_test.go b/util/coinset/coins_test.go index 0e75538a4..1e541dbcb 100644 --- a/util/coinset/coins_test.go +++ b/util/coinset/coins_test.go @@ -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" diff --git a/util/subnetworkid/subnetworkid.go b/util/subnetworkid/subnetworkid.go index 49019e288..d07f50b86 100644 --- a/util/subnetworkid/subnetworkid.go +++ b/util/subnetworkid/subnetworkid.go @@ -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 diff --git a/util/tx_test.go b/util/tx_test.go index 5bdf5d838..ee213d556 100644 --- a/util/tx_test.go +++ b/util/tx_test.go @@ -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++ { diff --git a/util/txsort/testdata/bip69-1.hex b/util/txsort/testdata/bip69-1.hex index a174d71e5..bf9055e9a 100644 --- a/util/txsort/testdata/bip69-1.hex +++ b/util/txsort/testdata/bip69-1.hex @@ -1 +1 @@ -0100000011AAD553BB1650007E9982A8AC79D227CD8C831E1573B11F25573A37664E5F3E64000000006A47304402205438CEDD30EE828B0938A863E08D810526123746C1F4ABEE5B7BC2312373450C02207F26914F4275F8F0040AB3375BACC8C5D610C095DB8ED0785DE5DC57456591A601210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFC26F3EB7932F7ACDDC5DDD26602B77E7516079B03090A16E2C2F5485D1FDE028000000006B483045022100F81D98C1DE9BB61063A5E6671D191B400FDA3A07D886E663799760393405439D0220234303C9AF4BAD3D665F00277FE70CDD26CD56679F114A40D9107249D29C979401210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF456A9E597129F5DF2E11B842833FC19A94C563F57449281D3CD01249A830A1F0000000006A47304402202310B00924794EF68A8F09564FD0BB128838C66BC45D1A3F95C5CAB52680F166022039FC99138C29F6C434012B14ACA651B1C02D97324D6BD9DD0FFCED0782C7E3BD01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF571FB3E02278217852DD5D299947E2B7354A639ADC32EC1FA7B82CFB5DEC530E000000006B483045022100D276251F1F4479D8521269EC8B1B45C6F0E779FCF1658EC627689FA8A55A9CA50220212A1E307E6182479818C543E1B47D62E4FC3CE6CC7FC78183C7071D245839DF01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF5D8DE50362FF33D3526AC3602E9EE25C1A349DEF086A7FC1D9941AAEB9E91D38010000006B4830450221008768EEB1240451C127B88D89047DD387D13357CE5496726FC7813EDC6ACD55AC022015187451C3FB66629AF38FDB061DFB39899244B15C45E4A7CCC31064A059730D01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF60AD3408B89EA19CAF3ABD5E74E7A084344987C64B1563AF52242E9D2A8320F3000000006B4830450221009BE4261EC050EBF33FA3D47248C7086E4C247CAFBB100EA7CEE4AA81CD1383F5022008A70D6402B153560096C849D7DA6FE61C771A60E41FF457AAC30673CECEAFEE01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFE9B483A8AC4129780C88D1BABE41E89DC10A26DEDBF14F80A28474E9A11104DE010000006B4830450221009BC40EEE321B39B5DC26883F79CD1F5A226FC6EED9E79E21D828F4C23190C57E022078182FD6086E265589105023D9EFA4CBA83F38C674A499481BD54EEE196B033F01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFE28DB9462D3004E21E765E03A45ECB147F136A20BA8BCA78BA60EBFC8E2F8B3B000000006A47304402200FB572B7C6916515452E370C2B6F97FCAE54ABE0793D804A5A53E419983FAE1602205191984B6928BF4A1E25B00E5B5569A0CE1ECB82DB2DEA75FE4378673B53B9E801210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF7A1EF65FF1B7B7740C662AB6C9735ACE4A16279C23A1DB5709ED652918FFFF54010000006A47304402206BC218A925F7280D615C8EA4F0131A9F26E7FC64CFF6EEEB44EDB88ABA14F1910220779D5D67231BC2D2D93C3C5AB74DCD193DD3D04023E58709AD7FFBF95161BE6201210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF850CECF958468CA7FFA6A490AFE13B8C271B1326B0DDC1FDFDF9F3C7E365FDBA000000006A473044022047DF98CC26BD2BFDC5B2B97C27AEAD78A214810FF023E721339292D5CE50823D02205FE99DC5F667908974DAE40CC7A9475AF7FA6671BA44F64A00FCD01FA12AB523012102CA46FA75454650AFBA1784BC7B079D687E808634411E4BEFF1F70E44596308A1FFFFFFFFFFFFFFFF8640E312040E476CF6727C60CA3F4A3AD51623500AACDDA96E7728DBDD99E8A5000000006A47304402205566AA84D3D84226D5AB93E6F253B57B3EF37EB09BB73441DAE35DE86271352A02206EE0B7F800F73695A2073A2967C9AD99E19F6DDF18CE877ADF822E408BA9291E01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF91C1889C5C24B93B56E643121F7A05A34C10C5495C450504C7B5AFCB37E11D7A000000006B483045022100DF61D45BBAA4571CDD6C5C822CBA458CDC55285CDF7BA9CD5BB9FC18096DEB9102201CAF8C771204DF7FD7C920C4489DA7BC3A60E1D23C1A97E237C63AFE53250B4A01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF2470947216EB81EA0EEEB4FE19362EC05767DB01C3AA3006BB499E8B6D6EAA26010000006A473044022031501A0B2846B8822A32B9947B058D89D32FC758E009FC2130C2E5EFFC925AF70220574EF3C9E350CEF726C75114F0701FD8B188C6EC5F84ADCE0ED5C393828A5AE001210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF0ABCD77D65CC14363F8262898335F184D6DA5AD060FF9E40BF201741022C2B40010000006B483045022100A6AC110802B699F9A2BFF0EEA252D32E3D572B19214D49D8BB7405EFA2AF28F1022033B7563EB595F6D7ED7EC01734E17B505214FE0851352ED9C3C8120D53268E9A01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFA43BEBBEBF07452A893A95BFEA1D5DB338D23579BE172FE803DCE02EEB7C037D010000006B483045022100EBC77ED0F11D15FE630FE533DC350C2DDC1C81CFEB81D5A27D0587163F58A28C02200983B2A32A1014BAB633BFC9258083AC282B79566B6B3FA45C1E6758610444F401210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFB102113FA46CE949616D9CDA00F6B10231336B3928EAAAC6BFE42D1BF3561D6C010000006A473044022010F8731929A55C1C49610722E965635529ED895B2292D781B183D465799906B20220098359ADCBC669CD4B294CC129B110FE035D2F76517248F4B7129F3BF793D07F01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFB861FAB2CDE188499758346BE46B5FBEC635ADDFC4E7B0C8A07C0A908F2B11B4000000006A47304402207328142BB02EF5D6496A210300F4AEA71F67683B842FA3DF32CAE6C88B49A9BB022020F56DDFF5042260CFDA2C9F39B7DEC858CC2F4A76A987CD2DC25945B04E15FE01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF027064D817000000001976A9144A5FBA237213A062F6F57978F796390BDCF8D01588AC00902F50090000001976A9145BE32612930B8323ADD2212A4EC03C1562084F8488AC00000000000000000100000000000000000000000000000000000000 \ No newline at end of file +0100000011AAD553BB1650007E9982A8AC79D227CD8C831E1573B11F25573A37664E5F3E64000000006A47304402205438CEDD30EE828B0938A863E08D810526123746C1F4ABEE5B7BC2312373450C02207F26914F4275F8F0040AB3375BACC8C5D610C095DB8ED0785DE5DC57456591A601210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFC26F3EB7932F7ACDDC5DDD26602B77E7516079B03090A16E2C2F5485D1FDE028000000006B483045022100F81D98C1DE9BB61063A5E6671D191B400FDA3A07D886E663799760393405439D0220234303C9AF4BAD3D665F00277FE70CDD26CD56679F114A40D9107249D29C979401210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF456A9E597129F5DF2E11B842833FC19A94C563F57449281D3CD01249A830A1F0000000006A47304402202310B00924794EF68A8F09564FD0BB128838C66BC45D1A3F95C5CAB52680F166022039FC99138C29F6C434012B14ACA651B1C02D97324D6BD9DD0FFCED0782C7E3BD01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF571FB3E02278217852DD5D299947E2B7354A639ADC32EC1FA7B82CFB5DEC530E000000006B483045022100D276251F1F4479D8521269EC8B1B45C6F0E779FCF1658EC627689FA8A55A9CA50220212A1E307E6182479818C543E1B47D62E4FC3CE6CC7FC78183C7071D245839DF01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF5D8DE50362FF33D3526AC3602E9EE25C1A349DEF086A7FC1D9941AAEB9E91D38010000006B4830450221008768EEB1240451C127B88D89047DD387D13357CE5496726FC7813EDC6ACD55AC022015187451C3FB66629AF38FDB061DFB39899244B15C45E4A7CCC31064A059730D01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF60AD3408B89EA19CAF3ABD5E74E7A084344987C64B1563AF52242E9D2A8320F3000000006B4830450221009BE4261EC050EBF33FA3D47248C7086E4C247CAFBB100EA7CEE4AA81CD1383F5022008A70D6402B153560096C849D7DA6FE61C771A60E41FF457AAC30673CECEAFEE01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFE9B483A8AC4129780C88D1BABE41E89DC10A26DEDBF14F80A28474E9A11104DE010000006B4830450221009BC40EEE321B39B5DC26883F79CD1F5A226FC6EED9E79E21D828F4C23190C57E022078182FD6086E265589105023D9EFA4CBA83F38C674A499481BD54EEE196B033F01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFE28DB9462D3004E21E765E03A45ECB147F136A20BA8BCA78BA60EBFC8E2F8B3B000000006A47304402200FB572B7C6916515452E370C2B6F97FCAE54ABE0793D804A5A53E419983FAE1602205191984B6928BF4A1E25B00E5B5569A0CE1ECB82DB2DEA75FE4378673B53B9E801210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF7A1EF65FF1B7B7740C662AB6C9735ACE4A16279C23A1DB5709ED652918FFFF54010000006A47304402206BC218A925F7280D615C8EA4F0131A9F26E7FC64CFF6EEEB44EDB88ABA14F1910220779D5D67231BC2D2D93C3C5AB74DCD193DD3D04023E58709AD7FFBF95161BE6201210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF850CECF958468CA7FFA6A490AFE13B8C271B1326B0DDC1FDFDF9F3C7E365FDBA000000006A473044022047DF98CC26BD2BFDC5B2B97C27AEAD78A214810FF023E721339292D5CE50823D02205FE99DC5F667908974DAE40CC7A9475AF7FA6671BA44F64A00FCD01FA12AB523012102CA46FA75454650AFBA1784BC7B079D687E808634411E4BEFF1F70E44596308A1FFFFFFFFFFFFFFFF8640E312040E476CF6727C60CA3F4A3AD51623500AACDDA96E7728DBDD99E8A5000000006A47304402205566AA84D3D84226D5AB93E6F253B57B3EF37EB09BB73441DAE35DE86271352A02206EE0B7F800F73695A2073A2967C9AD99E19F6DDF18CE877ADF822E408BA9291E01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF91C1889C5C24B93B56E643121F7A05A34C10C5495C450504C7B5AFCB37E11D7A000000006B483045022100DF61D45BBAA4571CDD6C5C822CBA458CDC55285CDF7BA9CD5BB9FC18096DEB9102201CAF8C771204DF7FD7C920C4489DA7BC3A60E1D23C1A97E237C63AFE53250B4A01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF2470947216EB81EA0EEEB4FE19362EC05767DB01C3AA3006BB499E8B6D6EAA26010000006A473044022031501A0B2846B8822A32B9947B058D89D32FC758E009FC2130C2E5EFFC925AF70220574EF3C9E350CEF726C75114F0701FD8B188C6EC5F84ADCE0ED5C393828A5AE001210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF0ABCD77D65CC14363F8262898335F184D6DA5AD060FF9E40BF201741022C2B40010000006B483045022100A6AC110802B699F9A2BFF0EEA252D32E3D572B19214D49D8BB7405EFA2AF28F1022033B7563EB595F6D7ED7EC01734E17B505214FE0851352ED9C3C8120D53268E9A01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFA43BEBBEBF07452A893A95BFEA1D5DB338D23579BE172FE803DCE02EEB7C037D010000006B483045022100EBC77ED0F11D15FE630FE533DC350C2DDC1C81CFEB81D5A27D0587163F58A28C02200983B2A32A1014BAB633BFC9258083AC282B79566B6B3FA45C1E6758610444F401210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFB102113FA46CE949616D9CDA00F6B10231336B3928EAAAC6BFE42D1BF3561D6C010000006A473044022010F8731929A55C1C49610722E965635529ED895B2292D781B183D465799906B20220098359ADCBC669CD4B294CC129B110FE035D2F76517248F4B7129F3BF793D07F01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFFB861FAB2CDE188499758346BE46B5FBEC635ADDFC4E7B0C8A07C0A908F2B11B4000000006A47304402207328142BB02EF5D6496A210300F4AEA71F67683B842FA3DF32CAE6C88B49A9BB022020F56DDFF5042260CFDA2C9F39B7DEC858CC2F4A76A987CD2DC25945B04E15FE01210391064D5B2D1C70F264969046FCFF853A7E2BFDE5D121D38DC5EBD7BC37C2B210FFFFFFFFFFFFFFFF027064D817000000001976A9144A5FBA237213A062F6F57978F796390BDCF8D01588AC00902F50090000001976A9145BE32612930B8323ADD2212A4EC03C1562084F8488AC00000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/util/txsort/testdata/bip69-2.hex b/util/txsort/testdata/bip69-2.hex index 515999887..93c2c0664 100644 --- a/util/txsort/testdata/bip69-2.hex +++ b/util/txsort/testdata/bip69-2.hex @@ -1 +1 @@ -010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000100000000000000000000000000000000000000 \ No newline at end of file +010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/util/txsort/testdata/bip69-3.hex b/util/txsort/testdata/bip69-3.hex index 9d91753bf..eaca1cb13 100644 --- a/util/txsort/testdata/bip69-3.hex +++ b/util/txsort/testdata/bip69-3.hex @@ -1 +1 @@ -0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000100000000000000000000000000000000000000 \ No newline at end of file +0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/util/txsort/testdata/bip69-4.hex b/util/txsort/testdata/bip69-4.hex index 99072ec63..558806f0e 100644 --- a/util/txsort/testdata/bip69-4.hex +++ b/util/txsort/testdata/bip69-4.hex @@ -1 +1 @@ -01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000100000000000000000000000000000000000000 \ No newline at end of file +01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/util/txsort/testdata/bip69-5.hex b/util/txsort/testdata/bip69-5.hex index 48972346a..63b268bf5 100644 --- a/util/txsort/testdata/bip69-5.hex +++ b/util/txsort/testdata/bip69-5.hex @@ -1 +1 @@ -01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000100000000000000000000000000000000000000 \ No newline at end of file +01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/util/txsort/txsort_test.go b/util/txsort/txsort_test.go index 7b7ce0fb7..88bf4df7b 100644 --- a/util/txsort/txsort_test.go +++ b/util/txsort/txsort_test.go @@ -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", }, } diff --git a/wire/bench_test.go b/wire/bench_test.go index aa8fdcd69..cb4ac5f07 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -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)) } diff --git a/wire/message_test.go b/wire/message_test.go index fd3187467..3172a9f34 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -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. diff --git a/wire/msgaddr.go b/wire/msgaddr.go index 0cd24f9fe..6b282f3ad 100644 --- a/wire/msgaddr.go +++ b/wire/msgaddr.go @@ -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), } } diff --git a/wire/msgaddr_test.go b/wire/msgaddr_test.go index 045802c6b..6212b1e2d 100644 --- a/wire/msgaddr_test.go +++ b/wire/msgaddr_test.go @@ -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) } diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index c5899be43..331a91bf8 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -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 } diff --git a/wire/msggetaddr.go b/wire/msggetaddr.go index b4a71a9c6..6b3e90f4e 100644 --- a/wire/msggetaddr.go +++ b/wire/msggetaddr.go @@ -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, } } diff --git a/wire/msggetaddr_test.go b/wire/msggetaddr_test.go index fca1c1b06..c4e71a1da 100644 --- a/wire/msggetaddr_test.go +++ b/wire/msggetaddr_test.go @@ -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, } diff --git a/wire/msgtx.go b/wire/msgtx.go index 02f8ed7b3..10e9fbb08 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -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) } diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index 3bdf3f118..9360aa04b 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -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 } diff --git a/wire/msgversion.go b/wire/msgversion.go index 8458d93db..e3e3af50d 100644 --- a/wire/msgversion.go +++ b/wire/msgversion.go @@ -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, } } diff --git a/wire/msgversion_test.go b/wire/msgversion_test.go index 0986ae9da..18e8c2be6 100644 --- a/wire/msgversion_test.go +++ b/wire/msgversion_test.go @@ -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,