diff --git a/execution/evm/account_test.go b/execution/evm/account_test.go new file mode 100644 index 0000000..6cdc21f --- /dev/null +++ b/execution/evm/account_test.go @@ -0,0 +1,444 @@ +package evm + +import ( + "encoding/json" + "math/big" + "reflect" + "testing" + +) + +// Test Account struct +func TestAccount(t *testing.T) { + t.Run("zero value initialization", func(t *testing.T) { + account := Account{} + + if !reflect.DeepEqual(account.Info, AccountInfo{}) { + t.Errorf("Expected empty AccountInfo, got %v", account.Info) + } + + if account.Storage != nil { + t.Errorf("Expected nil Storage, got %v", account.Storage) + } + + if account.Status != 0 { + t.Errorf("Expected Status 0, got %v", account.Status) + } + }) + + t.Run("initialization with values", func(t *testing.T) { + code := Bytecode{ + Kind: LegacyRawKind, + LegacyRaw: []byte{1, 2, 3}, + } + + info := AccountInfo{ + Balance: big.NewInt(100), + Nonce: 1, + CodeHash: B256{1, 2, 3}, + Code: &code, + } + + storage := make(EvmStorage) + storage[big.NewInt(1)] = EvmStorageSlot{ + OriginalValue: big.NewInt(10), + PresentValue: big.NewInt(20), + IsCold: true, + } + + account := Account{ + Info: info, + Storage: storage, + Status: Loaded, + } + + if !reflect.DeepEqual(account.Info, info) { + t.Errorf("Expected Info %v, got %v", info, account.Info) + } + + if !reflect.DeepEqual(account.Storage, storage) { + t.Errorf("Expected Storage %v, got %v", storage, account.Storage) + } + + if account.Status != Loaded { + t.Errorf("Expected Status Loaded, got %v", account.Status) + } + }) +} + +// Test AccountInfo struct and its constructor +func TestAccountInfo(t *testing.T) { + t.Run("NewAccountInfo constructor", func(t *testing.T) { + balance := big.NewInt(100) + nonce := uint64(1) + codeHash := B256{1, 2, 3} + code := Bytecode{ + Kind: LegacyRawKind, + LegacyRaw: []byte{1, 2, 3}, + } + + info := NewAccountInfo(balance, nonce, codeHash, code) + + if info.Balance.Cmp(balance) != 0 { + t.Errorf("Expected Balance %v, got %v", balance, info.Balance) + } + if info.Nonce != nonce { + t.Errorf("Expected Nonce %v, got %v", nonce, info.Nonce) + } + if !reflect.DeepEqual(info.CodeHash, codeHash) { + t.Errorf("Expected CodeHash %v, got %v", codeHash, info.CodeHash) + } + if !reflect.DeepEqual(*info.Code, code) { + t.Errorf("Expected Code %v, got %v", code, *info.Code) + } + }) +} + +// Test EvmStorage +func TestEvmStorage(t *testing.T) { + t.Run("storage operations", func(t *testing.T) { + storage := make(EvmStorage) + + // Test setting and getting values + key := big.NewInt(1) + slot := EvmStorageSlot{ + OriginalValue: big.NewInt(10), + PresentValue: big.NewInt(20), + IsCold: true, + } + + storage[key] = slot + + retrieved, exists := storage[key] + if !exists { + t.Error("Expected storage slot to exist") + } + + if !reflect.DeepEqual(retrieved, slot) { + t.Errorf("Expected slot %v, got %v", slot, retrieved) + } + }) +} + +// Test AccountStatus constants and operations +func TestAccountStatus(t *testing.T) { + tests := []struct { + name string + status AccountStatus + value uint8 + }{ + {"Loaded", Loaded, 0b00000000}, + {"Created", Created, 0b00000001}, + {"SelfDestructed", SelfDestructed, 0b00000010}, + {"Touched", Touched, 0b00000100}, + {"LoadedAsNotExisting", LoadedAsNotExisting, 0b0001000}, + {"Cold", Cold, 0b0010000}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if uint8(tt.status) != tt.value { + t.Errorf("%s: expected %b, got %b", tt.name, tt.value, uint8(tt.status)) + } + }) + } +} + +// Test Bytecode +func TestBytecode(t *testing.T) { + t.Run("legacy raw bytecode", func(t *testing.T) { + code := Bytecode{ + Kind: LegacyRawKind, + LegacyRaw: []byte{1, 2, 3}, + } + + if code.Kind != LegacyRawKind { + t.Errorf("Expected Kind LegacyRawKind, got %v", code.Kind) + } + if !reflect.DeepEqual(code.LegacyRaw, []byte{1, 2, 3}) { + t.Errorf("Expected LegacyRaw [1 2 3], got %v", code.LegacyRaw) + } + }) + + t.Run("legacy analyzed bytecode", func(t *testing.T) { + analyzed := &LegacyAnalyzedBytecode{ + Bytecode: []byte{1, 2, 3}, + OriginalLen: 3, + JumpTable: JumpTable{BitVector: &Bitvector{bits: []uint8{1}, size: 8}}, + } + + code := Bytecode{ + Kind: LegacyAnalyzedKind, + LegacyAnalyzed: analyzed, + } + + if code.Kind != LegacyAnalyzedKind { + t.Errorf("Expected Kind LegacyAnalyzedKind, got %v", code.Kind) + } + if !reflect.DeepEqual(code.LegacyAnalyzed, analyzed) { + t.Errorf("Expected LegacyAnalyzed %v, got %v", analyzed, code.LegacyAnalyzed) + } + }) +} + +// Test EOF related structs +func TestEof(t *testing.T) { + t.Run("eof header", func(t *testing.T) { + header := EofHeader{ + TypesSize: 2, + CodeSizes: []uint16{100, 200}, + ContainerSizes: []uint16{300, 400}, + DataSize: 500, + SumCodeSizes: 300, + SumContainerSizes: 700, + } + + // Test JSON marshaling/unmarshaling + data, err := json.Marshal(header) + if err != nil { + t.Fatalf("Failed to marshal EofHeader: %v", err) + } + + var decoded EofHeader + err = json.Unmarshal(data, &decoded) + if err != nil { + t.Fatalf("Failed to unmarshal EofHeader: %v", err) + } + + if !reflect.DeepEqual(header, decoded) { + t.Errorf("Expected header %+v, got %+v", header, decoded) + } + }) + + t.Run("eof body", func(t *testing.T) { + body := EofBody{ + TypesSection: []TypesSection{{ + Inputs: 1, + Outputs: 2, + MaxStackSize: 1024, + }}, + CodeSection: []Bytes{{1, 2, 3}}, + ContainerSection: []Bytes{{4, 5, 6}}, + DataSection: Bytes{7, 8, 9}, + IsDataFilled: true, + } + + // Test JSON marshaling/unmarshaling + data, err := json.Marshal(body) + if err != nil { + t.Fatalf("Failed to marshal EofBody: %v", err) + } + + var decoded EofBody + err = json.Unmarshal(data, &decoded) + if err != nil { + t.Fatalf("Failed to unmarshal EofBody: %v", err) + } + + if !reflect.DeepEqual(body, decoded) { + t.Errorf("Expected body %+v, got %+v", body, decoded) + } + }) +} +func TestBitvector(t *testing.T) { + t.Run("bitvector initialization", func(t *testing.T) { + bv := Bitvector{ + bits: []uint8{0b10101010}, + size: 8, + } + + if len(bv.bits) != 1 { + t.Errorf("Expected bits length 1, got %d", len(bv.bits)) + } + if bv.size != 8 { + t.Errorf("Expected size 8, got %d", bv.size) + } + }) +} + +// Test JumpTable +func TestJumpTable(t *testing.T) { + t.Run("jumptable initialization", func(t *testing.T) { + jt := JumpTable{ + BitVector: &Bitvector{ + bits: []uint8{0b11110000}, + size: 8, + }, + } + + if jt.BitVector == nil { + t.Error("Expected non-nil BitVector") + } + }) + + t.Run("jumptable sync.Once", func(t *testing.T) { + jt := JumpTable{} + initialized := false + + // Test lazy initialization + jt.once.Do(func() { + initialized = true + }) + + if !initialized { + t.Error("sync.Once did not execute initialization") + } + }) +} + + +func TestOpcode(t *testing.T) { + t.Run("opcode structure", func(t *testing.T) { + createdAddress := Address{Addr: [20]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} + opcode := Opcode{ + InitCode: Eof{Header: EofHeader{ + TypesSize: 1, + CodeSizes: []uint16{100}, + }, Body: EofBody{ + TypesSection: []TypesSection{{ + Inputs: 1, + Outputs: 1, + MaxStackSize: 100, + }}, + }, Raw: Bytes{1, 2, 3}}, + Input: Bytes{4, 5, 6}, + CreatedAddress: createdAddress, + } + + // Tests for opcode structure + if len(opcode.Input) != 3 { + t.Errorf("Expected Input length 3, got %d", len(opcode.Input)) + } + + if reflect.DeepEqual(opcode.InitCode, Eof{}) { + t.Error("Expected non-empty InitCode") + } + + if !reflect.DeepEqual(opcode.CreatedAddress, createdAddress) { + t.Errorf("Expected CreatedAddress %v, got %v", createdAddress, opcode.CreatedAddress) + } + }) +} + + + +// Test TypesSection +func TestTypesSection(t *testing.T) { + t.Run("types section values", func(t *testing.T) { + ts := TypesSection{ + Inputs: 2, + Outputs: 3, + MaxStackSize: 1024, + } + + if ts.Inputs != 2 { + t.Errorf("Expected Inputs 2, got %d", ts.Inputs) + } + if ts.Outputs != 3 { + t.Errorf("Expected Outputs 3, got %d", ts.Outputs) + } + if ts.MaxStackSize != 1024 { + t.Errorf("Expected MaxStackSize 1024, got %d", ts.MaxStackSize) + } + }) +} + +//Not done- Test EOFCreateKind JSON marshaling/unmarshaling + +func TestEvmStorageSlot(t *testing.T) { + t.Run("storage slot values", func(t *testing.T) { + slot := EvmStorageSlot{ + OriginalValue: big.NewInt(100), + PresentValue: big.NewInt(200), + IsCold: true, + } + + if slot.OriginalValue.Cmp(big.NewInt(100)) != 0 { + t.Errorf("Expected OriginalValue 100, got %v", slot.OriginalValue) + } + if slot.PresentValue.Cmp(big.NewInt(200)) != 0 { + t.Errorf("Expected PresentValue 200, got %v", slot.PresentValue) + } + if !slot.IsCold { + t.Error("Expected IsCold to be true") + } + }) + + t.Run("storage slot modifications", func(t *testing.T) { + slot := EvmStorageSlot{ + OriginalValue: big.NewInt(100), + PresentValue: big.NewInt(100), + IsCold: true, + } + + // Modify present value + slot.PresentValue = big.NewInt(150) + + if slot.PresentValue.Cmp(big.NewInt(150)) != 0 { + t.Error("Failed to modify PresentValue") + } + if slot.OriginalValue.Cmp(big.NewInt(100)) != 0 { + t.Error("OriginalValue should not change") + } + }) +} + +// Integration test for complex scenarios +func TestComplexScenarios(t *testing.T) { + t.Run("account with storage modifications", func(t *testing.T) { + // Create initial account state + account := Account{ + Info: NewAccountInfo( + big.NewInt(1000), + 1, + B256{1}, + Bytecode{Kind: LegacyRawKind, LegacyRaw: []byte{1, 2, 3}}, + ), + Storage: make(EvmStorage), + Status: Created, + } + + // Add some storage + key := big.NewInt(1) + account.Storage[key] = EvmStorageSlot{ + OriginalValue: big.NewInt(100), + PresentValue: big.NewInt(100), + IsCold: true, + } + + // Modify storage + slot := account.Storage[key] + slot.PresentValue = big.NewInt(200) + slot.IsCold = false + account.Storage[key] = slot + + // Verify all changes + if account.Storage[key].PresentValue.Cmp(big.NewInt(200)) != 0 { + t.Error("Storage modification failed") + } + if account.Storage[key].OriginalValue.Cmp(big.NewInt(100)) != 0 { + t.Error("Original value should not change") + } + if account.Storage[key].IsCold { + t.Error("IsCold should be false") + } + }) + + t.Run("account status transitions", func(t *testing.T) { + account := Account{Status: Created} + + // Test status transitions + transitions := []AccountStatus{ + Touched, + SelfDestructed, + Cold, + } + + for _, newStatus := range transitions { + account.Status = newStatus + if account.Status != newStatus { + t.Errorf("Failed to transition to status %v", newStatus) + } + } + }) +} \ No newline at end of file diff --git a/execution/evm/common_test.go b/execution/evm/common_test.go new file mode 100644 index 0000000..afcc8a5 --- /dev/null +++ b/execution/evm/common_test.go @@ -0,0 +1,82 @@ +package evm + +import ( + "math/big" + "testing" + + // "github.com/stretchr/testify" + Common "github.com/ethereum/go-ethereum/common" + "github.com/magiconair/properties/assert" +) + +func TestU256Initialization(t *testing.T) { + var zero U256 = big.NewInt(0) + if zero.Cmp(big.NewInt(0)) != 0 { + t.Errorf("Expected zero U256, got %v", zero) + } + var positive U256 = big.NewInt(17) + if positive.Cmp(big.NewInt(17)) != 0 { + t.Errorf("Expected U256 to be 17, got %v", positive) + } + largeNum := new(big.Int) + largeNum.SetString("123456789012345678901234567890", 10) + var uLarge U256 = largeNum + if uLarge.Cmp(largeNum) != 0 { + t.Errorf("Expected U256 to be large number %v, got %v", largeNum, uLarge) + } + if positive.Cmp(largeNum) == 0 { + t.Errorf("Expected U256 %v to be different from large number %v", positive, largeNum) + } + +} +func TestU256Equality(t *testing.T) { + var a U256 = big.NewInt(17) + var b U256 = big.NewInt(17) + var c U256 = big.NewInt(100) + if a.Cmp(b) != 0 { + t.Errorf("Expected U256 instances to be equal, got a: %v, b: %v", a, b) + } + if a.Cmp(c) == 0 { + t.Errorf("Expected U256 instances to be different, got a: %v, c: %v", a, c) + } +} +func TestB256Initialization(t *testing.T) { + var hash B256 = Common.BytesToHash([]byte("selene")) + expectedHash := Common.BytesToHash([]byte("selene")) + assert.Equal(t, expectedHash, hash, "Expected hash and expectedHash to be same") + +} +func TestAddressInitialization(t *testing.T) { + // Test Address initialization + addr := Common.HexToAddress("0x0000000000000000000000000000000000000001") + if addr.String() != "0x0000000000000000000000000000000000000001" { + t.Errorf("Expected Address to be 0x0000000000000000000000000000000000000001, got %v", addr) + } + + // Test Address validity with a valid input + validAddr := Common.HexToAddress("0x0000000000000000000000000000000000000001") + if validAddr == (Common.Address{}) { + t.Errorf("Expected a valid Address, got zero address") + } + + // Test Address validity with an invalid input + invalidAddr := Common.HexToAddress("invalid-address") + if invalidAddr != (Common.Address{}) { + t.Errorf("Expected zero Address for invalid input, got %v", invalidAddr) + } +} + + +func TestBytesInitialization(t *testing.T) { + // Test Bytes initialization + data := []byte{1, 2, 3, 4} + var byteData Bytes = data + + if len(byteData) != 4 { + t.Errorf("Expected Bytes length to be 4, got %v", len(byteData)) + } + + if byteData[0] != 1 { + t.Errorf("Expected first byte to be 1, got %v", byteData[0]) + } +} \ No newline at end of file diff --git a/execution/evm/database_test.go b/execution/evm/database_test.go new file mode 100644 index 0000000..514aaba --- /dev/null +++ b/execution/evm/database_test.go @@ -0,0 +1,178 @@ +package evm + +import ( + "errors" + "math/big" + "reflect" + "testing" +) + +func TestNewEmptyDB(t *testing.T) { + db := NewEmptyDB() + if db == nil { + t.Error("NewEmptyDB() returned nil") + } +} + +func TestEmptyDBBasic(t *testing.T) { + db := NewEmptyDB() + + testCases := []struct { + name string + address Address + wantErr string + }{ + { + name: "basic query", + address: Address{}, // zero address + wantErr: "EmptyDB: Basic not implemented", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + info, err := db.Basic(tc.address) + + // Check if error matches expected + if err == nil || err.Error() != tc.wantErr { + t.Errorf("Basic() error = %v, want %v", err, tc.wantErr) + } + + // Verify empty AccountInfo is returned + if !reflect.DeepEqual(info, AccountInfo{}) { + t.Errorf("Basic() info = %v, want empty AccountInfo", info) + } + }) + } +} + +func TestEmptyDBBlockHash(t *testing.T) { + db := NewEmptyDB() + + testCases := []struct { + name string + number uint64 + wantErr string + }{ + { + name: "block hash query", + number: 1, + wantErr: "EmptyDB: BlockHash not implemented", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + hash, err := db.BlockHash(tc.number) + + // Check if error matches expected + if err == nil || err.Error() != tc.wantErr { + t.Errorf("BlockHash() error = %v, want %v", err, tc.wantErr) + } + + // Verify empty B256 is returned + if !reflect.DeepEqual(hash, B256{}) { + t.Errorf("BlockHash() hash = %v, want empty B256", hash) + } + }) + } +} + +func TestEmptyDBStorage(t *testing.T) { + db := NewEmptyDB() + + testCases := []struct { + name string + address Address + index U256 + wantErr string + }{ + { + name: "storage query", + address: Address{}, + index: big.NewInt(0), + wantErr: "EmptyDB: Storage not implemented", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + value, err := db.Storage(tc.address, tc.index) + + // Check if error matches expected + if err == nil || err.Error() != tc.wantErr { + t.Errorf("Storage() error = %v, want %v", err, tc.wantErr) + } + + // Verify zero value is returned + if value.Cmp(big.NewInt(0)) != 0 { + t.Errorf("Storage() value = %v, want 0", value) + } + }) + } +} + +func TestEmptyDBCodeByHash(t *testing.T) { + db := NewEmptyDB() + + testCases := []struct { + name string + codeHash B256 + wantErr string + }{ + { + name: "code query", + codeHash: B256{}, + wantErr: "EmptyDB: CodeByHash not implemented", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + code, err := db.CodeByHash(tc.codeHash) + + // Check if error matches expected + if err == nil || err.Error() != tc.wantErr { + t.Errorf("CodeByHash() error = %v, want %v", err, tc.wantErr) + } + + // Verify empty Bytecode is returned + if !reflect.DeepEqual(code, Bytecode{}) { + t.Errorf("CodeByHash() code = %v, want empty Bytecode", code) + } + }) + } +} + +func TestDatabaseError(t *testing.T) { + testCases := []struct { + name string + err *DatabaseError + wantErr string + }{ + { + name: "with underlying error", + err: &DatabaseError{ + msg: "test message", + err: errors.New("underlying error"), + }, + wantErr: "underlying error", + }, + { + name: "without underlying error", + err: &DatabaseError{ + msg: "test message", + err: nil, + }, + wantErr: "test message", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if err := tc.err.Error(); err != tc.wantErr { + t.Errorf("DatabaseError.Error() = %v, want %v", err, tc.wantErr) + } + }) + } +} \ No newline at end of file diff --git a/execution/evm/frame_test.go b/execution/evm/frame_test.go new file mode 100644 index 0000000..bd863ad --- /dev/null +++ b/execution/evm/frame_test.go @@ -0,0 +1,382 @@ +package evm + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCallFrame(t *testing.T) { + // Arrange + expectedRange := Range{Start: 100, End: 200} + expectedFrameData := FrameData{ + Checkpoint: JournalCheckpoint{ + Log_i: 10, + Journal_i: 20, + }, + Interpreter: Interpreter{ + InstructionPointer: func(b byte) *byte { return &b }(0x10), + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + IsEof: true, + IsEofInit: true, + SharedMemory: SharedMemory{ + Buffer: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, + Checkpoints: []int{0, 2, 4}, + LastCheckpoint: 4, + MemoryLimit: 1024, + }, + Stack: Stack{ + Data: []*big.Int{big.NewInt(15)}, + }, + IsStatic: true, + Contract: Contract{ + Input: []byte{0xde, 0xad, 0xbe, 0xef}, + Bytecode: Bytecode{}, + Hash: &B256{0xaa, 0xbb, 0xcc, 0xdd, 0xee}, + TargetAddress: Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + Caller: Address{Addr: [20]byte{0x1b, 0x3d, 0x5f, 0x7a, 0x9c}}, + CallValue: U256(big.NewInt(1000)), + }, + + }, + } + + // Act + frame := CallFrame{ + ReturnMemoryRange: expectedRange, + FrameData: expectedFrameData, + } + + assert.Equal(t, expectedRange, frame.ReturnMemoryRange) + assert.Equal(t, expectedFrameData, frame.FrameData) +} + + +func TestCreateFrame(t *testing.T) { + // Arrange + expectedAddress := Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}} + expectedFrameData := FrameData{ + Checkpoint: JournalCheckpoint{ + Log_i: 10, + Journal_i: 20, + }, // Initialize with your checkpoint data + Interpreter: Interpreter{ + InstructionPointer: func(b byte) *byte { return &b }(0x10), + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + IsEof: true, + IsEofInit: true, + SharedMemory: SharedMemory{ + Buffer: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, + Checkpoints: []int{0, 2, 4}, + LastCheckpoint: 4, + MemoryLimit: 1024, + }, + Stack: Stack{ + Data: []*big.Int{big.NewInt(15)}, + }, + IsStatic: true, + Contract: Contract{ + Input: []byte{0xde, 0xad, 0xbe, 0xef}, + Bytecode: Bytecode{}, + Hash: &B256{0xaa, 0xbb, 0xcc, 0xdd, 0xee}, + TargetAddress: Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + Caller: Address{Addr: [20]byte{0x1b, 0x3d, 0x5f, 0x7a, 0x9c}}, + CallValue: U256(big.NewInt(1000)), + }, + + }, + } + + // Act + frame := CreateFrame{ + CreatedAddress: expectedAddress, + FrameData: expectedFrameData, + } + + // Assert + assert.Equal(t, expectedAddress, frame.CreatedAddress) + assert.Equal(t, expectedFrameData, frame.FrameData) +} +func TestEOFCreatedFrame(t *testing.T){ + expectedAddress := Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}} + expectedFrameData := FrameData{ + Checkpoint: JournalCheckpoint{ + Log_i: 10, + Journal_i: 20, + }, // Initialize with your checkpoint data + Interpreter: Interpreter{ + InstructionPointer: func(b byte) *byte { return &b }(0x10), + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + IsEof: true, + IsEofInit: true, + SharedMemory: SharedMemory{ + Buffer: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, + Checkpoints: []int{0, 2, 4}, + LastCheckpoint: 4, + MemoryLimit: 1024, + }, + Stack: Stack{ + Data: []*big.Int{big.NewInt(15)}, + }, + IsStatic: true, + Contract: Contract{ + Input: []byte{0xde, 0xad, 0xbe, 0xef}, + Bytecode: Bytecode{}, + Hash: &B256{0xaa, 0xbb, 0xcc, 0xdd, 0xee}, + TargetAddress: Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + Caller: Address{Addr: [20]byte{0x1b, 0x3d, 0x5f, 0x7a, 0x9c}}, + CallValue: U256(big.NewInt(1000)), + }, + + }, + } + + // Act + frame := EOFCreateFrame{ + CreatedAddress: expectedAddress, + FrameData: expectedFrameData, + } + + // Assert + assert.Equal(t, expectedAddress, frame.CreatedAddress) + assert.Equal(t, expectedFrameData, frame.FrameData) + +} +func TestFrameData(t *testing.T) { + expectedCheckpoint := JournalCheckpoint{ + Log_i: 10, + Journal_i: 50, + } + expectedInterpreter := Interpreter{ + InstructionPointer: func(b byte) *byte { return &b }(0x10), + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + IsEof: true, + IsEofInit: true, + SharedMemory: SharedMemory{ + Buffer: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, + Checkpoints: []int{0, 2, 4}, + LastCheckpoint: 4, + MemoryLimit: 1024, + }, + Stack: Stack{ + Data: []*big.Int{big.NewInt(15)}, + }, + IsStatic: true, + Contract: Contract{ + Input: []byte{0xde, 0xad, 0xbe, 0xef}, + Bytecode: Bytecode{}, + Hash: &B256{0xaa, 0xbb, 0xcc, 0xdd, 0xee}, + TargetAddress: Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + Caller: Address{Addr: [20]byte{0x1b, 0x3d, 0x5f, 0x7a, 0x9c}}, + CallValue: U256(big.NewInt(1000)), + }, + } + + // Act + frame := FrameData{ + Checkpoint: expectedCheckpoint, + Interpreter: expectedInterpreter, + } + + // Assert + assert.Equal(t, expectedCheckpoint, frame.Checkpoint) + assert.Equal(t, expectedInterpreter, frame.Interpreter) +} + +func TestCallOutcome(t *testing.T){ + expectedResult :=InterpreterResult{ + Result: 8, + Output: []byte{0xde, 0xad, 0xbe, 0xef}, + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + + } + expectedMemoryOffset := Range{Start: 100, End: 200} + + frame := CallOutcome{ + Result: expectedResult, + MemoryOffset: expectedMemoryOffset, + } + + // Use the frame variable to avoid the "declared and not used" error + assert.Equal(t, expectedResult, frame.Result) + assert.Equal(t, expectedMemoryOffset, frame.MemoryOffset) +} +func TestCreateOutcome(t *testing.T){ + expectedResult:=InterpreterResult{ + Result: 8, + Output: []byte{0xde, 0xad, 0xbe, 0xef}, + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + + } + expectedAddress:=Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}} + + frame := CreateOutcome{ + Result: expectedResult, + Address: &expectedAddress, + } + + // Use the frame variable to avoid the "declared and not used" error + assert.Equal(t, expectedResult, frame.Result) + assert.Equal(t, &expectedAddress, frame.Address) + +} +func TestFrame(t *testing.T) { + callFrame := &CallFrame{ + ReturnMemoryRange: Range{Start: 100, End: 200}, + FrameData: FrameData{ + Checkpoint: JournalCheckpoint{ + Log_i: 10, + Journal_i: 20, + }, + Interpreter: Interpreter{ + InstructionPointer: func(b byte) *byte { return &b }(0x10), + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + IsEof: true, + IsEofInit: true, + SharedMemory: SharedMemory{ + Buffer: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, + Checkpoints: []int{0, 2, 4}, + LastCheckpoint: 4, + MemoryLimit: 1024, + }, + Stack: Stack{ + Data: []*big.Int{big.NewInt(15)}, + }, + IsStatic: true, + Contract: Contract{ + Input: []byte{0xde, 0xad, 0xbe, 0xef}, + Bytecode: Bytecode{}, + Hash: &B256{0xaa, 0xbb, 0xcc, 0xdd, 0xee}, + TargetAddress: Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + Caller: Address{Addr: [20]byte{0x1b, 0x3d, 0x5f, 0x7a, 0x9c}}, + CallValue: U256(big.NewInt(1000)), + }, + }, + }, + } + + frame := Frame{ + Type: Call_Frame, + Call: callFrame, + } + + // Assert + assert.Equal(t, Call_Frame, frame.Type) + assert.Equal(t, callFrame, frame.Call) +} + +func TestFrameResult(t *testing.T) { + // Arrange + expectedResultType := FrameResultType(10) + expectedCall := CallOutcome{ + InterpreterResult{ + Result: 8, + Output: []byte{0xde, 0xad, 0xbe, 0xef}, + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + }, + Range{Start: 100, End: 200}, + } + expectedCreateOutcome := CreateOutcome{ + Result: InterpreterResult{ + Result: 8, + Output: []byte{0xde, 0xad, 0xbe, 0xef}, + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + }, + Address: &Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + } + frame := FrameResult{ + ResultType: expectedResultType, + Call: &expectedCall, + Create: &expectedCreateOutcome, + } + + // Use the frame variable to avoid the "declared and not used" error + assert.Equal(t, expectedResultType, frame.ResultType) + assert.Equal(t, &expectedCall, frame.Call) + assert.Equal(t, &expectedCreateOutcome, frame.Create) + +} + + + + +func TestFrameOrResult(t *testing.T) { + callFrame := Frame{ + Type: Call_Frame, + Call: &CallFrame{ + ReturnMemoryRange: Range{Start: 100, End: 200}, + FrameData: FrameData{ + Checkpoint: JournalCheckpoint{ + Log_i: 10, + Journal_i: 20, + }, + Interpreter: Interpreter{ + InstructionPointer: func(b byte) *byte { return &b }(0x10), + Gas: Gas{ + Limit: 100, + Remaining: 50, + Refunded: 50, + }, + IsEof: true, + Stack: Stack{ + Data: []*big.Int{big.NewInt(15)}, + }, + Contract: Contract{ + Input: []byte{0xde, 0xad, 0xbe, 0xef}, + Bytecode: Bytecode{}, + Hash: &B256{0xaa, 0xbb, 0xcc, 0xdd, 0xee}, + TargetAddress: Address{Addr: [20]byte{0x1a, 0x2b, 0x3c, 0x4d, 0x5e}}, + Caller: Address{Addr: [20]byte{0x1b, 0x3d, 0x5f, 0x7a, 0x9c}}, + CallValue: U256(big.NewInt(1000)), + }, + }, + }, + }, + } + + frameOrResult := FrameOrResult{ + Type: Frame_FrameOrResult, + Frame: callFrame, + } + + // Assert + assert.Equal(t, Frame_FrameOrResult, frameOrResult.Type) + assert.Equal(t, callFrame, frameOrResult.Frame) +}