From 9dde9b6f4f4757f7db3c47c43e7affc9114416f7 Mon Sep 17 00:00:00 2001 From: corverroos Date: Mon, 10 Jul 2023 11:24:40 -0400 Subject: [PATCH] cluster/manifest: use hardcoded legacy lock hash --- app/disk.go | 2 +- cluster/manifest/load.go | 2 +- cluster/manifest/load_test.go | 13 ++++- cluster/manifest/mutationaddvalidator_test.go | 2 +- cluster/manifest/mutationlegacylock.go | 40 ++++++++++--- cluster/manifest/mutationlegacylock_test.go | 2 +- cluster/manifest/mutationnodeapproval_test.go | 2 +- cluster/manifest/testdata/lock3.json | 57 +++++++++++++++++++ cmd/addvalidators.go | 2 +- cmd/combine/combine_test.go | 2 +- 10 files changed, 107 insertions(+), 17 deletions(-) create mode 100644 cluster/manifest/testdata/lock3.json diff --git a/app/disk.go b/app/disk.go index 08703707c..393e90fef 100644 --- a/app/disk.go +++ b/app/disk.go @@ -15,7 +15,7 @@ import ( // loadClusterManifest returns the cluster manifest from the given file path. func loadClusterManifest(ctx context.Context, conf Config) (*manifestpb.Cluster, error) { if conf.TestConfig.Lock != nil { - return manifest.NewClusterFromLock(*conf.TestConfig.Lock) + return manifest.NewClusterFromLockForT(nil, *conf.TestConfig.Lock) } verifyLock := func(lock cluster.Lock) error { diff --git a/cluster/manifest/load.go b/cluster/manifest/load.go index a84b2da51..e8389b2fe 100644 --- a/cluster/manifest/load.go +++ b/cluster/manifest/load.go @@ -53,7 +53,7 @@ func loadLegacyLock(input []byte, lockCallback func(cluster.Lock) error) (*manif } } - legacy, err := NewLegacyLock(lock) + legacy, err := NewRawLegacyLock(input) if err != nil { return nil, errors.Wrap(err, "create legacy lock") } diff --git a/cluster/manifest/load_test.go b/cluster/manifest/load_test.go index c3bb87f21..cd4ff6d32 100644 --- a/cluster/manifest/load_test.go +++ b/cluster/manifest/load_test.go @@ -4,6 +4,7 @@ package manifest_test import ( "encoding/json" + "fmt" "math/rand" "os" "path" @@ -34,7 +35,7 @@ func TestLoad(t *testing.T) { var lock cluster.Lock testutil.RequireNoError(t, json.Unmarshal(lockJSON, &lock)) - legacyLock, err := manifest.NewLegacyLock(lock) + legacyLock, err := manifest.NewLegacyLockForT(t, lock) require.NoError(t, err) cluster, err := manifest.Materialise(&manifestpb.SignedMutationList{Mutations: []*manifestpb.SignedMutation{legacyLock}}) @@ -129,3 +130,13 @@ func testLoadLegacy(t *testing.T, version string) { require.Equal(t, lock.Operators[i].ENR, operator.Enr) } } + +// TestLoadModifiedLegacyLock ensure the incorrect hard-coded hash is used for +// legacy locks. This ensures the cluster hash doesn't change even if lock files +// were modified and run with --no-verify. +func TestLoadModifiedLegacyLock(t *testing.T) { + cluster, err := manifest.Load("", "testdata/lock3.json", nil) + require.NoError(t, err) + hashHex := fmt.Sprintf("%x", cluster.InitialMutationHash) + require.Equal(t, "4073fe542", hashHex[:9]) +} diff --git a/cluster/manifest/mutationaddvalidator_test.go b/cluster/manifest/mutationaddvalidator_test.go index 885a07861..a2a958991 100644 --- a/cluster/manifest/mutationaddvalidator_test.go +++ b/cluster/manifest/mutationaddvalidator_test.go @@ -113,7 +113,7 @@ func TestAddValidators(t *testing.T) { }) t.Run("transform", func(t *testing.T) { - cluster, err := manifest.NewClusterFromLock(lock) + cluster, err := manifest.NewClusterFromLockForT(t, lock) require.NoError(t, err) cluster.Validators = nil diff --git a/cluster/manifest/mutationlegacylock.go b/cluster/manifest/mutationlegacylock.go index 13c56012a..46e83a3cf 100644 --- a/cluster/manifest/mutationlegacylock.go +++ b/cluster/manifest/mutationlegacylock.go @@ -3,7 +3,9 @@ package manifest import ( + "bytes" "encoding/json" + "testing" "time" "google.golang.org/protobuf/proto" @@ -15,8 +17,8 @@ import ( manifestpb "github.com/obolnetwork/charon/cluster/manifestpb/v1" ) -func NewClusterFromLock(lock cluster.Lock) (*manifestpb.Cluster, error) { - signed, err := NewLegacyLock(lock) +func NewClusterFromLockForT(_ *testing.T, lock cluster.Lock) (*manifestpb.Cluster, error) { + signed, err := NewLegacyLockForT(nil, lock) if err != nil { return nil, err } @@ -24,16 +26,17 @@ func NewClusterFromLock(lock cluster.Lock) (*manifestpb.Cluster, error) { return Materialise(&manifestpb.SignedMutationList{Mutations: []*manifestpb.SignedMutation{signed}}) } -// NewLegacyLock return a new legacy lock mutation from the provided lock. -func NewLegacyLock(lock cluster.Lock) (*manifestpb.SignedMutation, error) { - timestamp, err := time.Parse(time.RFC3339, lock.Timestamp) - if err != nil { - return nil, errors.Wrap(err, "parse lock timestamp") +// NewRawLegacyLock return a new legacy lock mutation from the provided raw json bytes. +func NewRawLegacyLock(b []byte) (*manifestpb.SignedMutation, error) { + // Verify that the bytes is a valid lock. + var l cluster.Lock + if err := json.Unmarshal(b, &l); err != nil { + return nil, errors.Wrap(err, "unmarshal lock") } - b, err := json.Marshal(lock) + timestamp, err := time.Parse(time.RFC3339, l.Timestamp) if err != nil { - return nil, errors.Wrap(err, "marshal lock") + return nil, errors.Wrap(err, "parse lock timestamp") } lockAny, err := anypb.New(&manifestpb.LegacyLock{Json: b}) @@ -54,6 +57,25 @@ func NewLegacyLock(lock cluster.Lock) (*manifestpb.SignedMutation, error) { }, nil } +// NewLegacyLockForT return a new legacy lock mutation from the provided lock. +func NewLegacyLockForT(_ *testing.T, lock cluster.Lock) (*manifestpb.SignedMutation, error) { + // Marshalling below re-calculates the lock hash, so ensure it matches. + lock2, err := lock.SetLockHash() + if err != nil { + return nil, errors.Wrap(err, "set lock hash") + } else if !bytes.Equal(lock2.LockHash, lock.LockHash) { + return nil, errors.New("this method only supports valid locks," + + " use NewRawLegacyLock for --no-verify support") + } + + b, err := json.Marshal(lock) + if err != nil { + return nil, errors.Wrap(err, "marshal lock") + } + + return NewRawLegacyLock(b) +} + // verifyLegacyLock verifies that the signed mutation is a valid legacy lock. func verifyLegacyLock(signed *manifestpb.SignedMutation) error { if MutationType(signed.Mutation.Type) != TypeLegacyLock { diff --git a/cluster/manifest/mutationlegacylock_test.go b/cluster/manifest/mutationlegacylock_test.go index 1d26cf0bd..adf48626b 100644 --- a/cluster/manifest/mutationlegacylock_test.go +++ b/cluster/manifest/mutationlegacylock_test.go @@ -31,7 +31,7 @@ func TestLegacyLock(t *testing.T) { var lock cluster.Lock testutil.RequireNoError(t, json.Unmarshal(lockJSON, &lock)) - legacyLock, err := manifest.NewLegacyLock(lock) + legacyLock, err := manifest.NewLegacyLockForT(t, lock) require.NoError(t, err) t.Run("proto", func(t *testing.T) { diff --git a/cluster/manifest/mutationnodeapproval_test.go b/cluster/manifest/mutationnodeapproval_test.go index 16ee8b5d6..d012b213f 100644 --- a/cluster/manifest/mutationnodeapproval_test.go +++ b/cluster/manifest/mutationnodeapproval_test.go @@ -64,7 +64,7 @@ func TestNodeApprovals(t *testing.T) { }) t.Run("transform", func(t *testing.T) { - cluster, err := manifest.NewClusterFromLock(lock) + cluster, err := manifest.NewClusterFromLockForT(t, lock) require.NoError(t, err) cluster2, err := manifest.Transform(cluster, composite) diff --git a/cluster/manifest/testdata/lock3.json b/cluster/manifest/testdata/lock3.json new file mode 100644 index 000000000..efa57fe33 --- /dev/null +++ b/cluster/manifest/testdata/lock3.json @@ -0,0 +1,57 @@ +{ + "cluster_definition": { + "name": "charon-prater-0", + "operators": [ + { + "address": "", + "enr": "enr:-HW4QF2RMV8obWowPwISf9fc3dQr2zw8U1DEqfu6Ar2uqQ6MKzTFwXqJSgM3iD9DaVPVY68isJObJV6FnfH3u0AOiUeAgmlkgnY0iXNlY3AyNTZrMaEDrQnhqfEOaHhhf3QXxY4uHRqILOMyMZuJUeFoltYE2Jc=", + "nonce": 0, + "config_signature": null, + "enr_signature": null + }, + { + "address": "", + "enr": "enr:-HW4QAc81iqAqHBRgAhPKqbda6oE31-0pkPuDaHuY90famQOIFF8UC-oa2fL4squdB_XAfmWFRv_FHTl0VVEkeR-KXGAgmlkgnY0iXNlY3AyNTZrMaECUi2Tux-Xh4J37bysHp7RVFclh9FO8A4TDaOJoturxDU=", + "nonce": 0, + "config_signature": null, + "enr_signature": null + }, + { + "address": "", + "enr": "enr:-HW4QP6hfTWouGrDs-C_1aoE5eHSNkYjq4CVU_JbFW5mEF9cdmcxIzGYAjUvOrHzHHck7PIdx90CtJ13ecHvvMz-X-2AgmlkgnY0iXNlY3AyNTZrMaEDXUMw0caVYc5QkbcyOZsM_x_OH8yM9zGdHbwaaaYtC_w=", + "nonce": 0, + "config_signature": null, + "enr_signature": null + }, + { + "address": "", + "enr": "enr:-HW4QMfl_MRPeNcytOtcKkVcozl0njNpdOCOWXa3TsBVGieWT8SrW1Fjjd_OCiAHubHKKvrLX77OywINd-m-TR4fzeeAgmlkgnY0iXNlY3AyNTZrMaECU1nCUb_kkmBfZhoTJbTfERVTwy_eCJAGtbUtJXq3NmQ=", + "nonce": 0, + "config_signature": null, + "enr_signature": null + } + ], + "timestamp": "2022-07-28T20:14:55+05:30", + "uuid": "AADB7802-4799-1F64-8A50-A0DC06E150B5", + "version": "v1.0.0", + "num_validators": 1, + "threshold": 3, + "dkg_algorithm": "default", + "fork_version": "0x00001020", + "config_hash": "MapzsnNQdn+vtDWPQIJBx42ksUshUIsoldOutrUBSIc=", + "definition_hash": "loLR8lM92XGS5RSvI9O3urZwTcmBBk21NdTlmjtOw0I=" + }, + "distributed_validators": [ + { + "distributed_public_key": "0x84c3aae6124973ad260ab2f783dfbcf512502c5b3dc174ecf624021361439dcc299d59718fed01c42691a9d7ba20f3d8", + "public_shares": [ + "tUPZ6bcIk9WsYY7Xz5A3Z3KI9iP4pkMszyDyYLChrSaGbVjN3mXw35H0rZwBC6MK", + "ofY0DKMUDakt7CChpdhLlGMOT03Lz/OV4l7srA8sO8ky4El37HezbS4kglL1kz/n", + "jNHlrN1eCoPaAr7NBdytgN5N6NBER+/ViQfgl8t9udvVgZgRoryZfgXln0E/uwDK", + "lMeTwxhP7VMVBbLSgavO8y7x5RIK9bz59GhVEmOTv8xmTv8b8tj2qsv5UejOnJXE" + ] + } + ], + "signature_aggregate": null, + "lock_hash": "QHP+VCPyLO5ecXxKEwaZu1qcBHxXzOtAVOXtv1I5ttI=" +} \ No newline at end of file diff --git a/cmd/addvalidators.go b/cmd/addvalidators.go index ed0cb6c0c..57a45534d 100644 --- a/cmd/addvalidators.go +++ b/cmd/addvalidators.go @@ -100,7 +100,7 @@ func runAddValidatorsSolo(ctx context.Context, conf addValidatorsConfig) (err er if conf.TestConfig.Manifest != nil { cluster = conf.TestConfig.Manifest } else if conf.TestConfig.Lock != nil { - cluster, err = manifest.NewClusterFromLock(*conf.TestConfig.Lock) + cluster, err = manifest.NewClusterFromLockForT(nil, *conf.TestConfig.Lock) if err != nil { return err } diff --git a/cmd/combine/combine_test.go b/cmd/combine/combine_test.go index ca0c4ea75..9b400ef21 100644 --- a/cmd/combine/combine_test.go +++ b/cmd/combine/combine_test.go @@ -184,7 +184,7 @@ func writeManifest( lock cluster.Lock, ) { t.Helper() - legacy, err := manifest.NewLegacyLock(modifyLockFile(valIdx, lock)) + legacy, err := manifest.NewLegacyLockForT(t, modifyLockFile(valIdx, lock)) require.NoError(t, err) cluster, err := manifest.Materialise(&manifestpb.SignedMutationList{Mutations: []*manifestpb.SignedMutation{legacy}})