Skip to content

Commit

Permalink
feat(network): adding public address to factory (#795)
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f authored Nov 4, 2023
1 parent c4b7906 commit ea06183
Show file tree
Hide file tree
Showing 17 changed files with 557 additions and 129 deletions.
3 changes: 2 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/pactus-project/pactus/www/grpc"
"github.com/pactus-project/pactus/www/http"
"github.com/pactus-project/pactus/www/nanomsg"
toml "github.com/pelletier/go-toml"
"github.com/pelletier/go-toml"
)

//go:embed example_config.toml
Expand All @@ -44,6 +44,7 @@ type NodeConfig struct {
}

func DefaultNodeConfig() *NodeConfig {
// TODO: We should have default config per network: Testnet, Mainnet.
return &NodeConfig{
NumValidators: 7,
}
Expand Down
2 changes: 2 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestSaveTestnetConfig(t *testing.T) {
assert.NoError(t, err)

assert.NoError(t, conf.BasicCheck())
assert.Equal(t, conf.Network.DefaultPort, 21777)
}

func TestSaveLocalnetConfig(t *testing.T) {
Expand All @@ -39,6 +40,7 @@ func TestSaveLocalnetConfig(t *testing.T) {
assert.NoError(t, conf.BasicCheck())
assert.Empty(t, conf.Network.Listens)
assert.Empty(t, conf.Network.RelayAddrs)
assert.Equal(t, conf.Network.DefaultPort, 21777)
}

func TestLoadFromFile(t *testing.T) {
Expand Down
19 changes: 15 additions & 4 deletions config/example_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
# `network_key` specifies the private key filename to use for node authentication and encryption in the p2p protocol.
## network_key = "network_key"

# `public_address` is a list of addresses that are public and accessible to other nodes.
# If it is empty, the node attempts to automatically detect its public IP addresses.
# It is recommended to set the public address if available.
# Example addresses:
# - "/ip4/1.2.3.4/tcp/21888"
# - "/ip6/2606:4700:4700::1111/udp/21888"
# - "/dnsaddr/my-server.amazonaws.com/tcp/21888"
## public_address = []

# `listens` specifies the addresses and ports where the node will listen for incoming connections from other nodes.
## listens = ["/ip4/0.0.0.0/tcp/21888", "/ip6/::/tcp/21888", "/ip4/0.0.0.0/udp/21888/quic-v1", "/ip6/::/udp/21888/quic-v1"]

Expand Down Expand Up @@ -58,15 +67,17 @@
# Default is false.
## enable_mdns = false

# `enable_metrics` if enabled, it provides network metrics for the Prometheus software.
# `enable_metrics` provides the network metrics for the Prometheus software.
# Default is false.
## enable_metrics = false

# `private_network` if enabled, connects to nodes in the private network.
# `force_private_network` forces the connection to nodes within a private network.
# A private network is a computer network that uses private addresses.
# Read more about private networks here: https://en.wikipedia.org/wiki/Private_network
# Default is false.
## private_network = false
## force_private_network = false

# `bootstrapper` if enabled, it runs the node in bootstrap mode.
# `bootstrapper` runs the node in bootstrap mode.
# Default is false.
## bootstrapper = false

Expand Down
13 changes: 13 additions & 0 deletions genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,16 @@ func (gen *Genesis) NetworkName() string {
return "unknown"
}
}

func (gen *Genesis) DefaultPort() int {
switch gen.ChainType() {
case Mainnet:
return 21888
case Testnet:
return 21777
case Localnet:
return 21666
default:
return 0
}
}
23 changes: 14 additions & 9 deletions genesis/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,21 @@ func TestMarshaling(t *testing.T) {
}

func TestGenesisTestNet(t *testing.T) {
g := genesis.TestnetGenesis()
assert.Equal(t, len(g.Validators()), 4)
assert.Equal(t, len(g.Accounts()), 1)
gen := genesis.TestnetGenesis()
assert.Equal(t, len(gen.Validators()), 4)
assert.Equal(t, len(gen.Accounts()), 1)

assert.Equal(t, g.Accounts()[crypto.TreasuryAddress].Balance(), int64(21e15))
assert.Equal(t, gen.Accounts()[crypto.TreasuryAddress].Balance(), int64(21e15))

genTime, _ := time.Parse("2006-01-02", "2023-10-15")
expected, _ := hash.FromString("da602b28f75902c35e3bafeb5733a686c94d5508c92aae68cbd9b37d81cfccf4")
assert.Equal(t, g.Hash(), expected)
assert.Equal(t, g.GenesisTime(), genTime)
assert.Equal(t, g.Params().BondInterval, uint32(120))
assert.Equal(t, g.ChainType(), genesis.Testnet)
assert.Equal(t, g.TotalSupply(), int64(42*1e15))
assert.Equal(t, gen.Hash(), expected)
assert.Equal(t, gen.GenesisTime(), genTime)
assert.Equal(t, gen.Params().BondInterval, uint32(120))
assert.Equal(t, gen.ChainType(), genesis.Testnet)
assert.Equal(t, gen.TotalSupply(), int64(42*1e15))
assert.Equal(t, gen.NetworkName(), "pactus-testnet")
assert.Equal(t, gen.DefaultPort(), 21777)
}

func TestCheckGenesisAccountAndValidator(t *testing.T) {
Expand All @@ -85,4 +87,7 @@ func TestCheckGenesisAccountAndValidator(t *testing.T) {
for i, val := range gen.Validators() {
assert.Equal(t, val.Hash(), vals[i].Hash())
}

assert.Equal(t, gen.NetworkName(), "pactus-localnet")
assert.Equal(t, gen.DefaultPort(), 21666)
}
50 changes: 28 additions & 22 deletions network/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ import (
)

type Config struct {
NetworkKey string `toml:"network_key"`
Listens []string `toml:"listens"`
RelayAddrs []string `toml:"relay_addresses"`
BootstrapAddrs []string `toml:"bootstrap_addresses"`
MinConns int `toml:"min_connections"`
MaxConns int `toml:"max_connections"`
EnableNAT bool `toml:"enable_nat"`
EnableRelay bool `toml:"enable_relay"`
EnableMdns bool `toml:"enable_mdns"`
EnableMetrics bool `toml:"enable_metrics"`
PrivateNetwork bool `toml:"private_network"`
Bootstrapper bool `toml:"bootstrapper"`
NetworkKey string `toml:"network_key"`
PublicAddress []string `toml:"public_address"`
Listens []string `toml:"listens"`
RelayAddrs []string `toml:"relay_addresses"`
BootstrapAddrs []string `toml:"bootstrap_addresses"`
MinConns int `toml:"min_connections"`
MaxConns int `toml:"max_connections"`
EnableNAT bool `toml:"enable_nat"`
EnableRelay bool `toml:"enable_relay"`
EnableMdns bool `toml:"enable_mdns"`
EnableMetrics bool `toml:"enable_metrics"`
ForcePrivateNetwork bool `toml:"force_private_network"`
Bootstrapper bool `toml:"bootstrapper"` // TODO: detect it automatically
DefaultPort int `toml:"-"`
}

func DefaultConfig() *Config {
Expand Down Expand Up @@ -47,16 +49,17 @@ func DefaultConfig() *Config {
"/ip4/0.0.0.0/tcp/21888", "/ip6/::/tcp/21888",
"/ip4/0.0.0.0/udp/21888/quic-v1", "/ip6/::/udp/21888/quic-v1",
},
RelayAddrs: []string{},
BootstrapAddrs: bootstrapAddrs,
MinConns: 8,
MaxConns: 16,
EnableNAT: true,
EnableRelay: false,
EnableMdns: false,
EnableMetrics: false,
PrivateNetwork: false,
Bootstrapper: false,
RelayAddrs: []string{},
BootstrapAddrs: bootstrapAddrs,
MinConns: 8,
MaxConns: 16,
EnableNAT: true,
EnableRelay: false,
EnableMdns: false,
EnableMetrics: false,
ForcePrivateNetwork: false,
Bootstrapper: false,
DefaultPort: 21777,
}
}

Expand All @@ -77,6 +80,9 @@ func (conf *Config) BasicCheck() error {
return errors.Errorf(errors.ErrInvalidConfig, "at least one relay address should be defined")
}
}
if err := validateAddresses(conf.PublicAddress); err != nil {
return err
}
if err := validateAddresses(conf.RelayAddrs); err != nil {
return err
}
Expand Down
4 changes: 4 additions & 0 deletions network/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func TestDefaultConfigCheck(t *testing.T) {
conf.Listens = []string{"/ip4"}
assert.Error(t, conf.BasicCheck())

conf = DefaultConfig()
conf.PublicAddress = []string{"/ip4"}
assert.Error(t, conf.BasicCheck())

conf = DefaultConfig()
conf.RelayAddrs = []string{"/ip4"}
assert.Error(t, conf.BasicCheck())
Expand Down
2 changes: 1 addition & 1 deletion network/dht.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func newDHTService(ctx context.Context, host lp2phost.Host, protocolID lp2pcore.
if conf.Bootstrapper {
mode = lp2pdht.ModeServer
}
bootstrapAddrs := PeerAddrsToAddrInfo(conf.BootstrapAddrs)
bootstrapAddrs, _ := MakeAddrInfos(conf.BootstrapAddrs)
opts := []lp2pdht.Option{
lp2pdht.Mode(mode),
lp2pdht.ProtocolPrefix(protocolID),
Expand Down
86 changes: 86 additions & 0 deletions network/gater.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package network

import (
lp2pconnmgr "github.com/libp2p/go-libp2p/core/connmgr"
lp2pcontrol "github.com/libp2p/go-libp2p/core/control"
lp2pnetwork "github.com/libp2p/go-libp2p/core/network"
lp2ppeer "github.com/libp2p/go-libp2p/core/peer"
lp2pconngater "github.com/libp2p/go-libp2p/p2p/net/conngater"
"github.com/multiformats/go-multiaddr"
"github.com/pactus-project/pactus/util/logger"
)

var _ lp2pconnmgr.ConnectionGater = &ConnectionGater{}

type ConnectionGater struct {
*lp2pconngater.BasicConnectionGater

logger *logger.SubLogger
}

func NewConnectionGater(conf *Config) (*ConnectionGater, error) {
connGater, err := lp2pconngater.NewBasicConnectionGater(nil)
if err != nil {
return nil, err
}

if !conf.ForcePrivateNetwork {
privateSubnets := PrivateSubnets()
for _, sn := range privateSubnets {
err := connGater.BlockSubnet(sn)
if err != nil {
return nil, LibP2PError{Err: err}
}
}
}

return &ConnectionGater{
BasicConnectionGater: connGater,
}, nil
}

func (g *ConnectionGater) SetLogger(log *logger.SubLogger) {
g.logger = log
}

func (g *ConnectionGater) InterceptPeerDial(p lp2ppeer.ID) bool {
allow := g.BasicConnectionGater.InterceptPeerDial(p)
if !allow {
g.logger.Debug("InterceptPeerDial not allowed", "p")
}

return allow
}

func (g *ConnectionGater) InterceptAddrDial(p lp2ppeer.ID, ma multiaddr.Multiaddr) bool {
allow := g.BasicConnectionGater.InterceptAddrDial(p, ma)
if !allow {
g.logger.Debug("InterceptAddrDial not allowed", "p", p, "ma", ma.String())
}

return allow
}

func (g *ConnectionGater) InterceptAccept(cma lp2pnetwork.ConnMultiaddrs) bool {
allow := g.BasicConnectionGater.InterceptAccept(cma)
if !allow {
g.logger.Debug("InterceptAccept not allowed")
}

return allow
}

func (g *ConnectionGater) InterceptSecured(dir lp2pnetwork.Direction, p lp2ppeer.ID,
cma lp2pnetwork.ConnMultiaddrs,
) bool {
allow := g.BasicConnectionGater.InterceptSecured(dir, p, cma)
if !allow {
g.logger.Debug("InterceptSecured not allowed", "p", p)
}

return allow
}

func (g *ConnectionGater) InterceptUpgraded(con lp2pnetwork.Conn) (bool, lp2pcontrol.DisconnectReason) {
return g.BasicConnectionGater.InterceptUpgraded(con)
}
1 change: 1 addition & 0 deletions network/gater_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package network
14 changes: 7 additions & 7 deletions network/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"

lp2pcore "github.com/libp2p/go-libp2p/core"
"github.com/libp2p/go-libp2p/core/peer"
lp2ppeer "github.com/libp2p/go-libp2p/core/peer"
"github.com/pactus-project/pactus/util/testsuite"
)

Expand All @@ -21,12 +21,12 @@ type MockNetwork struct {

PublishCh chan PublishData
EventCh chan Event
ID peer.ID
ID lp2ppeer.ID
OtherNets []*MockNetwork
SendError error
}

func MockingNetwork(ts *testsuite.TestSuite, id peer.ID) *MockNetwork {
func MockingNetwork(ts *testsuite.TestSuite, id lp2ppeer.ID) *MockNetwork {
return &MockNetwork{
TestSuite: ts,
PublishCh: make(chan PublishData, 100),
Expand Down Expand Up @@ -55,7 +55,7 @@ func (mock *MockNetwork) JoinConsensusTopic() error {
return nil
}

func (mock *MockNetwork) SelfID() peer.ID {
func (mock *MockNetwork) SelfID() lp2ppeer.ID {
return mock.ID
}

Expand All @@ -78,7 +78,7 @@ func (mock *MockNetwork) Broadcast(data []byte, _ TopicID) error {
return nil
}

func (mock *MockNetwork) SendToOthers(data []byte, target *peer.ID) {
func (mock *MockNetwork) SendToOthers(data []byte, target *lp2ppeer.ID) {
for _, net := range mock.OtherNets {
if target == nil {
// Broadcast message
Expand All @@ -99,15 +99,15 @@ func (mock *MockNetwork) SendToOthers(data []byte, target *peer.ID) {
}
}

func (mock *MockNetwork) CloseConnection(pid peer.ID) {
func (mock *MockNetwork) CloseConnection(pid lp2ppeer.ID) {
for i, net := range mock.OtherNets {
if net.ID == pid {
mock.OtherNets = append(mock.OtherNets[:i], mock.OtherNets[i+1:]...)
}
}
}

func (mock *MockNetwork) IsClosed(pid peer.ID) bool {
func (mock *MockNetwork) IsClosed(pid lp2ppeer.ID) bool {
for _, net := range mock.OtherNets {
if net.ID == pid {
return false
Expand Down
Loading

0 comments on commit ea06183

Please sign in to comment.