Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: supporting localnet #492

Merged
merged 1 commit into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 40 additions & 3 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ import (
"github.com/manifoldco/promptui"
"github.com/pactus-project/pactus/config"
"github.com/pactus-project/pactus/crypto"
"github.com/pactus-project/pactus/crypto/bls"
"github.com/pactus-project/pactus/genesis"
"github.com/pactus-project/pactus/node"
"github.com/pactus-project/pactus/types/account"
"github.com/pactus-project/pactus/types/param"
"github.com/pactus-project/pactus/types/validator"
"github.com/pactus-project/pactus/util"
"github.com/pactus-project/pactus/wallet"
)

Expand Down Expand Up @@ -282,6 +287,8 @@ func CreateNode(numValidators int, chain genesis.ChainType, workingDir string,
genPath := PactusGenesisPath(workingDir)

switch chain {
case genesis.Mainnet:
panic("not yet!")
case genesis.Testnet:
err = genesis.TestnetGenesis().SaveToFile(genPath)
if err != nil {
Expand All @@ -292,8 +299,16 @@ func CreateNode(numValidators int, chain genesis.ChainType, workingDir string,
if err != nil {
return nil, nil, err
}
case genesis.Mainnet:
panic("not yet!")
case genesis.Localnet:
err = makeLocalGenesis(*wallet).SaveToFile(genPath)
if err != nil {
return nil, nil, err
}

err := config.SaveLocalnetConfig(confPath, numValidators)
if err != nil {
return nil, nil, err
}
}

err = wallet.UpdatePassword("", walletPassword)
Expand All @@ -316,7 +331,7 @@ func StartNode(workingDir string, passwordFetcher func(*wallet.Wallet) (string,
return nil, nil, err
}

if gen.ChainType().IsTestnet() {
if !gen.ChainType().IsMainnet() {
crypto.AddressHRP = "tpc"
crypto.PublicKeyHRP = "tpublic"
crypto.PrivateKeyHRP = "tsecret"
Expand Down Expand Up @@ -419,3 +434,25 @@ func StartNode(workingDir string, passwordFetcher func(*wallet.Wallet) (string,

return node, wallet, nil
}

// makeLocalGenesis makes genesis file for the local network.
func makeLocalGenesis(w wallet.Wallet) *genesis.Genesis {
// Treasury account
acc := account.NewAccount(0)
acc.AddToBalance(21 * 1e14)
accs := map[crypto.Address]*account.Account{
crypto.TreasuryAddress: acc}

vals := make([]*validator.Validator, 4)
for i := 0; i < 4; i++ {
ai := w.AddressInfo(w.AddressLabels()[i].Address)
vals[i] = validator.NewValidator(
ai.Pub.(*bls.PublicKey), int32(i))
}

// create genesis
params := param.DefaultParams()
params.BlockVersion = 0
gen := genesis.MakeGenesis(util.RoundNow(60), accs, vals, params)
return gen
}
17 changes: 13 additions & 4 deletions cmd/daemon/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ func Init() func(c *cli.Cmd) {
Desc: "Initialize working directory for joining the testnet",
Value: true, // TODO: make it false after mainnet launch
})
localnetOpt := c.Bool(cli.BoolOpt{
Name: "localnet",
Desc: "Initialize working directory for localnet (for developers)",
Value: false,
})

c.LongDesc = "Initializing the working directory by new validator's private key and genesis file"
c.Before = func() { fmt.Println(cmd.Pactus) }
Expand Down Expand Up @@ -55,11 +60,15 @@ func Init() func(c *cli.Cmd) {
cmd.PrintInfoMsg("You can define validators based on the amount of coins you want to stake.")
numValidators := cmd.PromptInputWithRange("Number of Validators", 7, 1, 32)

network := genesis.Mainnet
chain := genesis.Mainnet
// The order of checking the network (chain type) matters here.
if *testnetOpt {
network = genesis.Testnet
chain = genesis.Testnet
}
if *localnetOpt {
chain = genesis.Localnet
}
validatorAddrs, rewardAddrs, err := cmd.CreateNode(numValidators, network, workingDir, mnemonic, password)
validatorAddrs, rewardAddrs, err := cmd.CreateNode(numValidators, chain, workingDir, mnemonic, password)
cmd.FatalErrorCheck(err)

cmd.PrintLine()
Expand All @@ -75,7 +84,7 @@ func Init() func(c *cli.Cmd) {
}

cmd.PrintLine()
cmd.PrintInfoMsgBold("Network: %v", network.String())
cmd.PrintInfoMsgBold("Network: %v", chain.String())
cmd.PrintLine()
cmd.PrintSuccessMsg("A pactus node is successfully initialized at %v", workingDir)
cmd.PrintLine()
Expand Down
2 changes: 1 addition & 1 deletion cmd/gtk/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func main() {

// Create a new app.
// When using GtkApplication, it is not necessary to call gtk_init() manually.
app, err := gtk.ApplicationNew(appID, glib.APPLICATION_FLAGS_NONE)
app, err := gtk.ApplicationNew(appID, glib.APPLICATION_NON_UNIQUE)
fatalErrorCheck(err)

// Connect function to application startup event, this is not required.
Expand Down
21 changes: 21 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,27 @@ func SaveTestnetConfig(path string, numValidators int) error {
return util.WriteFile(path, conf.toTOML())
}

func SaveLocalnetConfig(path string, numValidators int) error {
conf := DefaultConfig()
conf.Node.NumValidators = numValidators
conf.Network.Name = "pactus-localnet"
conf.Network.Listens = []string{}
conf.Network.EnableNAT = false
conf.Network.Bootstrap.Addresses = []string{}
conf.Network.Bootstrap.MinThreshold = 4
conf.Network.Bootstrap.MaxThreshold = 8
conf.GRPC.Enable = true
conf.GRPC.Listen = "[::]:0"
conf.GRPC.Gateway.Enable = true
conf.GRPC.Gateway.Listen = "[::]:0"
conf.HTTP.Enable = true
conf.HTTP.Listen = "[::]:0"
conf.Nanomsg.Enable = true
conf.Nanomsg.Listen = "tcp://127.0.0.1:0"

return util.WriteFile(path, conf.toTOML())
}

func (conf *Config) toTOML() []byte {
buf := new(bytes.Buffer)
encoder := toml.NewEncoder(buf)
Expand Down
13 changes: 13 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ func TestSaveTestnetConfig(t *testing.T) {
assert.Equal(t, conf.Network.Name, "pactus-testnet")
}

func TestSaveLocalnetConfig(t *testing.T) {
path := util.TempFilePath()
assert.NoError(t, SaveLocalnetConfig(path, 4))

conf, err := LoadFromFile(path, true)
assert.NoError(t, err)

assert.NoError(t, conf.SanityCheck())
assert.Equal(t, conf.Network.Name, "pactus-localnet")
assert.Empty(t, conf.Network.Listens)
assert.Empty(t, conf.Network.RelayAddrs)
}

func TestLoadFromFile(t *testing.T) {
path := util.TempFilePath()
_, err := LoadFromFile(path, true)
Expand Down
9 changes: 9 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ and then start the node:
./pactus-daemon start -w=<working_dir>
```

### Local net

You can create a local node to set up a local network for development purposes on your machine:

```text
./pactus-daemon init -w=<working_dir> --localnet
./pactus-daemon start -w=<working_dir>
```

## What is pactus-wallet?

Pactus wallet is a native wallet in the Pactus blockchain that lets users easily manage
Expand Down
15 changes: 9 additions & 6 deletions genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
type ChainType uint8

const (
Unknown ChainType = 0xff
Mainnet ChainType = 0
Testnet ChainType = 1
Mainnet ChainType = 0
Testnet ChainType = 1
Localnet ChainType = 2
)

func (n ChainType) IsTestnet() bool {
return n == Testnet
func (n ChainType) IsMainnet() bool {
return n == Mainnet

Check warning on line 28 in genesis/genesis.go

View check run for this annotation

Codecov / codecov/patch

genesis/genesis.go#L28

Added line #L28 was not covered by tests
}

func (n ChainType) String() string {
Expand All @@ -34,6 +34,8 @@
return "Mainnet"
case Testnet:
return "Testnet"
case Localnet:
return "Localnet"

Check warning on line 38 in genesis/genesis.go

View check run for this annotation

Codecov / codecov/patch

genesis/genesis.go#L37-L38

Added lines #L37 - L38 were not covered by tests
default:
return "Unknown"
}
Expand Down Expand Up @@ -172,6 +174,7 @@
if gen.Hash() == TestnetGenesis().Hash() {
return Testnet
}
// TODO: add mainnet here

return Unknown
return Localnet

Check warning on line 179 in genesis/genesis.go

View check run for this annotation

Codecov / codecov/patch

genesis/genesis.go#L179

Added line #L179 was not covered by tests
}
5 changes: 3 additions & 2 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ func Create(path, mnemonic, password string, chain genesis.ChainType) (*Wallet,
switch chain {
case genesis.Mainnet:
coinType = 21888
case genesis.Testnet:
case genesis.Testnet,
genesis.Localnet:
coinType = 21777
default:
return nil, ErrInvalidNetwork
Expand Down Expand Up @@ -102,7 +103,7 @@ func Create(path, mnemonic, password string, chain genesis.ChainType) (*Wallet,
}

func newWallet(path string, store *store, offline bool) (*Wallet, error) {
if store.Network.IsTestnet() {
if !store.Network.IsMainnet() {
crypto.AddressHRP = "tpc"
crypto.PublicKeyHRP = "tpublic"
crypto.PrivateKeyHRP = "tsecret"
Expand Down