github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/teams/merkle_test.go (about)

     1  package teams
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/davecgh/go-spew/spew"
     8  	"github.com/keybase/client/go/kbtest"
     9  	"github.com/keybase/client/go/libkb"
    10  	"github.com/keybase/client/go/protocol/keybase1"
    11  	"github.com/keybase/client/go/teams/hidden"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  // Test getting the merkle leaf from the server.
    16  // This is a test of MerkleClient.
    17  func TestMerkle(t *testing.T) {
    18  	tc := SetupTest(t, "team", 1)
    19  	defer tc.Cleanup()
    20  
    21  	_, err := kbtest.CreateAndSignupFakeUser("team", tc.G)
    22  	require.NoError(t, err)
    23  
    24  	name := createTeam(tc)
    25  
    26  	team, err := GetForTestByStringName(context.TODO(), tc.G, name)
    27  	require.NoError(t, err)
    28  
    29  	leaf, err := tc.G.MerkleClient.LookupTeam(libkb.NewMetaContextForTest(tc), team.ID)
    30  	require.NoError(t, err)
    31  	require.NotNil(t, leaf)
    32  	t.Logf("team merkle leaf: %v", spew.Sdump(leaf))
    33  	if leaf.TeamID.IsNil() {
    34  		t.Fatalf("nil teamID; likely merkle hasn't yet published and polling is busted")
    35  	}
    36  	require.Equal(t, team.ID, leaf.TeamID, "team id")
    37  	require.Equal(t, team.chain().GetLatestSeqno(), leaf.Private.Seqno)
    38  	require.Equal(t, team.chain().GetLatestLinkID(), leaf.Private.LinkID.Export())
    39  	// leaf.Private.SigID not checked
    40  	require.Nil(t, leaf.Public, "team public leaf")
    41  }
    42  
    43  func TestMerkleWithHidden(t *testing.T) {
    44  	tc := SetupTest(t, "team", 1)
    45  	defer tc.Cleanup()
    46  
    47  	_, err := kbtest.CreateAndSignupFakeUser("team", tc.G)
    48  	require.NoError(t, err)
    49  
    50  	name := createTeam(tc)
    51  
    52  	team, err := GetForTestByStringName(context.TODO(), tc.G, name)
    53  	require.NoError(t, err)
    54  
    55  	leaf, hiddenResp, lastMerkleRoot, err := tc.G.MerkleClient.LookupTeamWithHidden(libkb.NewMetaContextForTest(tc), team.ID, hidden.ProcessHiddenResponseFunc)
    56  	require.NoError(t, err)
    57  	require.NotNil(t, lastMerkleRoot)
    58  	require.NotNil(t, leaf)
    59  	t.Logf("team merkle leaf: %v", spew.Sdump(leaf))
    60  	if leaf.TeamID.IsNil() {
    61  		t.Fatalf("nil teamID; likely merkle hasn't yet published and polling is busted")
    62  	}
    63  	require.Equal(t, team.ID, leaf.TeamID, "team id")
    64  	require.Equal(t, team.chain().GetLatestSeqno(), leaf.Private.Seqno)
    65  	require.Equal(t, team.chain().GetLatestLinkID(), leaf.Private.LinkID.Export())
    66  	// leaf.Private.SigID not checked
    67  	require.Nil(t, leaf.Public, "team public leaf")
    68  	require.Equal(t, libkb.MerkleHiddenResponseTypeABSENCEPROOF, hiddenResp.RespType)
    69  	require.EqualValues(t, 0, hiddenResp.UncommittedSeqno)
    70  	require.Nil(t, hiddenResp.CommittedHiddenTail)
    71  
    72  	// make a hidden rotation to later check that merkle/path returns the appropriate result
    73  	err = team.Rotate(context.TODO(), keybase1.RotationType_HIDDEN)
    74  	require.NoError(t, err)
    75  	// reload the team after the hidden rotation
    76  	team, err = GetForTestByStringName(context.TODO(), tc.G, name)
    77  	require.NoError(t, err)
    78  
    79  	leaf, hiddenResp, lastMerkleRoot, err = tc.G.MerkleClient.LookupTeamWithHidden(libkb.NewMetaContextForTest(tc), team.ID, hidden.ProcessHiddenResponseFunc)
    80  	require.NoError(t, err)
    81  	require.NotNil(t, lastMerkleRoot)
    82  	require.NotNil(t, leaf)
    83  	require.Equal(t, team.ID, leaf.TeamID, "team id mismatch")
    84  	require.Equal(t, team.chain().GetLatestSeqno(), leaf.Private.Seqno)
    85  	require.Equal(t, team.chain().GetLatestLinkID(), leaf.Private.LinkID.Export())
    86  	require.True(t, hiddenResp.RespType == libkb.MerkleHiddenResponseTypeABSENCEPROOF || hiddenResp.RespType == libkb.MerkleHiddenResponseTypeOK)
    87  	require.EqualValues(t, 1, hiddenResp.UncommittedSeqno)
    88  	if hiddenResp.RespType == libkb.MerkleHiddenResponseTypeABSENCEPROOF {
    89  		t.Logf("The hidden rotation was not yet committed to the blind tree. This is expected.")
    90  		require.Nil(t, hiddenResp.CommittedHiddenTail)
    91  	} else {
    92  		//  This can happen if the architect concurrently builds a new tree
    93  		t.Logf("Surprisingly, the hidden chain was already committed to the blind tree.")
    94  		require.NotNil(t, team.HiddenChain(), "NIL hidden chain")
    95  		committedHiddenTail := hiddenResp.CommittedHiddenTail
    96  		require.Equal(t, team.HiddenChain().TailTriple().Seqno, committedHiddenTail.Seqno)
    97  		require.EqualValues(t, team.HiddenChain().TailTriple().LinkID, committedHiddenTail.Hash.String())
    98  		require.Equal(t, team.HiddenChain().TailTriple().SeqType, committedHiddenTail.ChainType)
    99  	}
   100  
   101  	requestNewBlindTreeFromArchitectAndWaitUntilDone(t, &tc)
   102  
   103  	leaf, hiddenResp, lastMerkleRoot, err = tc.G.MerkleClient.LookupTeamWithHidden(libkb.NewMetaContextForTest(tc), team.ID, hidden.ProcessHiddenResponseFunc)
   104  	require.NoError(t, err)
   105  	require.NotNil(t, lastMerkleRoot)
   106  	require.NotNil(t, leaf)
   107  	require.Equal(t, team.ID, leaf.TeamID, "team id")
   108  	require.Equal(t, team.chain().GetLatestSeqno(), leaf.Private.Seqno)
   109  	require.Equal(t, team.chain().GetLatestLinkID(), leaf.Private.LinkID.Export())
   110  	require.True(t, hiddenResp.RespType == libkb.MerkleHiddenResponseTypeOK)
   111  	require.EqualValues(t, 1, hiddenResp.UncommittedSeqno)
   112  	require.NotNil(t, team.HiddenChain(), "NIL hidden chain")
   113  	committedHiddenTail := hiddenResp.CommittedHiddenTail
   114  	require.Equal(t, team.HiddenChain().TailTriple().Seqno, committedHiddenTail.Seqno)
   115  	require.EqualValues(t, team.HiddenChain().TailTriple().LinkID, committedHiddenTail.Hash.String())
   116  	require.Equal(t, team.HiddenChain().TailTriple().SeqType, committedHiddenTail.ChainType)
   117  }