diff --git a/eotsmanager/cmd/eotsd/daemon/pop.go b/eotsmanager/cmd/eotsd/daemon/pop.go index 38235550..b151a1ae 100644 --- a/eotsmanager/cmd/eotsd/daemon/pop.go +++ b/eotsmanager/cmd/eotsd/daemon/pop.go @@ -67,9 +67,13 @@ type PoPExportDelete struct { var ( PoPCommands = cli.Command{ - Name: "pop", - Usage: "Proof of Possession commands", - Subcommands: cli.Commands{PoPExportCommand, PoPDeleteCommand}, + Name: "pop", + Usage: "Proof of Possession commands", + Subcommands: cli.Commands{ + PoPExportCommand, + PoPDeleteCommand, + PoPValidateExportCommand, + }, } PoPExportCommand = cli.Command{ Name: "export", @@ -164,6 +168,19 @@ var ( }, Action: deletePop, } + PoPValidateExportCommand = cli.Command{ + Name: "validate", + Usage: "Validates the PoP of the pop export command.", + Description: `Receives as an argument the output of eotsd pop export as a raw string '{...}'`, + UsageText: `eotsd pop validate '{ + "eotsPublicKey": "3d0bebcbe800236ce8603c5bb1ab6c2af0932e947db4956a338f119797c37f1e", + "babyPublicKey": "A0V6yw74EdvoAWVauFqkH/GVM9YIpZitZf6bVEzG69tT", + "babySignEotsPk": "GO7xlC+BIypdcQdnIDsM+Ts75X9JKTOkDpXt5t4TSOIt/P1puAHVNhaYbweStVs25J9uRK+4XfrjD0M+t0Qy4g==", + "eotsSignBaby": "pR6vxgU0gXq+VqO+y7dHpZgHTz3zr5hdqXXh0WcWNkqUnRjHrizhYAHDMV8gh4vks4PqzKAIgZ779Wqwf5UrXQ==", + "babyAddress": "bbn1f04czxeqprn0s9fe7kdzqyde2e6nqj63dllwsm" +}'`, + Action: validatePop, + } ) func exportPop(ctx *cli.Context) error { @@ -217,6 +234,27 @@ func exportPop(ctx *cli.Context) error { return nil } +func validatePop(ctx *cli.Context) error { + args := ctx.Args() + strExportJSON := args.First() + var pop PoPExport + if err := json.Unmarshal([]byte(strExportJSON), &pop); err != nil { + return fmt.Errorf("failed to marshal %s into PoPExport structure", strExportJSON) + } + + valid, err := ValidPopExport(pop) + if err != nil { + return fmt.Errorf("failed to validate pop %+v, reason: %w", pop, err) + } + if !valid { + return fmt.Errorf("invalid pop %+v", pop) + } + + fmt.Println("Proof of Possession is valid!") + + return nil +} + func deletePop(ctx *cli.Context) error { eotsHomePath, eotsKeyName, eotsFpPubKeyStr, eotsKeyringBackend, err := eotsFlags(ctx) if err != nil { @@ -417,7 +455,7 @@ func SignCosmosAdr36( return babySignBytes, nil } -func VerifyPopExport(pop PoPExport) (bool, error) { +func ValidPopExport(pop PoPExport) (bool, error) { valid, err := ValidEotsSignBaby(pop.EotsPublicKey, pop.BabyAddress, pop.EotsSignBaby) if err != nil || !valid { return false, err diff --git a/eotsmanager/cmd/eotsd/daemon/pop_test.go b/eotsmanager/cmd/eotsd/daemon/pop_test.go index 2044fccd..28e76359 100644 --- a/eotsmanager/cmd/eotsd/daemon/pop_test.go +++ b/eotsmanager/cmd/eotsd/daemon/pop_test.go @@ -1,7 +1,10 @@ package daemon_test import ( + "encoding/json" + "math/rand" "testing" + "time" "github.com/babylonlabs-io/finality-provider/eotsmanager/cmd/eotsd/daemon" "github.com/stretchr/testify/require" @@ -59,8 +62,23 @@ func TestPoPValidBabySignEotsPk(t *testing.T) { func TestPoPVerify(t *testing.T) { t.Parallel() for _, pop := range popsToVerify { - valid, err := daemon.VerifyPopExport(pop) + valid, err := daemon.ValidPopExport(pop) require.NoError(t, err) require.True(t, valid) } } + +func TestPoPValidate(t *testing.T) { + t.Parallel() + app := testApp() + + r := rand.New(rand.NewSource(time.Now().Unix())) + for _, pop := range popsToVerify { + jsonString, err := json.MarshalIndent(pop, "", " ") + require.NoError(t, err) + + outputKeysAdd := appRunWithOutput(r, t, app, []string{"eotsd", "pop", "validate", string(jsonString)}) + + require.Equal(t, outputKeysAdd, "Proof of Possession is valid!\n") + } +}