github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/utils/unittest/protocol_state.go (about) 1 package unittest 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/mock" 8 "github.com/stretchr/testify/require" 9 10 "github.com/onflow/flow-go/model/flow" 11 "github.com/onflow/flow-go/state/protocol" 12 mockprotocol "github.com/onflow/flow-go/state/protocol/mock" 13 ) 14 15 // FinalizedProtocolStateWithParticipants returns a protocol state with finalized participants 16 func FinalizedProtocolStateWithParticipants(participants flow.IdentityList) ( 17 *flow.Block, *mockprotocol.Snapshot, *mockprotocol.State, *mockprotocol.Snapshot) { 18 sealed := BlockFixture() 19 block := BlockWithParentFixture(sealed.Header) 20 head := block.Header 21 22 // set up protocol snapshot mock 23 snapshot := &mockprotocol.Snapshot{} 24 snapshot.On("Identities", mock.Anything).Return( 25 func(filter flow.IdentityFilter[flow.Identity]) flow.IdentityList { 26 return participants.Filter(filter) 27 }, 28 nil, 29 ) 30 snapshot.On("Identity", mock.Anything).Return(func(id flow.Identifier) *flow.Identity { 31 for _, n := range participants { 32 if n.ID() == id { 33 return n 34 } 35 } 36 return nil 37 }, nil) 38 snapshot.On("Head").Return( 39 func() *flow.Header { 40 return head 41 }, 42 nil, 43 ) 44 45 sealedSnapshot := &mockprotocol.Snapshot{} 46 sealedSnapshot.On("Head").Return( 47 func() *flow.Header { 48 return sealed.Header 49 }, 50 nil, 51 ) 52 53 // set up protocol state mock 54 state := &mockprotocol.State{} 55 state.On("Final").Return( 56 func() protocol.Snapshot { 57 return snapshot 58 }, 59 ) 60 state.On("Sealed").Return(func() protocol.Snapshot { 61 return sealedSnapshot 62 }, 63 ) 64 state.On("AtBlockID", mock.Anything).Return( 65 func(blockID flow.Identifier) protocol.Snapshot { 66 return snapshot 67 }, 68 ) 69 return block, snapshot, state, sealedSnapshot 70 } 71 72 // SealBlock seals a block B by building two blocks on it, the first containing 73 // a receipt for the block (BR), the second (BS) containing a seal for the block. 74 // B <- BR(Result_B) <- BS(Seal_B) 75 // Returns the two generated blocks. 76 func SealBlock(t *testing.T, st protocol.ParticipantState, mutableProtocolState protocol.MutableProtocolState, block *flow.Block, receipt *flow.ExecutionReceipt, seal *flow.Seal) (br *flow.Block, bs *flow.Block) { 77 78 block2 := BlockWithParentFixture(block.Header) 79 block2.SetPayload(flow.Payload{ 80 Receipts: []*flow.ExecutionReceiptMeta{receipt.Meta()}, 81 Results: []*flow.ExecutionResult{&receipt.ExecutionResult}, 82 ProtocolStateID: block.Payload.ProtocolStateID, 83 }) 84 err := st.Extend(context.Background(), block2) 85 require.NoError(t, err) 86 87 block3 := BlockWithParentFixture(block2.Header) 88 seals := []*flow.Seal{seal} 89 updatedStateId, dbUpdates, err := mutableProtocolState.EvolveState(block3.Header.ParentID, block3.Header.View, seals) 90 require.NoError(t, err) 91 require.False(t, dbUpdates.IsEmpty()) 92 93 block3.SetPayload(flow.Payload{ 94 Seals: seals, 95 ProtocolStateID: updatedStateId, 96 }) 97 err = st.Extend(context.Background(), block3) 98 require.NoError(t, err) 99 100 return block2, block3 101 } 102 103 // InsertAndFinalize inserts, then finalizes, the input block. 104 func InsertAndFinalize(t *testing.T, st protocol.ParticipantState, block *flow.Block) { 105 err := st.Extend(context.Background(), block) 106 require.NoError(t, err) 107 err = st.Finalize(context.Background(), block.ID()) 108 require.NoError(t, err) 109 }