diff --git a/cmd/gtk/assets/ui/dialog_wallet_create_address.ui b/cmd/gtk/assets/ui/dialog_wallet_create_address.ui
new file mode 100644
index 000000000..1964b2bad
--- /dev/null
+++ b/cmd/gtk/assets/ui/dialog_wallet_create_address.ui
@@ -0,0 +1,136 @@
+
+
+
+
+
+
diff --git a/cmd/gtk/assets/ui/widget_node.ui b/cmd/gtk/assets/ui/widget_node.ui
index 6c25fb646..c0e84a0af 100644
--- a/cmd/gtk/assets/ui/widget_node.ui
+++ b/cmd/gtk/assets/ui/widget_node.ui
@@ -104,7 +104,7 @@
0
- 2
+ 3
@@ -118,7 +118,7 @@
1
- 2
+ 3
@@ -133,7 +133,7 @@
0
- 3
+ 4
@@ -147,7 +147,7 @@
1
- 3
+ 4
@@ -162,7 +162,7 @@
0
- 4
+ 5
@@ -176,7 +176,7 @@
1
- 4
+ 5
@@ -191,7 +191,7 @@
0
- 5
+ 6
@@ -204,7 +204,7 @@
1
- 5
+ 6
@@ -237,6 +237,36 @@
1
+
+
+ True
+ False
+ start
+ start
+ True
+ True
+ Network ID:
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+ start
+ start
+ True
+ True
+ True
+
+
+ 1
+ 2
+
+
diff --git a/cmd/gtk/dialog_wallet_create_address.go b/cmd/gtk/dialog_wallet_create_address.go
new file mode 100644
index 000000000..f708b93f3
--- /dev/null
+++ b/cmd/gtk/dialog_wallet_create_address.go
@@ -0,0 +1,73 @@
+//go:build gtk
+
+package main
+
+import (
+ _ "embed"
+ "fmt"
+
+ "github.com/gotk3/gotk3/gtk"
+
+ "github.com/pactus-project/pactus/wallet"
+)
+
+//go:embed assets/ui/dialog_wallet_create_address.ui
+var uiWalletCreateAddressDialog []byte
+
+func createAddress(ww *widgetWallet) {
+ builder, err := gtk.BuilderNewFromString(string(uiWalletCreateAddressDialog))
+ fatalErrorCheck(err)
+
+ dlg := getDialogObj(builder, "id_dialog_wallet_create_address")
+ addressLabel := getEntryObj(builder, "id_entry_account_label")
+
+ addressTypeCombo := getComboBoxTextObj(builder, "id_combo_address_type")
+ addressTypeCombo.Append(wallet.AddressTypeBLSAccount, "Account")
+ addressTypeCombo.Append(wallet.AddressTypeValidator, "Validator")
+
+ addressTypeCombo.SetActive(0)
+
+ getButtonObj(builder, "id_button_ok").SetImage(OkIcon())
+ getButtonObj(builder, "id_button_cancel").SetImage(CancelIcon())
+
+ onOk := func() {
+ walletAddressLabel, err := addressLabel.GetText()
+ fatalErrorCheck(err)
+
+ walletAddressType := addressTypeCombo.GetActiveID()
+ fatalErrorCheck(err)
+
+ if walletAddressType == wallet.AddressTypeBLSAccount {
+ _, err = ww.model.wallet.NewBLSAccountAddress(walletAddressLabel)
+ } else if walletAddressType == wallet.AddressTypeValidator {
+ _, err = ww.model.wallet.NewValidatorAddress(walletAddressLabel)
+ } else {
+ err = fmt.Errorf("invalid address type '%s'", walletAddressType)
+ }
+
+ errorCheck(err)
+
+ err = ww.model.wallet.Save()
+ errorCheck(err)
+
+ ww.model.rebuildModel()
+
+ dlg.Close()
+ }
+
+ onCancel := func() {
+ dlg.Close()
+ }
+
+ // Map the handlers to callback functions, and connect the signals
+ // to the Builder.
+ signals := map[string]interface{}{
+ "on_ok": onOk,
+ "on_cancel": onCancel,
+ }
+ builder.ConnectSignals(signals)
+
+ dlg.SetModal(true)
+
+ dlg.Run()
+}
diff --git a/cmd/gtk/model_wallet.go b/cmd/gtk/model_wallet.go
index d87f4b653..db44c8cf1 100644
--- a/cmd/gtk/model_wallet.go
+++ b/cmd/gtk/model_wallet.go
@@ -84,37 +84,3 @@ func (model *walletModel) rebuildModel() {
})
}()
}
-
-func (model *walletModel) createAddress() error {
- address, err := model.wallet.NewBLSAccountAddress("")
- if err != nil {
- return err
- }
-
- iter := model.listStore.Append()
- err = model.listStore.Set(iter,
- []int{
- IDAddressesColumnNo,
- IDAddressesColumnAddress,
- IDAddressesColumnLabel,
- IDAddressesColumnBalance,
- IDAddressesColumnStake,
- },
- []interface{}{
- fmt.Sprintf("%v", model.wallet.AddressCount()+1),
- address,
- "",
- "0",
- "0",
- })
- if err != nil {
- return err
- }
-
- err = model.wallet.Save()
- if err != nil {
- return err
- }
-
- return nil
-}
diff --git a/cmd/gtk/widget_node.go b/cmd/gtk/widget_node.go
index f13a9889d..4625f8108 100644
--- a/cmd/gtk/widget_node.go
+++ b/cmd/gtk/widget_node.go
@@ -42,6 +42,7 @@ func buildWidgetNode(model *nodeModel) (*widgetNode, error) {
box := getBoxObj(builder, "id_box_node")
labelLocation := getLabelObj(builder, "id_label_working_directory")
labelNetwork := getLabelObj(builder, "id_label_network")
+ labelNetworkID := getLabelObj(builder, "id_label_network_id")
cwd, err := os.Getwd()
if err != nil {
@@ -49,6 +50,7 @@ func buildWidgetNode(model *nodeModel) (*widgetNode, error) {
}
labelLocation.SetText(cwd)
labelNetwork.SetText(model.node.State().Genesis().ChainType().String())
+ labelNetworkID.SetText(model.node.Network().SelfID().String())
w := &widgetNode{
Box: box,
diff --git a/cmd/gtk/widget_wallet.go b/cmd/gtk/widget_wallet.go
index 6bb07efaa..655ca17e2 100644
--- a/cmd/gtk/widget_wallet.go
+++ b/cmd/gtk/widget_wallet.go
@@ -147,15 +147,14 @@ func buildWidgetWallet(model *walletModel) (*widgetWallet, error) {
return w, nil
}
-func (ww *widgetWallet) onNewAddress() {
- err := ww.model.createAddress()
- errorCheck(err)
-}
-
func (ww *widgetWallet) onChangePassword() {
changePassword(ww.model.wallet)
}
+func (ww *widgetWallet) onNewAddress() {
+ createAddress(ww)
+}
+
func (ww *widgetWallet) onShowSeed() {
password, ok := getWalletPassword(ww.model.wallet)
if !ok {
diff --git a/cmd/wallet/address.go b/cmd/wallet/address.go
index a9568bcad..c93e211f1 100644
--- a/cmd/wallet/address.go
+++ b/cmd/wallet/address.go
@@ -6,6 +6,7 @@ import (
"github.com/pactus-project/pactus/cmd"
"github.com/pactus-project/pactus/crypto/bls"
"github.com/pactus-project/pactus/util"
+ "github.com/pactus-project/pactus/wallet"
"github.com/spf13/cobra"
)
@@ -41,20 +42,20 @@ func buildAllAddressesCmd(parentCmd *cobra.Command) {
false, "Display the validator stake for each address")
allAddressCmd.Run = func(_ *cobra.Command, _ []string) {
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
cmd.PrintLine()
- for i, info := range wallet.AddressInfos() {
+ for i, info := range wlt.AddressInfos() {
line := fmt.Sprintf("%v- %s\t", i+1, info.Address)
if *balanceOpt {
- balance, _ := wallet.Balance(info.Address)
+ balance, _ := wlt.Balance(info.Address)
line += fmt.Sprintf("%v\t", util.ChangeToCoin(balance))
}
if *stakeOpt {
- stake, _ := wallet.Stake(info.Address)
+ stake, _ := wlt.Stake(info.Address)
line += fmt.Sprintf("%v\t", util.ChangeToCoin(stake))
}
@@ -76,15 +77,27 @@ func buildNewAddressCmd(parentCmd *cobra.Command) {
}
parentCmd.AddCommand(newAddressCmd)
+ addressType := newAddressCmd.Flags().String("type",
+ wallet.AddressTypeBLSAccount, "the type of address: bls_account or validator")
+
newAddressCmd.Run = func(_ *cobra.Command, _ []string) {
+ var addr string
+ var err error
+
label := cmd.PromptInput("Label")
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- addr, err := wallet.NewBLSAccountAddress(label)
+ if *addressType == wallet.AddressTypeBLSAccount {
+ addr, err = wlt.NewBLSAccountAddress(label)
+ } else if *addressType == wallet.AddressTypeValidator {
+ addr, err = wlt.NewValidatorAddress(label)
+ } else {
+ err = fmt.Errorf("invalid address type '%s'", *addressType)
+ }
cmd.FatalErrorCheck(err)
- err = wallet.Save()
+ err = wlt.Save()
cmd.FatalErrorCheck(err)
cmd.PrintLine()
@@ -104,14 +117,14 @@ func buildBalanceCmd(parentCmd *cobra.Command) {
balanceCmd.Run = func(_ *cobra.Command, args []string) {
addr := args[0]
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
cmd.PrintLine()
- balance, err := wallet.Balance(addr)
+ balance, err := wlt.Balance(addr)
cmd.FatalErrorCheck(err)
- stake, err := wallet.Stake(addr)
+ stake, err := wlt.Stake(addr)
cmd.FatalErrorCheck(err)
cmd.PrintInfoMsgf("balance: %v\tstake: %v",
@@ -133,11 +146,11 @@ func buildPrivateKeyCmd(parentCmd *cobra.Command) {
privateKeyCmd.Run = func(_ *cobra.Command, args []string) {
addr := args[0]
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- password := getPassword(wallet, *passOpt)
- prv, err := wallet.PrivateKey(password, addr)
+ password := getPassword(wlt, *passOpt)
+ prv, err := wlt.PrivateKey(password, addr)
cmd.FatalErrorCheck(err)
cmd.PrintLine()
@@ -157,10 +170,10 @@ func buildPublicKeyCmd(parentCmd *cobra.Command) {
publicKeyCmd.Run = func(_ *cobra.Command, args []string) {
addr := args[0]
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- info := wallet.AddressInfo(addr)
+ info := wlt.AddressInfo(addr)
if info == nil {
cmd.PrintErrorMsgf("Address not found")
return
@@ -187,17 +200,17 @@ func buildImportPrivateKeyCmd(parentCmd *cobra.Command) {
importPrivateKeyCmd.Run = func(_ *cobra.Command, _ []string) {
prvStr := cmd.PromptInput("Private Key")
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
prv, err := bls.PrivateKeyFromString(prvStr)
cmd.FatalErrorCheck(err)
- password := getPassword(wallet, *passOpt)
- err = wallet.ImportPrivateKey(password, prv)
+ password := getPassword(wlt, *passOpt)
+ err = wlt.ImportPrivateKey(password, prv)
cmd.FatalErrorCheck(err)
- err = wallet.Save()
+ err = wlt.Save()
cmd.FatalErrorCheck(err)
cmd.PrintLine()
@@ -217,16 +230,16 @@ func buildSetLabelCmd(parentCmd *cobra.Command) {
setLabelCmd.Run = func(c *cobra.Command, args []string) {
addr := args[0]
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- oldLabel := wallet.Label(addr)
+ oldLabel := wlt.Label(addr)
newLabel := cmd.PromptInputWithSuggestion("Label", oldLabel)
- err = wallet.SetLabel(addr, newLabel)
+ err = wlt.SetLabel(addr, newLabel)
cmd.FatalErrorCheck(err)
- err = wallet.Save()
+ err = wlt.Save()
cmd.FatalErrorCheck(err)
cmd.PrintLine()
diff --git a/cmd/wallet/create.go b/cmd/wallet/create.go
index f5b740cff..8ce6b6c18 100644
--- a/cmd/wallet/create.go
+++ b/cmd/wallet/create.go
@@ -53,16 +53,16 @@ func buildChangePasswordCmd(parentCmd *cobra.Command) {
passOpt := addPasswordOption(changePasswordCmd)
changePasswordCmd.Run = func(_ *cobra.Command, _ []string) {
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- oldPassword := getPassword(wallet, *passOpt)
+ oldPassword := getPassword(wlt, *passOpt)
newPassword := cmd.PromptPassword("New Password", true)
- err = wallet.UpdatePassword(oldPassword, newPassword)
+ err = wlt.UpdatePassword(oldPassword, newPassword)
cmd.FatalErrorCheck(err)
- err = wallet.Save()
+ err = wlt.Save()
cmd.FatalErrorCheck(err)
cmd.PrintLine()
diff --git a/cmd/wallet/history.go b/cmd/wallet/history.go
index 78662f3da..aaa27b961 100644
--- a/cmd/wallet/history.go
+++ b/cmd/wallet/history.go
@@ -31,16 +31,16 @@ func buildAddToHistoryCmd(parentCmd *cobra.Command) {
addToHistoryCmd.Run = func(_ *cobra.Command, args []string) {
txID := args[0]
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
id, err := hash.FromString(txID)
cmd.FatalErrorCheck(err)
- err = wallet.AddTransaction(id)
+ err = wlt.AddTransaction(id)
cmd.FatalErrorCheck(err)
- err = wallet.Save()
+ err = wlt.Save()
cmd.FatalErrorCheck(err)
cmd.PrintInfoMsgf("Transaction successfully added to the wallet.")
@@ -59,10 +59,10 @@ func buildShowHistoryCmd(parentCmd *cobra.Command) {
showHistoryCmd.Run = func(_ *cobra.Command, args []string) {
addr := args[0]
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- history := wallet.GetHistory(addr)
+ history := wlt.GetHistory(addr)
for i, h := range history {
if h.Time != nil {
cmd.PrintInfoMsgf("%d %v %v %v %s\t%v",
diff --git a/cmd/wallet/recover.go b/cmd/wallet/recover.go
index 0c2cf31a5..98359ad1e 100644
--- a/cmd/wallet/recover.go
+++ b/cmd/wallet/recover.go
@@ -51,11 +51,11 @@ func buildGetSeedCmd(parentCmd *cobra.Command) {
passOpt := addPasswordOption(getSeedCmd)
getSeedCmd.Run = func(_ *cobra.Command, _ []string) {
- wallet, err := openWallet()
+ wlt, err := openWallet()
cmd.FatalErrorCheck(err)
- password := getPassword(wallet, *passOpt)
- mnemonic, err := wallet.Mnemonic(password)
+ password := getPassword(wlt, *passOpt)
+ mnemonic, err := wlt.Mnemonic(password)
cmd.FatalErrorCheck(err)
cmd.PrintLine()
diff --git a/config/config.go b/config/config.go
index 0b7215cf9..34cccba77 100644
--- a/config/config.go
+++ b/config/config.go
@@ -98,6 +98,7 @@ func SaveMainnetConfig(path string, numValidators int) error {
return util.WriteFile(path, []byte(conf))
}
+//nolint:all
func SaveTestnetConfig(path string, numValidators int) error {
conf := DefaultConfig()
conf.Node.NumValidators = numValidators
@@ -107,30 +108,25 @@ func SaveTestnetConfig(path string, numValidators int) error {
}
conf.Network.BootstrapAddrs = []string{
"/ip4/94.101.184.118/tcp/21777/p2p/12D3KooWCwQZt8UriVXobQHPXPR8m83eceXVoeT6brPNiBHomebc",
- "/ip4/94.101.184.118/udp/21777/quic-v1/p2p/12D3KooWCwQZt8UriVXobQHPXPR8m83eceXVoeT6brPNiBHomebc",
"/ip4/172.104.46.145/tcp/21777/p2p/12D3KooWNYD4bB82YZRXv6oNyYPwc5ozabx2epv75ATV3D8VD3Mq",
- "/ip4/172.104.46.145/udp/21777/quic-v1/p2p/12D3KooWNYD4bB82YZRXv6oNyYPwc5ozabx2epv75ATV3D8VD3Mq",
- "/ip6/2400:8901::f03c:93ff:fe1c:c3ec/tcp/21777/p2p/12D3KooWNYD4bB82YZRXv6oNyYPwc5ozabx2epv75ATV3D8VD3Mq",
- "/ip6/2400:8901::f03c:93ff:fe1c:c3ec/udp/21777/quic-v1/p2p/12D3KooWNYD4bB82YZRXv6oNyYPwc5ozabx2epv75ATV3D8VD3Mq",
"/ip4/13.115.190.71/tcp/21777/p2p/12D3KooWBGNEH8NqdK1UddSnPV1yRHGLYpaQUcnujC24s7YNWPiq",
- "/ip4/13.115.190.71/udp/21777/quic-v1/p2p/12D3KooWBGNEH8NqdK1UddSnPV1yRHGLYpaQUcnujC24s7YNWPiq",
"/ip4/51.158.118.181/tcp/21777/p2p/12D3KooWDF8a4goNCHriP1y922y4jagaPwHdX4eSrG5WtQpjzS6k",
- "/ip4/51.158.118.181/udp/21777/quic-v1/p2p/12D3KooWDF8a4goNCHriP1y922y4jagaPwHdX4eSrG5WtQpjzS6k",
+ "/ip4/159.148.146.149/tcp/21777/p2p/12D3KooWPQAGVMdxbUCeNETPiMkeascvMRorZAwtMUs2UVxftKgZ", // SGTstake (adorid@sgtstake.com)
+ "/ip4/109.123.246.47/tcp/21777/p2p/12D3KooWERCpnEzD7QgTa7uLhqQjj3L4YmQtAGbW6w76Ckjaop7s", // Stakes.Works (info@stake.works)
+ "/ip4/173.249.27.146/tcp/21777/p2p/12D3KooWSJREEzTZRzc9wpkU3EW2m9ZGfzrC9jjuwS6wR5uaAZme", // Karma Nodes (karma.nodes@proton.me)
+ "/ip4/16.170.148.83/tcp/21777/p2p/12D3KooWGaU7u6D9XT8rXnpGWSbNVF3Ezts7ZV3gCV5vuJ4d2jAo", // Mr HoDL (1llusiv387@gmail.com)
+ "/dns/pactus.nodesync.top/tcp/21777/p2p/12D3KooWP25ejVsd7cL5DvWAPwEu4JTUwnPniHBf4w93tgSezVt8", // NodeSync.Top (lthuan2011@gmail.com)
+ "/ip6/2400:8901::f03c:93ff:fe1c:c3ec/tcp/21777/p2p/12D3KooWNYD4bB82YZRXv6oNyYPwc5ozabx2epv75ATV3D8VD3Mq",
"/ip6/2001:bc8:700:8017::1/tcp/21777/p2p/12D3KooWDF8a4goNCHriP1y922y4jagaPwHdX4eSrG5WtQpjzS6k",
- "/ip6/2001:bc8:700:8017::1/udp/21777/quic-v1/p2p/12D3KooWDF8a4goNCHriP1y922y4jagaPwHdX4eSrG5WtQpjzS6k",
}
conf.Network.MinConns = 8
conf.Network.MaxConns = 16
conf.Network.EnableRelay = true
conf.Network.RelayAddrs = []string{
"/ip4/139.162.153.10/tcp/4002/p2p/12D3KooWNR79jqHVVNhNVrqnDbxbJJze4VjbEsBjZhz6mkvinHAN",
- "/ip4/139.162.153.10/udp/4002/quic/p2p/12D3KooWNR79jqHVVNhNVrqnDbxbJJze4VjbEsBjZhz6mkvinHAN",
- "/ip6/2a01:7e01::f03c:93ff:fed2:84c5/tcp/4002/p2p/12D3KooWNR79jqHVVNhNVrqnDbxbJJze4VjbEsBjZhz6mkvinHAN",
- "/ip6/2a01:7e01::f03c:93ff:fed2:84c5/udp/4002/quic/p2p/12D3KooWNR79jqHVVNhNVrqnDbxbJJze4VjbEsBjZhz6mkvinHAN",
"/ip4/188.121.102.178/tcp/4002/p2p/12D3KooWCRHn8vjrKNBEQcut8uVCYX5q77RKidPaE6iMK31qEVHb",
- "/ip4/188.121.102.178/udp/4002/quic/p2p/12D3KooWCRHn8vjrKNBEQcut8uVCYX5q77RKidPaE6iMK31qEVHb",
+ "/ip6/2a01:7e01::f03c:93ff:fed2:84c5/tcp/4002/p2p/12D3KooWNR79jqHVVNhNVrqnDbxbJJze4VjbEsBjZhz6mkvinHAN",
"/ip6/2a07:3900:1:1::113/tcp/4002/p2p/12D3KooWCRHn8vjrKNBEQcut8uVCYX5q77RKidPaE6iMK31qEVHb",
- "/ip6/2a07:3900:1:1::113/udp/4002/quic/p2p/12D3KooWCRHn8vjrKNBEQcut8uVCYX5q77RKidPaE6iMK31qEVHb",
}
conf.GRPC.Enable = true
conf.GRPC.Listen = "[::]:50052"
diff --git a/consensus/voteset/vote_box.go b/consensus/voteset/vote_box.go
index 89359ddf2..f789fad19 100644
--- a/consensus/voteset/vote_box.go
+++ b/consensus/voteset/vote_box.go
@@ -18,6 +18,8 @@ func newVoteBox() *voteBox {
}
func (vs *voteBox) addVote(vote *vote.Vote, power int64) {
- vs.votes[vote.Signer()] = vote
- vs.votedPower += power
+ if vs.votes[vote.Signer()] == nil {
+ vs.votes[vote.Signer()] = vote
+ vs.votedPower += power
+ }
}
diff --git a/consensus/voteset/vote_box_test.go b/consensus/voteset/vote_box_test.go
new file mode 100644
index 000000000..33d7ad301
--- /dev/null
+++ b/consensus/voteset/vote_box_test.go
@@ -0,0 +1,28 @@
+package voteset
+
+import (
+ "testing"
+
+ "github.com/pactus-project/pactus/types/vote"
+ "github.com/pactus-project/pactus/util/testsuite"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestDuplicateVote(t *testing.T) {
+ ts := testsuite.NewTestSuite(t)
+
+ hash := ts.RandHash()
+ height := ts.RandHeight()
+ round := ts.RandRound()
+ signer := ts.RandValAddress()
+ power := ts.RandInt64(1000)
+
+ v := vote.NewPrepareVote(hash, height, round, signer)
+
+ vb := newVoteBox()
+
+ vb.addVote(v, power)
+ vb.addVote(v, power)
+
+ assert.Equal(t, vb.votedPower, power)
+}
diff --git a/network/dht.go b/network/dht.go
index 81cb43862..5767d87cd 100644
--- a/network/dht.go
+++ b/network/dht.go
@@ -28,8 +28,6 @@ func newDHTService(ctx context.Context, host lp2phost.Host, protocolID lp2pcore.
opts := []lp2pdht.Option{
lp2pdht.Mode(mode),
lp2pdht.ProtocolPrefix(protocolID),
- lp2pdht.DisableProviders(),
- lp2pdht.DisableValues(),
lp2pdht.BootstrapPeers(bootsrapAddrs...),
}
diff --git a/network/gossip.go b/network/gossip.go
index 442d68ef4..548f39132 100644
--- a/network/gossip.go
+++ b/network/gossip.go
@@ -21,9 +21,16 @@ type gossipService struct {
}
func newGossipService(ctx context.Context, host lp2phost.Host, eventCh chan Event,
- logger *logger.SubLogger,
+ config *Config, logger *logger.SubLogger,
) *gossipService {
- pubsub, err := lp2pps.NewGossipSub(ctx, host)
+ opts := []lp2pps.Option{}
+
+ if config.Bootstrapper {
+ // enable Peer eXchange on bootstrappers
+ opts = append(opts, lp2pps.WithPeerExchange(true))
+ }
+
+ pubsub, err := lp2pps.NewGossipSub(ctx, host, opts...)
if err != nil {
logger.Panic("unable to start Gossip service", "error", err)
return nil
@@ -100,7 +107,7 @@ func (g *gossipService) onReceiveMessage(m *lp2pps.Message) {
return
}
- g.logger.Debug("receiving new gossip message",
+ g.logger.Trace("receiving new gossip message",
"source", m.GetFrom(), "from", m.ReceivedFrom)
event := &GossipMessage{
Source: m.GetFrom(),
diff --git a/network/network.go b/network/network.go
index 5a6ff315a..0abd80aac 100644
--- a/network/network.go
+++ b/network/network.go
@@ -95,8 +95,15 @@ func newNetwork(networkName string, conf *Config, opts []lp2p.Option) (*network,
return nil, LibP2PError{Err: err}
}
- rmgr, err := lp2prcmgr.NewResourceManager(
- lp2prcmgr.NewFixedLimiter(lp2prcmgr.DefaultLimits.AutoScale()),
+ maxConns := conf.MaxConns
+ changes := lp2prcmgr.PartialLimitConfig{}
+ changes.System.ConnsInbound = lp2prcmgr.LimitVal(logScale(maxConns))
+ changes.System.ConnsOutbound = lp2prcmgr.LimitVal(logScale(maxConns))
+ changes.System.Conns = lp2prcmgr.LimitVal(logScale(2 * maxConns))
+ limit := changes.Build(lp2prcmgr.DefaultLimits.AutoScale())
+
+ resMgr, err := lp2prcmgr.NewResourceManager(
+ lp2prcmgr.NewFixedLimiter(limit),
lp2prcmgr.WithTraceReporter(str),
)
if err != nil {
@@ -116,7 +123,7 @@ func newNetwork(networkName string, conf *Config, opts []lp2p.Option) (*network,
lp2p.Identity(networkKey),
lp2p.ListenAddrStrings(conf.Listens...),
lp2p.UserAgent(version.Agent()),
- lp2p.ResourceManager(rmgr),
+ lp2p.ResourceManager(resMgr),
lp2p.ConnectionManager(connMgr),
)
@@ -183,12 +190,14 @@ func newNetwork(networkName string, conf *Config, opts []lp2p.Option) (*network,
n.dht = newDHTService(n.ctx, n.host, kadProtocolID, conf, n.logger)
n.stream = newStreamService(ctx, n.host, streamProtocolID, relayAddrs, n.eventChannel, n.logger)
- n.gossip = newGossipService(ctx, n.host, n.eventChannel, n.logger)
+ n.gossip = newGossipService(ctx, n.host, n.eventChannel, conf, n.logger)
n.notifee = newNotifeeService(n.host, n.eventChannel, n.logger, streamProtocolID)
n.host.Network().Notify(n.notifee)
- n.logger.Info("network setup", "id", n.host.ID(), "address", conf.Listens)
+ n.logger.Info("network setup", "id", n.host.ID(),
+ "address", conf.Listens,
+ "bootstrapper", conf.Bootstrapper)
return n, nil
}
@@ -209,13 +218,6 @@ func (n *network) Start() error {
n.gossip.Start()
n.stream.Start()
- if n.config.EnableRelay {
- for _, relayAddr := range n.config.RelayAddrs {
- addrInfo, _ := MakeAddressInfo(relayAddr)
- ConnectAsync(n.ctx, n.host, *addrInfo, n.logger)
- }
- }
-
n.logger.Info("network started", "addr", n.host.Addrs())
return nil
}
@@ -245,7 +247,7 @@ func (n *network) SendTo(msg []byte, pid lp2pcore.PeerID) error {
}
func (n *network) Broadcast(msg []byte, topicID TopicID) error {
- n.logger.Debug("publishing new message", "topic", topicID)
+ n.logger.Trace("publishing new message", "topic", topicID)
switch topicID {
case TopicIDGeneral:
if n.generalTopic == nil {
diff --git a/network/notifee.go b/network/notifee.go
index 3a638a1b5..e328ae9ba 100644
--- a/network/notifee.go
+++ b/network/notifee.go
@@ -11,6 +11,7 @@ import (
)
type NotifeeService struct {
+ host lp2phost.Host
eventChannel chan<- Event
logger *logger.SubLogger
protocolID protocol.ID
@@ -20,6 +21,7 @@ func newNotifeeService(host lp2phost.Host, eventChannel chan<- Event,
logger *logger.SubLogger, protocolID protocol.ID,
) *NotifeeService {
notifee := &NotifeeService{
+ host: host,
eventChannel: eventChannel,
logger: logger,
protocolID: protocolID,
@@ -30,23 +32,23 @@ func newNotifeeService(host lp2phost.Host, eventChannel chan<- Event,
func (n *NotifeeService) Connected(lp2pn lp2pnetwork.Network, conn lp2pnetwork.Conn) {
peerID := conn.RemotePeer()
+ n.logger.Info("connected to peer", "pid", peerID)
go func() {
- for i := 0; i < 6; i++ {
+ for i := 0; i < 10; i++ {
// TODO: better way?
// Wait to complete libp2p identify
- time.Sleep(200 * time.Millisecond)
+ time.Sleep(1 * time.Second)
protocols, _ := lp2pn.Peerstore().SupportsProtocols(peerID, n.protocolID)
if len(protocols) > 0 {
- n.logger.Info("connected to peer", "pid", peerID)
n.eventChannel <- &ConnectEvent{PeerID: peerID}
-
return
}
}
- n.logger.Info("this node doesn't support stream protocol", "pid", peerID)
+ n.logger.Info("unable to get supported protocols", "pid", peerID)
+ _ = n.host.Network().ClosePeer(peerID)
}()
}
diff --git a/network/stream.go b/network/stream.go
index c07fb2b45..bf03d9614 100644
--- a/network/stream.go
+++ b/network/stream.go
@@ -47,7 +47,7 @@ func (s *streamService) Stop() {
func (s *streamService) handleStream(stream lp2pnetwork.Stream) {
from := stream.Conn().RemotePeer()
- s.logger.Debug("receiving stream", "from", from)
+ s.logger.Trace("receiving stream", "from", from)
event := &StreamMessage{
Source: from,
Reader: stream,
diff --git a/network/utils.go b/network/utils.go
index 6df001764..b56bcfb33 100644
--- a/network/utils.go
+++ b/network/utils.go
@@ -2,6 +2,7 @@ package network
import (
"context"
+ "math/bits"
"time"
lp2phost "github.com/libp2p/go-libp2p/core/host"
@@ -57,3 +58,8 @@ func ConnectAsync(ctx context.Context, h lp2phost.Host, addrInfo lp2ppeer.AddrIn
}
}()
}
+
+func logScale(val int) int {
+ bitlen := bits.Len(uint(val))
+ return 1 << bitlen
+}
diff --git a/node/node.go b/node/node.go
index ee26f8e1f..70ac54b6c 100644
--- a/node/node.go
+++ b/node/node.go
@@ -170,3 +170,7 @@ func (n *Node) State() state.Facade {
func (n *Node) GRPC() *grpc.Server {
return n.grpc
}
+
+func (n *Node) Network() network.Network {
+ return n.network
+}
diff --git a/sync/handler_hello.go b/sync/handler_hello.go
index 73bdb0513..7f1df8aa4 100644
--- a/sync/handler_hello.go
+++ b/sync/handler_hello.go
@@ -61,7 +61,7 @@ func (handler *helloHandler) ParseMessage(m message.Message, initiator peer.ID)
}
handler.peerSet.UpdateHeight(initiator, msg.Height, msg.BlockHash)
- handler.peerSet.UpdateStatus(initiator, peerset.StatusCodeConnected)
+ handler.peerSet.UpdateStatus(initiator, peerset.StatusCodeKnown)
response := message.NewHelloAckMessage(message.ResponseCodeOK, "Ok")
return handler.acknowledge(response, initiator)
diff --git a/sync/handler_hello_test.go b/sync/handler_hello_test.go
index 5fcc8cba2..842852d6b 100644
--- a/sync/handler_hello_test.go
+++ b/sync/handler_hello_test.go
@@ -99,7 +99,7 @@ func TestParsingHelloMessages(t *testing.T) {
p := td.sync.peerSet.GetPeer(pid)
pub := valKey.PublicKey()
- assert.Equal(t, p.Status, peerset.StatusCodeConnected)
+ assert.Equal(t, p.Status, peerset.StatusCodeKnown)
assert.Equal(t, p.Agent, version.Agent())
assert.Equal(t, p.Moniker, "kitty")
assert.Contains(t, p.ConsensusKeys, pub)
diff --git a/wallet/client.go b/wallet/client.go
index e7e6c8480..886f3858d 100644
--- a/wallet/client.go
+++ b/wallet/client.go
@@ -12,6 +12,11 @@ import (
"google.golang.org/grpc/credentials/insecure"
)
+const (
+ AddressTypeBLSAccount string = "bls_account"
+ AddressTypeValidator string = "validator"
+)
+
type grpcClient struct {
blockchainClient pactus.BlockchainClient
transactionClient pactus.TransactionClient