worksish
This commit is contained in:
parent
f71826357b
commit
ac19eff060
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,3 +18,4 @@ logs
|
|||||||
*.iml
|
*.iml
|
||||||
rebar3.crashdump
|
rebar3.crashdump
|
||||||
*~
|
*~
|
||||||
|
/gaj
|
||||||
|
|||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "lib/gajumaru"]
|
||||||
|
path = lib/gajumaru
|
||||||
|
url = https://git.qpq.swiss/QPQ-AG/gajumaru.git
|
||||||
42
Makefile
Normal file
42
Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
APP_NAME = gmplugin_hello
|
||||||
|
GAJUMARU_LIB = lib/gajumaru
|
||||||
|
BUILD_DIR = $(GAJUMARU_LIB)/_build/prod/rel/gajumaru
|
||||||
|
TARGET_NETWORK = localnet
|
||||||
|
|
||||||
|
# steps are
|
||||||
|
# 1. call rebar3 gm_plugin to build the plugin
|
||||||
|
# 2. build the node
|
||||||
|
# 3. start the node with a configuration where it knows it needs to load our plugin
|
||||||
|
# 4. run a shell in the node context
|
||||||
|
|
||||||
|
|
||||||
|
all: compile
|
||||||
|
|
||||||
|
init: submodules
|
||||||
|
|
||||||
|
submodules:
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
|
||||||
|
compile:
|
||||||
|
rebar3 compile
|
||||||
|
|
||||||
|
build-my-plugin: compile
|
||||||
|
rebar3 gm_plugin
|
||||||
|
|
||||||
|
# adapted from gmp_ix
|
||||||
|
build-gm-with-my-plugin: build-my-plugin
|
||||||
|
cp _build/default/$(APP_NAME).ez $(GAJUMARU_LIB)/plugins
|
||||||
|
cd $(GAJUMARU_LIB) && make prod-build
|
||||||
|
cp -rvf gmconfig/$(TARGET_NETWORK)/gajumaru/* $(BUILD_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
fresh-console: build-gm-with-my-plugin console
|
||||||
|
|
||||||
|
console:
|
||||||
|
$(BUILD_DIR)/bin/gajumaru console
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rebar3 clean
|
||||||
|
cd $(GAJUMARU_LIB) && make prod-clean
|
||||||
|
rm -f $(GAJUMARU_LIB)/plugins/$(APP_NAME).ez
|
||||||
67
README.md
67
README.md
@ -1,9 +1,64 @@
|
|||||||
gmplugin_hello
|
# `gmplugin_hello`
|
||||||
=====
|
|
||||||
|
|
||||||
An OTP application
|
This is a minimal Gajumaru plugin. This is meant to be a minimal working
|
||||||
|
template on which development can occur immediately.
|
||||||
|
|
||||||
Build
|
# Quickstart
|
||||||
-----
|
|
||||||
|
|
||||||
$ rebar3 compile
|
## System Prereqs
|
||||||
|
|
||||||
|
## After clone
|
||||||
|
|
||||||
|
```
|
||||||
|
make init
|
||||||
|
make build-gm-with-my-plugin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```
|
||||||
|
make fresh-console
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
(gajumaru@localhost)1> gmplugin_hello_app:hello().
|
||||||
|
"hello, world"
|
||||||
|
(gajumaru@localhost)2> gmplugin_hello_app:network_id().
|
||||||
|
<<"localnet">>
|
||||||
|
(gajumaru@localhost)3> gmplugin_hello_app:height().
|
||||||
|
{ok,1}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Questions
|
||||||
|
|
||||||
|
|
||||||
|
## What is a Gajumaru?
|
||||||
|
|
||||||
|
In the context of this document, "Gajumaru" with no qualification means the
|
||||||
|
Erlang software that runs a gajumaru node.
|
||||||
|
|
||||||
|
## What is a Gajumaru plugin?
|
||||||
|
|
||||||
|
A Gajumaru plugin is an Erlang application that runs in the same Erlang process
|
||||||
|
context as `gajumaru`, meaning it can natively call `aeu_db:whatever`.
|
||||||
|
|
||||||
|
## What is the point of a Gajumaru plugin?
|
||||||
|
|
||||||
|
Let's say you're developing a point-of-sale app for your daughter's lemonade
|
||||||
|
stand. Your application needs to interact with Gajumaru in some way. You're
|
||||||
|
going to have your LemonPay app talk to your own local gajumaru node that
|
||||||
|
you're running on your old laptop on `192.168.2.1`.
|
||||||
|
|
||||||
|
The idea here is that the portion of your LemonPay business logic that needs to
|
||||||
|
interact intimately with data on the chain should run in the relatively
|
||||||
|
frictionless Erlang-to-Erlang context of the gajumaru application. Then you
|
||||||
|
expose a service interface on port `9876` that is tailored specifically for
|
||||||
|
LemonPay. LemonPay talks to `192.168.2.1:9876`.
|
||||||
|
|
||||||
|
## How does anything do anything?
|
||||||
|
|
||||||
|
The important thing to understand is that **gajumaru starts your plugin**.
|
||||||
|
|
||||||
|
Therefore, when you're developing and iterating on your plugin, you need to
|
||||||
|
have a way to start gajumaru, start your plugin, mess around with it.
|
||||||
|
|||||||
1
gmconfig/localnet/gajumaru/data/gajumaru_defaults.json
Normal file
1
gmconfig/localnet/gajumaru/data/gajumaru_defaults.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
51
gmconfig/localnet/gajumaru/gajumaru.json
Normal file
51
gmconfig/localnet/gajumaru/gajumaru.json
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"logging": {
|
||||||
|
"levels": [
|
||||||
|
{
|
||||||
|
"target": "console",
|
||||||
|
"level": "debug"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"chain" : {
|
||||||
|
"db_backend" : "rocksdb",
|
||||||
|
"persist" : true
|
||||||
|
},
|
||||||
|
"governance" : {
|
||||||
|
"network_id" : "localnet"
|
||||||
|
},
|
||||||
|
"system" : {
|
||||||
|
"dev_mode" : true,
|
||||||
|
"plugins" : [
|
||||||
|
{
|
||||||
|
"name" : "gmplugin_hello"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hard_forks" : {
|
||||||
|
"versions" : {
|
||||||
|
"1" : {
|
||||||
|
"height" : 0,
|
||||||
|
"type" : {
|
||||||
|
"on_demand" : {
|
||||||
|
"mining" : {
|
||||||
|
"autostart" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data" : {
|
||||||
|
"data" : [
|
||||||
|
{ "accounts" : {
|
||||||
|
"ak_4JJZNZynTy7RhTQBn7k9q6ZRehwLFPB1ncSQcyenZ3j3zYn6c" : 1000000000000000000000,
|
||||||
|
"ak_2PPgx59oeXLKL87jNkxE5wFY5hC3vNS5kXWFQbCoy3znMcDHo" : 1000000000000000000000,
|
||||||
|
"ak_2nyQQiU38XGDYdfU4Z9RXmyY5YBcPxbpnGGvvBs8i6CCgiJjAM" : 1000000000000000000000,
|
||||||
|
"ak_3AVVjGNmSQCT6bzUWjhhZYd3yaFWztzyVANx4QD9sFBRxAsGM" : 1000000000000000000000,
|
||||||
|
"ak_2GZCX7k6AorKpF59XYQVmNehBXM4BD1XWaP9WjeHFgcCzeUvRM" : 1000000000000000000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
0
gmconfig/mainnet/gajumaru/.gitkeep
Normal file
0
gmconfig/mainnet/gajumaru/.gitkeep
Normal file
0
gmconfig/testnet/gajumaru/.gitkeep
Normal file
0
gmconfig/testnet/gajumaru/.gitkeep
Normal file
1
lib/gajumaru
Submodule
1
lib/gajumaru
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 752c8d0ae5546ce42e3ec1bd4326606459975e20
|
||||||
15
rebar.config
15
rebar.config
@ -1,5 +1,18 @@
|
|||||||
{erl_opts, [debug_info]}.
|
{erl_opts, [debug_info]}.
|
||||||
{deps, []}.
|
|
||||||
|
% there's some bug somewhere... this list must be nonempty for some reason
|
||||||
|
{deps, [
|
||||||
|
{gmserialization, {gm, gmserialization}}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{project_apps_dir, "lib/gajumaru/apps"}.
|
||||||
|
|
||||||
|
{plugins, [
|
||||||
|
{gmplugin_rebar3, {git, "https://git.qpq.swiss/QPQ-AG/gmplugin_rebar3.git", {branch,"master"}}}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{gajumaru_root, {git, "https://git.qpq.swiss/QPQ-AG/gajumaru", "master"}}.
|
||||||
|
|
||||||
|
|
||||||
{shell, [
|
{shell, [
|
||||||
%% {config, "config/sys.config"},
|
%% {config, "config/sys.config"},
|
||||||
|
|||||||
17
rebar.lock
Normal file
17
rebar.lock
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{"1.2.0",
|
||||||
|
[{<<"base58">>,
|
||||||
|
{git,"https://git.qpq.swiss/QPQ-AG/erl-base58.git",
|
||||||
|
{ref,"e6aa62eeae3d4388311401f06e4b939bf4e94b9c"}},
|
||||||
|
1},
|
||||||
|
{<<"eblake2">>,{pkg,<<"eblake2">>,<<"1.0.0">>},1},
|
||||||
|
{<<"enacl">>,
|
||||||
|
{git,"https://git.qpq.swiss/QPQ-AG/enacl.git",
|
||||||
|
{ref,"4eb7ec70084ba7c87b1af8797c4c4e90c84f95a2"}},
|
||||||
|
1},
|
||||||
|
{<<"gmserialization">>,{gm,gmserialization},0}]}.
|
||||||
|
[
|
||||||
|
{pkg_hash,[
|
||||||
|
{<<"eblake2">>, <<"EC8AD20E438AAB3F2E8D5D118C366A0754219195F8A0F536587440F8F9BCF2EF">>}]},
|
||||||
|
{pkg_hash_ext,[
|
||||||
|
{<<"eblake2">>, <<"3C4D300A91845B25D501929A26AC2E6F7157480846FAB2347A4C11AE52E08A99">>}]}
|
||||||
|
].
|
||||||
@ -7,8 +7,16 @@
|
|||||||
|
|
||||||
-behaviour(application).
|
-behaviour(application).
|
||||||
|
|
||||||
|
|
||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1]).
|
||||||
|
|
||||||
|
% tests
|
||||||
|
-export([
|
||||||
|
hello/0,
|
||||||
|
network_id/0,
|
||||||
|
height/0
|
||||||
|
]).
|
||||||
|
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
gmplugin_hello_sup:start_link().
|
gmplugin_hello_sup:start_link().
|
||||||
|
|
||||||
@ -16,3 +24,28 @@ stop(_State) ->
|
|||||||
ok.
|
ok.
|
||||||
|
|
||||||
%% internal functions
|
%% internal functions
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
-spec hello() -> string().
|
||||||
|
|
||||||
|
hello() ->
|
||||||
|
"hello, world".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-spec network_id() -> binary().
|
||||||
|
|
||||||
|
network_id() ->
|
||||||
|
aec_governance:get_network_id().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-spec height() -> {ok, Height :: pos_integer()}
|
||||||
|
| {error, no_top_block}.
|
||||||
|
|
||||||
|
height() ->
|
||||||
|
case aec_chain:top_height() of
|
||||||
|
undefined -> {error, no_top_block};
|
||||||
|
Height -> {ok, Height}
|
||||||
|
end.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user