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

Update postcli for compatibility with multismeshing #270

Merged
merged 8 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ install: get-postrs-lib
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.54.2
go install gotest.tools/[email protected]
go install honnef.co/go/tools/cmd/[email protected]
go install go.uber.org/mock/mockgen@v0.3.0
go install go.uber.org/mock/mockgen@v0.4.0
.PHONY: install

tidy:
Expand Down
182 changes: 128 additions & 54 deletions cmd/postcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"github.com/spacemeshos/post/verifying"
)

const edKeyFileName = "key.bin"
const edKeyFileName = "identity.key"

var (
cfg = config.MainnetConfig()
Expand All @@ -41,9 +41,7 @@ var (
fraction float64

idHex string
id []byte
commitmentAtxIdHex string
commitmentAtxId []byte
reset bool
numUnits uint64

Expand Down Expand Up @@ -102,75 +100,144 @@ func askForConfirmation() {
return
}

fmt.Println("Are you sure you want to continue (y/N)?")
log.Println("Are you sure you want to continue (y/N)?")

var answer string
_, err := fmt.Scanln(&answer)
if err != nil || !(answer == "y" || answer == "Y") {
fmt.Println("Aborting")
os.Exit(1)
log.Fatal("Aborting")
}
}

func processFlags() error {
func processFlags() {
meta, err := initialization.LoadMetadata(opts.DataDir)
switch {
case errors.Is(err, initialization.ErrStateMetadataFileMissing):
case err != nil:
log.Fatalln("failed to load metadata:", err)
default:
if idHex == "" {
idHex = hex.EncodeToString(meta.NodeId)
} else if idHex != hex.EncodeToString(meta.NodeId) {
log.Println("WARNING: it appears that", opts.DataDir, "was previously initialized with a different `id` value.")
log.Println("\tCurrent value:", hex.EncodeToString(meta.NodeId))
log.Println("\tValue passed to postcli:", idHex)
if !yes {
log.Println("CONTINUING MIGHT ERASE EXISTING DATA. MAKE ABSOLUTELY SURE YOU SPECIFY THE CORRECT VALUE.")
}
askForConfirmation()
}
}

key, err := loadKey()
switch {
case errors.Is(err, os.ErrNotExist):
case err != nil:
log.Fatalln("failed to load key:", err)
case meta != nil && !bytes.Equal(meta.NodeId, key):
log.Fatalln("WARNING: inconsistent state:", edKeyFileName, "file does not match metadata in", opts.DataDir)
default:
if idHex == "" {
idHex = hex.EncodeToString(key)
} else if idHex != hex.EncodeToString(key) {
log.Println("WARNING: it appears that", opts.DataDir, "was previously initialized with a generated key.")
log.Println("The provided id does not match the generated key.")
log.Println("\tCurrent value:", hex.EncodeToString(key))
log.Println("\tValue passed to postcli:", idHex)
if !yes {
log.Println("CONTINUING MIGHT ERASE EXISTING DATA. MAKE ABSOLUTELY SURE YOU SPECIFY THE CORRECT VALUE.")
}
askForConfirmation()
}
fasmat marked this conversation as resolved.
Show resolved Hide resolved
}

// we require the user to explicitly pass numUnits to avoid erasing existing data
if !flagSet["numUnits"] {
return fmt.Errorf("-numUnits must be specified to perform initialization. to use the default value, "+
"run with -numUnits %d. note: if there's more than this amount of data on disk, "+
"THIS WILL ERASE EXISTING DATA. MAKE ABSOLUTELY SURE YOU SPECIFY THE CORRECT VALUE", opts.NumUnits)
if !flagSet["numUnits"] && meta != nil {
log.Fatalln("-numUnits must be specified to perform initialization.")
}

if flagSet["numUnits"] && numUnits != uint64(meta.NumUnits) {
log.Println("WARNING: it appears that", opts.DataDir, "was previously initialized with a different `numUnits` value.")
log.Println("\tCurrent value:", meta.NumUnits)
log.Println("\tValue passed to postcli:", numUnits)
if (numUnits < uint64(meta.NumUnits)) && !yes {
log.Println("CONTINUING MIGHT ERASE EXISTING DATA. MAKE ABSOLUTELY SURE YOU SPECIFY THE CORRECT VALUE.")
}
askForConfirmation()
}

if flagSet["numUnits"] && (numUnits < uint64(cfg.MinNumUnits) || numUnits > uint64(cfg.MaxNumUnits)) {
fmt.Println("WARNING: numUnits is outside of range valid for mainnet (min:",
log.Println("WARNING: numUnits is outside of range valid for mainnet (min:",
cfg.MinNumUnits, "max:", cfg.MaxNumUnits, ")")
if !yes {
log.Println("CONTINUING WILL INITIALIZE DATA INCOMPATIBLE WITH MAINNET. MAKE ABSOLUTELY SURE YOU WANT TO DO THIS.")
}
askForConfirmation()
cfg.MinNumUnits = uint32(numUnits)
cfg.MaxNumUnits = uint32(numUnits)
}

if !flagSet["provider"] {
return errors.New("-provider flag is required")
if !flagSet["commitmentAtxId"] && meta != nil {
log.Fatalln("-commitmentAtxId must be specified to perform initialization.")
}

if !flagSet["commitmentAtxId"] {
return errors.New("-commitmentAtxId flag is required")
if flagSet["commitmentAtxId"] {
commitmentAtxId, err := hex.DecodeString(commitmentAtxIdHex)
if err != nil {
log.Println("invalid commitmentAtxId:", err)
}
if meta != nil && !bytes.Equal(commitmentAtxId, meta.CommitmentAtxId) {
log.Println("WARNING: it appears that", opts.DataDir, "was previously initialized with a different `commitmentAtxId` value.")
log.Println("\tCurrent value:", hex.EncodeToString(meta.CommitmentAtxId))
log.Println("\tValue passed to postcli:", commitmentAtxIdHex)
if !yes {
log.Println("CONTINUING MIGHT ERASE EXISTING DATA. MAKE ABSOLUTELY SURE YOU SPECIFY THE CORRECT VALUE.")
}
askForConfirmation()
commitmentAtxIdHex = hex.EncodeToString(meta.CommitmentAtxId)
}
fasmat marked this conversation as resolved.
Show resolved Hide resolved
}
var err error
commitmentAtxId, err = hex.DecodeString(commitmentAtxIdHex)
if err != nil {
return fmt.Errorf("invalid commitmentAtxId: %w", err)

if !flagSet["provider"] {
log.Fatalln("-provider flag is required")
}

if flagSet["labelsPerUnit"] && (cfg.LabelsPerUnit != config.MainnetConfig().LabelsPerUnit) {
fmt.Println("WARNING: labelsPerUnit is set to a non-default value. This makes the initialization incompatible " +
"with mainnet. If you're trying to initialize for mainnet, please remove the -labelsPerUnit flag")
log.Println("WARNING: labelsPerUnit is set to a non-default value.")
log.Println("If you're trying to initialize for mainnet, please remove the -labelsPerUnit flag")
if !yes {
log.Println("CONTINUING WILL INITIALIZE DATA INCOMPATIBLE WITH MAINNET. MAKE ABSOLUTELY SURE YOU WANT TO DO THIS.")
}
askForConfirmation()
}

if flagSet["scryptN"] {
fmt.Println("WARNING: scryptN is set to a non-default value. This makes the initialization incompatible " +
"with mainnet. If you're trying to initialize for mainnet, please remove the -scryptN flag")
if flagSet["scryptN"] && (opts.Scrypt.N != config.MainnetInitOpts().Scrypt.N) {
log.Println("WARNING: scryptN is set to a non-default value.")
log.Println("If you're trying to initialize for mainnet, please remove the -scryptN flag")
if !yes {
log.Println("CONTINUING WILL INITIALIZE DATA INCOMPATIBLE WITH MAINNET. MAKE ABSOLUTELY SURE YOU WANT TO DO THIS.")
}
askForConfirmation()
}

if (opts.FromFileIdx != 0 || opts.ToFileIdx != nil) && idHex == "" {
return errors.New("-id flag is required when using -fromFile or -toFile")
log.Fatalln("-id flag is required when using -fromFile or -toFile")
}

if idHex == "" {
log.Println("cli: generating new identity")
pub, priv, err := ed25519.GenerateKey(nil)
if err != nil {
return fmt.Errorf("failed to generate identity: %w", err)
log.Fatalln("failed to generate identity:", err)
}
id = pub
log.Printf("cli: generated id %x\n", id)
return saveKey(priv)
}
id, err = hex.DecodeString(idHex)
if err != nil {
return fmt.Errorf("invalid id: %w", err)
if err := saveKey(priv); err != nil {
log.Fatalln("failed to save identity:", err)
}
idHex = hex.EncodeToString(pub)
log.Println("generated key in", edKeyFileName)
log.Println("copy this file to the `data/identities` directory of your node")
return
}
return nil
}

func main() {
Expand All @@ -187,7 +254,7 @@ func main() {

if printNumFiles {
totalFiles := opts.TotalFiles(cfg.LabelsPerUnit)
fmt.Println(totalFiles)
log.Println(totalFiles)
return
}

Expand Down Expand Up @@ -248,12 +315,16 @@ func main() {
return
}

err = processFlags()
switch {
case errors.Is(err, ErrKeyFileExists):
log.Fatalln("cli: key file already exists. This appears to be a mistake. If you're trying to initialize a new identity delete key.bin and try again otherwise specify identity with `-id` flag")
case err != nil:
log.Fatalln("failed to process flags:", err)
processFlags()

id, err := hex.DecodeString(idHex)
if err != nil {
log.Fatalf("failed to decode id %s: %s\n", idHex, err)
}

commitmentAtxId, err := hex.DecodeString(commitmentAtxIdHex)
if err != nil {
log.Fatalf("failed to decode commitmentAtxId %s: %s\n", commitmentAtxIdHex, err)
}

init, err := initialization.NewInitializer(
Expand All @@ -277,11 +348,8 @@ func main() {

err = init.Initialize(ctx)
switch {
case errors.Is(err, shared.ErrInitCompleted):
log.Panic(err.Error())
return
case errors.Is(err, context.Canceled):
log.Println("cli: initialization interrupted")
log.Fatalln("cli: initialization interrupted")
return
case err != nil:
log.Println("cli: initialization error", err)
Expand Down Expand Up @@ -327,13 +395,11 @@ func saveKey(key ed25519.PrivateKey) error {
return nil
}

func cmdVerifyPos(opts config.InitOpts, fraction float64, logger *zap.Logger) {
log.Println("cli: verifying key.bin")

func loadKey() (ed25519.PublicKey, error) {
keyPath := filepath.Join(opts.DataDir, edKeyFileName)
data, err := os.ReadFile(keyPath)
if err != nil {
log.Fatalf("could not read private key from %s: %s\n", keyPath, err)
return nil, fmt.Errorf("could not read private key from %s: %w", keyPath, err)
}

dst := make([]byte, ed25519.PrivateKeySize)
Expand All @@ -344,19 +410,27 @@ func cmdVerifyPos(opts config.InitOpts, fraction float64, logger *zap.Logger) {
if n != ed25519.PrivateKeySize {
log.Fatalf("size of key (%d) not expected size %d\n", n, ed25519.PrivateKeySize)
}
pub := ed25519.NewKeyFromSeed(dst[:ed25519.SeedSize]).Public().(ed25519.PublicKey)
return ed25519.NewKeyFromSeed(dst[:ed25519.SeedSize]).Public().(ed25519.PublicKey), nil
}

func cmdVerifyPos(opts config.InitOpts, fraction float64, logger *zap.Logger) {
log.Println("cli: verifying", edKeyFileName)
pub, err := loadKey()
if err != nil {
log.Fatalf("failed to load public key from %s: %s\n", edKeyFileName, err)
}
poszu marked this conversation as resolved.
Show resolved Hide resolved

metafile := filepath.Join(opts.DataDir, initialization.MetadataFileName)
metaFile := filepath.Join(opts.DataDir, initialization.MetadataFileName)
meta, err := initialization.LoadMetadata(opts.DataDir)
if err != nil {
log.Fatalf("failed to load metadata from %s: %s\n", opts.DataDir, err)
}

if !bytes.Equal(meta.NodeId, pub) {
log.Fatalf("NodeID in %s (%x) does not match public key from key.bin (%x)", metafile, meta.NodeId, pub)
log.Fatalf("NodeID in %s (%x) does not match public key from %s (%x)", metaFile, meta.NodeId, edKeyFileName, pub)
}

log.Println("cli: key.bin is valid")
log.Println("cli:", edKeyFileName, "is valid")
log.Println("cli: verifying POS data")

params := postrs.NewScryptParams(opts.Scrypt.N, opts.Scrypt.R, opts.Scrypt.P)
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/spacemeshos/post

go 1.20
go 1.21

require (
github.com/davecgh/go-spew v1.1.1
Expand All @@ -13,9 +13,9 @@ require (
)

require (
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
9 changes: 5 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -16,6 +16,7 @@ github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvv
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
Expand All @@ -25,8 +26,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
Loading