Skip to content

Commit

Permalink
feat(ssz): add support for transactions (lambdaclass#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaRedHand authored Sep 20, 2023
1 parent 16f7938 commit e4ef8c1
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 9 deletions.
23 changes: 16 additions & 7 deletions lib/ssz.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ defmodule Ssz do
def to_ssz(map, config \\ MainnetConfig)

def to_ssz(%name{} = map, config) do
map
|> encode()
|> to_ssz_rs(name, config)
to_ssz_typed(map, name, config)
end

def to_ssz([], config) do
Expand All @@ -20,9 +18,14 @@ defmodule Ssz do
end

def to_ssz([%name{} | _tail] = list, config) do
list
to_ssz_typed(list, name, config)
end

@spec to_ssz_typed(term, module, module) :: {:ok, binary} | {:error, String.t()}
def to_ssz_typed(term, schema, config \\ MainnetConfig) do
term
|> encode()
|> to_ssz_rs(name, config)
|> to_ssz_rs(schema, config)
end

@spec from_ssz(binary, module, module) :: {:ok, struct} | {:error, String.t()}
Expand Down Expand Up @@ -50,17 +53,23 @@ defmodule Ssz do

@spec hash_list_tree_root(list(struct), integer, module) ::
{:ok, SszTypes.root()} | {:error, String.t()}
def hash_list_tree_root(map, max_size, config \\ MainnetConfig)
def hash_list_tree_root(list, max_size, config \\ MainnetConfig)

def hash_list_tree_root([], max_size, config) do
# Type isn't used in this case
hash_tree_root_list_rs([], max_size, SszTypes.ForkData, config)
end

def hash_list_tree_root([%name{} | _tail] = list, max_size, config) do
hash_list_tree_root_typed(list, max_size, name, config)
end

@spec hash_list_tree_root_typed(list(struct), integer, module, module) ::
{:ok, binary} | {:error, String.t()}
def hash_list_tree_root_typed(list, max_size, schema, config \\ MainnetConfig) do
list
|> encode()
|> hash_tree_root_list_rs(max_size, name, config)
|> hash_tree_root_list_rs(max_size, schema, config)
end

##### Rust-side function stubs
Expand Down
File renamed without changes.
5 changes: 5 additions & 0 deletions lib/ssz_types/transaction.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule SszTypes.Transaction do
@moduledoc """
Alias for `SszTypes.transaction`. Is used when explicit typing is needed.
"""
end
2 changes: 1 addition & 1 deletion native/ssz_nif/src/elx_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type BLSPubkey<'a> = Bytes48<'a>;
type BLSSignature<'a> = Bytes96<'a>;
#[allow(dead_code)]
type ParticipationFlags = u8;
type Transaction<'a> = Binary<'a>; // max size: 1073741824
pub(crate) type Transaction<'a> = Binary<'a>; // max size: 1073741824
type ExecutionAddress<'a> = Bytes20<'a>;
type WithdrawalIndex = u64;

Expand Down
3 changes: 2 additions & 1 deletion native/ssz_nif/src/ssz_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ type BLSPubkey = Bytes48;
type BLSSignature = Bytes96;
#[allow(dead_code)]
type ParticipationFlags = u8;
type Transaction = VariableList<u8, /* `MAX_BYTES_PER_TRANSACTION` */ typenum::U1073741824>;
pub(crate) type Transaction =
VariableList<u8, /* `MAX_BYTES_PER_TRANSACTION` */ typenum::U1073741824>;
type ExecutionAddress = Bytes20;
type WithdrawalIndex = u64;

Expand Down
1 change: 1 addition & 0 deletions native/ssz_nif/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ macro_rules! schema_match {
SignedAggregateAndProof<C>,
BeaconBlocksByRangeRequest,
BeaconBlocksByRangeResponse<C>,
Transaction,
}
)
};
Expand Down
25 changes: 25 additions & 0 deletions test/unit/ssz_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,29 @@ defmodule SSZTests do
assert {:ok, ^deserialized} = Ssz.list_from_ssz(serialized, SszTypes.VoluntaryExit)
assert {:ok, _hash} = Ssz.hash_list_tree_root(deserialized, 4)
end

test "serialize and hash list of transactions" do
# These would be bytes
t1 = "asfasfas"
t2 = "18418280192"
t3 = "zd9g8as0f70a0sf"

deserialized = [t1, t2, t3]

initial_offset = length(deserialized) * 4

serialized =
Enum.join([
<<initial_offset::32-little>>,
<<initial_offset + byte_size(t1)::32-little>>,
<<initial_offset + byte_size(t1) + byte_size(t2)::32-little>>,
Enum.join(deserialized)
])

assert {:ok, ^serialized} = Ssz.to_ssz_typed(deserialized, SszTypes.Transaction)
assert {:ok, ^deserialized} = Ssz.list_from_ssz(serialized, SszTypes.Transaction)

assert {:ok, _hash} =
Ssz.hash_list_tree_root_typed(deserialized, 1_048_576, SszTypes.Transaction)
end
end

0 comments on commit e4ef8c1

Please sign in to comment.