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  }