Skip to content
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 Boolean.toByte operation #932

Open
wants to merge 9 commits into
base: v6.0.0
Choose a base branch
from

Conversation

ross-weir
Copy link
Contributor

@ross-weir ross-weir commented Nov 8, 2023

Let me know if anything more needs to be done (tests, etc)

closes #931

@ross-weir ross-weir changed the base branch from develop to v6.0.0 November 8, 2023 03:20
@@ -507,6 +507,10 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext =>
else
error(s"The type of $obj is expected to be Collection to select 'size' property", obj.sourceContext.toOption)

case Select(obj, SBoolean.ToByte, _) if obj.tpe.isBoolean =>
val bool = eval(obj.asBoolValue)
Copy link
Contributor Author

@ross-weir ross-weir Nov 8, 2023

Choose a reason for hiding this comment

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

Not sure if this can be done inline like this or maybe we need to add a class in transformers and a new (or existing?) OpCode for boolean.toByte

Copy link
Member

Choose a reason for hiding this comment

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

I guess opcode is not needed, from investigating MethodCallSerializer

Copy link
Member

Choose a reason for hiding this comment

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

yes, opcode is not necessary. Another question here is how to make sure VersionContext.current has correct version in place when this code is executed as part of the application/tooling compiling ErgoTree?

@@ -202,6 +203,21 @@ class TestingInterpreterSpecification extends CompilerTestingCommons
|}""".stripMargin)
}

property("Evaluate boolean casting ops") {
Copy link
Contributor Author

@ross-weir ross-weir Nov 23, 2023

Choose a reason for hiding this comment

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

This property runs the test block for each activated script version / ergotree version. Something is causing SigmaParser to execute a different code path between test cases, SBoolean.getMethods is only called at the start when version is v0 so it returns Seq() for methods, presumably even for v3 since getMethods isn't called when the version is set to v3 and the test fails with a "Missing method" error.

I'm not sure if this is intended and methods are cached somewhere or if there's a global var not getting reset between test cases, or something else. Need to debug deeper

Copy link
Member

Choose a reason for hiding this comment

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

There's caching indeed, in types.scala: 370

  lazy val methods: Seq[SMethod] = {

changing lazy val to def is fixing tests.

I think methods should be reworked in a way that for every version methods should be cached, and then def methods should return value from cache for VersionContext.current (or calculate value and cache it).

Copy link
Member

Choose a reason for hiding this comment

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

yes, the cache should be versioned, the suggested change sounds good.
Basically the cache needs to change from Seq[SMethod] to a function Version => Seq[SMethod], which can be implemented with the help of Map[Byte, Seq[SMethod]] under the hood.

core/shared/src/main/scala/sigma/VersionContext.scala Outdated Show resolved Hide resolved
core/shared/src/main/scala/sigma/VersionContext.scala Outdated Show resolved Hide resolved
core/shared/src/test/scala/sigma/VersionTesting.scala Outdated Show resolved Hide resolved
_currErgoTreeVersion.withValue(treeVersion)(block)
_currErgoTreeVersion.withValue(treeVersion) {
VersionContext.withVersions(activatedVersion, treeVersion)(block)
}
Copy link
Member

@aslesarenko aslesarenko Dec 2, 2023

Choose a reason for hiding this comment

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

What is the reason for this change?

@@ -507,6 +507,10 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext =>
else
error(s"The type of $obj is expected to be Collection to select 'size' property", obj.sourceContext.toOption)

case Select(obj, SBoolean.ToByte, _) if obj.tpe.isBoolean =>
val bool = eval(obj.asBoolValue)
Copy link
Member

Choose a reason for hiding this comment

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

yes, opcode is not necessary. Another question here is how to make sure VersionContext.current has correct version in place when this code is executed as part of the application/tooling compiling ErgoTree?

.withInfo(PropertyCall, "Convert true to 1 and false to 0")

protected override def getMethods(): Seq[SMethod] = {
if (VersionContext.current.isEvolutionActivated) {
Copy link
Member

Choose a reason for hiding this comment

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

This code influences the MethodCall deserialization as part of ErgoTree deserialization. And we need to make a decision here. If we just enable this based only on activatedVersion, then is will be available after the activation on mainnet for all ErgoTrees regardless of their version. Is this what we want?
Should ErgoTree v0 be allowed to have new methods?

Copy link
Member

Choose a reason for hiding this comment

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

It should not, but I do not see where tree-based version can be injected with the current design, in both serializers and here tree version is not available. So we need to discuss where to inject tree version.

Copy link
Member

@aslesarenko aslesarenko Dec 5, 2023

Choose a reason for hiding this comment

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

It is more or less clear how to make activatedVersion and ergoTreeVersion available in this code place when it is used in the interpreter, I can do this. Because the values are coming from the block being validated.
But this code is also used in compiler, and there we need to decide, how applications should respect those versions. I.e. if some dApp or tool uses the compiler, how the versions can be specified?

Copy link
Member

Choose a reason for hiding this comment

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

I think SigmaByteReader should include tree version. Interpreter is another issue.

 if some dApp or tool uses the compiler, how the versions can be specified

this question already exists in the wild, as compiler sets ErgoTree version.

@@ -202,6 +203,21 @@ class TestingInterpreterSpecification extends CompilerTestingCommons
|}""".stripMargin)
}

property("Evaluate boolean casting ops") {
Copy link
Member

Choose a reason for hiding this comment

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

yes, the cache should be versioned, the suggested change sounds good.
Basically the cache needs to change from Seq[SMethod] to a function Version => Seq[SMethod], which can be implemented with the help of Map[Byte, Seq[SMethod]] under the hood.

@kushti kushti added this to the v6.0 milestone Dec 22, 2023
@kushti kushti added the 6.0 label Dec 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement SBoolean.toByte
3 participants