Coder Social home page Coder Social logo

Improve neighbors finding about ruthenium HOT 6 CLOSED

my-cloud avatar my-cloud commented on June 1, 2024
Improve neighbors finding

from ruthenium.

Comments (6)

JeremyPansier avatar JeremyPansier commented on June 1, 2024

In GitLab by @Styks on Jul 22, 2022, 09:02

created branch 3-improve-neighbors-finding to address this issue

from ruthenium.

JeremyPansier avatar JeremyPansier commented on June 1, 2024

In GitLab by @Styks on Jul 22, 2022, 16:21

A good paper talking about the neighbors finding, more precisely about how to select the good neighbors to improve th enumber of transaction by second without increasing the risk of creating forks.

https://arxiv.org/pdf/1906.00719.pdf

from ruthenium.

JeremyPansier avatar JeremyPansier commented on June 1, 2024

In GitLab by @Styks on Jul 23, 2022, 12:37

Here is what is done in the full node bitcoin implementation written in Go:

The main file is btcd.go in the main package (github.com/btcsuite/btcd), which have a main function calling a "real main" function named btcdMain:

func main() {
...
	if err := btcdMain(nil); err != nil {
		os.Exit(1)
	}
}

In the btcdMain function, the server is instantiated and then its Start function is called:

func btcdMain(serverChan chan<- *server) error {
...
	server, err := newServer(cfg.Listeners, cfg.AgentBlacklist, cfg.AgentWhitelist, db, activeNetParams.Params, interrupt)
...
	server.Start()
...
}

The server is of type struct named server and implemented in the file server.go in the main package. The Start methdod calls the peerHandler from its own server instance using a goroutine:

func (s *server) Start() {
...
	go s.peerHandler()
...
}

The peerHandler function calls a helper function called SeedFromDNS from the connmgr package (github.com/btcsuite/btcd/connmgr) with the following arguments:

  • activeNetParams.Params, having the value defined by MainNetParams which are the network parameters for the main Bitcoin network.
  • defaultRequiredServices, set with SFNodeNetwork, an enumeration value used to indicate a peer is a full node
  • btcdLookup, a function described below
  • a function to add the found peers addresses into a ledger
func (s *server) peerHandler() {
...
		connmgr.SeedFromDNS(activeNetParams.Params, defaultRequiredServices,
			btcdLookup, func(addrs []*wire.NetAddressV2) {
				// Bitcoind uses a lookup of the dns seeder here. This
				// is rather strange since the values looked up by the
				// DNS seed lookups will vary quite a lot.
				// to replicate this behaviour we put all addresses as
				// having come from the first one.
				s.addrManager.AddAddresses(addrs, addrs[0])
			})
...
}

The btcdLookup function is implemented in the file config.go of the main package and is used to resolve the IP of a given host. It calls the lookup function from a cfg object:

func btcdLookup(host string) ([]net.IP, error) {
	...
	return cfg.lookup(host)
}

The cfg.lookup function implementation is defined in the loadConfig function. It might have 3 different implementations depending on the case, but the net.LookupIP implementation from the net library is used by default.

Now lets dive into the SeedFromDNS function implemented in the seed.go file of the connmgr package:

// SeedFromDNS uses DNS seeding to populate the address manager with peers.
func SeedFromDNS(chainParams *chaincfg.Params, reqServices wire.ServiceFlag,
	lookupFn LookupFunc, seedFn OnSeed) {

	for _, dnsseed := range chainParams.DNSSeeds {
		var host string
		if !dnsseed.HasFiltering || reqServices == wire.SFNodeNetwork {
			host = dnsseed.Host
		} else {
			host = fmt.Sprintf("x%x.%s", uint64(reqServices), dnsseed.Host)
		}

		go func(host string) {
			randSource := mrand.New(mrand.NewSource(time.Now().UnixNano()))

			seedpeers, err := lookupFn(host)
			if err != nil {
				log.Infof("DNS discovery failed on seed %s: %v", host, err)
				return
			}
			numPeers := len(seedpeers)

			log.Infof("%d addresses found from DNS seed %s", numPeers, host)

			if numPeers == 0 {
				return
			}
			addresses := make([]*wire.NetAddressV2, len(seedpeers))
			// if this errors then we have *real* problems
			intPort, _ := strconv.Atoi(chainParams.DefaultPort)
			for i, peer := range seedpeers {
				addresses[i] = wire.NetAddressV2FromBytes(
					// bitcoind seeds with addresses from
					// a time randomly selected between 3
					// and 7 days ago.
					time.Now().Add(-1*time.Second*time.Duration(secondsIn3Days+
						randSource.Int31n(secondsIn4Days))),
					0, peer, uint16(intPort))
			}

			seedFn(addresses)
		}(host)
	}
}

As seen above:

  1. In our case the chainParams parameter have the value defined by MainNetParams, therefore the chainParams.DefaultPort is "8333"and the chainParams.DNSSeeds value is:
	DNSSeeds: []DNSSeed{
		{"seed.bitcoin.sipa.be", true},
		{"dnsseed.bluematt.me", true},
		{"dnsseed.bitcoin.dashjr.org", false},
		{"seed.bitcoinstats.com", true},
		{"seed.bitnodes.io", false},
		{"seed.bitcoin.jonasschnelli.ch", true},
	},
  1. In our case, the result of reqServices == wire.SFNodeNetwork is true.
  2. In most of the cases, the lookupFn function implementation is net.LookupIP.
  3. The seedFn function is used to "populate the address manager with peers", i.e. to register the peers addresses into a ledger.

The last thing we need to know is what the wire.NetAddressV2FromBytes function does. In few words, in creates an object holding the peer address, port and registration time, with a slight optimization concerning the given bytes slice size and an handling for the specific case where the ip address is an encoded tor v2 address.

from ruthenium.

JeremyPansier avatar JeremyPansier commented on June 1, 2024

In GitLab by @Styks on Jul 23, 2022, 17:14

In our code, it shoul look like this:
undefined

With DefaultPort = 8333 and:

blockchain.seeds = []string{
		"seed.bitcoin.sipa.be",
		"dnsseed.bluematt.me",
		"dnsseed.bitcoin.dashjr.org",
		"seed.bitcoinstats.com",
		"seed.bitnodes.io",
		"seed.bitcoin.jonasschnelli.ch",
	}

from ruthenium.

JeremyPansier avatar JeremyPansier commented on June 1, 2024

In GitLab by @Styks on Jul 25, 2022, 06:10

I choose port 8106, see https://www.speedguide.net/port.php?port=8106

from ruthenium.

JeremyPansier avatar JeremyPansier commented on June 1, 2024

In GitLab by @Styks on Jul 26, 2022, 16:02

mentioned in commit cdf82e5

from ruthenium.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.