Skip to content

Add elixir bindings#535

Merged
jtraglia merged 24 commits intoethereum:mainfrom
BlazeWasHere:main
Mar 10, 2025
Merged

Add elixir bindings#535
jtraglia merged 24 commits intoethereum:mainfrom
BlazeWasHere:main

Conversation

@BlazeWasHere
Copy link
Contributor

@BlazeWasHere BlazeWasHere commented Feb 14, 2025

Adds elixir bindings through an Erlang NIF
Was using the python bindings as a reference FFI implementation, not sure if i am missing some things

also not sure if this even cross compiles (i hope :cc_precompiler works)

@jtraglia
Copy link
Member

Hey @BlazeWasHere, this is cool! I would be happy to include this when it's ready. Out of curiosity, what will use these bindings? And another TODO item would be to add CI tests, see: https://github.com/ethereum/c-kzg-4844/tree/main/.github/workflows

@BlazeWasHere
Copy link
Contributor Author

@jtraglia no worries, one main user would be elixir_ethers via ExWeb3/elixir_ethers#178. also saw that lambdaclass used c-kzg-4844 in their elixir consensus client but used bindings from c -> rust -> elixir in kzg_nif (im assuming because there were no elixir bindings at the time)

@jtraglia
Copy link
Member

Okay nice. So this does have real value. Feel free to ping me if you have any questions.

@BlazeWasHere
Copy link
Contributor Author

ok im struggling to find the reason for the segfault in compute_blob_kzg_proof (TLDR: only segfaults for valid blobs and on -O2 flag)
putting my debug process and brain dump here

DEBUG=1 iex -S mix test test/ckzg_test.exs:84 -b --trace
# run in shell
> System.pid

# another shell
lldb attach-pid <pid>

# run tests
c

then if you step till segfault

(lldb) c
Process 95133 resuming
Process 95133 stopped
* thread #28, name = 'erts_dcpus_12', stop reason = signal SIGSEGV: invalid permissions for mapped object (fault address: 0x747326f93000)
    frame #0: 0x0000747326b9fb12 ckzg_nif.so`sub_mod_256 + 82
ckzg_nif.so`sub_mod_256:
->  0x747326b9fb12 <+82>: movq   %r9, 0x8(%rdi)
    0x747326b9fb16 <+86>: adcq   %rbp, %r11
    0x747326b9fb19 <+89>: movq   %r10, 0x10(%rdi)
    0x747326b9fb1d <+93>: movq   %r11, 0x18(%rdi)
(lldb) bt
* thread #28, name = 'erts_dcpus_12', stop reason = signal SIGSEGV: invalid permissions for mapped object (fault address: 0x747326f93000)
  * frame #0: 0x0000747326b9fb12 ckzg_nif.so`sub_mod_256 + 82
    frame #1: 0x0000747326b76b1f ckzg_nif.so`compute_kzg_proof_impl(proof_out=0x000074731d800790, y_out=0x0000747326fa4b70, polynomial=<unavailable>, z=0x0000747326fa4a80, s=0x000063cdde676c28) at eip4844.c:458:9
    frame #2: 0x0000747326b76fa0 ckzg_nif.so`compute_blob_kzg_proof(out=0x000074731d800790, blob=0x000074732666a370, commitment_bytes=<unavailable>, s=0x000063cdde676c28) at eip4844.c:535:11
    frame #3: 0x0000747326b74037 ckzg_nif.so`compute_blob_kzg_proof_nif(env=0x0000747326fe4ca0, argc=<unavailable>, argv=0x0000747333f70580) at ckzg_wrap.c:271:21
    frame #4: 0x000063cdaaa7cbe6 beam.smp`erts_call_dirty_nif(esdp=0x00007473316f5c80, c_p=0x000063cdde892988, I=0x000063cdde5e09f0, reg=0x0000747333f70580) at erl_nif.c:469:19
    frame #5: 0x000063cdaa8e6ee6 beam.smp`erts_dirty_process_main(esdp=0x00007473316f5c80) at beam_common.c:283:23
    frame #6: 0x000063cdaa80652b beam.smp`sched_dirty_cpu_thread_func(vesdp=0x00007473316f5c80) at erl_process.c:8743:5
    frame #7: 0x000063cdaab58f82 beam.smp`thr_wrapper(vtwd=0x000063cdaa806410) at ethread.c:116:26
    frame #8: 0x0000747374894ac3 libc.so.6`start_thread(arg=<unavailable>) at pthread_create.c:442:8
    frame #9: 0x0000747374926850 libc.so.6`__clone3 at clone3.S:81

and if you check where the location is (in eip4844.c)

(lldb) n
Process 95133 stopped
* thread #28, name = 'erts_dcpus_12', stop reason = step over
    frame #0: 0x0000747326b76b45 ckzg_nif.so`compute_kzg_proof_impl(proof_out=0x000074731d800790, y_out=0x0000747326fa4b70, polynomial=0x0000747326fc4bc8, z=0x0000747326fa4a80, s=0x000063cdde676c28) at eip4844.c:451:26
   448 	    if (ret != C_KZG_OK) goto out;
   449 	
   450 	    for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
-> 451 	        if (fr_equal(z, &brp_roots_of_unity[i])) {
   452 	            /* We are asked to compute a KZG proof inside the domain */
   453 	            m = i + 1;
   454 	            inverses_in[i] = FR_ONE;
(lldb)  
Process 95133 stopped
* thread #28, name = 'erts_dcpus_12', stop reason = step over
    frame #0: 0x0000747326b76b00 ckzg_nif.so`compute_kzg_proof_impl(proof_out=0x000074731d800790, y_out=0x0000747326fa4b70, polynomial=0x0000747326fc4bc8, z=0x0000747326fa4a80, s=0x000063cdde676c28) at eip4844.c:458:22
   455 	            continue;
   456 	        }
   457 	        // (p_i - y) / (ω_i - z)
-> 458 	        blst_fr_sub(&q.evals[i], &polynomial->evals[i], y_out);
   459 	        blst_fr_sub(&inverses_in[i], &brp_roots_of_unity[i], z);
   460 	    }
   461 	

and the variables passed to compute_kzg_proof_impl(out, &y, &polynomial, &evaluation_challenge_fr, s). note that it is compiled with -O2 -g because it only reproduces with -O2 flag.

Details
* thread #28, name = 'erts_dcpus_12', stop reason = breakpoint 4.1
    frame #0: 0x0000747326b76f92 ckzg_nif.so`compute_blob_kzg_proof(out=0x000074731d800790, blob=0x000074732666a370, commitment_bytes=<unavailable>, s=0x000063cdde676c28) at eip4844.c:535:11
   532 	    compute_challenge(&evaluation_challenge_fr, blob, &commitment_g1);
   533 	
   534 	    /* Call helper function to compute proof and y */
-> 535 	    ret = compute_kzg_proof_impl(out, &y, &polynomial, &evaluation_challenge_fr, s);
   536 	    if (ret != C_KZG_OK) goto out;
   537 	
   538 	out:
(lldb) fr variable 
(KZGProof *) out = 0x000074731d800790
(const Blob *) blob = 0x000074732666a370
(const Bytes48 *) commitment_bytes = <could not evaluate DW_OP_entry_value: no matching call site param found>

(const KZGSettings *) s = 0x000063cdde676c28
(Polynomial) polynomial = {
  evals = {
    [0] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [1] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [2] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [3] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [4] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [5] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [6] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [7] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [8] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [9] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [10] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [11] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [12] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [13] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [14] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [15] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [16] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [17] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [18] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [19] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [20] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [21] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [22] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [23] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [24] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [25] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [26] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [27] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [28] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [29] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [30] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [31] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [32] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [33] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [34] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [35] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [36] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [37] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [38] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [39] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [40] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [41] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [42] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [43] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [44] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [45] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [46] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [47] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [48] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [49] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [50] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [51] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [52] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [53] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [54] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [55] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [56] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [57] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [58] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [59] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [60] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [61] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [62] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [63] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [64] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [65] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [66] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [67] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [68] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [69] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [70] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [71] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [72] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [73] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [74] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [75] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [76] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [77] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [78] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [79] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [80] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [81] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [82] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [83] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [84] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [85] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [86] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [87] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [88] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [89] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [90] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [91] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [92] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [93] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [94] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [95] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [96] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [97] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [98] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [99] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [100] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [101] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [102] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [103] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [104] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [105] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [106] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [107] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [108] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [109] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [110] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [111] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [112] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [113] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [114] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [115] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [116] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [117] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [118] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [119] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [120] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [121] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [122] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [123] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [124] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [125] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [126] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [127] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [128] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [129] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [130] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [131] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [132] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [133] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [134] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [135] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [136] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [137] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [138] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [139] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [140] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [141] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [142] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [143] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [144] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [145] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [146] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [147] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [148] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [149] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [150] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [151] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [152] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [153] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [154] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [155] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [156] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [157] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [158] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [159] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [160] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [161] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [162] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [163] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [164] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [165] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [166] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [167] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [168] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [169] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [170] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [171] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [172] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [173] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [174] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [175] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [176] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [177] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [178] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [179] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [180] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [181] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [182] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [183] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [184] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [185] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [186] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [187] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [188] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [189] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [190] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [191] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [192] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [193] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [194] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [195] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [196] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [197] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [198] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [199] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [200] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [201] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [202] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [203] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [204] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [205] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [206] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [207] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [208] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [209] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [210] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [211] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [212] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [213] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [214] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [215] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [216] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [217] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [218] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [219] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [220] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [221] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [222] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [223] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [224] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [225] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [226] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [227] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [228] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [229] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [230] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [231] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [232] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [233] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [234] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [235] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [236] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [237] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [238] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [239] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [240] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [241] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [242] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [243] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [244] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [245] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [246] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [247] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [248] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [249] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [250] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [251] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [252] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [253] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [254] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    [255] = {
      l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
    }
    ...
  }
}
(g1_t) commitment_g1 = {
  x = {
    l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0)
  }
  y = {
    l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0)
  }
  z = {
    l = ([0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0)
  }
}
(fr_t) evaluation_challenge_fr = {
  l = ([0] = 2654319690706462847, [1] = 17543739849117376762, [2] = 16339604651344585569, [3] = 6982868803808586812)
}
(fr_t) y = {
  l = ([0] = 4996253744963408710, [1] = 6859358674981636434, [2] = 0, [3] = 4503599627370496)
}
(C_KZG_RET) ret = <variable not available>

*** Some of the displayed variables have more members than the debugger will show by default. To show all of them, you can either use the --show-all-children option to frame variable or raise the limit by changing the target.max-children-count setting.

ok so it seems like the method is writing to read only data (writing to const region). but by definition
permalink

C_KZG_RET compute_blob_kzg_proof(
    KZGProof *out, const Blob *blob, const Bytes48 *commitment_bytes, const KZGSettings *s
);

the only mutable data is out and the rest are const.

in ckzg_wrap.c
permalink

    C_KZG_RET ret = compute_blob_kzg_proof(
        (KZGProof *)proof, (Blob *)blob.data, (Bytes48 *)commitment.data, settings
    );

blob.data commitment.data and settings are all read only because of how enif_inspect_* works.
and proof is mutable because of the call made here
permalink

    ERL_NIF_TERM proof_term;
    unsigned char *proof = enif_make_new_binary(env, BYTES_PER_PROOF, &proof_term);
    if (proof == NULL) return make_error(env, ckzg_atoms.out_of_memory);

so im very confused on how the segfault is happening. maybe data misalignment? @jtraglia @alisinabh

@jtraglia
Copy link
Member

jtraglia commented Feb 25, 2025

Hey @BlazeWasHere, I did some debugging myself and it appears that the issue is related to allocating the very large polynomials on the stack. I suspect we're surpassing the stack limit. I do not know how to raise this in Elixir though. We ran into several stack size issues when developing the Rust bindings too.

I've pushed a commit which will dynamically allocate this. With this, it no longer crashes for me. If it's possible to fix this in these bindings somehow, that would be preferred. If not, we look into keeping this core implementation change.

Also, I'm working on macOS & when I ran the tests it wanted a .so file instead of .dylib. So I made this change to the Makefile. Feel free to revert this if that's incorrect.

But overall, this is looking really great. Thanks for all of your work!

@BlazeWasHere
Copy link
Contributor Author

@jtraglia thanks so much, i was going crazy thinking it was something on my end!
will try to see if i can increase stack limit for enif programs

Also, I'm working on macOS & when I ran the tests it wanted a .so file instead of .dylib. So I made this change to the Makefile. Feel free to revert this if that's incorrect.

will fix this soon, thanks for reporting

@BlazeWasHere
Copy link
Contributor Author

We ran into several stack size issues when developing the Rust bindings too.

@jtraglia how was this solved? i dont see a stack size increase request

@jtraglia
Copy link
Member

We ran into several stack size issues when developing the Rust bindings too.

@jtraglia how was this solved? i dont see a stack size increase request

Our solution there was to Box objects. So they were allocated on the heap instead of the stack. For example:

pub fn compute_cells(&self, blob: &Blob) -> Result<Box<[Cell; CELLS_PER_EXT_BLOB]>, Error> {
let mut cells = [Cell::default(); CELLS_PER_EXT_BLOB];
unsafe {
let res = compute_cells_and_kzg_proofs(cells.as_mut_ptr(), ptr::null_mut(), blob, self);
if let C_KZG_RET::C_KZG_OK = res {
Ok(Box::new(cells))
} else {
Err(Error::CError(res))
}
}
}

@BlazeWasHere BlazeWasHere marked this pull request as ready for review February 27, 2025 20:59
@BlazeWasHere
Copy link
Contributor Author

Will revert fea1ea3 pending merge of #539

Copy link
Member

@jtraglia jtraglia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seriously great work. I have provided some small comments, but I am happy with the current state of this. If you're willing to make some little changes, I'll wait to merge. Otherwise happy to merge whenever. I see no real problems.

@BlazeWasHere
Copy link
Contributor Author

Seriously great work. I have provided some small comments, but I am happy with the current state of this. If you're willing to make some little changes, I'll wait to merge. Otherwise happy to merge whenever. I see no real problems.

thanks for the review, will address changes in the coming days and will add some speedups and better VM interactions in another PR

@BlazeWasHere
Copy link
Contributor Author

@jtraglia should i add publishing via CI to hex.pm in this PR or another? i also do not mind being a maintainer of the elixir bindings

@jtraglia
Copy link
Member

jtraglia commented Mar 6, 2025

@jtraglia should i add publishing via CI to hex.pm in this PR or another? i also do not mind being a maintainer of the elixir bindings

Up to you. But I think a subsequent PR would be better. And thank you! That would help a lot.

@jtraglia jtraglia merged commit d800f8f into ethereum:main Mar 10, 2025
44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants