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 }