Compare commits

...

2 Commits

Author SHA1 Message Date
stasatdaglabs
c5827febf7 [NOD-114] On start, DNSSeeder should update its addresses more frequently (#250)
* [NOD-114] Added a minimum address amount GetAddrs.

* [NOD-114] Added smallNetwork intervals for when the network is small.

* [NOD-114] Fixed bad minimum address calculation.
2019-04-15 15:57:43 +03:00
Ori Newman
7353a49469 [NOD-109] Reverse the order of .PastUTXO() and .RestoreUTXO() parameters (#249) 2019-04-15 10:37:06 +03:00
5 changed files with 96 additions and 53 deletions

View File

@@ -160,6 +160,10 @@ const (
// will consider evicting an address.
minBadDays = 7
// getAddrMin is the least addresses that we will send in response
// to a getAddr. If we have less than this amount, we send everything.
getAddrMin = 50
// getAddrMax is the most addresses that we will send in response
// to a getAddr (in practise the most addresses we will return from a
// call to AddressCache()).
@@ -844,6 +848,12 @@ func (a *AddrManager) AddressCache(includeAllSubnetworks bool, subnetworkID *sub
if numAddresses > getAddrMax {
numAddresses = getAddrMax
}
if len(allAddr) < getAddrMin {
numAddresses = len(allAddr)
}
if len(allAddr) > getAddrMin && numAddresses < getAddrMin {
numAddresses = getAddrMin
}
// Fisher-Yates shuffle the array. We only need to do the first
// `numAddresses' since we are throwing the rest.

View File

@@ -751,7 +751,7 @@ func (dag *BlockDAG) applyDAGChanges(node *blockNode, block *util.Block, newBloc
dag.virtual.AddTip(node)
// Build a UTXO set for the new virtual block
newVirtualUTXO, _, err := dag.virtual.blockNode.pastUTXO(dag)
newVirtualUTXO, _, err := dag.pastUTXO(&dag.virtual.blockNode)
if err != nil {
return nil, fmt.Errorf("could not restore past UTXO for virtual %s: %s", dag.virtual, err)
}
@@ -814,7 +814,7 @@ func (node *blockNode) addTxsToAcceptanceData(txsAcceptanceData MultiBlockTxsAcc
func (node *blockNode) verifyAndBuildUTXO(dag *BlockDAG, transactions []*util.Tx, fastAdd bool) (
newBlockUTXO UTXOSet, txsAcceptanceData MultiBlockTxsAcceptanceData, newBlockFeeData compactFeeData, err error) {
pastUTXO, txsAcceptanceData, err := node.pastUTXO(dag)
pastUTXO, txsAcceptanceData, err := dag.pastUTXO(node)
if err != nil {
return nil, nil, nil, err
}
@@ -913,16 +913,57 @@ func (node *blockNode) applyBlueBlocks(selectedParentUTXO UTXOSet, blueBlocks []
return pastUTXO, txsAcceptanceData, nil
}
// updateParents adds this block to the children sets of its parents
// and updates the diff of any parent whose DiffChild is this block
func (node *blockNode) updateParents(dag *BlockDAG, newBlockUTXO UTXOSet) error {
node.updateParentsChildren()
return node.updateParentsDiffs(dag, newBlockUTXO)
}
// updateParentsDiffs updates the diff of any parent whose DiffChild is this block
func (node *blockNode) updateParentsDiffs(dag *BlockDAG, newBlockUTXO UTXOSet) error {
virtualDiffFromNewBlock, err := dag.virtual.utxoSet.diffFrom(newBlockUTXO)
if err != nil {
return err
}
err = dag.utxoDiffStore.setBlockDiff(node, virtualDiffFromNewBlock)
if err != nil {
return err
}
for _, parent := range node.parents {
diffChild, err := dag.utxoDiffStore.diffChildByNode(parent)
if err != nil {
return err
}
if diffChild == nil {
parentUTXO, err := dag.restoreUTXO(parent)
if err != nil {
return err
}
dag.utxoDiffStore.setBlockDiffChild(parent, node)
diff, err := newBlockUTXO.diffFrom(parentUTXO)
if err != nil {
return err
}
dag.utxoDiffStore.setBlockDiff(parent, diff)
}
}
return nil
}
// pastUTXO returns the UTXO of a given block's past
// To save traversals over the blue blocks, it also returns the transaction acceptance data for
// all blue blocks
func (node *blockNode) pastUTXO(dag *BlockDAG) (
func (dag *BlockDAG) pastUTXO(node *blockNode) (
pastUTXO UTXOSet, bluesTxsAcceptanceData MultiBlockTxsAcceptanceData, err error) {
if node.isGenesis() {
return genesisPastUTXO(dag.virtual), MultiBlockTxsAcceptanceData{}, nil
}
selectedParentUTXO, err := node.selectedParent.restoreUTXO(dag)
selectedParentUTXO, err := dag.restoreUTXO(node.selectedParent)
if err != nil {
return nil, nil, err
}
@@ -936,7 +977,7 @@ func (node *blockNode) pastUTXO(dag *BlockDAG) (
}
// restoreUTXO restores the UTXO of a given block from its diff
func (node *blockNode) restoreUTXO(dag *BlockDAG) (UTXOSet, error) {
func (dag *BlockDAG) restoreUTXO(node *blockNode) (UTXOSet, error) {
stack := []*blockNode{}
for current := node; current != nil; {
@@ -964,51 +1005,10 @@ func (node *blockNode) restoreUTXO(dag *BlockDAG) (UTXOSet, error) {
return utxo, nil
}
// updateParents adds this block to the children sets of its parents
// and updates the diff of any parent whose DiffChild is this block
func (node *blockNode) updateParents(dag *BlockDAG, newBlockUTXO UTXOSet) error {
node.updateParentsChildren()
return node.updateParentsDiffs(dag, newBlockUTXO)
}
// updateParentsDiffs updates the diff of any parent whose DiffChild is this block
func (node *blockNode) updateParentsDiffs(dag *BlockDAG, newBlockUTXO UTXOSet) error {
virtualDiffFromNewBlock, err := dag.virtual.utxoSet.diffFrom(newBlockUTXO)
if err != nil {
return err
}
err = dag.utxoDiffStore.setBlockDiff(node, virtualDiffFromNewBlock)
if err != nil {
return err
}
for _, parent := range node.parents {
diffChild, err := dag.utxoDiffStore.diffChildByNode(parent)
if err != nil {
return err
}
if diffChild == nil {
parentUTXO, err := parent.restoreUTXO(dag)
if err != nil {
return err
}
dag.utxoDiffStore.setBlockDiffChild(parent, node)
diff, err := newBlockUTXO.diffFrom(parentUTXO)
if err != nil {
return err
}
dag.utxoDiffStore.setBlockDiff(parent, diff)
}
}
return nil
}
// updateTipsUTXO builds and applies new diff UTXOs for all the DAG's tips
func updateTipsUTXO(dag *BlockDAG, virtualUTXO UTXOSet) error {
for _, tip := range dag.virtual.parents {
tipUTXO, err := tip.restoreUTXO(dag)
tipUTXO, err := dag.restoreUTXO(tip)
if err != nil {
return err
}

View File

@@ -197,7 +197,7 @@ func GetVirtualFromParentsForTest(dag *BlockDAG, parentHashes []*daghash.Hash) (
}
virtual := newVirtualBlock(parents, dag.dagParams.K)
pastUTXO, _, err := virtual.pastUTXO(dag)
pastUTXO, _, err := dag.pastUTXO(&virtual.blockNode)
if err != nil {
return nil, err
}

View File

@@ -92,8 +92,9 @@ func creep() {
peers = amgr.Addresses()
}
if len(peers) == 0 {
log.Printf("No stale addresses -- sleeping for 10 minutes")
for i := 0; i < 600; i++ {
creepIntervalInSeconds := int(amgr.creepInterval().Seconds())
log.Printf("No stale addresses -- sleeping for %d seconds", creepIntervalInSeconds)
for i := 0; i < creepIntervalInSeconds; i++ {
time.Sleep(time.Second)
if atomic.LoadInt32(&systemShutdown) != 0 {
log.Printf("Creep thread shutdown")

View File

@@ -45,6 +45,10 @@ const (
// stale.
defaultStaleTimeout = time.Hour
// smallNetworkStaleTimeout is the time in which a host is considered
// stale if the network is small.
smallNetworkStaleTimeout = time.Second * 30
// dumpAddressInterval is the interval used to dump the address
// cache to disk for future use.
dumpAddressInterval = time.Second * 30
@@ -59,6 +63,18 @@ const (
// pruneExpireTimeout is the expire time in which a node is
// considered dead.
pruneExpireTimeout = time.Hour * 8
// defaultCreepInterval is the interval between creep runs.
defaultCreepInterval = time.Minute * 10
// defaultCreepInterval is the interval between creep runs if the
// network is small.
smallNetworkCreepInterval = time.Second * 30
// smallNetworkNodeAmount is amount of nodes under which a network
// is considered small. A small network has shorter timeouts and
// intervals to encourage faster network growth.
smallNetworkNodeAmount = 50
)
var (
@@ -181,8 +197,8 @@ func (m *Manager) Addresses() []*wire.NetAddress {
if i == 0 {
break
}
if now.Sub(node.LastSuccess) < defaultStaleTimeout ||
now.Sub(node.LastAttempt) < defaultStaleTimeout {
if now.Sub(node.LastSuccess) < m.staleTimeout() ||
now.Sub(node.LastAttempt) < m.staleTimeout() {
continue
}
addrs = append(addrs, node.Addr)
@@ -198,6 +214,22 @@ func (m *Manager) AddressCount() int {
return len(m.nodes)
}
func (m *Manager) staleTimeout() time.Duration {
if m.AddressCount() < smallNetworkNodeAmount {
return smallNetworkStaleTimeout
}
return defaultStaleTimeout
}
func (m *Manager) creepInterval() time.Duration {
if m.AddressCount() < smallNetworkNodeAmount {
return smallNetworkCreepInterval
}
return defaultCreepInterval
}
// 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, includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) []*wire.NetAddress {
@@ -230,7 +262,7 @@ func (m *Manager) GoodAddresses(qtype uint16, services wire.ServiceFlag, include
}
if node.LastSuccess.IsZero() ||
now.Sub(node.LastSuccess) > defaultStaleTimeout {
now.Sub(node.LastSuccess) > m.staleTimeout() {
continue
}