Skip to content

Commit

Permalink
POS verification in postcli
Browse files Browse the repository at this point in the history
  • Loading branch information
poszu committed Jul 17, 2023
1 parent cdd8699 commit 677cfc3
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Makefile.Inc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ else
endif
endif

POSTRS_SETUP_REV = 0.4.0
POSTRS_SETUP_REV = 0.4.1-rc1
POSTRS_SETUP_ZIP = libpost-$(platform)-v$(POSTRS_SETUP_REV).zip
POSTRS_SETUP_URL_ZIP ?= https://github.com/spacemeshos/post-rs/releases/download/v$(POSTRS_SETUP_REV)/$(POSTRS_SETUP_ZIP)
ifeq ($(platform), windows)
Expand Down
59 changes: 48 additions & 11 deletions cmd/postcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ import (
const edKeyFileName = "key.bin"

var (
cfg = config.MainnetConfig()
opts = config.MainnetInitOpts()
printProviders bool
printNumFiles bool
printConfig bool
genProof bool
cfg = config.MainnetConfig()
opts = config.MainnetInitOpts()
printProviders bool
printNumFiles bool
printConfig bool
genProof bool

verifyPos bool
fraction float64

idHex string
id []byte
commitmentAtxIdHex string
Expand All @@ -41,6 +45,9 @@ var (
)

func parseFlags() {
flag.BoolVar(&verifyPos, "verify", false, "verify initialized data")
flag.Float64Var(&fraction, "fraction", 1.0, "fraction of POS data to verify")

flag.BoolVar(&printProviders, "printProviders", false, "print the list of compute providers")
flag.BoolVar(&printNumFiles, "printNumFiles", false, "print the total number of files that would be initialized")
flag.BoolVar(&printConfig, "printConfig", false, "print the used config and options")
Expand Down Expand Up @@ -121,14 +128,20 @@ func main() {
return
}

if err := processFlags(); err != nil {
log.Fatalln("failed to process flags", err)
}

zapLog, err := zap.NewProduction()
zapLog, err := zap.NewProduction(zap.AddStacktrace(zap.PanicLevel))
if err != nil {
log.Fatalln("failed to initialize zap logger:", err)
}
postrs.SetLogCallback(zapLog)

if verifyPos {
ec := cmdVerifyPos(opts, fraction)
os.Exit(ec)
}

if err := processFlags(); err != nil {
log.Fatalln("failed to process flags", err)
}

init, err := initialization.NewInitializer(
initialization.WithConfig(cfg),
Expand Down Expand Up @@ -198,3 +211,27 @@ func saveKey(key ed25519.PrivateKey) error {
}
return nil
}

func cmdVerifyPos(opts config.InitOpts, fraction float64) int {
params := postrs.TranslateScryptParams(opts.Scrypt.N, opts.Scrypt.R, opts.Scrypt.P)
verifyOpts := []postrs.VerifyPosOptionsFunc{
postrs.WithFraction(fraction),
postrs.FromFile(uint32(opts.FromFileIdx)),
}
if opts.ToFileIdx != nil {
verifyOpts = append(verifyOpts, postrs.ToFile(uint32(*opts.ToFileIdx)))
}

err := postrs.VerifyPos(opts.DataDir, params, verifyOpts...)
switch {
case err == nil:
log.Println("cli: POS data is valid")
return 0
case errors.Is(err, postrs.ErrInvalidPos):
log.Println(err)
return 1
default:
log.Printf("cli: failed (%v)\n", err)
return 2
}
}
59 changes: 59 additions & 0 deletions initialization/pos_verification_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package initialization

import (
"context"
"os"
"testing"

"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"

"github.com/spacemeshos/post/config"
"github.com/spacemeshos/post/internal/postrs"
)

func TestVerifyPos(t *testing.T) {
r := require.New(t)
cfg := config.DefaultConfig()
cfg.LabelsPerUnit = 128

opts := config.DefaultInitOpts()
opts.DataDir = t.TempDir()
opts.NumUnits = 5
opts.MaxFileSize = 2 * cfg.UnitSize()
opts.ProviderID = int(CPUProviderID())
opts.Scrypt.N = 2

init, err := NewInitializer(
WithNodeId(nodeId),
WithCommitmentAtxId(commitmentAtxId),
WithConfig(cfg),
WithInitOpts(opts),
WithLogger(zaptest.NewLogger(t, zaptest.Level(zap.DebugLevel))),
)
r.NoError(err)
err = init.Initialize(context.Background())
r.NoError(err)

scryptParams := postrs.TranslateScryptParams(opts.Scrypt.N, opts.Scrypt.R, opts.Scrypt.P)

t.Run("valid", func(t *testing.T) {
err = postrs.VerifyPos(opts.DataDir, scryptParams, postrs.WithFraction(100.0))
r.NoError(err)
})
t.Run("invalid N", func(t *testing.T) {
wrongScrypt := postrs.TranslateScryptParams(4, opts.Scrypt.R, opts.Scrypt.P)
err = postrs.VerifyPos(opts.DataDir, wrongScrypt, postrs.WithFraction(100.0))
r.ErrorContains(err, "invalid POS")
})
t.Run("corrupted data", func(t *testing.T) {
file, err := os.OpenFile(opts.DataDir+"/postdata_0.bin", os.O_WRONLY, 0)
r.NoError(err)
_, err = file.WriteAt([]byte("1234567890123456"), 0)
r.NoError(err)

err = postrs.VerifyPos(opts.DataDir, scryptParams, postrs.WithFraction(100.0))
r.ErrorContains(err, "invalid POS")
})
}
2 changes: 1 addition & 1 deletion internal/postrs/initializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func InitResultToError(retVal uint32) error {
// initializer.
func cNewInitializer(opt *option) (*C.Initializer, error) {
if opt.logger != nil {
setLogCallback(opt.logger)
SetLogCallback(opt.logger)
}

cProviderId := C.uint32_t(*opt.providerID)
Expand Down
2 changes: 1 addition & 1 deletion internal/postrs/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var (
}
)

func setLogCallback(logger *zap.Logger) {
func SetLogCallback(logger *zap.Logger) {
oncer.Do(func() {
C.set_logging_callback(levelMap[logger.Level()], C.callback(C.logCallback))
log = logger
Expand Down
69 changes: 69 additions & 0 deletions internal/postrs/pos_verifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package postrs

// #cgo LDFLAGS: -lpost
// #include <stdlib.h>
// #include "post.h"
import "C"

import (
"errors"
"unsafe"
)

type VerifyPosOptions struct {
fromFile *uint32
toFile *uint32
fraction float64
}

var ErrInvalidPos = errors.New("invalid POS")

type VerifyPosOptionsFunc func(*VerifyPosOptions) error

func FromFile(fromFile uint32) VerifyPosOptionsFunc {
return func(o *VerifyPosOptions) error {
o.fromFile = &fromFile
return nil
}
}

func ToFile(toFile uint32) VerifyPosOptionsFunc {
return func(o *VerifyPosOptions) error {
o.toFile = &toFile
return nil
}
}

func WithFraction(fraction float64) VerifyPosOptionsFunc {
return func(o *VerifyPosOptions) error {
o.fraction = fraction
return nil
}
}

func VerifyPos(dataDir string, scryptParams ScryptParams, o ...VerifyPosOptionsFunc) error {
opts := &VerifyPosOptions{
fraction: 5.0,
}

for _, opt := range o {
if err := opt(opts); err != nil {
return err
}
}

dataDirPtr := C.CString(dataDir)
defer C.free(unsafe.Pointer(dataDirPtr))

result := C.verify_pos(dataDirPtr, (*C.uint32_t)(opts.fromFile), (*C.uint32_t)(opts.toFile), C.double(opts.fraction), scryptParams)
switch result {
case C.Ok:
return nil
case C.Invalid:
return ErrInvalidPos
case C.InvalidArgument:
return ErrInvalidArgument
default:
return ErrUnknown
}
}
4 changes: 2 additions & 2 deletions internal/postrs/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func GenerateProof(dataDir string, challenge []byte, logger *zap.Logger, nonces,
}
}
if logger != nil {
setLogCallback(logger)
SetLogCallback(logger)
}

dataDirPtr := C.CString(dataDir)
Expand Down Expand Up @@ -175,7 +175,7 @@ func (v *Verifier) VerifyProof(
}
}
if logger != nil {
setLogCallback(logger)
SetLogCallback(logger)
}

if proof == nil {
Expand Down

0 comments on commit 677cfc3

Please sign in to comment.