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

Call _initialize() automatically #1572

Merged
merged 3 commits into from
Apr 18, 2020
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/neo/SmartContract/InteropService.Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ private static bool Contract_CallEx(ApplicationEngine engine)

private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHash, string method, Array args, CallFlags flags)
{
if (method.StartsWith('_')) return false;
erikzhang marked this conversation as resolved.
Show resolved Hide resolved

ContractState contract = engine.Snapshot.Contracts.TryGet(contractHash);
if (contract is null) return false;

Expand Down Expand Up @@ -174,6 +176,10 @@ private static bool Contract_CallEx(ApplicationEngine engine, UInt160 contractHa
context_new.EvaluationStack.Push(args[i]);
context_new.InstructionPointer = md.Offset;
}

md = contract.Manifest.Abi.GetMethod("_initialize");
if (md != null) engine.LoadClonedContext(md.Offset);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the eval stack of _initialize context be empty?

Copy link
Member Author

Choose a reason for hiding this comment

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

Why?

Copy link
Contributor

Choose a reason for hiding this comment

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

Both can influence each other, as we have already put the arguments on the eval stack.

Copy link
Contributor

Choose a reason for hiding this comment

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

If one contract A invokes another contract B many times, every time we'll load the _initialize of B, it's not very efficient.

How about creating a .sdata(static data) segment in NEF file, where to put the static variables, when we load a contract, we can just pass the data into static slot.

Copy link
Member Author

Choose a reason for hiding this comment

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

They are static variables, not constants.

Copy link
Contributor

Choose a reason for hiding this comment

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

They are static variables, not constants.

It doesn't matter, the static variables will not be persisted, which will not affect the next time to load.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering whether the contract on the chain is stateful or stateless. If it is stateless, then we can call _initialize every time. If it is stateful, _initialize should only be called once.

Copy link
Contributor

Choose a reason for hiding this comment

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

contract A{
  int a = 0;

  function inc(){
      return ++a
  }
}

If a contract is stateful, when call inc method, it'll increase the a.
If a contract is stateless, when call inc method, it'll only return 1 every time.

This will affect how the compiler treats the contract variables.


return true;
}

Expand Down