-
Notifications
You must be signed in to change notification settings - Fork 9
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
Add Template: Native Simulator Debug #14
Conversation
2cdcb71
to
15645dc
Compare
Personally, I think the change here is far too intrusive here:
This is all I have for now, tho I do want to take another look again when the above issues are resolved. |
There are actually 3 different names used, so as to refer to the same thing:
Please make sure to use the same word to refer to the same thing, across all parts of code changes. |
One additional point: I wasn't sure if there is the need for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed the documentation is removed, care to explain why?
@@ -0,0 +1,7 @@ | |||
# {{project-name}} | |||
|
|||
TODO: Write this readme |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please state it clearly that this template is used to provide native simulator for a particular contract, and is not designed to be used on its own.
Right now this README resembles the README for a typical contract too much.
native-simulator/cargo-generate.toml
Outdated
|
||
[placeholders] | ||
contract_name = { prompt = "contract name", type = "string" } | ||
contract_crate_name = { prompt = "contract crate name", type = "string" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 things:
- Right now the contracts generated will use the same value as
contract_name
andcontract_crate_name
, so there is no point in requesting 2 values here. - The current convention, is to provide values as makefile arguments, such as
make CONTRACT=iamacontract
. I'm not saying we cannot use prompts, but if you do need prompts over makefile arguments here, please spend the time to elaborate the reason.
stack-reorder-contract/src/main.rs
Outdated
@@ -12,15 +12,15 @@ ckb_std::entry!(program_entry); | |||
default_alloc!(); | |||
|
|||
pub fn program_entry() -> i8 { | |||
let mut x: u64; | |||
let mut _x: u64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you share the reason leading to those changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some cases, there will be a warning here.
https://github.com/cryptape/ckb-script-templates/actions/runs/10552002309/job/29230208410#step:11:474
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend diving more into those cases. What really happened there? Why the assembly line is not processed at all?
Even for some reasons, we cannot work around the problems, to me it's better to explicitly add statements like #[allow(unused_variables)]
and #[allow(unused_assignments)]
. To me it might not be a good thing to access a variable with _
prefix.
workspace/Cargo.toml
Outdated
|
||
# TODO: Will be deleted after release | ||
[replace] | ||
"ckb-std:0.15.3" = { git = "https://github.com/nervosnetwork/ckb-std.git", branch = "master" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please lock specific version via rev
, right now this is far too vague.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally, this code shouldn't be here. However, since the modified ckb-std hasn't been released yet, I've used replace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do understand the rationale behind those lines(waiting on a new version of ckb-std), but I believe they are separate issues: if you want to propose such a change in the PR here, make sure it is added properly using rev, otherwise you should leave it out.
@@ -0,0 +1,75 @@ | |||
#!/usr/bin/env bash | |||
# | |||
# Add code for native debugging to existing onchain-script |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't see why a full script is required here. To me we should aim to make the whole process as simple as a single cargo generate
, it would be helpful if you can share the reason why you need a script here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- A native simulator project must correspond to a specific contract. Therefore, users should be guided to select an existing contract, which will also help standardize the naming of native simulator projects.
- After the project is generated, some modifications need to be made to the contract for it to work. For example, the target contract should have
features: simulator
added, along with some changes inmain.rs
related to the simulator.
Regarding point 1, generating both a contract and a cdylib
in the same project can lead to some unavoidable warnings and increase code complexity.
As for point 2, while developers can handle the necessary code modifications themselves, I believe it would be more convenient to include them automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's dissect the included script bit by bit as of this commit version:
- Line 6 - line 49 are just trying to select the contract to generate simulator code. For a standalone script, it might be helpful but here we are integrating the workflow in the makefile. Note that a makefile actually executes the script, not an individual user. This way, I don't see the reason providing those flexibilities. The makefile shall already know the exact contract name to generate simulator for.
- Line 54 actually does the bulk of the work but this is a single invocation of
cargo generate
, we can simply include it in the workspace-level makefile - Line 55 could really have the potential of becoming a mysterious act that confuses a lot of people. And what it really does to me, is just to tweak the behavior slightly, in the presense of
simulator
feature. We can just modify existing contract templates with a newlib.rs
file, to me it won't cause problem either way(the newly added code is all under asimulator
feature). - Line 57 - 61 confuses me: why does
native-simulators
directory needs its own makefile? Why not change the workspace level makefile? See Compile native crates inmake build
as well #16 for an example for customizing crates in certain folders - Line 64 - 69, IMO, can also be incorporated in current contract templates. They won't affect the compilation process when native simulator is missing
- Line 71 - 75 are also lines that can be included in current templates. They are just feature depended configs.
I don't see any part in this script, that has to do with cdylib
.
One more thought: I really recommend that we shall rename the feature here to native-simulator
. The single word simulator
is far too vague to me. But changing it here alone won't help(actually to me it does more harm if we name the feature native-simulator
here but simulator
in ckb-std), if we want to make the change, we should only make the change when we can change the same feature name in ckb-std.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I generate a native-simulator
directory in the workspace? There will be Cargo.toml and Makefile in it, so that I don't need to deal with this part every time I create a new native-simulator project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there really the need to have separate Cargo.toml
and Makefile
in the root folder of native-simulator
directory? What problem do they solve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use Cargo.toml
file at the root of workspace folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this is really my biggest concern here: we already have Cargo.toml
and Makefile
at the root of the workspace folder, why bother adding a new set of those 2 files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it appropriate to put this kind of project specifically used for debugging in the project root directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are Rust crates, I don't see why now(unless of course, some feature conflict will require you to use a different Rust-cargo-workspace-level Cargo.toml, that will be a different story). For example, the Cargo.toml
at workspace root directory contains a tests
crate for writing tests, I see no difference between tests
crate and simulator crates.
So my suggestion here is: if we can use a single Cargo.toml
file, we should definitely stick to one, but if there is other requirements(I suspect there is a feature conflict: contracts have to be built without simulator feature, while simulator crates require simulator feature), a proper way can be:
- We add a new
native-simulator-workspace
template, containingCargo.toml
andMakefile
for simulators. - When generating a new simulator, first test if
native-simulator
directory exists, if not, usenative-simulator-workspace
template to populate this directory first - Generate the simulator crate for the contract specified in
native-simulator
directory then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will modify it.
This document will be moved to the ckb-standalone-debugger after revisions. I believe users who need to debug will naturally use ckb-debugger, so it makes sense to place the documentation here. |
It is fine if the majority of the documentation shall be put in |
Ok, I'll add it later |
workspace/Cargo.toml
Outdated
@@ -12,3 +12,12 @@ members = [ | |||
overflow-checks = true | |||
strip = true | |||
codegen-units = 1 | |||
|
|||
[profile.ckb-debug] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this profile do and where is it used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using ckb-debugger to debug, a contract with a symbol file is required, so this profile is added.
I'll add a comment later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If symbols are the only blocker, we can ask a bigger question: is it true that the workspace level cargo file strips all symbols by default? What if we change the above strip
from true to false, then in makefile, use a separate step to strip the binary, so actually here we are providing both types of binary? To me that's a better solution than adding a new profile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is better, but developers need to install llvm additionally. (llvm-objcopy)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly I'm fine with requiring LLVM to be present all the time.
workspace/Makefile
Outdated
@@ -48,6 +48,20 @@ build: | |||
$(MAKE) -e -C contracts/$(CONTRACT) build; \ | |||
fi | |||
|
|||
build-simulator: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not build the simulators when executing make build
? Why use a separate command?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that most of the time, developers don’t need native-simulator
, so I divide it into two commands here.
Or for convenience, add a dependency build
to build-simulator
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would personally stick to a single make build
command, it avoids potential build inconsistencies(what if someone types make test
but do not type make build-simulator
). If you don't need native-simulator
, don't generate the crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When there is no build-simulator
, the contract will be executed. And tests need to add the features: simulator
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are talking about different points. Assuming there is make build
and make build-simulator
, what if someone executes one but not the other? Are all intermediate files compiled from the same source code? What if there are the differences?
To me having a single make build
is much better when it takes care of everything, ther e is less confusion.
In addition, when one opts to generate the simulator code for one contract, he / she should already know they will pay the extra cost, including compilation time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After build-simulator
is merged with build
, native-simulator files will be generated in build/release. Is this okay?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a problem with it but I do want to ask why this is the case? The files in build/release
are manually copied over, what's the problem against tweaking this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this way, ckb-testtool can automatically load these libs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must say I don't really understand the reasons here. Seems like just work, not real blockers.
workspace/Makefile
Outdated
--destination native-simulators \ | ||
-d contract_name=$(CRATE) \ | ||
-d contract_crate_name=`echo "$(CRATE)" | tr '-' '_'`; \ | ||
mv native-simulators/$(CRATE)-sim/src/contract-lib.rs contracts/$(CRATE)/src/lib.rs; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This simply shifts the complexity discussed here from a script, to make command. It does not truly simply the workflow, please fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If create a native-simulator, we will have to modify the corresponding contract. Or should these modifications be added directly to the contract
template, or instructions be provided so that developers can modify them themselves?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the content of the changes, I would favor directly adding those changes to current templates(notice there are quite a few templates other than contract
), if you want, you can write some instructions in the README part on how to migrate existing contracts over with simulator support.
workspace/tests/Cargo.toml
Outdated
@@ -3,6 +3,10 @@ name = "tests" | |||
version = "0.1.0" | |||
edition = "2021" | |||
|
|||
[features] | |||
# default = [ "simulator" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this line for?
cb1b983
to
138548f
Compare
workspace/Makefile
Outdated
cargo generate $(TEMPLATE_TYPE) $(TEMPLATE_REPO) native-simulator \ | ||
-n $(CRATE)-sim \ | ||
--destination native-simulators \ | ||
-d contract_name=$(CRATE) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is a comment unresolved that got lost in history. Personally, I don't see the need to add prompts here. Cargo generate does provide enough filters in templates:
- https://cargo-generate.github.io/cargo-generate/templates/index.html#additional-liquid-filters
- https://shopify.github.io/liquid/filters/remove/
I believe we can derive the values of contract_name
and contract_crate_name
from the builtin placeholders project-name
and crate_name
workspace/Makefile
Outdated
fi | ||
fi; \ | ||
for sim in $(wildcard native-simulators/*); do \ | ||
cd $$sim && cargo build && cd ../..; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please respect
MODE_ARGS
andCARGO_ARGS
here - Does
cargo build -p
work? If so, we can remove thecd
part
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Maybe it's worthwhile to test against
CONTRACT
variable, if it is set, we should build only the simulator for this specific contract.
native-simulator/Cargo.toml
Outdated
@@ -5,7 +5,7 @@ edition = "2021" | |||
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |||
[dependencies] | |||
{{contract_name}} = { path = "../../contracts/{{contract_name}}", features = ["native-simulator"] } | |||
{{project-name | remove: "-sim"}} = { path = "../../contracts/{{project-name | remove: "-sim"}}", features = ["native-simulator"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry just want to be picky one more more item(and I believe we should be good here), right now, this solution requires that -sim
cannot be used as project name, for example, I cannot name my contract as my-simple-project
, since remove filter will remove all occurrences of -sim
.
I suggest we apply this pattern, what we can do here is:
project-name | append: "@@SIMULATOR_PLACEHOLDER@@" | remove "-sim@@SIMULATOR_PLACEHOLDER@@"
This can ensure that only the last -sim
part is removed, no occurrences of -sim
in the middle of the name will be affected.
* build-simulator dependencies build * clean can clear *-dbg
* Contracts support native-simulator by default. * native-simulator project no longer requires scripts to add code to contracts. * simulator renamed to native-simulator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one minor issue, rest is good to me
native-simulator/src/lib.rs
Outdated
@@ -0,0 +1 @@ | |||
ckb_std::entry_simulator!({{project-name | remove: "-sim" | replace: "-", "_"}}::program_entry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the same technique above to append a placeholder first, then remove -sim
together with the placeholder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I neglected it, I will change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
2 more points here:
- There seems to be a CI error on aarch64 system, might want to fix the relavant code in
ckb-std
first - For now, cargo file is modified to use a patched
ckb-std
version. Considering the fact that upgrading dependencies can be a reluctant task, one idea might be to release a newckb-std
version first, then update the code to use a properckb-std
version. However that will depend on release schedule ofckb-std
itself, I don't have strong opinions either way, and will just leave it to you.
I'm dealing with this problem on ckb-std. |
ea81591
to
fa78d67
Compare
contract/Makefile
Outdated
@@ -6,7 +6,7 @@ TOP := $(cur_dir) | |||
# RUSTFLAGS that are likely to be tweaked by developers. For example, | |||
# while we enable debug logs by default here, some might want to strip them | |||
# for minimal code size / consumed cycles. | |||
CUSTOM_RUSTFLAGS := --cfg debug_assertions | |||
CUSTOM_RUSTFLAGS := -C debug_assertions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are those changes still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will be an error here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They should have made the changes here
Using the ckb-debugger for contract development can be quite cumbersome. Therefore, we offer an alternative debugging method:
Compile the contract into a native platform dynamic library and use the ckb-testtool to run this dynamic library similarly to a contract. This allows developers to debug the contract directly using their existing IDE.
Creation
When creating a contract, a native dynamic library named
<contract_name>-dbg
will be created in the contract directory. If you do not want to create this project, use the parameterALSO_ADD_DEBUGGER=false
.Usage
Run
make build-simulator
to complete the compilation. Once compiled, during debugging, open thetests
directory in the project and enable thefeatures: simulator
. This will automatically load and execute the native simulator.