From 3d7922afdce9fd0144e16aae08bea061c0ad1aee Mon Sep 17 00:00:00 2001 From: Pavel Kalinnikov Date: Thu, 28 Apr 2022 11:05:30 +0100 Subject: [PATCH] Remove the inmemory Merkle tree, use external one (#2725) --- go.mod | 2 +- go.sum | 4 +- integration/log.go | 2 +- internal/merkle/inmemory/reference_test.go | 206 --------------------- internal/merkle/inmemory/tree.go | 125 ------------- internal/merkle/inmemory/tree_test.go | 205 -------------------- merkle/logverifier/log_verifier_test.go | 2 +- server/proof_fetcher_test.go | 2 +- 8 files changed, 6 insertions(+), 542 deletions(-) delete mode 100644 internal/merkle/inmemory/reference_test.go delete mode 100644 internal/merkle/inmemory/tree.go delete mode 100644 internal/merkle/inmemory/tree_test.go diff --git a/go.mod b/go.mod index b1fd389d73..ba41be4983 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/pseudomuto/protoc-gen-doc v1.5.1 github.com/spf13/cobra v1.4.0 // indirect github.com/stretchr/testify v1.7.1 // indirect - github.com/transparency-dev/merkle v0.0.0-20220425113829-c120179f55ad + github.com/transparency-dev/merkle v0.0.0-20220427153749-09877c5f5967 github.com/urfave/cli v1.22.7 // indirect go.etcd.io/etcd/client/v3 v3.5.4 go.etcd.io/etcd/etcdctl/v3 v3.5.4 diff --git a/go.sum b/go.sum index abbf60b513..007839fb72 100644 --- a/go.sum +++ b/go.sum @@ -813,8 +813,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= -github.com/transparency-dev/merkle v0.0.0-20220425113829-c120179f55ad h1:82yvTO+VijfWulMsMQvqQSZ0zNEAgmEUeBG+ArrO9Js= -github.com/transparency-dev/merkle v0.0.0-20220425113829-c120179f55ad/go.mod h1:B8FIw5LTq6DaULoHsVFRzYIUDkl8yuSwCdZnOZGKL/A= +github.com/transparency-dev/merkle v0.0.0-20220427153749-09877c5f5967 h1:0HykT2IlbcP8a0VlH5XsX+a2OCtB+MUVth/SjAK3E2w= +github.com/transparency-dev/merkle v0.0.0-20220427153749-09877c5f5967/go.mod h1:B8FIw5LTq6DaULoHsVFRzYIUDkl8yuSwCdZnOZGKL/A= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= diff --git a/integration/log.go b/integration/log.go index 37b2107bef..5c3c339b0c 100644 --- a/integration/log.go +++ b/integration/log.go @@ -27,11 +27,11 @@ import ( "github.com/golang/glog" "github.com/google/trillian" "github.com/google/trillian/client/backoff" - "github.com/google/trillian/internal/merkle/inmemory" "github.com/google/trillian/types" "github.com/transparency-dev/merkle/compact" "github.com/transparency-dev/merkle/proof" "github.com/transparency-dev/merkle/rfc6962" + inmemory "github.com/transparency-dev/merkle/testonly" ) // TestParameters bundles up all the settings for a test run diff --git a/internal/merkle/inmemory/reference_test.go b/internal/merkle/inmemory/reference_test.go deleted file mode 100644 index 52a8fbc2d0..0000000000 --- a/internal/merkle/inmemory/reference_test.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2022 Google LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package inmemory - -import ( - "encoding/hex" - "fmt" - "math/bits" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/transparency-dev/merkle" - "github.com/transparency-dev/merkle/rfc6962" - to "github.com/transparency-dev/merkle/testonly" -) - -// The reference Merkle tree hashing and proof algorithms in this file directly -// implement the definitions from RFC 6962 [1]. We use this implementation only -// for testing correctness of other more flexible and performant algorithms, -// such as the in-memory Tree type and compact ranges. -// -// [1] https://datatracker.ietf.org/doc/html/rfc6962#section-2 - -// refRootHash returns the root hash of a Merkle tree with the given entries. -// This is a reference implementation for cross-checking. -func refRootHash(entries [][]byte, hasher merkle.LogHasher) []byte { - if len(entries) == 0 { - return hasher.EmptyRoot() - } - if len(entries) == 1 { - return hasher.HashLeaf(entries[0]) - } - split := downToPowerOfTwo(uint64(len(entries))) - return hasher.HashChildren( - refRootHash(entries[:split], hasher), - refRootHash(entries[split:], hasher)) -} - -// refInclusionProof returns the inclusion proof for the given leaf index in a -// Merkle tree with the given entries. This is a reference implementation for -// cross-checking. -func refInclusionProof(entries [][]byte, index uint64, hasher merkle.LogHasher) [][]byte { - size := uint64(len(entries)) - if size == 1 || index >= size { - return nil - } - split := downToPowerOfTwo(size) - if index < split { - return append( - refInclusionProof(entries[:split], index, hasher), - refRootHash(entries[split:], hasher)) - } - return append( - refInclusionProof(entries[split:], index-split, hasher), - refRootHash(entries[:split], hasher)) -} - -// refConsistencyProof returns the consistency proof for the two tree sizes, in -// a Merkle tree with the given entries. This is a reference implementation for -// cross-checking. -func refConsistencyProof(entries [][]byte, size2, size1 uint64, hasher merkle.LogHasher, haveRoot1 bool) [][]byte { - if size1 == 0 || size1 > size2 { - return nil - } - // Consistency proof for two equal sizes is empty. - if size1 == size2 { - // Record the hash of this subtree if it's not the root for which the proof - // was originally requested (which happens when size1 is a power of 2). - if !haveRoot1 { - return [][]byte{refRootHash(entries[:size1], hasher)} - } - return nil - } - - // At this point: 0 < size1 < size2. - split := downToPowerOfTwo(size2) - if size1 <= split { - // Root of size1 is in the left subtree of size2. Prove that the left - // subtrees are consistent, and record the hash of the right subtree (only - // present in size2). - return append( - refConsistencyProof(entries[:split], split, size1, hasher, haveRoot1), - refRootHash(entries[split:], hasher)) - } - - // Root of size1 is at the same level as size2 root. Prove that the right - // subtrees are consistent. The right subtree doesn't contain the root of - // size1, so set haveRoot1 = false. Record the hash of the left subtree - // (equal in both trees). - return append( - refConsistencyProof(entries[split:], size2-split, size1-split, hasher, false), - refRootHash(entries[:split], hasher)) -} - -// downToPowerOfTwo returns the largest power of two smaller than x. -func downToPowerOfTwo(x uint64) uint64 { - if x < 2 { - panic("downToPowerOfTwo requires value >= 2") - } - return uint64(1) << (bits.Len64(x-1) - 1) -} - -func TestDownToPowerOfTwo(t *testing.T) { - for _, inOut := range [][2]uint64{ - {2, 1}, {7, 4}, {8, 4}, {63, 32}, {28937, 16384}, - } { - if got, want := downToPowerOfTwo(inOut[0]), inOut[1]; got != want { - t.Errorf("downToPowerOfTwo(%d): got %d, want %d", inOut[0], got, want) - } - } -} - -func TestRefInclusionProof(t *testing.T) { - for _, tc := range []struct { - index uint64 - size uint64 - want [][]byte - }{ - {index: 0, size: 1, want: nil}, - {index: 0, size: 2, want: [][]byte{ - hx("96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7"), - }}, - {index: 1, size: 2, want: [][]byte{ - hx("6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"), - }}, - {index: 2, size: 3, want: [][]byte{ - hx("fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125"), - }}, - {index: 1, size: 5, want: [][]byte{ - hx("6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"), - hx("5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e"), - hx("bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b"), - }}, - {index: 0, size: 8, want: [][]byte{ - hx("96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7"), - hx("5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e"), - hx("6b47aaf29ee3c2af9af889bc1fb9254dabd31177f16232dd6aab035ca39bf6e4"), - }}, - {index: 5, size: 8, want: [][]byte{ - hx("bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b"), - hx("ca854ea128ed050b41b35ffc1b87b8eb2bde461e9e3b5596ece6b9d5975a0ae0"), - hx("d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7"), - }}, - } { - t.Run(fmt.Sprintf("%d:%d", tc.index, tc.size), func(t *testing.T) { - entries := to.LeafInputs() - got := refInclusionProof(entries[:tc.size], tc.index, rfc6962.DefaultHasher) - if diff := cmp.Diff(got, tc.want); diff != "" { - t.Errorf("refInclusionProof: diff (-got +want)\n%s", diff) - } - }) - } -} - -func TestRefConsistencyProof(t *testing.T) { - for _, tc := range []struct { - size1 uint64 - size2 uint64 - want [][]byte - }{ - {size1: 1, size2: 1, want: nil}, - {size1: 1, size2: 8, want: [][]byte{ - hx("96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7"), - hx("5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e"), - hx("6b47aaf29ee3c2af9af889bc1fb9254dabd31177f16232dd6aab035ca39bf6e4"), - }}, - {size1: 2, size2: 5, want: [][]byte{ - hx("5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e"), - hx("bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b"), - }}, - {size1: 6, size2: 8, want: [][]byte{ - hx("0ebc5d3437fbe2db158b9f126a1d118e308181031d0a949f8dededebc558ef6a"), - hx("ca854ea128ed050b41b35ffc1b87b8eb2bde461e9e3b5596ece6b9d5975a0ae0"), - hx("d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7"), - }}, - } { - t.Run(fmt.Sprintf("%d:%d", tc.size1, tc.size2), func(t *testing.T) { - entries := to.LeafInputs() - got := refConsistencyProof(entries[:tc.size2], tc.size2, tc.size1, rfc6962.DefaultHasher, true) - if diff := cmp.Diff(got, tc.want); diff != "" { - t.Errorf("refConsistencyProof: diff (-got +want)\n%s", diff) - } - }) - } -} - -// hx decodes a hex string or panics. -func hx(hs string) []byte { - data, err := hex.DecodeString(hs) - if err != nil { - panic(fmt.Errorf("failed to decode test data: %s", hs)) - } - return data -} diff --git a/internal/merkle/inmemory/tree.go b/internal/merkle/inmemory/tree.go deleted file mode 100644 index a6a8de4ece..0000000000 --- a/internal/merkle/inmemory/tree.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2022 Google LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package inmemory provides an in-memory Merkle tree implementation. -package inmemory - -import ( - "github.com/transparency-dev/merkle" - "github.com/transparency-dev/merkle/compact" - "github.com/transparency-dev/merkle/proof" -) - -// Tree implements an append-only Merkle tree. For testing. -type Tree struct { - hasher merkle.LogHasher - size uint64 - hashes [][][]byte // Node hashes, indexed by node (level, index). -} - -// New returns a new empty Merkle tree. -func New(hasher merkle.LogHasher) *Tree { - return &Tree{hasher: hasher} -} - -// AppendData adds the leaf hashes of the given entries to the end of the tree. -func (t *Tree) AppendData(entries ...[]byte) { - for _, data := range entries { - t.appendImpl(t.hasher.HashLeaf(data)) - } -} - -// Append adds the given leaf hashes to the end of the tree. -func (t *Tree) Append(hashes ...[]byte) { - for _, hash := range hashes { - t.appendImpl(hash) - } -} - -func (t *Tree) appendImpl(hash []byte) { - level := 0 - for ; (t.size>>level)&1 == 1; level++ { - row := append(t.hashes[level], hash) - hash = t.hasher.HashChildren(row[len(row)-2], hash) - t.hashes[level] = row - } - if level > len(t.hashes) { - panic("gap in tree appends") - } else if level == len(t.hashes) { - t.hashes = append(t.hashes, nil) - } - - t.hashes[level] = append(t.hashes[level], hash) - t.size++ -} - -// Size returns the current number of leaves in the tree. -func (t *Tree) Size() uint64 { - return t.size -} - -// LeafHash returns the leaf hash at the given index. -// Requires 0 <= index < Size(), otherwise panics. -func (t *Tree) LeafHash(index uint64) []byte { - return t.hashes[0][index] -} - -// Hash returns the current root hash of the tree. -func (t *Tree) Hash() []byte { - return t.HashAt(t.size) -} - -// HashAt returns the root hash at the given size. -// Requires 0 <= size <= Size(), otherwise panics. -func (t *Tree) HashAt(size uint64) []byte { - if size == 0 { - return t.hasher.EmptyRoot() - } - hashes := t.getNodes(compact.RangeNodes(0, size, nil)) - - hash := hashes[len(hashes)-1] - for i := len(hashes) - 2; i >= 0; i-- { - hash = t.hasher.HashChildren(hashes[i], hash) - } - return hash -} - -// InclusionProof returns the inclusion proof for the given leaf index in the -// tree of the given size. Requires 0 <= index < size <= Size(), otherwise may -// panic. -func (t *Tree) InclusionProof(index, size uint64) ([][]byte, error) { - nodes, err := proof.Inclusion(index, size) - if err != nil { - return nil, err - } - return nodes.Rehash(t.getNodes(nodes.IDs), t.hasher.HashChildren) -} - -// ConsistencyProof returns the consistency proof between the two given tree -// sizes. Requires 0 <= size1 <= size2 <= Size(), otherwise may panic. -func (t *Tree) ConsistencyProof(size1, size2 uint64) ([][]byte, error) { - nodes, err := proof.Consistency(size1, size2) - if err != nil { - return nil, err - } - return nodes.Rehash(t.getNodes(nodes.IDs), t.hasher.HashChildren) -} - -func (t *Tree) getNodes(ids []compact.NodeID) [][]byte { - hashes := make([][]byte, len(ids)) - for i, id := range ids { - hashes[i] = t.hashes[id.Level][id.Index] - } - return hashes -} diff --git a/internal/merkle/inmemory/tree_test.go b/internal/merkle/inmemory/tree_test.go deleted file mode 100644 index d433197b4b..0000000000 --- a/internal/merkle/inmemory/tree_test.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2022 Google LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package inmemory - -import ( - "bytes" - "fmt" - "math/rand" - "strconv" - "testing" - - _ "github.com/golang/glog" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "github.com/transparency-dev/merkle/rfc6962" - to "github.com/transparency-dev/merkle/testonly" -) - -func validateTree(t *testing.T, mt *Tree, size uint64) { - t.Helper() - if got, want := mt.Size(), size; got != want { - t.Errorf("Size: %d, want %d", got, want) - } - roots := to.RootHashes() - if got, want := mt.Hash(), roots[size]; !bytes.Equal(got, want) { - t.Errorf("Hash(%d): %x, want %x", size, got, want) - } - for s := uint64(0); s <= size; s++ { - if got, want := mt.HashAt(s), roots[s]; !bytes.Equal(got, want) { - t.Errorf("HashAt(%d/%d): %x, want %x", s, size, got, want) - } - } -} - -func TestBuildTreeBuildOneAtATime(t *testing.T) { - mt := newTree(nil) - validateTree(t, mt, 0) - for i, entry := range to.LeafInputs() { - mt.AppendData(entry) - validateTree(t, mt, uint64(i+1)) - } -} - -func TestBuildTreeBuildTwoChunks(t *testing.T) { - entries := to.LeafInputs() - mt := newTree(nil) - mt.AppendData(entries[:3]...) - validateTree(t, mt, 3) - mt.AppendData(entries[3:8]...) - validateTree(t, mt, 8) -} - -func TestBuildTreeBuildAllAtOnce(t *testing.T) { - mt := newTree(nil) - mt.AppendData(to.LeafInputs()...) - validateTree(t, mt, 8) -} - -func TestTreeHashAt(t *testing.T) { - test := func(desc string, entries [][]byte) { - t.Run(desc, func(t *testing.T) { - mt := newTree(entries) - for size := 0; size <= len(entries); size++ { - got := mt.HashAt(uint64(size)) - want := refRootHash(entries[:size], mt.hasher) - if !bytes.Equal(got, want) { - t.Errorf("HashAt(%d): %x, want %x", size, got, want) - } - } - }) - } - - entries := to.LeafInputs() - for size := 0; size <= len(entries); size++ { - test(fmt.Sprintf("size:%d", size), entries[:size]) - } - test("generated", genEntries(256)) -} - -func TestTreeInclusionProof(t *testing.T) { - test := func(desc string, entries [][]byte) { - t.Run(desc, func(t *testing.T) { - mt := newTree(entries) - for index, size := uint64(0), uint64(len(entries)); index < size; index++ { - got, err := mt.InclusionProof(index, size) - if err != nil { - t.Fatalf("InclusionProof(%d, %d): %v", index, size, err) - } - want := refInclusionProof(entries[:size], index, mt.hasher) - if diff := cmp.Diff(got, want, cmpopts.EquateEmpty()); diff != "" { - t.Fatalf("InclusionProof(%d, %d): diff (-got +want)\n%s", index, size, diff) - } - } - }) - } - - test("generated", genEntries(256)) - entries := to.LeafInputs() - for size := 0; size < len(entries); size++ { - test(fmt.Sprintf("golden:%d", size), entries[:size]) - } -} - -func TestTreeConsistencyProof(t *testing.T) { - entries := to.LeafInputs() - mt := newTree(entries) - validateTree(t, mt, 8) - - if _, err := mt.ConsistencyProof(6, 3); err == nil { - t.Error("ConsistencyProof(6, 3) succeeded unexpectedly") - } - - for size1 := uint64(0); size1 <= 8; size1++ { - for size2 := size1; size2 <= 8; size2++ { - t.Run(fmt.Sprintf("%d:%d", size1, size2), func(t *testing.T) { - got, err := mt.ConsistencyProof(size1, size2) - if err != nil { - t.Fatalf("ConsistencyProof: %v", err) - } - want := refConsistencyProof(entries[:size2], size2, size1, mt.hasher, true) - if diff := cmp.Diff(got, want, cmpopts.EquateEmpty()); diff != "" { - t.Errorf("ConsistencyProof: diff (-got +want)\n%s", diff) - } - }) - } - } -} - -// Make random proof queries and check against the reference implementation. -func TestTreeConsistencyProofFuzz(t *testing.T) { - entries := genEntries(256) - - for treeSize := int64(1); treeSize <= 256; treeSize++ { - mt := newTree(entries[:treeSize]) - for i := 0; i < 8; i++ { - size2 := uint64(rand.Int63n(treeSize + 1)) - size1 := uint64(rand.Int63n(int64(size2) + 1)) - - got, err := mt.ConsistencyProof(size1, size2) - if err != nil { - t.Fatalf("ConsistencyProof: %v", err) - } - want := refConsistencyProof(entries[:size2], size2, size1, mt.hasher, true) - if diff := cmp.Diff(got, want, cmpopts.EquateEmpty()); diff != "" { - t.Errorf("ConsistencyProof: diff (-got +want)\n%s", diff) - } - } - } -} - -func TestTreeAppend(t *testing.T) { - entries := genEntries(256) - mt1 := newTree(entries) - - mt2 := newTree(nil) - for _, entry := range entries { - mt2.Append(rfc6962.DefaultHasher.HashLeaf(entry)) - } - - if diff := cmp.Diff(mt1, mt2, cmp.AllowUnexported(Tree{})); diff != "" { - t.Errorf("Trees built with AppendData and Append mismatch: diff (-mt1 +mt2)\n%s", diff) - } -} - -func TestTreeAppendAssociativity(t *testing.T) { - entries := genEntries(256) - mt1 := newTree(nil) - mt1.AppendData(entries...) - - mt2 := newTree(nil) - for _, entry := range entries { - mt2.AppendData(entry) - } - - if diff := cmp.Diff(mt1, mt2, cmp.AllowUnexported(Tree{})); diff != "" { - t.Errorf("AppendData is not associative: diff (-mt1 +mt2)\n%s", diff) - } -} - -func newTree(entries [][]byte) *Tree { - tree := New(rfc6962.DefaultHasher) - tree.AppendData(entries...) - return tree -} - -// genEntries a slice of entries of the given size. -func genEntries(size uint64) [][]byte { - entries := make([][]byte, size) - for i := range entries { - entries[i] = []byte(strconv.Itoa(i)) - } - return entries -} diff --git a/merkle/logverifier/log_verifier_test.go b/merkle/logverifier/log_verifier_test.go index c31a058f40..5e920a643a 100644 --- a/merkle/logverifier/log_verifier_test.go +++ b/merkle/logverifier/log_verifier_test.go @@ -22,8 +22,8 @@ import ( "testing" _ "github.com/golang/glog" - "github.com/google/trillian/internal/merkle/inmemory" "github.com/google/trillian/merkle/rfc6962" // nolint:staticcheck + inmemory "github.com/transparency-dev/merkle/testonly" ) type inclusionProofTestVector struct { diff --git a/server/proof_fetcher_test.go b/server/proof_fetcher_test.go index 2bc514095f..64dccf3d85 100644 --- a/server/proof_fetcher_test.go +++ b/server/proof_fetcher_test.go @@ -20,10 +20,10 @@ import ( "fmt" "testing" - "github.com/google/trillian/internal/merkle/inmemory" "github.com/google/trillian/storage/testonly" "github.com/transparency-dev/merkle/proof" "github.com/transparency-dev/merkle/rfc6962" + inmemory "github.com/transparency-dev/merkle/testonly" ) // An arbitrary tree revision to be used in tests.