forked from TrueCloudLab/neoneo-go
Merge pull request #338 from nspcc-dev/drop-redundant-dev-code-part-6
The big delete (#307) series episode six airs today for every subscriber of the neo-go repo (previous episodes: #315, #318, #322, #328, #330). This one is easy, nothing moved, just the red things.
This commit is contained in:
commit
9de8413d06
15 changed files with 0 additions and 816 deletions
|
@ -1,44 +0,0 @@
|
||||||
package chaincfg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/payload"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Params are the parameters needed to setup the network
|
|
||||||
type Params struct {
|
|
||||||
GenesisBlock payload.Block
|
|
||||||
}
|
|
||||||
|
|
||||||
//NetParams returns the parameters for the chosen network magic
|
|
||||||
func NetParams(magic protocol.Magic) (Params, error) {
|
|
||||||
switch magic {
|
|
||||||
case protocol.MainNet:
|
|
||||||
return mainnet()
|
|
||||||
default:
|
|
||||||
return mainnet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Mainnet returns the parameters needed for mainnet
|
|
||||||
func mainnet() (Params, error) {
|
|
||||||
rawHex := "000000000000000000000000000000000000000000000000000000000000000000000000f41bc036e39b0d6b0579c851c6fde83af802fa4e57bec0bc3365eae3abf43f8065fc8857000000001dac2b7c0000000059e75d652b5d3827bf04c165bbe9ef95cca4bf55010001510400001dac2b7c00000000400000455b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e882a1227d2c7b226c616e67223a22656e222c226e616d65223a22416e745368617265227d5d0000c16ff28623000000da1745e9b549bd0bfa1a569971c77eba30cd5a4b00000000400001445b7b226c616e67223a227a682d434e222c226e616d65223a22e5b08fe89a81e5b881227d2c7b226c616e67223a22656e222c226e616d65223a22416e74436f696e227d5d0000c16ff286230008009f7fd096d37ed2c0e3f7f0cfc924beef4ffceb680000000001000000019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50000c16ff28623005fa99d93303775fe50ca119c327759313eccfa1c01000151"
|
|
||||||
rawBytes, err := hex.DecodeString(rawHex)
|
|
||||||
if err != nil {
|
|
||||||
return Params{}, err
|
|
||||||
}
|
|
||||||
reader := bytes.NewReader(rawBytes)
|
|
||||||
|
|
||||||
block := payload.Block{}
|
|
||||||
err = block.Decode(reader)
|
|
||||||
if err != nil {
|
|
||||||
return Params{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return Params{
|
|
||||||
GenesisBlock: block,
|
|
||||||
}, nil
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package chaincfg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMainnet(t *testing.T) {
|
|
||||||
p, err := mainnet()
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, p.GenesisBlock.Hash.ReverseString(), "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf")
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package connmgr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config contains all methods which will be set by the caller to setup the connection manager.
|
|
||||||
type Config struct {
|
|
||||||
// GetAddress will return a single address for the connection manager to connect to
|
|
||||||
// This will be the source of addresses for the connection manager
|
|
||||||
GetAddress func() (string, error)
|
|
||||||
|
|
||||||
// OnConnection is called by the connection manager when we successfully connect to a peer
|
|
||||||
// The caller should ideally inform the address manager that we have connected to this address in this function
|
|
||||||
OnConnection func(conn net.Conn, addr string)
|
|
||||||
|
|
||||||
// OnAccept will take an established connection
|
|
||||||
OnAccept func(net.Conn)
|
|
||||||
|
|
||||||
// AddressPort is the address port of the local node in the format "address:port"
|
|
||||||
AddressPort string
|
|
||||||
|
|
||||||
// DialTimeout is the amount of time to wait, before we can disconnect a pending dialed connection
|
|
||||||
DialTimeout int
|
|
||||||
}
|
|
|
@ -1,245 +0,0 @@
|
||||||
package connmgr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// maxOutboundConn is the maximum number of active peers
|
|
||||||
// that the connection manager will try to have
|
|
||||||
maxOutboundConn = 10
|
|
||||||
|
|
||||||
// maxRetries is the maximum amount of successive retries that
|
|
||||||
// we can have before we stop dialing that peer
|
|
||||||
maxRetries = uint8(5)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Connmgr manages pending/active/failed cnnections
|
|
||||||
type Connmgr struct {
|
|
||||||
config Config
|
|
||||||
PendingList map[string]*Request
|
|
||||||
ConnectedList map[string]*Request
|
|
||||||
actionch chan func()
|
|
||||||
}
|
|
||||||
|
|
||||||
//New creates a new connection manager
|
|
||||||
func New(cfg Config) (*Connmgr, error) {
|
|
||||||
listener, err := net.Listen("tcp", cfg.AddressPort)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cnnmgr := &Connmgr{
|
|
||||||
cfg,
|
|
||||||
make(map[string]*Request),
|
|
||||||
make(map[string]*Request),
|
|
||||||
make(chan func(), 300),
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
listener.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
|
|
||||||
conn, err := listener.Accept()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
go cfg.OnAccept(conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
}()
|
|
||||||
|
|
||||||
return cnnmgr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequest will make a new connection gets the address from address func in config
|
|
||||||
// Then dials it and assigns it to pending
|
|
||||||
func (c *Connmgr) NewRequest() error {
|
|
||||||
|
|
||||||
// Fetch address
|
|
||||||
addr, err := c.config.GetAddress()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error getting address " + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
r := &Request{
|
|
||||||
Addr: addr,
|
|
||||||
}
|
|
||||||
return c.Connect(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect will dial the address in the Request
|
|
||||||
// Updating the request object depending on the outcome
|
|
||||||
func (c *Connmgr) Connect(r *Request) error {
|
|
||||||
|
|
||||||
r.Retries++
|
|
||||||
|
|
||||||
conn, err := c.dial(r.Addr)
|
|
||||||
if err != nil {
|
|
||||||
c.failed(r)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Conn = conn
|
|
||||||
r.Inbound = true
|
|
||||||
|
|
||||||
// r.Permanent is set by the address manager/caller. default is false
|
|
||||||
// The permanent connections will be the ones that are hardcoded, e.g seed3.ngd.network
|
|
||||||
// or are reliable. The connmgr will be more leniennt to permanent addresses as they have
|
|
||||||
// a track record or reputation of being reliable.
|
|
||||||
|
|
||||||
return c.connected(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Disconnect will remove the request from the connected/pending list and close the connection
|
|
||||||
func (c *Connmgr) Disconnect(addr string) {
|
|
||||||
|
|
||||||
var r *Request
|
|
||||||
|
|
||||||
// fetch from connected list
|
|
||||||
r, ok := c.ConnectedList[addr]
|
|
||||||
if !ok {
|
|
||||||
// If not in connected, check pending
|
|
||||||
r, _ = c.PendingList[addr]
|
|
||||||
}
|
|
||||||
|
|
||||||
c.disconnected(r)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial is used to dial up connections given the addres and ip in the form address:port
|
|
||||||
func (c *Connmgr) dial(addr string) (net.Conn, error) {
|
|
||||||
dialTimeout := 1 * time.Second
|
|
||||||
conn, err := net.DialTimeout("tcp", addr, dialTimeout)
|
|
||||||
if err != nil {
|
|
||||||
if !isConnected() {
|
|
||||||
return nil, errors.New("Fatal Error: You do not seem to be connected to the internet")
|
|
||||||
}
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
return conn, nil
|
|
||||||
}
|
|
||||||
func (c *Connmgr) failed(r *Request) {
|
|
||||||
|
|
||||||
c.actionch <- func() {
|
|
||||||
// priority to check if it is permanent or inbound
|
|
||||||
// if so then these peers are valuable in NEO and so we will just retry another time
|
|
||||||
if r.Inbound || r.Permanent {
|
|
||||||
multiplier := time.Duration(r.Retries * 10)
|
|
||||||
time.AfterFunc(multiplier*time.Second,
|
|
||||||
func() {
|
|
||||||
c.Connect(r)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
// if not then we should check if this request has had maxRetries
|
|
||||||
// if it has then get a new address
|
|
||||||
// if not then call Connect on it again
|
|
||||||
} else if r.Retries > maxRetries {
|
|
||||||
if c.config.GetAddress != nil {
|
|
||||||
go c.NewRequest()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
go c.Connect(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disconnected is called when a peer disconnects.
|
|
||||||
// we take the addr from peer, which is also it's key in the map
|
|
||||||
// and we use it to remove it from the connectedList
|
|
||||||
func (c *Connmgr) disconnected(r *Request) error {
|
|
||||||
|
|
||||||
if r == nil {
|
|
||||||
// if object is nil, we return nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// if for some reason the underlying connection is not closed, close it
|
|
||||||
err := r.Conn.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove from any pending/connected list
|
|
||||||
delete(c.PendingList, r.Addr)
|
|
||||||
delete(c.ConnectedList, r.Addr)
|
|
||||||
|
|
||||||
// If permanent,then lets retry
|
|
||||||
if r.Permanent {
|
|
||||||
return c.Connect(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//Connected is called when the connection manager makes a successful connection.
|
|
||||||
func (c *Connmgr) connected(r *Request) error {
|
|
||||||
|
|
||||||
// This should not be the case, since we connected
|
|
||||||
if r == nil {
|
|
||||||
return errors.New("request object as nil inside of the connected function")
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset retries to 0
|
|
||||||
r.Retries = 0
|
|
||||||
|
|
||||||
// add to connectedList
|
|
||||||
c.ConnectedList[r.Addr] = r
|
|
||||||
|
|
||||||
// remove from pending if it was there
|
|
||||||
delete(c.PendingList, r.Addr)
|
|
||||||
|
|
||||||
if c.config.OnConnection != nil {
|
|
||||||
c.config.OnConnection(r.Conn, r.Addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pending is synchronous, we do not want to continue with logic
|
|
||||||
// until we are certain it has been added to the pendingList
|
|
||||||
func (c *Connmgr) pending(r *Request) error {
|
|
||||||
|
|
||||||
if r == nil {
|
|
||||||
return errors.New("request object is nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
c.PendingList[r.Addr] = r
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run will start the connection manager
|
|
||||||
func (c *Connmgr) Run() error {
|
|
||||||
fmt.Println("Connection manager started")
|
|
||||||
go c.loop()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Connmgr) loop() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case f := <-c.actionch:
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/50056144/check-for-internet-connection-from-application
|
|
||||||
func isConnected() (ok bool) {
|
|
||||||
_, err := http.Get("http://clients3.google.com/generate_204")
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
package connmgr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDial(t *testing.T) {
|
|
||||||
cfg := Config{
|
|
||||||
GetAddress: nil,
|
|
||||||
OnConnection: nil,
|
|
||||||
OnAccept: nil,
|
|
||||||
AddressPort: "",
|
|
||||||
DialTimeout: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := New(cfg)
|
|
||||||
err := cm.Run()
|
|
||||||
assert.Equal(t, nil, err)
|
|
||||||
|
|
||||||
ipport := "google.com:80" // google unlikely to go offline, a better approach to test Dialing is welcome.
|
|
||||||
|
|
||||||
conn, err := cm.dial(ipport)
|
|
||||||
assert.Equal(t, nil, err)
|
|
||||||
assert.NotEqual(t, nil, conn)
|
|
||||||
}
|
|
||||||
func TestConnect(t *testing.T) {
|
|
||||||
cfg := Config{
|
|
||||||
GetAddress: nil,
|
|
||||||
OnConnection: nil,
|
|
||||||
OnAccept: nil,
|
|
||||||
AddressPort: "",
|
|
||||||
DialTimeout: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := New(cfg)
|
|
||||||
cm.Run()
|
|
||||||
|
|
||||||
ipport := "google.com:80"
|
|
||||||
|
|
||||||
r := Request{Addr: ipport}
|
|
||||||
|
|
||||||
err := cm.Connect(&r)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, 1, len(cm.ConnectedList))
|
|
||||||
|
|
||||||
}
|
|
||||||
func TestNewRequest(t *testing.T) {
|
|
||||||
|
|
||||||
address := "google.com:80"
|
|
||||||
|
|
||||||
var getAddr = func() (string, error) {
|
|
||||||
return address, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := Config{
|
|
||||||
GetAddress: getAddr,
|
|
||||||
OnConnection: nil,
|
|
||||||
OnAccept: nil,
|
|
||||||
AddressPort: "",
|
|
||||||
DialTimeout: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := New(cfg)
|
|
||||||
|
|
||||||
cm.Run()
|
|
||||||
|
|
||||||
cm.NewRequest()
|
|
||||||
|
|
||||||
if _, ok := cm.ConnectedList[address]; ok {
|
|
||||||
assert.Equal(t, true, ok)
|
|
||||||
assert.Equal(t, 1, len(cm.ConnectedList))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Fail(t, "Could not find the address in the connected lists")
|
|
||||||
|
|
||||||
}
|
|
||||||
func TestDisconnect(t *testing.T) {
|
|
||||||
|
|
||||||
address := "google.com:80"
|
|
||||||
|
|
||||||
var getAddr = func() (string, error) {
|
|
||||||
return address, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := Config{
|
|
||||||
GetAddress: getAddr,
|
|
||||||
OnConnection: nil,
|
|
||||||
OnAccept: nil,
|
|
||||||
AddressPort: "",
|
|
||||||
DialTimeout: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := New(cfg)
|
|
||||||
|
|
||||||
cm.Run()
|
|
||||||
|
|
||||||
cm.NewRequest()
|
|
||||||
|
|
||||||
cm.Disconnect(address)
|
|
||||||
|
|
||||||
assert.Equal(t, 0, len(cm.ConnectedList))
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Package - Connection Manager
|
|
||||||
|
|
||||||
## Responsibility
|
|
||||||
|
|
||||||
- Manages the active, failed and pending connections for the node.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Takes an Request, dials it and logs information based on the connectivity.
|
|
||||||
|
|
||||||
- Retry failed connections.
|
|
||||||
|
|
||||||
- Removable address source. The connection manager does not manage addresses, only connections.
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
The following methods are exposed from the Connection manager:
|
|
||||||
|
|
||||||
- Connect(r *Request) : This takes a Request object and connects to it. It follow the same logic as NewRequest() however instead of getting the address from the datasource given upon initialisation, you directly feed the address you want to connect to.
|
|
||||||
|
|
||||||
- Disconnect(addrport string) : Given an address:port, this will disconnect it, close the connection and remove it from the connected and pending list, if it was there.
|
|
|
@ -1,15 +0,0 @@
|
||||||
package connmgr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Request is a layer on top of connection and allows us to add metadata to the net.Conn
|
|
||||||
// that the connection manager can use to determine whether to retry and other useful heuristics
|
|
||||||
type Request struct {
|
|
||||||
Conn net.Conn
|
|
||||||
Addr string
|
|
||||||
Permanent bool
|
|
||||||
Inbound bool
|
|
||||||
Retries uint8 // should not be trying more than 255 tries
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
// etAddress will return a viable address to connect to
|
|
||||||
// Currently it is hardcoded to be one neo node until address manager is implemented
|
|
||||||
func (s *Server) getAddress() (string, error) {
|
|
||||||
return "seed1.ngd.network:10333", nil
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/chain"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/database"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupChain(db database.Database, net protocol.Magic) (*chain.Chain, error) {
|
|
||||||
chain, err := chain.New(db, net)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return chain, nil
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/connmgr"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peer"
|
|
||||||
iputils "github.com/CityOfZion/neo-go/pkg/wire/util/ip"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupConnManager(s *Server, port uint16) (*connmgr.Connmgr, error) {
|
|
||||||
cfg := connmgr.Config{
|
|
||||||
GetAddress: s.getAddress,
|
|
||||||
OnAccept: s.onAccept,
|
|
||||||
OnConnection: s.onConnection,
|
|
||||||
AddressPort: iputils.GetLocalIP().String() + ":" + strconv.FormatUint(uint64(port), 10),
|
|
||||||
}
|
|
||||||
return connmgr.New(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) onConnection(conn net.Conn, addr string) {
|
|
||||||
fmt.Println("We have connected successfully to: ", addr)
|
|
||||||
|
|
||||||
p := peer.NewPeer(conn, false, *s.peerCfg)
|
|
||||||
err := p.Run()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error running peer" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s.pmg.AddPeer(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) onAccept(conn net.Conn) {
|
|
||||||
fmt.Println("A peer with address: ", conn.RemoteAddr().String(), "has connect to us")
|
|
||||||
|
|
||||||
p := peer.NewPeer(conn, true, *s.peerCfg)
|
|
||||||
err := p.Run()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error running peer" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.pmg.AddPeer(p)
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/database"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupDatabase(net protocol.Magic) (database.Database, error) {
|
|
||||||
db, err := database.New(net.String())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return db, nil
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peer"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupPeerConfig(s *Server, port uint16, net protocol.Magic) *peer.LocalConfig {
|
|
||||||
return &peer.LocalConfig{
|
|
||||||
Net: net,
|
|
||||||
UserAgent: "NEO-GO",
|
|
||||||
Services: protocol.NodePeerService,
|
|
||||||
Nonce: rand.Uint32(),
|
|
||||||
ProtocolVer: 0,
|
|
||||||
Relay: false,
|
|
||||||
Port: port,
|
|
||||||
StartHeight: s.chain.CurrentHeight,
|
|
||||||
OnHeader: s.onHeader,
|
|
||||||
OnBlock: s.onBlock,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peermgr"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupPeerManager() *peermgr.PeerMgr {
|
|
||||||
return peermgr.New()
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peermgr"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/chain"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/connmgr"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peer"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/syncmgr"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/database"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Server orchestrates all of the modules
|
|
||||||
type Server struct {
|
|
||||||
net protocol.Magic
|
|
||||||
stopCh chan error
|
|
||||||
|
|
||||||
// Modules
|
|
||||||
db database.Database
|
|
||||||
smg *syncmgr.Syncmgr
|
|
||||||
cmg *connmgr.Connmgr
|
|
||||||
pmg *peermgr.PeerMgr
|
|
||||||
chain *chain.Chain
|
|
||||||
|
|
||||||
peerCfg *peer.LocalConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
//New creates a new server object for a particular network and sets up each module
|
|
||||||
func New(net protocol.Magic, port uint16) (*Server, error) {
|
|
||||||
s := &Server{
|
|
||||||
net: net,
|
|
||||||
stopCh: make(chan error, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup database
|
|
||||||
db, err := setupDatabase(net)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s.db = db
|
|
||||||
|
|
||||||
// setup peermgr
|
|
||||||
peermgr := setupPeerManager()
|
|
||||||
s.pmg = peermgr
|
|
||||||
|
|
||||||
// Setup chain
|
|
||||||
chain, err := setupChain(db, net)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s.chain = chain
|
|
||||||
|
|
||||||
// Setup sync manager
|
|
||||||
syncmgr, err := setupSyncManager(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s.smg = syncmgr
|
|
||||||
|
|
||||||
// Setup connection manager
|
|
||||||
connmgr, err := setupConnManager(s, port)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s.cmg = connmgr
|
|
||||||
|
|
||||||
// Setup peer config
|
|
||||||
peerCfg := setupPeerConfig(s, port, net)
|
|
||||||
s.peerCfg = peerCfg
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run starts the daemon by connecting to previously nodes or connectng to seed nodes.
|
|
||||||
// This should be called once all modules have been setup
|
|
||||||
func (s *Server) Run() error {
|
|
||||||
fmt.Println("Server is starting up")
|
|
||||||
|
|
||||||
// start the connmgr
|
|
||||||
err := s.cmg.Run()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to connect to a peer
|
|
||||||
err = s.cmg.NewRequest()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request header to start synchronisation
|
|
||||||
bestHeader, err := s.chain.Db.GetLastHeader()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.pmg.RequestHeaders(bestHeader.Hash)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println("Server Successfully started")
|
|
||||||
return s.wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) wait() error {
|
|
||||||
err := <-s.stopCh
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop stops the server
|
|
||||||
func (s *Server) Stop(err error) error {
|
|
||||||
fmt.Println("Server is shutting down")
|
|
||||||
s.stopCh <- err
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peermgr"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/peer"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/syncmgr"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/payload"
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupSyncManager(s *Server) (*syncmgr.Syncmgr, error) {
|
|
||||||
|
|
||||||
cfg := &syncmgr.Config{
|
|
||||||
ProcessBlock: s.processBlock,
|
|
||||||
ProcessHeaders: s.processHeaders,
|
|
||||||
|
|
||||||
RequestBlock: s.requestBlock,
|
|
||||||
RequestHeaders: s.requestHeaders,
|
|
||||||
|
|
||||||
GetNextBlockHash: s.getNextBlockHash,
|
|
||||||
AskForNewBlocks: s.askForNewBlocks,
|
|
||||||
|
|
||||||
FetchHeadersAgain: s.fetchHeadersAgain,
|
|
||||||
FetchBlockAgain: s.fetchBlockAgain,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add nextBlockIndex in syncmgr
|
|
||||||
lastBlock, err := s.chain.Db.GetLastBlock()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
nextBlockIndex := lastBlock.Index + 1
|
|
||||||
|
|
||||||
return syncmgr.New(cfg, nextBlockIndex), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) onHeader(peer *peer.Peer, hdrsMessage *payload.HeadersMessage) {
|
|
||||||
s.pmg.MsgReceived(peer, hdrsMessage.Command())
|
|
||||||
s.smg.OnHeader(peer, hdrsMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) onBlock(peer *peer.Peer, blockMsg *payload.BlockMessage) {
|
|
||||||
s.pmg.BlockMsgReceived(peer, peermgr.BlockInfo{
|
|
||||||
BlockHash: blockMsg.Hash,
|
|
||||||
BlockIndex: blockMsg.Index,
|
|
||||||
})
|
|
||||||
s.smg.OnBlock(peer, blockMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) processBlock(block payload.Block) error {
|
|
||||||
return s.chain.ProcessBlock(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) processHeaders(hdrs []*payload.BlockBase) error {
|
|
||||||
return s.chain.ProcessHeaders(hdrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) requestHeaders(hash util.Uint256) error {
|
|
||||||
return s.pmg.RequestHeaders(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) requestBlock(hash util.Uint256, index uint32) error {
|
|
||||||
return s.pmg.RequestBlock(peermgr.BlockInfo{
|
|
||||||
BlockHash: hash,
|
|
||||||
BlockIndex: index,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// getNextBlockHash searches the database for the blockHash
|
|
||||||
// that is the height above our best block. The hash will be taken from a header.
|
|
||||||
func (s *Server) getNextBlockHash() (util.Uint256, error) {
|
|
||||||
bestBlock, err := s.chain.Db.GetLastBlock()
|
|
||||||
if err != nil {
|
|
||||||
// Panic!
|
|
||||||
// XXX: One alternative, is to get the network, erase the database and then start again from scratch.
|
|
||||||
// This should never happen. The latest block will always be atleast the genesis block
|
|
||||||
panic("could not get best block from database" + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
index := make([]byte, 4)
|
|
||||||
binary.BigEndian.PutUint32(index, bestBlock.Index+1)
|
|
||||||
|
|
||||||
hdr, err := s.chain.Db.GetHeaderFromHeight(index)
|
|
||||||
if err != nil {
|
|
||||||
return util.Uint256{}, err
|
|
||||||
}
|
|
||||||
return hdr.Hash, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) getBestBlockHash() (util.Uint256, error) {
|
|
||||||
return util.Uint256{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) askForNewBlocks() {
|
|
||||||
// send a getblocks message with the latest block saved
|
|
||||||
|
|
||||||
// when we receive something then send get data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) fetchHeadersAgain(util.Uint256) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) fetchBlockAgain(util.Uint256) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in a new issue