Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execution #15

Merged
merged 31 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fa92817
WIP: Lambdaworks wrapper
toni-calvin Jul 31, 2023
ed3ae71
Wrapper around lambdaworks library
toni-calvin Jul 31, 2023
1301f2a
Execution functionality
mmsc2 Jul 31, 2023
9a7e4d5
compute addresses
mmsc2 Jul 31, 2023
af26140
Merge branch 'main' into Execution
mmsc2 Jul 31, 2023
9c4260f
Merge branch 'main' into Execution
mmsc2 Aug 1, 2023
cfaf8f5
Compute Operands
mmsc2 Aug 1, 2023
83a6a53
Fix tests
mmsc2 Aug 1, 2023
b6e4d05
Decode operands tests
mmsc2 Aug 3, 2023
665bca2
Merge branch 'main' into Execution
mmsc2 Aug 3, 2023
dec1bbb
Fixing test
mmsc2 Aug 3, 2023
1e33246
Test compute operands
mmsc2 Aug 3, 2023
6bf80f7
merge conflicts
mmsc2 Aug 3, 2023
143dd6e
Opcode assertions (#32)
toni-calvin Aug 3, 2023
5ea14fe
merge main
mmsc2 Aug 3, 2023
7a70892
Fix merge conflicts
mmsc2 Aug 3, 2023
c0f9603
Merge branch 'main' into Execution
mmsc2 Aug 3, 2023
3740c5b
merge main
mmsc2 Aug 3, 2023
fddcf0b
Fix comments
mmsc2 Aug 3, 2023
5a981d9
fix typos
mmsc2 Aug 3, 2023
67dbfd1
Delete circular dependency
mmsc2 Aug 3, 2023
bf129e7
Delete unused struct
mmsc2 Aug 4, 2023
f62926d
leave comment code for once deductions is done
mmsc2 Aug 4, 2023
b8f8e27
Merge branch 'main' into Execution
mmsc2 Aug 4, 2023
7848f67
Fix felt usage
mmsc2 Aug 4, 2023
0c25650
Fix merge conflicts
mmsc2 Aug 4, 2023
5baabbb
refactor Add felt in maybe relocatable add
mmsc2 Aug 4, 2023
51fa19a
Delete duplicated function
mmsc2 Aug 4, 2023
6c67c6f
Update pkg/vm/run_context.go
pablodeymo Aug 4, 2023
b34f44b
Update pkg/vm/memory/relocatable.go
pablodeymo Aug 4, 2023
5e8436d
Update pkg/vm/memory/relocatable.go
pablodeymo Aug 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pkg/lambdaworks/lambdaworks.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ package lambdaworks
#include <stdlib.h>
*/
import "C"

import (
"errors"
"unsafe"
)

Expand Down Expand Up @@ -104,6 +106,16 @@ func (a Felt) Mul(b Felt) Felt {
}

// Writes the result variable with a / b.

// turns a felt to usize
func (felt Felt) ToU64() (uint64, error) {
if felt.limbs[0] == 0 && felt.limbs[1] == 0 && felt.limbs[2] == 0 {
return uint64(felt.limbs[3]), nil
} else {
return 0, errors.New("Cannot convert felt to u64")
}
}

func (a Felt) Div(b Felt) Felt {
var result C.felt_t
var a_c C.felt_t = a.toC()
Expand Down
10 changes: 3 additions & 7 deletions pkg/lambdaworks/lib/lambdaworks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use lambdaworks_math::{
field::element::FieldElement,
field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField,
unsigned_integer::element::UnsignedInteger,
unsigned_integer::element::U256
unsigned_integer::element::UnsignedInteger, unsigned_integer::element::U256,
};

extern crate libc;
Expand Down Expand Up @@ -63,15 +62,12 @@ pub extern "C" fn from_dec_str(result: Limbs, value: *const libc::c_char) {
let val_str = val_cstr.to_str().unwrap();
let felt = match val_str.strip_prefix("-") {
Some(stripped) => {
let val = U256::from_dec_str(stripped).unwrap();
let val = U256::from_dec_str(stripped).unwrap();
Felt::from(0) - Felt::from(&val)
}
None => {
Felt::from(&U256::from_dec_str(val_str).unwrap())
}
None => Felt::from(&U256::from_dec_str(val_str).unwrap()),
};
felt_to_limbs(felt, result)

}

#[no_mangle]
Expand Down
5 changes: 3 additions & 2 deletions pkg/runners/cairo_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package runners_test
import (
"testing"

"github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
"github.com/lambdaclass/cairo-vm.go/pkg/runners"
"github.com/lambdaclass/cairo-vm.go/pkg/vm"
"github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
Expand Down Expand Up @@ -72,7 +73,7 @@ func TestInitializeRunnerNoBuiltinsNoProofModeEmptyProgram(t *testing.T) {
func TestInitializeRunnerNoBuiltinsNoProofModeNonEmptyProgram(t *testing.T) {
// Create a Program with one fake instruction
program_data := make([]memory.MaybeRelocatable, 1)
program_data[0] = *memory.NewMaybeRelocatableInt(1)
program_data[0] = *memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(1))
program := vm.Program{Data: program_data}
// Create CairoRunner
runner := runners.NewCairoRunner(program)
Expand Down Expand Up @@ -110,7 +111,7 @@ func TestInitializeRunnerNoBuiltinsNoProofModeNonEmptyProgram(t *testing.T) {
t.Errorf("Memory Get error in test: %s", err)
}
int, ok := value.GetInt()
if !ok || int.Felt != 1 {
if !ok || int.Felt != lambdaworks.FeltFromUint64(1) {
t.Errorf("Wrong value for address 0:0: %d", int)
}

Expand Down
1 change: 0 additions & 1 deletion pkg/vm/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ func (m *Memory) Insert(addr Relocatable, val *MaybeRelocatable) error {
if ok && prev_elem != *val {
return errors.New("Memory is write-once, cannot overwrite memory value")
}

m.data[addr] = *val

return nil
Expand Down
21 changes: 11 additions & 10 deletions pkg/vm/memory/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"reflect"
"testing"

"github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
"github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
)

Expand All @@ -16,7 +17,7 @@ func TestMemoryInsert(t *testing.T) {
// Instantiate the address where we want to insert and the value.
// We will insert the value Int(5) in segment 1, offset 0
key := memory.NewRelocatable(1, 0)
val := memory.NewMaybeRelocatableInt(5)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))

// Make the insertion
err := mem.Insert(key, val)
Expand Down Expand Up @@ -45,7 +46,7 @@ func TestMemoryInsertWithHoles(t *testing.T) {
// Instantiate the address where we want to insert and the value.
// We will insert the MaybeRelocatable Int(7) in segment 1, offset 2
key := memory.NewRelocatable(1, 2)
val := memory.NewMaybeRelocatableInt(7)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(7))

// Make the insertion
err := mem.Insert(key, val)
Expand All @@ -71,7 +72,7 @@ func TestMemoryInsertOverWriteSameValue(t *testing.T) {

// We will insert the MaybeRelocatable Int(7) in segment 0, offset 0
key := mem_manager.AddSegment()
val := memory.NewMaybeRelocatableInt(7)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(7))

// Make the insertion
err := mem.Insert(key, val)
Expand All @@ -92,7 +93,7 @@ func TestMemoryInsertOverWriteValue(t *testing.T) {

// We will insert the MaybeRelocatable Int(7) in segment 0, offset 0
key := mem_manager.AddSegment()
val := memory.NewMaybeRelocatableInt(7)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(7))

// Make the insertion
err := mem.Insert(key, val)
Expand All @@ -101,7 +102,7 @@ func TestMemoryInsertOverWriteValue(t *testing.T) {
}

// Insert another value into the same address and check that it fails
val2 := memory.NewMaybeRelocatableInt(8)
val2 := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(8))
err2 := mem.Insert(key, val2)
if err2 == nil {
t.Errorf("Overwritting memory value should fail")
Expand All @@ -115,7 +116,7 @@ func TestMemoryInsertUnallocatedSegment(t *testing.T) {
// Instantiate the address where we want to insert and the value.
// We will insert the value Int(5) in segment 1, offset 0
key := memory.NewRelocatable(1, 0)
val := memory.NewMaybeRelocatableInt(5)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))

// Make the insertion
err := mem.Insert(key, val)
Expand All @@ -128,7 +129,7 @@ func TestMemorySegmentsLoadDataUnallocatedSegment(t *testing.T) {
mem_manager := memory.NewMemorySegmentManager()

ptr := memory.NewRelocatable(1, 0)
data := []memory.MaybeRelocatable{*memory.NewMaybeRelocatableInt(5)}
data := []memory.MaybeRelocatable{*memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))}

// Load Data
_, err := mem_manager.LoadData(ptr, &data)
Expand All @@ -142,7 +143,7 @@ func TestMemorySegmentsLoadDataOneElement(t *testing.T) {
mem_manager.AddSegment()

ptr := memory.NewRelocatable(0, 0)
val := memory.NewMaybeRelocatableInt(5)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))
data := []memory.MaybeRelocatable{*val}

// Load Data
Expand Down Expand Up @@ -174,8 +175,8 @@ func TestMemorySegmentsLoadDataTwoElements(t *testing.T) {
mem_manager.AddSegment()

ptr := memory.NewRelocatable(0, 0)
val := memory.NewMaybeRelocatableInt(5)
val2 := memory.NewMaybeRelocatableInt(5)
val := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))
val2 := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))
data := []memory.MaybeRelocatable{*val, *val2}

// Load Data
Expand Down
95 changes: 84 additions & 11 deletions pkg/vm/memory/relocatable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package memory
import (
"errors"
"fmt"

"github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
)

// Relocatable in the Cairo VM represents an address
Expand All @@ -23,8 +25,13 @@ func NewRelocatable(segment_idx int, offset uint) Relocatable {
// Adds a Felt value to a Relocatable
// Fails if the new offset exceeds the size of a uint
func (r *Relocatable) AddFelt(other Int) (Relocatable, error) {
new_offset := r.Offset + other.Felt // TODO: Placeholder
return NewRelocatable(r.SegmentIndex, new_offset), nil
felt_offset := lambdaworks.FeltFromUint64(uint64(r.Offset))
new_offset := felt_offset.Add(other.Felt)
res_offset, err := new_offset.ToU64()
if err != nil {
return Relocatable{}, err
}
return NewRelocatable(r.SegmentIndex, uint(res_offset)), nil

}

Expand All @@ -41,12 +48,28 @@ func (r *Relocatable) RelocateAddress(relocationTable *[]uint) uint {
return (*relocationTable)[r.SegmentIndex] + r.Offset
}

func (r *Relocatable) IsEqual(r1 *Relocatable) bool {
return (r.SegmentIndex == r1.SegmentIndex && r.Offset == r1.Offset)
}

func (relocatable *Relocatable) SubUint(other uint) (Relocatable, error) {
if relocatable.Offset < other {
return NewRelocatable(0, 0), &SubReloctableError{Msg: "RelocatableSubUsizeNegOffset"}
} else {
new_offset := relocatable.Offset - other
return NewRelocatable(relocatable.SegmentIndex, new_offset), nil
}
}

func (relocatable *Relocatable) AddUint(other uint) (Relocatable, error) {
new_offset := relocatable.Offset + other
return NewRelocatable(relocatable.SegmentIndex, new_offset), nil
}

// Int in the Cairo VM represents a value in memory that
// is not an address.
type Int struct {
// FIXME: Here we should use Lambdaworks felt, just mocking
// this for now.
Felt uint
Felt lambdaworks.Felt
}

// MaybeRelocatable is the type of the memory cells in the Cairo
Expand All @@ -58,7 +81,7 @@ type MaybeRelocatable struct {
}

// Creates a new MaybeRelocatable with an Int inner value
func NewMaybeRelocatableInt(felt uint) *MaybeRelocatable {
func NewMaybeRelocatableInt(felt lambdaworks.Felt) *MaybeRelocatable {
return &MaybeRelocatable{inner: Int{felt}}
}

Expand All @@ -81,23 +104,73 @@ func (m *MaybeRelocatable) GetRelocatable() (Relocatable, bool) {

func (m *MaybeRelocatable) IsZero() bool {
felt, is_int := m.GetInt()
return is_int && felt.Felt == 0
return is_int && felt.Felt == lambdaworks.FeltFromUint64(0)
}

// Turns a MaybeRelocatable into a Felt252 value.
// If the inner value is an Int, it will extract the Felt252 value from it.
// If the inner value is a Relocatable, it will relocate it according to the relocation_table
// TODO: Return value should be of type (felt, error)
func (m *MaybeRelocatable) RelocateValue(relocationTable *[]uint) (uint, error) {
func (m *MaybeRelocatable) RelocateValue(relocationTable *[]uint) (lambdaworks.Felt, error) {
inner_int, ok := m.GetInt()
if ok {
return inner_int.Felt, nil
}

inner_relocatable, ok := m.GetRelocatable()
if ok {
return inner_relocatable.RelocateAddress(relocationTable), nil
return lambdaworks.FeltFromUint64(uint64(inner_relocatable.RelocateAddress(relocationTable))), nil
}

return 0, errors.New(fmt.Sprintf("Unexpected type %T", m.inner))
return lambdaworks.FeltFromUint64(0), errors.New(fmt.Sprintf("Unexpected type %T", m.inner))
}

func (m *MaybeRelocatable) IsEqual(m1 *MaybeRelocatable) bool {
a, a_type := m.GetInt()
b, b_type := m1.GetInt()
if a_type == b_type {
if a_type {
return a == b
} else {
a, _ := m.GetRelocatable()
b, _ := m1.GetRelocatable()
return a.IsEqual(&b)
}
} else {
return false
}
}

func (m MaybeRelocatable) AddMaybeRelocatable(other MaybeRelocatable) (MaybeRelocatable, error) {
// check if they are felt
m_int, m_is_int := m.GetInt()
other_int, other_is_int := other.GetInt()

if m_is_int && other_is_int {
result := NewMaybeRelocatableInt(m_int.Felt.Add(other_int.Felt))
return *result, nil
}

// check if one is relocatable and the other int
m_rel, is_rel_m := m.GetRelocatable()
other_rel, is_rel_other := other.GetRelocatable()

if is_rel_m && !is_rel_other {
other_felt, _ := other.GetInt()
felt, err := m_rel.AddFelt(other_felt)
if err != nil {
return MaybeRelocatable{}, nil
}
return *NewMaybeRelocatableRelocatable(felt), nil
pablodeymo marked this conversation as resolved.
Show resolved Hide resolved

} else if !is_rel_m && is_rel_other {

m_felt, _ := m.GetInt()
felt, err := other_rel.AddFelt(m_felt)
if err != nil {
return MaybeRelocatable{}, err
}
return *NewMaybeRelocatableRelocatable(felt), nil
pablodeymo marked this conversation as resolved.
Show resolved Hide resolved
} else {
return MaybeRelocatable{}, errors.New("RelocatableAdd")
}
}
9 changes: 9 additions & 0 deletions pkg/vm/memory/relocatable_err.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package memory

type SubReloctableError struct {
Msg string
}

func (e *SubReloctableError) Error() string {
return e.Msg
}
9 changes: 5 additions & 4 deletions pkg/vm/memory/relocatable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import (
"reflect"
"testing"

"github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
"github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
)

func TestMaybeRelocatableIsZeroInt(t *testing.T) {
zero := memory.NewMaybeRelocatableInt(0)
zero := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(0))
if !zero.IsZero() {
t.Errorf("MaybeRelocatable(0) should be zero")
}
not_zero := memory.NewMaybeRelocatableInt(1)
not_zero := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(1))
if not_zero.IsZero() {
t.Errorf("MaybeRelocatable(1) should not be zero")
}
Expand All @@ -31,7 +32,7 @@ func TestMaybeRelocatableIsZeroRelocatable(t *testing.T) {
}

func TestMaybeRelocatableAddFelt(t *testing.T) {
felt := memory.Int{Felt: 5}
felt := memory.Int{Felt: lambdaworks.FeltFromUint64(5)}
rel := memory.Relocatable{}
res, err := rel.AddFelt(felt)
if err != nil {
Expand All @@ -43,7 +44,7 @@ func TestMaybeRelocatableAddFelt(t *testing.T) {
}

func TestMaybeRelocatableAddMaybeRelocatableInt(t *testing.T) {
mr := memory.NewMaybeRelocatableInt(5)
mr := memory.NewMaybeRelocatableInt(lambdaworks.FeltFromUint64(5))
rel := memory.Relocatable{}
res, err := rel.AddMaybeRelocatable(*mr)
if err != nil {
Expand Down
8 changes: 5 additions & 3 deletions pkg/vm/memory/segments.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ type MemorySegmentManager struct {
Memory Memory
}

func NewMemorySegmentManager() *MemorySegmentManager {
func NewMemorySegmentManager() MemorySegmentManager {
memory := NewMemory()
return &MemorySegmentManager{make(map[uint]uint), *memory}
return MemorySegmentManager{make(map[uint]uint), *memory}
}

// Adds a memory segment and returns the first address of the new segment
Expand Down Expand Up @@ -71,7 +71,9 @@ func (s *MemorySegmentManager) RelocateMemory(relocationTable *[]uint) (map[uint
if err != nil {
return nil, err
}
relocatedMemory[relocatedAddr] = value
// Todo: fix this, should be a felt
val, _ := value.ToU64()
relocatedMemory[relocatedAddr] = uint(val)
fmoletta marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down
Loading
Loading