github.com/datachainlab/burrow@v0.25.0/execution/evm/memory_test.go (about)

     1  package evm
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/hyperledger/burrow/execution/errors"
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"math/big"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  // Test static memory allocation with maximum == initial capacity - memory should not grow
    15  func TestDynamicMemory_StaticAllocation(t *testing.T) {
    16  	err := errors.FirstOnly()
    17  	mem := NewDynamicMemory(4, 4, err).(*dynamicMemory)
    18  	mem.Write(big.NewInt(0), []byte{1})
    19  	mem.Write(big.NewInt(1), []byte{0, 0, 1})
    20  	assert.Equal(t, []byte{1, 0, 0, 1}, mem.slice)
    21  	assert.Equal(t, 4, cap(mem.slice), "Slice capacity should not grow")
    22  	require.NoError(t, err.Error())
    23  }
    24  
    25  // Test reading beyond the current capacity - memory should grow
    26  func TestDynamicMemory_ReadAhead(t *testing.T) {
    27  	err := errors.FirstOnly()
    28  	mem := NewDynamicMemory(4, 8, err).(*dynamicMemory)
    29  	value := mem.Read(big.NewInt(2), big.NewInt(4))
    30  	require.NoError(t, err.Error())
    31  	// Value should be size requested
    32  	assert.Equal(t, []byte{0, 0, 0, 0}, value)
    33  	// Slice should have grown to that plus offset
    34  	assert.Equal(t, []byte{0, 0, 0, 0, 0, 0}, mem.slice)
    35  
    36  	err.Reset()
    37  	value = mem.Read(big.NewInt(2), big.NewInt(6))
    38  	require.NoError(t, err.Error())
    39  	assert.Equal(t, []byte{0, 0, 0, 0, 0, 0}, value)
    40  	assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 0}, mem.slice)
    41  
    42  	// Check cannot read out of bounds
    43  	mem.Read(big.NewInt(2), big.NewInt(7))
    44  	assert.Error(t, err.Error())
    45  }
    46  
    47  // Test writing beyond the current capacity - memory should grow
    48  func TestDynamicMemory_WriteAhead(t *testing.T) {
    49  	err := errors.FirstOnly()
    50  	mem := NewDynamicMemory(4, 8, err).(*dynamicMemory)
    51  	mem.Write(big.NewInt(4), []byte{1, 2, 3, 4})
    52  	require.NoError(t, err.Error())
    53  	assert.Equal(t, []byte{0, 0, 0, 0, 1, 2, 3, 4}, mem.slice)
    54  
    55  	mem.Write(big.NewInt(4), []byte{1, 2, 3, 4, 5})
    56  	assert.Error(t, err.Error())
    57  }
    58  
    59  func TestDynamicMemory_WriteRead(t *testing.T) {
    60  	err := errors.FirstOnly()
    61  	mem := NewDynamicMemory(1, 0x10000000, err).(*dynamicMemory)
    62  	// Text is out of copyright
    63  	bytesToWrite := []byte(`He paused. He felt the rhythm of the verse about him in the room.
    64  How melancholy it was! Could he, too, write like that, express the
    65  melancholy of his soul in verse? There were so many things he wanted
    66  to describe: his sensation of a few hours before on Grattan Bridge, for
    67  example. If he could get back again into that mood....`)
    68  
    69  	// Write the bytes
    70  	offset := big.NewInt(0x1000000)
    71  	mem.Write(offset, bytesToWrite)
    72  	require.NoError(t, err.Error())
    73  	assert.Equal(t, append(make([]byte, offset.Uint64()), bytesToWrite...), mem.slice)
    74  	assert.Equal(t, offset.Uint64()+uint64(len(bytesToWrite)), uint64(len(mem.slice)))
    75  
    76  	// Read them back
    77  	value := mem.Read(offset, big.NewInt(int64(len(bytesToWrite))))
    78  	require.NoError(t, err.Error())
    79  	assert.Equal(t, bytesToWrite, value)
    80  }
    81  
    82  func TestDynamicMemory_ZeroInitialMemory(t *testing.T) {
    83  	err := errors.FirstOnly()
    84  	mem := NewDynamicMemory(0, 16, err).(*dynamicMemory)
    85  	mem.Write(big.NewInt(4), []byte{1, 2, 3, 4})
    86  	require.NoError(t, err.Error())
    87  	assert.Equal(t, []byte{0, 0, 0, 0, 1, 2, 3, 4}, mem.slice)
    88  }
    89  
    90  func TestDynamicMemory_Capacity(t *testing.T) {
    91  	err := errors.FirstOnly()
    92  	mem := NewDynamicMemory(1, 0x10000000, err).(*dynamicMemory)
    93  
    94  	assert.Equal(t, big.NewInt(1), mem.Capacity())
    95  
    96  	capacity := big.NewInt(1234)
    97  	mem.ensureCapacity(capacity.Uint64())
    98  	require.NoError(t, err.Error())
    99  	assert.Equal(t, capacity, mem.Capacity())
   100  
   101  	capacity = big.NewInt(123456789)
   102  	mem.ensureCapacity(capacity.Uint64())
   103  	require.NoError(t, err.Error())
   104  	assert.Equal(t, capacity, mem.Capacity())
   105  
   106  	// Check doesn't shrink or err
   107  	mem.ensureCapacity(12)
   108  	require.NoError(t, err.Error())
   109  	assert.Equal(t, capacity, mem.Capacity())
   110  }
   111  
   112  func TestDynamicMemory_ensureCapacity(t *testing.T) {
   113  	mem := NewDynamicMemory(4, 16, errors.FirstOnly()).(*dynamicMemory)
   114  	// Check we can grow within bounds
   115  	err := mem.ensureCapacity(8)
   116  	require.NoError(t, err)
   117  	expected := make([]byte, 8)
   118  	assert.Equal(t, expected, mem.slice)
   119  
   120  	// Check we can grow to bounds
   121  	err = mem.ensureCapacity(16)
   122  	require.NoError(t, err)
   123  	expected = make([]byte, 16)
   124  	assert.Equal(t, expected, mem.slice)
   125  
   126  	err = mem.ensureCapacity(1)
   127  	require.NoError(t, err)
   128  	assert.Equal(t, 16, len(mem.slice))
   129  
   130  	err = mem.ensureCapacity(17)
   131  	assert.Error(t, err, "Should not be possible to grow over capacity")
   132  
   133  }