github.com/koko1123/flow-go-1@v0.29.6/fvm/derived/derived_chain_data_test.go (about)

     1  package derived
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/onflow/cadence/runtime/common"
     7  	"github.com/onflow/cadence/runtime/interpreter"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/koko1123/flow-go-1/model/flow"
    11  )
    12  
    13  func TestDerivedChainData(t *testing.T) {
    14  	testBlockId := func(i byte) flow.Identifier {
    15  		id := flow.ZeroID
    16  		id[0] = i
    17  		return id
    18  	}
    19  
    20  	testLocation := func(hex string) common.AddressLocation {
    21  		return common.AddressLocation{
    22  			Address: common.Address(flow.HexToAddress(hex)),
    23  			Name:    hex,
    24  		}
    25  	}
    26  
    27  	programs, err := NewDerivedChainData(2)
    28  	require.NoError(t, err)
    29  
    30  	//
    31  	// Creating a DerivedBlockData from scratch
    32  	//
    33  
    34  	blockId1 := testBlockId(1)
    35  
    36  	block1 := programs.GetOrCreateDerivedBlockData(blockId1, flow.ZeroID)
    37  	require.NotNil(t, block1)
    38  
    39  	loc1 := testLocation("0a")
    40  	prog1 := &Program{
    41  		Program: &interpreter.Program{},
    42  	}
    43  
    44  	txn, err := block1.NewDerivedTransactionData(0, 0)
    45  	require.NoError(t, err)
    46  
    47  	txn.SetProgram(loc1, prog1, nil)
    48  	err = txn.Commit()
    49  	require.NoError(t, err)
    50  
    51  	entry := block1.programs.GetForTestingOnly(loc1)
    52  	require.NotNil(t, entry)
    53  	require.Same(t, prog1, entry.Value)
    54  
    55  	//
    56  	// Creating a DerivedBlockData from parent
    57  	//
    58  
    59  	blockId2 := testBlockId(2)
    60  
    61  	block2 := programs.GetOrCreateDerivedBlockData(blockId2, blockId1)
    62  	require.NotNil(t, block2)
    63  	require.NotSame(t, block1, block2)
    64  
    65  	loc2 := testLocation("0b")
    66  	prog2 := &Program{
    67  		Program: &interpreter.Program{},
    68  	}
    69  
    70  	txn, err = block2.NewDerivedTransactionData(0, 0)
    71  	require.NoError(t, err)
    72  
    73  	txn.SetProgram(loc2, prog2, nil)
    74  	err = txn.Commit()
    75  	require.NoError(t, err)
    76  
    77  	entry = block2.programs.GetForTestingOnly(loc1)
    78  	require.NotNil(t, entry)
    79  	require.Same(t, prog1, entry.Value)
    80  
    81  	entry = block2.programs.GetForTestingOnly(loc2)
    82  	require.NotNil(t, entry)
    83  	require.Same(t, prog2, entry.Value)
    84  
    85  	//
    86  	// Reuse exising DerivedBlockData in cache
    87  	//
    88  
    89  	foundBlock := programs.GetOrCreateDerivedBlockData(blockId1, flow.ZeroID)
    90  	require.Same(t, block1, foundBlock)
    91  
    92  	foundBlock = programs.Get(blockId1)
    93  	require.Same(t, block1, foundBlock)
    94  
    95  	entry = block1.programs.GetForTestingOnly(loc1)
    96  	require.NotNil(t, entry)
    97  	require.Same(t, prog1, entry.Value)
    98  
    99  	// writes to block2 did't poplute block1.
   100  	entry = block1.programs.GetForTestingOnly(loc2)
   101  	require.Nil(t, entry)
   102  
   103  	//
   104  	// Test eviction
   105  	//
   106  
   107  	blockId3 := testBlockId(3)
   108  
   109  	// block3 forces block1 to evict
   110  	block3 := programs.GetOrCreateDerivedBlockData(blockId3, blockId2)
   111  	require.NotNil(t, block3)
   112  	require.NotSame(t, block1, block3)
   113  	require.NotSame(t, block2, block3)
   114  
   115  	entry = block3.programs.GetForTestingOnly(loc1)
   116  	require.NotNil(t, entry)
   117  	require.Same(t, prog1, entry.Value)
   118  
   119  	entry = block3.programs.GetForTestingOnly(loc2)
   120  	require.NotNil(t, entry)
   121  	require.Same(t, prog2, entry.Value)
   122  
   123  	// block1 forces block2 to evict
   124  	foundBlock = programs.GetOrCreateDerivedBlockData(blockId1, flow.ZeroID)
   125  	require.NotSame(t, block1, foundBlock)
   126  
   127  	entry = foundBlock.programs.GetForTestingOnly(loc1)
   128  	require.Nil(t, entry)
   129  
   130  	entry = foundBlock.programs.GetForTestingOnly(loc2)
   131  	require.Nil(t, entry)
   132  
   133  	block1 = foundBlock
   134  
   135  	//
   136  	// Scripts don't poplute the cache
   137  	//
   138  
   139  	// Create from cached current block
   140  	scriptBlock := programs.NewDerivedBlockDataForScript(blockId3)
   141  	require.NotNil(t, scriptBlock)
   142  	require.NotSame(t, block2, scriptBlock)
   143  	require.NotSame(t, block3, scriptBlock)
   144  
   145  	entry = scriptBlock.programs.GetForTestingOnly(loc1)
   146  	require.NotNil(t, entry)
   147  	require.Same(t, prog1, entry.Value)
   148  
   149  	entry = scriptBlock.programs.GetForTestingOnly(loc2)
   150  	require.NotNil(t, entry)
   151  	require.Same(t, prog2, entry.Value)
   152  
   153  	foundBlock = programs.Get(blockId3)
   154  	require.Same(t, block3, foundBlock)
   155  
   156  	foundBlock = programs.Get(blockId1)
   157  	require.Same(t, block1, foundBlock)
   158  
   159  	foundBlock = programs.Get(blockId2)
   160  	require.Nil(t, foundBlock)
   161  }