mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-64] Remove subnetwork id supports all (#237)
* [NOD-64] Intermediate commit: need check tests on master * [NOD-64] Commit before changing subnetwork IDS to new values * [NOD-64] Fixed tests after changing subnetworks IDs constants * [NOD-64] Extract duplicate code into functions * [NOD-64] Renamed IsAllSubnetworks ==> IncludeAllSubnetworks
This commit is contained in:
parent
67358d1e85
commit
7c30bc4301
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -49,8 +49,7 @@ func TestBlockCount(t *testing.T) {
|
||||
|
||||
// Create a new database and DAG instance to run tests against.
|
||||
dag, teardownFunc, err := DAGSetup("TestBlockCount", Config{
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to setup DAG instance: %v", err)
|
||||
@ -99,8 +98,7 @@ func TestHaveBlock(t *testing.T) {
|
||||
|
||||
// Create a new database and DAG instance to run tests against.
|
||||
dag, teardownFunc, err := DAGSetup("haveblock", Config{
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to setup DAG instance: %v", err)
|
||||
@ -194,10 +192,10 @@ func TestHaveBlock(t *testing.T) {
|
||||
{hash: dagconfig.SimNetParams.GenesisHash.String(), want: true},
|
||||
|
||||
// Block 3b should be present (as a second child of Block 2).
|
||||
{hash: "08a3f0182ac8ff0326497f592d2e28b8b3b2b7e3fd77c7cb6f31ca872536cf7b", want: true},
|
||||
{hash: "040c43ca52ded708dacef2a9fa589f41e4f7565345f7f1e61f379dbf32bb6b48", want: true},
|
||||
|
||||
// Block 100000 should be present (as an orphan).
|
||||
{hash: "25d5494f3e1f895774c58034f1bd50f7b279e75db6007514affec8573ace4389", want: true},
|
||||
{hash: "3da8f9ec89820deee1a4d26ff0e69c53686166ea4fbc1895fa1e0b1ccb651374", want: true},
|
||||
|
||||
// Random hashes should not be available.
|
||||
{hash: "123", want: false},
|
||||
@ -782,8 +780,7 @@ func testErrorThroughPatching(t *testing.T, expectedErrorMessage string, targetF
|
||||
|
||||
// Create a new database and dag instance to run tests against.
|
||||
dag, teardownFunc, err := DAGSetup("testErrorThroughPatching", Config{
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to setup dag instance: %v", err)
|
||||
@ -841,11 +838,10 @@ func TestNew(t *testing.T) {
|
||||
os.RemoveAll(testDbRoot)
|
||||
}()
|
||||
config := &Config{
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
|
||||
DB: db,
|
||||
TimeSource: NewMedianTime(),
|
||||
SigCache: txscript.NewSigCache(1000),
|
||||
DAGParams: &dagconfig.SimNetParams,
|
||||
DB: db,
|
||||
TimeSource: NewMedianTime(),
|
||||
SigCache: txscript.NewSigCache(1000),
|
||||
}
|
||||
_, err = New(config)
|
||||
if err != nil {
|
||||
@ -855,9 +851,9 @@ func TestNew(t *testing.T) {
|
||||
config.SubnetworkID = &subnetworkid.SubnetworkID{0xff}
|
||||
_, err = New(config)
|
||||
expectedErrorMessage := fmt.Sprintf("Cannot start btcd with subnetwork ID %s because"+
|
||||
" its database is already built with subnetwork ID %s. If you"+
|
||||
" its database is already built with subnetwork ID <nil>. If you"+
|
||||
" want to switch to a new database, please reset the"+
|
||||
" database by starting btcd with --reset-db flag", config.SubnetworkID, subnetworkid.SubnetworkIDSupportsAll)
|
||||
" database by starting btcd with --reset-db flag", config.SubnetworkID)
|
||||
if err.Error() != expectedErrorMessage {
|
||||
t.Errorf("Unexpected error. Expected error '%s' but got '%s'", expectedErrorMessage, err)
|
||||
}
|
||||
@ -867,8 +863,7 @@ func TestValidateFeeTransaction(t *testing.T) {
|
||||
params := dagconfig.SimNetParams
|
||||
params.K = 1
|
||||
dag, teardownFunc, err := DAGSetup("TestValidateFeeTransaction", Config{
|
||||
DAGParams: ¶ms,
|
||||
SubnetworkID: subnetworkid.SubnetworkIDSupportsAll,
|
||||
DAGParams: ¶ms,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to setup DAG instance: %v", err)
|
||||
|
@ -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"+
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
BIN
blockdag/testdata/blk_0_to_4.dat
vendored
BIN
blockdag/testdata/blk_0_to_4.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3A.dat
vendored
BIN
blockdag/testdata/blk_3A.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3B.dat
vendored
BIN
blockdag/testdata/blk_3B.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3C.dat
vendored
BIN
blockdag/testdata/blk_3C.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3D.dat
vendored
BIN
blockdag/testdata/blk_3D.dat
vendored
Binary file not shown.
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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},
|
||||
}
|
||||
|
@ -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,
|
||||
|
BIN
database/testdata/blocks1-256.bz2
vendored
BIN
database/testdata/blocks1-256.bz2
vendored
Binary file not shown.
4
database/testdata/generator.go
vendored
4
database/testdata/generator.go
vendored
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.",
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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++ {
|
||||
|
2
util/txsort/testdata/bip69-1.hex
vendored
2
util/txsort/testdata/bip69-1.hex
vendored
File diff suppressed because one or more lines are too long
2
util/txsort/testdata/bip69-2.hex
vendored
2
util/txsort/testdata/bip69-2.hex
vendored
@ -1 +1 @@
|
||||
010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000100000000000000000000000000000000000000
|
||||
010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000000000000000000000000000000000000000000
|
2
util/txsort/testdata/bip69-3.hex
vendored
2
util/txsort/testdata/bip69-3.hex
vendored
@ -1 +1 @@
|
||||
0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000100000000000000000000000000000000000000
|
||||
0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000000000000000000000000000000000000000000
|
2
util/txsort/testdata/bip69-4.hex
vendored
2
util/txsort/testdata/bip69-4.hex
vendored
@ -1 +1 @@
|
||||
01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000100000000000000000000000000000000000000
|
||||
01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000000000000000000000000000000000000000000
|
2
util/txsort/testdata/bip69-5.hex
vendored
2
util/txsort/testdata/bip69-5.hex
vendored
@ -1 +1 @@
|
||||
01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000100000000000000000000000000000000000000
|
||||
01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000000000000000000000000000000000000000000
|
@ -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",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user