aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-06-02 15:01:18 +0200
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-06-02 15:01:18 +0200
commit0c5cd634e95d0ce07908a8ac32ecf80639f52785 (patch)
treede2ec3fc1b6adc848bae45b01784c260651e31a6
parent6e04ae48997ae5fa6e0f803792b674ca24bad8f0 (diff)
added refactored GetInclusionProof
-rw-r--r--trillian/client.go29
-rw-r--r--trillian/client_test.go113
2 files changed, 139 insertions, 3 deletions
diff --git a/trillian/client.go b/trillian/client.go
index 7b8a00a..cbeb1ca 100644
--- a/trillian/client.go
+++ b/trillian/client.go
@@ -108,7 +108,34 @@ func (c *Client) GetConsistencyProof(ctx context.Context, req *types.Consistency
}
func (c *Client) GetInclusionProof(ctx context.Context, req *types.InclusionProofRequest) (*types.InclusionProof, error) {
- return nil, fmt.Errorf("TODO")
+ rsp, err := c.GRPC.GetInclusionProofByHash(ctx, &trillian.GetInclusionProofByHashRequest{
+ LogId: c.TreeID,
+ LeafHash: req.LeafHash[:],
+ TreeSize: int64(req.TreeSize),
+ OrderBySequence: true,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("backend failure: %v", err)
+ }
+ if rsp == nil {
+ return nil, fmt.Errorf("no response")
+ }
+ if len(rsp.Proof) != 1 {
+ return nil, fmt.Errorf("bad proof count: %d", len(rsp.Proof))
+ }
+ proof := rsp.Proof[0]
+ if len(proof.Hashes) == 0 {
+ return nil, fmt.Errorf("not an inclusion proof: empty")
+ }
+ path, err := nodePathFromHashes(proof.Hashes)
+ if err != nil {
+ return nil, fmt.Errorf("not an inclusion proof: %v", err)
+ }
+ return &types.InclusionProof{
+ TreeSize: req.TreeSize,
+ LeafIndex: uint64(proof.LeafIndex),
+ Path: path,
+ }, nil
}
func (c *Client) GetLeaves(ctx context.Context, req *types.LeavesRequest) (*types.LeafList, error) {
diff --git a/trillian/client_test.go b/trillian/client_test.go
index 1d1c16f..001d1dc 100644
--- a/trillian/client_test.go
+++ b/trillian/client_test.go
@@ -287,5 +287,114 @@ func TestGetConsistencyProof(t *testing.T) {
}
}
-func TestGetInclusionProof(t *testing.T) {}
-func TestGetLeaves(t *testing.T) {}
+func TestGetInclusionProof(t *testing.T) {
+ req := &types.InclusionProofRequest{
+ TreeSize: 4,
+ LeafHash: &[types.HashSize]byte{},
+ }
+ for _, table := range []struct {
+ description string
+ req *types.InclusionProofRequest
+ rsp *trillian.GetInclusionProofByHashResponse
+ err error
+ wantErr bool
+ wantProof *types.InclusionProof
+ }{
+ {
+ description: "invalid: backend failure",
+ req: req,
+ err: fmt.Errorf("something went wrong"),
+ wantErr: true,
+ },
+ {
+ description: "invalid: no response",
+ req: req,
+ wantErr: true,
+ },
+ {
+ description: "invalid: bad proof count",
+ req: req,
+ rsp: &trillian.GetInclusionProofByHashResponse{
+ Proof: []*trillian.Proof{
+ &trillian.Proof{},
+ &trillian.Proof{},
+ },
+ },
+ wantErr: true,
+ },
+ {
+ description: "invalid: not an inclusion proof (1/2)",
+ req: req,
+ rsp: &trillian.GetInclusionProofByHashResponse{
+ Proof: []*trillian.Proof{
+ &trillian.Proof{
+ LeafIndex: 1,
+ Hashes: [][]byte{},
+ },
+ },
+ },
+ wantErr: true,
+ },
+ {
+ description: "invalid: not an inclusion proof (2/2)",
+ req: req,
+ rsp: &trillian.GetInclusionProofByHashResponse{
+ Proof: []*trillian.Proof{
+ &trillian.Proof{
+ LeafIndex: 1,
+ Hashes: [][]byte{
+ make([]byte, types.HashSize),
+ make([]byte, types.HashSize+1),
+ },
+ },
+ },
+ },
+ wantErr: true,
+ },
+ {
+ description: "valid",
+ req: req,
+ rsp: &trillian.GetInclusionProofByHashResponse{
+ Proof: []*trillian.Proof{
+ &trillian.Proof{
+ LeafIndex: 1,
+ Hashes: [][]byte{
+ make([]byte, types.HashSize),
+ make([]byte, types.HashSize),
+ },
+ },
+ },
+ },
+ wantProof: &types.InclusionProof{
+ TreeSize: 4,
+ LeafIndex: 1,
+ Path: []*[types.HashSize]byte{
+ &[types.HashSize]byte{},
+ &[types.HashSize]byte{},
+ },
+ },
+ },
+ } {
+ // Run deferred functions at the end of each iteration
+ func() {
+ ctrl := gomock.NewController(t)
+ defer ctrl.Finish()
+ grpc := mockclient.NewMockTrillianLogClient(ctrl)
+ grpc.EXPECT().GetInclusionProofByHash(gomock.Any(), gomock.Any()).Return(table.rsp, table.err)
+ client := Client{GRPC: grpc}
+
+ proof, err := client.GetInclusionProof(context.Background(), table.req)
+ if got, want := err != nil, table.wantErr; got != want {
+ t.Errorf("got error %v but wanted %v in test %q: %v", got, want, table.description, err)
+ }
+ if err != nil {
+ return
+ }
+ if got, want := proof, table.wantProof; !reflect.DeepEqual(got, want) {
+ t.Errorf("got proof\n\t%v\nbut wanted\n\t%v\nin test %q", got, want, table.description)
+ }
+ }()
+ }
+}
+
+func TestGetLeaves(t *testing.T) {}