From cc1420fc44bfb5f1f16fe96d145808732c0535ab Mon Sep 17 00:00:00 2001 From: Yang Hau Date: Mon, 18 Sep 2023 17:55:40 +0200 Subject: [PATCH] fix: Fix blobHash collision --- .../wasm/corecontracts/test/core_blob_test.go | 4 +- packages/vm/core/blob/internal.go | 14 ++++-- packages/vm/core/blob/internal_test.go | 44 +++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 packages/vm/core/blob/internal_test.go diff --git a/contracts/wasm/corecontracts/test/core_blob_test.go b/contracts/wasm/corecontracts/test/core_blob_test.go index 2f0f0238ce..387de372f0 100644 --- a/contracts/wasm/corecontracts/test/core_blob_test.go +++ b/contracts/wasm/corecontracts/test/core_blob_test.go @@ -14,7 +14,7 @@ import ( ) // this is the expected blob hash for key0/val0 key1/val1 -const expectedBlobHash = "0x5fec3bfc701d80bdf75e337cb3dcb401c2423d15fc17a74d5b644dae143118b1" +const expectedBlobHash = "0xc3a428b98c8a0385da56aceaa36d82032fb22fe372bb78b9ec9993a24acb1d35" func setupBlob(t *testing.T) *wasmsolo.SoloContext { ctx := setup(t) @@ -81,7 +81,7 @@ func TestListBlobs(t *testing.T) { fStore.Params.Blobs().GetBytes("key1").SetValue([]byte("_val1")) fStore.Func.Post() require.NoError(t, ctx.Err) - expectedHash := "0x462af4abe5977f4dd985a0a097705925b9fa6c033c9d931c1e2171f710693462" + expectedHash := "0xc5b04323dd23505d1c6af7dfdf3ef3ea102c516ad787fcc1ec4ccee39168af54" require.Equal(t, expectedHash, fStore.Results.Hash().Value().String()) fList := coreblob.ScFuncs.ListBlobs(ctx) diff --git a/packages/vm/core/blob/internal.go b/packages/vm/core/blob/internal.go index 4baca537cd..0645dfffc2 100644 --- a/packages/vm/core/blob/internal.go +++ b/packages/vm/core/blob/internal.go @@ -1,6 +1,7 @@ package blob import ( + "bytes" "fmt" "github.com/iotaledger/wasp/packages/hashing" @@ -25,11 +26,16 @@ func mustGetBlobHash(fields dict.Dict) (hashing.HashValue, []kv.Key, [][]byte) { sorted := fields.KeysSorted() // mind determinism values := make([][]byte, 0, len(sorted)) all := make([][]byte, 0, 2*len(sorted)) - for _, k := range sorted { - v := fields.Get(k) + for _, key := range sorted { + v := fields.Get(key) values = append(values, v) - all = append(all, v) - all = append(all, []byte(k)) + // escape all key and value + // TODO may be better solution exist? + dash := []byte("-") + escDash := []byte("/-") + v = bytes.Replace(v, dash, escDash, -1) + k := bytes.Replace([]byte(key), dash, escDash, -1) + all = append(all, k, dash, v) } return hashing.HashData(all...), sorted, values } diff --git a/packages/vm/core/blob/internal_test.go b/packages/vm/core/blob/internal_test.go new file mode 100644 index 0000000000..90a029f90f --- /dev/null +++ b/packages/vm/core/blob/internal_test.go @@ -0,0 +1,44 @@ +package blob + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/iotaledger/wasp/packages/kv/dict" +) + +func TestMustGetBlobHash(t *testing.T) { + t.Run("normal", func(t *testing.T) { + fields := dict.Dict{ + "key0": []byte("val0"), + "key1": []byte("val1"), + } + + h, keys, values := mustGetBlobHash(fields) + for i, k := range keys { + require.Equal(t, fields[k], values[i]) + } + + resHash, err := hex.DecodeString("2e42c9185213b81ab77236086c13b7e45471c7104d058197a573a4f10b12ab35") + require.NoError(t, err) + require.Equal(t, resHash, h.Bytes()) + }) + t.Run("with escape separator", func(t *testing.T) { + fields := dict.Dict{ + "key0": []byte("-val0"), + "key1": []byte("/-val1"), + "key2": []byte("//-val2"), + } + + h, keys, values := mustGetBlobHash(fields) + for i, k := range keys { + require.Equal(t, fields[k], values[i]) + } + + resHash, err := hex.DecodeString("b143143db9451db8e1a3623ae1561d5f1bd18ce4b0aa0c9c651290af54e9ea08") + require.NoError(t, err) + require.Equal(t, resHash, h.Bytes()) + }) +}