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 }