Skip to content

Add get_entrypoint_name function in core + bump to ligo 1.6.0 #11

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ligo_compiler?=docker run --rm -v "$$PWD":"$$PWD" -w "$$PWD" ligolang/ligo:1.0.0
ligo_compiler?=docker run --rm -v "$$PWD":"$$PWD" -w "$$PWD" ligolang/ligo:1.6.0

PROTOCOL_OPT?=

Expand All @@ -9,7 +9,7 @@ help:

.PHONY: test

test: test_ligo_utils test_ligo_math test_ligo_float test_ligo_trigo_float test_ligo_trigo_rational test_ligo_trigo_rational
test: test_ligo_utils test_ligo_utils_getentrypointname test_ligo_math test_ligo_float test_ligo_trigo_float test_ligo_trigo_rational test_ligo_trigo_rational

test_ligo_trigo_rational: rational/test/test_trigo_rational.mligo
@echo "Running integration tests (trigo rational)"
Expand All @@ -31,6 +31,11 @@ test_ligo_utils: core/test/test_utils.mligo
@echo "Running integration tests (is_implicit, bytes_to_nat)"
@$(ligo_compiler) run test $^ $(PROTOCOL_OPT)

test_ligo_utils_getentrypointname: core/test/test_utils_getentrypointname.mligo
@echo "Running integration tests (get_entrypoint_name)"
@$(ligo_compiler) run test $^ $(PROTOCOL_OPT)


test_ligo_math: core/test/test_math.mligo
@echo "Running integration tests (Math)"
@$(ligo_compiler) run test $^ $(PROTOCOL_OPT)
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# math-lib-cameligo

This repository contains a math library for [LIGO](https://ligolang.org/). It is
provided in two flavors (`Float` & `Rational`), and the project is structured as
follows
provided in two flavors (`Float` & `Rational`), and the project is structured as
follows

1. [core](./core/README.md): This contains basic math functions
like `isqrt`, `power`, `factorial`, `min`, `max`, `log_10`.
like `isqrt`, `power`, `factorial`, `min`, `max`, `log_10`. It also provides some
useful hack functions like `get_entrypoint_name`, `is_implicit` ("tz1.." ? "KT1..").
2. [float](./float/README.md): This provides floating point arithmetic
for LIGO (which is not supported natively by Michelson). It also provides some
useful trigonometric functions.
3. [rational](./rational/README.md): This provides rational arithmetic
for LIGO (which is not supported natively by Michelson). It also provides some
useful trigonometric functions.
useful trigonometric functions.
30 changes: 15 additions & 15 deletions core/test/test_math.mligo
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#import "../math.mligo" "Math"
let test =
let _test_isqrt =
let () = assert (Math.isqrt (4n) = 2n) in
let () = assert (Math.isqrt (8n) = 2n) in
let () = assert (Math.isqrt (9n) = 3n) in
let () = assert (Math.isqrt (15n) = 3n) in
let () = assert (Math.isqrt (16n) = 4n) in
let () = assert (Math.isqrt (17n) = 4n) in
Test.log ("Test 'isqrt' finished") in
let () = Assert.assert (Math.isqrt (4n) = 2n) in
let () = Assert.assert (Math.isqrt (8n) = 2n) in
let () = Assert.assert (Math.isqrt (9n) = 3n) in
let () = Assert.assert (Math.isqrt (15n) = 3n) in
let () = Assert.assert (Math.isqrt (16n) = 4n) in
let () = Assert.assert (Math.isqrt (17n) = 4n) in
Test.Next.IO.log ("Test 'isqrt' finished") in
let _test_factorial =
let () = assert (Math.factorial (0n) = 1n) in
let () = assert (Math.factorial (1n) = 1n) in
let () = assert (Math.factorial (2n) = 2n) in
let () = assert (Math.factorial (3n) = 6n) in
let () = assert (Math.factorial (4n) = 24n) in
let () = assert (Math.factorial (5n) = 120n) in
let () = assert (Math.factorial (6n) = 720n) in
Test.log ("Test 'factorial' finished") in
let () = Assert.assert (Math.factorial (0n) = 1n) in
let () = Assert.assert (Math.factorial (1n) = 1n) in
let () = Assert.assert (Math.factorial (2n) = 2n) in
let () = Assert.assert (Math.factorial (3n) = 6n) in
let () = Assert.assert (Math.factorial (4n) = 24n) in
let () = Assert.assert (Math.factorial (5n) = 120n) in
let () = Assert.assert (Math.factorial (6n) = 720n) in
Test.Next.IO.log ("Test 'factorial' finished") in
()
36 changes: 18 additions & 18 deletions core/test/test_utils.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ let test =
//0x050a00000016 00 00430d6ec166d9c623104776aaad3bb50615c6791f
// let is_implicit(elt: address) : bool =
// let pack_elt : bytes = Bytes.pack elt in
// let () = Test.log((elt, pack_elt)) in
// let () = Test.Next.IO.log((elt, pack_elt)) in
// let size : nat = Bytes.length pack_elt in
// let is_imp : bytes = Bytes.sub 6n 1n pack_elt in
// let addr_bin : bytes = Bytes.sub 7n (abs(size - 7n)) pack_elt in
// let value : nat = Utils.Bytes.bytes_to_nat(addr_bin) in
// let () = Test.log(value) in
// let () = Test.Next.IO.log(value) in
// ( is_imp = 0x00 )
// in
// TEST
Expand Down Expand Up @@ -68,7 +68,7 @@ let test =
let run_test (elt : (address * bool)) : unit =
let calculated : bool = f (elt.0) in
let expected : bool = elt.1 in
assert (calculated = expected) in
Assert.assert (calculated = expected) in
List.iter run_test all_tests in
// for KT1... is_implicit() should answer false

Expand All @@ -80,7 +80,7 @@ let test =
// Run tests

let () = run_tests all_tests Utils.Address.is_implicit in
Test.log ("Test finished") in
Test.Next.IO.log ("Test finished") in
let _test_bytes_is_adddress =
(* chest key/payload and time matches -> OK *)

Expand All @@ -91,53 +91,53 @@ let test =
let () =
match value with
None -> failwith ("a boolean true was expected")
| Some b -> assert (b = true) in
| Some b -> Assert.assert (b = true) in
let payload : bytes =
0x050a0000001601f4186c23ee65145a1038193686882c29a1f2009e00 in
let value : bool option =
Utils.Bytes.Packed.is_internal_address_implicit (payload) in
let () =
match value with
None -> failwith ("a boolean false was expected")
| Some b -> assert (b = false) in
| Some b -> Assert.assert (b = false) in
let payload : bytes =
0x07020000001601f4186c23ee65145a1038193686882c29a1f2009e00 in
let value : bool option =
Utils.Bytes.Packed.is_internal_address_implicit (payload) in
let () =
match value with
None -> assert (true)
None -> Assert.assert (true)
| Some _ -> failwith ("a None was expected") in
Test.log ("Test finished") in
Test.Next.IO.log ("Test finished") in
let _test_convert_bytes_to_nat =
(* chest key/payload and time matches -> OK *)

let payload : bytes = 0x00 in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 0n) in
let () = Assert.assert (value = 0n) in
let payload : bytes = 0x0a in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 10n) in
let () = Assert.assert (value = 10n) in
let payload : bytes = 0x0A in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 10n) in
let () = Assert.assert (value = 10n) in
let payload : bytes = 0x2c in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 44n) in
let () = Assert.assert (value = 44n) in
let payload : bytes = 0x2C in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 44n) in
let () = Assert.assert (value = 44n) in
let payload : bytes = 0xFF in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 255n) in
let () = Assert.assert (value = 255n) in
let payload : bytes = 0x1234 in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 4660n) in
let () = Assert.assert (value = 4660n) in
let payload : bytes = 0x001234 in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 4660n) in
let () = Assert.assert (value = 4660n) in
let payload : bytes = 0x123400 in
let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in
let () = assert (value = 4660n * 256n) in
Test.log ("Test 'rational' finished") in
let () = Assert.assert (value = 4660n * 256n) in
Test.Next.IO.log ("Test 'rational' finished") in
()
38 changes: 38 additions & 0 deletions core/test/test_utils_getentrypointname.mligo
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#import "../utils.mligo" "Utils"

module Counter = struct
type storage = int

type ret = operation list * storage

[@entry]
let increment (delta : int) (store : storage) : ret = [], store + delta

[@entry]
let decrement (delta : int) (store : storage) : ret = [], store - delta

[@entry]
let reset (() : unit) (_ : storage) : ret = [], 0
end


let test =
let _test_get_entrypoint_name =
// let user = Test.nth_bootstrap_account 1 in
let orig = Test.Next.Originate.contract (contract_of Counter) 42 0tez in
let contract = Test.Next.Typed_address.to_contract orig.taddr in
let contract_address : address = Tezos.address contract in

let verify_entrypoint_name (type a) (name: string) (ep: a contract option) : unit =
match ep with
| None -> failwith "[Test get_entrypoint_name] Unknown entrypoint"
| Some ep -> Assert.assert (Utils.Entrypoint.get_entrypoint_name(ep) = name)
in
let ep_inc = (Tezos.get_entrypoint_opt "%increment" contract_address : int contract option) in
let ep_dec = (Tezos.get_entrypoint_opt "%decrement" contract_address : int contract option) in
let ep_res = (Tezos.get_entrypoint_opt "%reset" contract_address : unit contract option) in
let () = verify_entrypoint_name "%increment" ep_inc in
let () = verify_entrypoint_name "%decrement" ep_dec in
let () = verify_entrypoint_name "%reset" ep_res in
Test.Next.IO.log ("Test 'get_entrypoint_name' finished") in
()
35 changes: 33 additions & 2 deletions core/utils.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,43 @@ module Address = struct
//let size : nat = Bytes.length pack_elt in
//let addr_bin : bytes = Bytes.sub 7n (abs(size - 7n)) pack_elt in
//let value : nat = bytes_to_nat(addr_bin) in
//let () = Test.log(value) in
//let () = Test.Next.IO.log(value) in

(is_imp = 0x00)

end

module Entrypoint = struct
(** Retrieves the entrypoint name from a given entrypoint ('a contract). The returned entrypoint name is prefixed with "%" *)
let get_entrypoint_name (type a) (ep : a contract) : string =
let pad4 (seq: bytes) : bytes =
let rec padding (bts: bytes) (current_size: nat) (expected_size: nat) : bytes =
if current_size = expected_size then
bts
else
padding (Bytes.concat 0x00 bts) (current_size + 1n) expected_size
in
let current_size = Bytes.length seq in
let () = Assert.Error.assert(current_size <= 4n) "[@ligo/math-lib/core/utils] Error in Entrypoint.get_entrypoint_name (name too long)" in
padding seq current_size 4n
in
let pack_ep : bytes = Bytes.pack ep in
let size = Bytes.length pack_ep in
let () = Assert.Error.assert(size > 28n) "[@ligo/math-lib/core/utils] Error in Entrypoint.get_entrypoint_name (bytes representation too short)" in
let nb_to_read = abs(size - 28n) in
let name_bytes : bytes = Bytes.sub 28n nb_to_read pack_ep in
let nb_to_read_bytes = bytes nb_to_read in
let nb_to_read_4bytes = pad4 nb_to_read_bytes in
// Add prefix for string
let full_name_bytes = Bytes.concat 0x0501 (Bytes.concat nb_to_read_4bytes name_bytes) in
let name : string = match Bytes.unpack full_name_bytes with
| None -> failwith "[@ligo/math-lib/core/utils] Error in Entrypoint.get_entrypoint_name"
| Some n -> n
in
String.concat "%" name

end

module Bytes = struct
module Packed = struct
let is_internal_address (pack_elt : bytes) : bool =
Expand Down Expand Up @@ -59,7 +90,7 @@ module Bytes = struct
[@private]
let byte_to_nat (hexa : bytes) : nat =
let _check_size : unit =
assert_with_error (Bytes.length hexa = 1n) "Can only convert 1 byte" in
Assert.Error.assert (Bytes.length hexa = 1n) "Can only convert 1 byte" in
if hexa = 0x00
then 0n
else
Expand Down
26 changes: 13 additions & 13 deletions float/test/test_float.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,47 @@ let test =
let _test_scientific =
let a : Float.t = Float.inverse (Float.new 6 0) in
let value_resolved : int = Float.resolve a 3n in
let () = assert (value_resolved = 166) in
let () = Assert.assert (value_resolved = 166) in
let a : Float.t = Float.inverse (Float.new (6) 0) in
let a : Float.t = Float.mul (Float.new (-1) 0) a in
let value_resolved : int = Float.resolve a 3n in
let () = assert (value_resolved = -166) in
let () = Assert.assert (value_resolved = -166) in
let a : Float.t = Float.inverse (Float.new 3 0) in
let b : Float.t = Float.inverse (Float.new 2 0) in
let value : Float.t = Float.add a b in
//let () = assert(value = { p=5; q=6 }) in
//let () = Assert.assert(value = { p=5; q=6 }) in

let value_resolved : int = Float.resolve value 3n in
let () = assert (value_resolved = 833) in
let () = Assert.assert (value_resolved = 833) in
let a : Float.t = Float.inverse (Float.new 3 0) in
let b : Float.t = Float.inverse (Float.new 2 0) in
let value : Float.t = Float.sub a b in
//let () = assert(value = { p=-1; q=6 }) in
//let () = Assert.assert(value = { p=-1; q=6 }) in

let value_resolved : int = Float.resolve value 3n in
let () = assert (value_resolved = -166) in
let () = Assert.assert (value_resolved = -166) in
let a : Float.t = Float.inverse (Float.new 3 0) in
let b : Float.t = Float.inverse (Float.new 2 0) in
let value : Float.t = Float.mul a b in
//let () = assert(value = { p=1; q=6 }) in
//let () = Assert.assert(value = { p=1; q=6 }) in

let value_resolved : int = Float.resolve value 3n in
let () = assert (value_resolved = 166) in
let () = Assert.assert (value_resolved = 166) in
let a : Float.t = Float.inverse (Float.new 3 0) in
let b : Float.t = Float.inverse (Float.new 2 0) in
let value : Float.t = Float.div a b in
//let () = assert(value = { p=2; q=3 }) in
//let () = Assert.assert(value = { p=2; q=3 }) in

let value_resolved : int = Float.resolve value 3n in
let () = assert (value_resolved = 666) in
let () = Assert.assert (value_resolved = 666) in
// 1/2 % 1/3

let a : Float.t = Float.inverse (Float.new 2 0) in
let b : Float.t = Float.inverse (Float.new 3 0) in
let value : Float.t = Float.modulo a b in
//let () = assert(value = { p=2; q=3 }) in
//let () = Assert.assert(value = { p=2; q=3 }) in

let value_resolved : int = Float.resolve value 3n in
let () = assert (value_resolved = 166) in
Test.log ("Test finished") in
let () = Assert.assert (value_resolved = 166) in
Test.Next.IO.log ("Test finished") in
()
Loading