Skip to content

Commit 1f43ce3

Browse files
author
dtfiedler
committed
Merge remote-tracking branch 'upstream/edge'
2 parents eddd22e + 596b697 commit 1f43ce3

21 files changed

Lines changed: 1162 additions & 461 deletions

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ WAMR_DIR = _build/wamr
88

99
GENESIS_WASM_BRANCH = tillathehun0/cu-experimental
1010
GENESIS_WASM_REPO = https://github.com/permaweb/ao.git
11-
GENESIS_WASM_SERVER_DIR = _build/genesis-wasm-server
11+
GENESIS_WASM_SERVER_DIR = _build/genesis_wasm/genesis-wasm-server
1212

1313
ifdef HB_DEBUG
1414
WAMR_FLAGS = -DWAMR_ENABLE_LOG=1 -DWAMR_BUILD_DUMP_CALL_STACK=1 -DCMAKE_BUILD_TYPE=Debug
@@ -98,7 +98,7 @@ setup-genesis-wasm: $(GENESIS_WASM_SERVER_DIR)
9898
echo "Error: Node.js is not installed. Please install Node.js before continuing."; \
9999
echo "For Ubuntu/Debian, you can install it with:"; \
100100
echo " curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && \\"; \
101-
echo " apt-get install -y nodejs && \\"; \
101+
echo " apt-get install -y nodejs=22.16.0-1nodesource1 --allow-downgrades && \\"; \
102102
echo " node -v && npm -v"; \
103103
exit 1; \
104104
fi

rebar.config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
{erl_opts, [{d, 'ENABLE_GENESIS_WASM', true}]},
2525
{pre_hooks, [
2626
{compile, "make -C \"${REBAR_ROOT_DIR}\" setup-genesis-wasm"}
27+
]},
28+
{relx, [
29+
{overlay, [
30+
{copy, "_build/genesis_wasm/genesis-wasm-server", "genesis-wasm-server"}
31+
]}
2732
]}
2833
]},
2934
{rocksdb, [

src/ar_bundles.erl

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ encode_tags([]) ->
379379
encode_tags(Tags) ->
380380
EncodedBlocks = lists:flatmap(
381381
fun({Name, Value}) ->
382-
Res = [encode_avro_string(Name), encode_avro_string(Value)],
382+
Res = [encode_avro_name(Name), encode_avro_value(Value)],
383383
case lists:member(error, Res) of
384384
true ->
385385
throw({cannot_encode_empty_string, Name, Value});
@@ -394,14 +394,22 @@ encode_tags(Tags) ->
394394
<<ZigZagCount/binary, (list_to_binary(EncodedBlocks))/binary, 0>>.
395395

396396
%% @doc Encode a string for Avro using ZigZag and VInt encoding.
397-
encode_avro_string(<<>>) ->
398-
% Zero length strings are treated as a special case, due to the Avro encoder.
397+
encode_avro_name(<<>>) ->
398+
% Zero length names are treated as a special case, due to the Avro encoder.
399399
<< 0 >>;
400-
encode_avro_string(String) ->
401-
StringBytes = unicode:characters_to_binary(String, utf8),
400+
encode_avro_name(String) ->
401+
StringBytes = utf8_encoded(String),
402402
Length = byte_size(StringBytes),
403403
<<(encode_zigzag(Length))/binary, StringBytes/binary>>.
404404

405+
encode_avro_value(<<>>) ->
406+
% Zero length values are treated as a special case, due to the Avro encoder.
407+
<< 0 >>;
408+
encode_avro_value(Value) when is_binary(Value) ->
409+
% Tag values can be raw binaries
410+
Length = byte_size(Value),
411+
<<(encode_zigzag(Length))/binary, Value/binary>>.
412+
405413
%% @doc Encode an integer using ZigZag encoding.
406414
encode_zigzag(Int) when Int >= 0 ->
407415
encode_vint(Int bsl 1);
@@ -635,9 +643,45 @@ ar_bundles_test_() ->
635643
{timeout, 30, fun test_basic_member_id/0},
636644
{timeout, 30, fun test_deep_member/0},
637645
{timeout, 30, fun test_extremely_large_bundle/0},
638-
{timeout, 30, fun test_serialize_deserialize_deep_signed_bundle/0}
646+
{timeout, 30, fun test_serialize_deserialize_deep_signed_bundle/0},
647+
{timeout, 30, fun test_encode_tags/0}
639648
].
640649

650+
test_encode_tags() ->
651+
BinValue = <<1, 2, 3, 255, 254>>,
652+
TestCases = [
653+
{simple_string_tags, [{<<"tag1">>, <<"value1">>}]},
654+
{binary_value_tag, [{<<"binary-tag">>, BinValue}]},
655+
{mixed_tags,
656+
[
657+
{<<"string-tag">>, <<"string-value">>},
658+
{<<"binary-tag">>, BinValue}
659+
]
660+
},
661+
{empty_value_tag, [{<<"empty-value-tag">>, <<>>}]},
662+
{unicode_tag, [{<<"unicode-tag">>, <<"你好世界">>}]}
663+
],
664+
lists:foreach(
665+
fun({Label, InputTags}) ->
666+
Encoded = encode_tags(InputTags),
667+
Wrapped =
668+
<<
669+
(length(InputTags)):64/little,
670+
(byte_size(Encoded)):64/little,
671+
Encoded/binary
672+
>>,
673+
{DecodedTags, <<>>} = decode_tags(Wrapped),
674+
?assertEqual(InputTags, DecodedTags, Label)
675+
end,
676+
TestCases
677+
),
678+
% Test case: Empty tags list
679+
EmptyTags = [],
680+
EncodedEmpty = encode_tags(EmptyTags),
681+
?assertEqual(<<>>, EncodedEmpty),
682+
WrappedEmpty = <<0:64/little, 0:64/little>>,
683+
{[], <<>>} = decode_tags(WrappedEmpty).
684+
641685
run_test() ->
642686
test_with_zero_length_tag().
643687

@@ -648,12 +692,9 @@ test_no_tags() ->
648692
Anchor = crypto:strong_rand_bytes(32),
649693
DataItem = new_item(Target, Anchor, [], <<"data">>),
650694
SignedDataItem = sign_item(DataItem, {Priv, Pub}),
651-
652695
?assertEqual(true, verify_item(SignedDataItem)),
653696
assert_data_item(KeyType, Owner, Target, Anchor, [], <<"data">>, SignedDataItem),
654-
655697
SignedDataItem2 = deserialize(serialize(SignedDataItem)),
656-
657698
?assertEqual(SignedDataItem, SignedDataItem2),
658699
?assertEqual(true, verify_item(SignedDataItem2)),
659700
assert_data_item(KeyType, Owner, Target, Anchor, [], <<"data">>, SignedDataItem2).
@@ -666,12 +707,9 @@ test_with_tags() ->
666707
Tags = [{<<"tag1">>, <<"value1">>}, {<<"tag2">>, <<"value2">>}],
667708
DataItem = new_item(Target, Anchor, Tags, <<"taggeddata">>),
668709
SignedDataItem = sign_item(DataItem, {Priv, Pub}),
669-
670710
?assertEqual(true, verify_item(SignedDataItem)),
671711
assert_data_item(KeyType, Owner, Target, Anchor, Tags, <<"taggeddata">>, SignedDataItem),
672-
673712
SignedDataItem2 = deserialize(serialize(SignedDataItem)),
674-
675713
?assertEqual(SignedDataItem, SignedDataItem2),
676714
?assertEqual(true, verify_item(SignedDataItem2)),
677715
assert_data_item(KeyType, Owner, Target, Anchor, Tags, <<"taggeddata">>, SignedDataItem2).

src/dev_genesis_wasm.erl

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ compute(Msg, Msg2, Opts) ->
5959
ensure_started(Opts) ->
6060
% Check if the `genesis-wasm@1.0' device is already running. The presence
6161
% of the registered name implies its availability.
62+
{ok, Cwd} = file:get_cwd(),
63+
?event({ensure_started, cwd, Cwd}),
64+
% Determine path based on whether we're in a release or development
65+
GenesisWasmServerDir = filename:join([Cwd, "genesis-wasm-server"]),
66+
?event({ensure_started, genesis_wasm_server_dir, GenesisWasmServerDir}),
6267
?event({ensure_started, genesis_wasm, self()}),
6368
IsRunning = is_genesis_wasm_server_running(Opts),
6469
IsCompiled = hb_features:genesis_wasm(),
@@ -77,22 +82,22 @@ ensure_started(Opts) ->
7782
NodeURL =
7883
"http://localhost:" ++
7984
integer_to_list(hb_opts:get(port, no_port, Opts)),
80-
DBDir =
81-
filename:absname(
82-
hb_util:list(
83-
hb_opts:get(
84-
genesis_wasm_db_dir,
85-
"cache-mainnet/genesis-wasm",
86-
Opts
87-
)
85+
RelativeDBDir =
86+
hb_util:list(
87+
hb_opts:get(
88+
genesis_wasm_db_dir,
89+
"cache-mainnet/genesis-wasm",
90+
Opts
8891
)
8992
),
93+
DBDir =
94+
filename:absname(RelativeDBDir),
9095
CheckpointDir =
9196
filename:absname(
9297
hb_util:list(
9398
hb_opts:get(
9499
genesis_wasm_checkpoints_dir,
95-
"cache-mainnet/genesis-wasm/checkpoints",
100+
RelativeDBDir ++ "/checkpoints",
96101
Opts
97102
)
98103
)
@@ -103,16 +108,16 @@ ensure_started(Opts) ->
103108
Port =
104109
open_port(
105110
{spawn_executable,
106-
"/opt/_build/genesis-wasm-server/launch-monitored.sh"
111+
filename:join([GenesisWasmServerDir, "launch-monitored.sh"])
107112
},
108113
[
109114
binary, use_stdio, stderr_to_stdout,
110115
{args, [
111116
"npm",
112117
"--prefix",
113-
"/opt/_build/genesis-wasm-server",
118+
GenesisWasmServerDir,
114119
"run",
115-
"dev"
120+
"start"
116121
]},
117122
{env,
118123
[
@@ -128,7 +133,7 @@ ensure_started(Opts) ->
128133
)
129134
},
130135
{"DB_URL", DatabaseUrl},
131-
{"NODE_CONFIG_ENV", "development"},
136+
{"NODE_CONFIG_ENV", "production"},
132137
{"DEFAULT_LOG_LEVEL",
133138
hb_util:list(
134139
hb_opts:get(

src/dev_green_zone.erl

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -388,17 +388,14 @@ finalize_become(KeyResp, NodeLocation, NodeID, GreenZoneAES, Opts) ->
388388
priv_wallet => GreenZoneWallet
389389
}
390390
},
391+
NewOpts = Opts#{
392+
identities => UpdatedIdentities
393+
},
391394
ok =
392395
hb_http_server:set_opts(
393-
Opts#{
394-
identities => UpdatedIdentities
395-
}
396+
NewOpts
396397
),
397-
% Print the updated wallet address
398-
Wallet = hb_opts:get(priv_wallet, undefined, Opts),
399-
?event(green_zone,
400-
{become, wallet, hb_util:human_id(ar_wallet:to_address(Wallet))}
401-
),
398+
try_mount_encrypted_volume(GreenZoneWallet, NewOpts),
402399
?event(green_zone, {become, update_wallet, complete}),
403400
{ok, #{
404401
<<"body">> => #{
@@ -487,8 +484,6 @@ join_peer(PeerLocation, PeerID, _M1, _M2, InitOpts) ->
487484
priv_green_zone_aes => AESKey
488485
},
489486
hb_http_server:set_opts(NewOpts),
490-
?event(successfully_joined_greenzone),
491-
try_mount_encrypted_volume(AESKey, NewOpts),
492487
{ok, #{
493488
<<"body">> =>
494489
<<"Node joined green zone successfully.">>,
@@ -614,13 +609,20 @@ validate_peer_opts(Req, Opts) ->
614609
RequiredConfig =
615610
hb_ao:normalize_keys(
616611
hb_opts:get(green_zone_required_opts, #{}, Opts)),
617-
?event(green_zone, {validate_peer_opts, required_config, RequiredConfig}),
612+
ConvertedRequiredConfig =
613+
hb_message:uncommitted(
614+
hb_cache:ensure_all_loaded(
615+
hb_message:commit(RequiredConfig, Opts),
616+
Opts
617+
)
618+
),
619+
?event(green_zone, {validate_peer_opts, required_config, ConvertedRequiredConfig}),
618620
PeerOpts =
619621
hb_ao:normalize_keys(
620622
hb_ao:get(<<"node-message">>, Req, undefined, Opts)),
621623
% Validate each item in node_history has required options
622624
Result = try
623-
case hb_opts:ensure_node_history(PeerOpts, RequiredConfig) of
625+
case hb_opts:ensure_node_history(PeerOpts, ConvertedRequiredConfig) of
624626
{ok, _} ->
625627
?event(green_zone, {validate_peer_opts, history_items_check, valid}),
626628
true;
@@ -730,23 +732,23 @@ decrypt_zone_key(EncZoneKey, Opts) ->
730732
%% The encryption key used for the volume is the same AES key used for green zone
731733
%% communication, ensuring that only nodes in the green zone can access the data.
732734
%%
733-
%% @param AESKey The AES key obtained from joining the green zone.
735+
%% @param Key The password for the encrypted volume.
734736
%% @param Opts A map of configuration options.
735737
%% @returns ok (implicit) in all cases, with detailed event logs of the results.
736-
try_mount_encrypted_volume(AESKey, Opts) ->
737-
?event(green_zone, {try_mount_encrypted_volume, start}),
738+
try_mount_encrypted_volume(Key, Opts) ->
739+
?event(debug_volume, {try_mount_encrypted_volume, start}),
738740
% Set up options for volume mounting with default paths
739741
VolumeOpts = Opts#{
740-
priv_volume_key => AESKey,
742+
priv_volume_key => Key,
741743
volume_skip_decryption => <<"true">>
742744
},
743745
% Call the dev_volume:mount function to handle the complete process
744746
case dev_volume:mount(undefined, undefined, VolumeOpts) of
745747
{ok, Result} ->
746-
?event(green_zone, {volume_mount, success, Result}),
748+
?event(debug_volume, {volume_mount, success, Result}),
747749
ok;
748750
{error, Error} ->
749-
?event(green_zone, {volume_mount, error, Error}),
751+
?event(debug_volume, {volume_mount, error, Error}),
750752
ok % Still return ok as this is an optional operation
751753
end.
752754

@@ -780,4 +782,4 @@ rsa_wallet_integration_test() ->
780782
% Verify roundtrip
781783
?assertEqual(PlainText, Decrypted),
782784
% Verify wallet structure
783-
?assertEqual(KeyType, {rsa, 65537}).
785+
?assertEqual(KeyType, {rsa, 65537}).

src/dev_lua_test_ledgers.erl

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,46 @@ subledger_registration_test_disabled() ->
591591
% Alice can send tokens to Bob on SubLedger2.
592592
verify_net(RootLedger, [SubLedger1, SubLedger2], Opts).
593593

594+
single_subledger_to_subledger_test_() -> {timeout, 30, fun single_subledger_to_subledger/0}.
595+
single_subledger_to_subledger() ->
596+
Opts = test_opts(),
597+
Alice = ar_wallet:new(),
598+
Bob = ar_wallet:new(),
599+
RootLedger =
600+
ledger(
601+
<<"scripts/hyper-token.lua">>,
602+
#{ <<"balance">> => #{ Alice => 100 } },
603+
Opts
604+
),
605+
SubLedger1 = subledger(RootLedger, Opts),
606+
SL1ID = hb_message:id(SubLedger1, signed, Opts),
607+
?event(debug, {sl1ID, SL1ID}),
608+
SubLedger2 = subledger(RootLedger, Opts),
609+
SL2ID = hb_message:id(SubLedger2, signed, Opts),
610+
?event(debug, {sl2ID, SL2ID}),
611+
Names = #{
612+
Alice => alice,
613+
Bob => bob,
614+
RootLedger => root,
615+
SubLedger1 => subledger1,
616+
SubLedger2 => subledger2
617+
},
618+
?event(debug, {root_ledger, RootLedger}),
619+
?event(debug, {sl1, SubLedger1}),
620+
?event(debug, {sl2, SubLedger2}),
621+
?assertEqual(100, balance(RootLedger, Alice, Opts)),
622+
% 2. Alice sends 90 tokens to herself on SubLedger1.
623+
?event(debug, {transfer_1}),
624+
transfer(RootLedger, Alice, Alice, 90, SubLedger1, Opts),
625+
?assertEqual(10, balance(RootLedger, Alice, Opts)),
626+
?assertEqual(90, balance(SubLedger1, Alice, Opts)),
627+
?event(debug, {transfer_2}),
628+
PushRes = transfer(SubLedger1, Alice, Alice, 80, SubLedger2, Opts),
629+
?event(debug, {push_res, PushRes}),
630+
?event(debug, {map, map([RootLedger, SubLedger1, SubLedger2], Opts)}),
631+
?assertEqual(80, balance(SubLedger2, Alice, Opts)),
632+
?assertEqual(10, balance(SubLedger1, Alice, Opts)).
633+
594634
%% @doc Verify that registered sub-ledgers are able to send tokens to each other
595635
%% without the need for messages on the root ledger.
596636
subledger_to_subledger_test_() -> {timeout, 30, fun subledger_to_subledger/0}.
@@ -615,12 +655,11 @@ subledger_to_subledger() ->
615655
},
616656
% 1. Alice has tokens on the root ledger.
617657
?assertEqual(100, balance(RootLedger, Alice, Opts)),
618-
% 2. Alice registers with SubLedger1.
619-
register(SubLedger1, SubLedger2, Opts),
620-
% 3. Alice sends 90 tokens to herself on SubLedger1.
658+
% 2. Alice sends 90 tokens to herself on SubLedger1.
621659
transfer(RootLedger, Alice, Alice, 90, SubLedger1, Opts),
622-
% 4. Alice sends 10 tokens to Bob on SubLedger2.
660+
% 3. Alice sends 10 tokens to Bob on SubLedger2.
623661
transfer(SubLedger1, Alice, Bob, 10, SubLedger2, Opts),
662+
?event(debug, {map, map([RootLedger, SubLedger1, SubLedger2], Names, Opts)}),
624663
?assertEqual(10, balance(RootLedger, Alice, Opts)),
625664
?assertEqual(80, balance(SubLedger1, Alice, Opts)),
626665
?assertEqual(10, balance(SubLedger2, Bob, Opts)),

src/dev_p4.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ response(State, RawResponse, NodeMsg) ->
238238
end,
239239
<<"request">> => Request
240240
},
241-
hb_opts:get(priv_wallet, no_viable_wallet, NodeMsg)
241+
NodeMsg
242242
),
243243
?event(payment,
244244
{post_charge,

0 commit comments

Comments
 (0)