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

[testsvc] Wrong SCORE Class in the Context callstack #2

Closed
ICONationDevTeam opened this issue May 23, 2021 · 3 comments
Closed

[testsvc] Wrong SCORE Class in the Context callstack #2

ICONationDevTeam opened this issue May 23, 2021 · 3 comments

Comments

@ICONationDevTeam
Copy link
Contributor

ICONationDevTeam commented May 23, 2021

I believe there's a bug about in the SCORE callstack in the Context class of testsvc.

TLDR ; abstract classes mess up with the Context callstack, the caller is set to the abstract class instead of the implementation class.

Here's a test code I'm using :

// Accounts
Account owner = sm.createAccount();
Account alice = sm.createAccount();

// Deploy a IRC2 token implemented in the class `UnderlyingToken`
Score coin = sm.deploy(owner, UnderlyingToken.class, "UnderlyingToken", "UC", 18);
// Deploy another contract (not really matters what it does) that we'll call "pool"
Score pool = sm.deploy(owner, Pool.class, coin.getAddress());

// Mint 10 tokens to Alice, and transfer them to the pool
BigInteger amount = BigInteger.TEN;
coin.invoke(owner, "mintTo", alice.getAddress(), amount);
coin.invoke(alice, "transfer", pool.getAddress(), amount, "transfer".getBytes()); // <--- Bug!

When executing the following code, I got this error :

Stack trace:

java.lang.AssertionError: com.iconloop.score.token.irc2.IRC2Basic not found
	at com.iconloop.testsvc.Score.call(Score.java:81)
	at com.iconloop.testsvc.Score.invoke(Score.java:62)
	at xxx.pool.test.test(DepositTest.java:53)
        [...]

The bug actually occurs when the IRC2Basic instance redirects the execution to the tokenFallback method to the pool from its transfer method.

https://i.imgur.com/E5bpI05.png

When digging into the call method of the Context class of the testsvc package, we can see that the caller variable returned by the stackWalker is com.iconloop.score.token.irc2.IRC2Basic instead of the UnderlyingToken class I deployed.

https://i.imgur.com/wZvIH7M.png

It makes sense because the caller is indeed IRC2Basic and not UnderlyingToken.

However, as IRC2Basic is an abstract class and not a SCORE implementation, the ServiceManager.call fails because it can't retrieve the SCORE from the IRC2Basic class:

https://i.imgur.com/W7xU4mV.png

Alternatively, if I copy the IRC2Basic implementation to my UnderlyingToken class directly (thus not relying on abstract IRC2Basic class at all), the test passes; beucase the caller is effectively "UnderlyingToken" and not IRC2Basic.

https://i.imgur.com/tPUXOnZ.png

The code fails because testsvc should detect the parent class that implements the SCORE logic instead of using the inherited abstract class.

@sink772
Copy link
Member

sink772 commented May 24, 2021

Yes, I could reproduce the issue with the sample-crowdsale project.
I am looking into it and it will be resolved soon.
Thanks for your report.

@ICONationDevTeam
Copy link
Contributor Author

ICONationDevTeam commented May 24, 2021

Another related issue I'd like to report that is related to the classScoreMap :

If the same SCORE is deployed twice, the getScoreFromClass method will always return the second SCORE, as the first SCORE is overriden by the second SCORE registered in the classScoreMap.

Consequently, if I deploy two IRC2 contracts, Context.getAddress() in the first IRC2 will return the second IRC2 address instead.

@sink772
Copy link
Member

sink772 commented May 25, 2021

testsvc module is just an emulation layer and intended to be used only for unit testing, i.e. testing individual methods. If you want to test more complex integrate or functional testing, you need to use another way. testinteg module is for that purpose.

I'm not sure what you're trying to do, but deploying two same IRC2 contracts is complex enough and beyond the testsvc functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants