Why are _initializing and isTopLevelCall variables used in Initializable contract of Openzeppelin? - solidity

This is abstract contract in the context of Proxy pattern:
abstract contract Initializable {
bool private _initialized;
bool private _initializing;
modifier initializer() {
require(_initializing || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
}
contract UpgradebleTest1 is Initializable {
uint public x;
function initialize(uint _x) public initializer {
x = _x;
}
}
I don't understand the necessity of _initializing and isTopLevelCall. Is not enough doing control using only _initialized?
Thanks,

The _initializing and isTopLevelCall combination allow for chained calls with the initializer modifier:
contract UpgradebleTest1 is Initializable {
uint public x;
function initialize(uint _x) public initializer {
internalInit(_x);
}
function internalInit(uint _x) internal initializer {
x = _x;
}
}
Without the _initializing and isTopLevelCall check, the initializer modifier would pass on the first call (initialize()) but fail on the second call (internalInit()).
modifier initializer() {
require(!_initialized, "Initializable: contract is already initialized");
_initialized = true;
}

abstract contract Initializable {
bool private _initialized;
modifier initializer() {
require(!_initialized, "Initializable: co...");
_;
_initialized = true;
}
}
contract UpgradebleTestParent is Initializable {
uint public x;
function initialize(uint _x) internal initializer {
x = _x;
}
}
contract UpgradebleTestMain is UpgradebleTestParent {
function init(uint _x) public initializer {
initialize(_x);
}
}
If it is as above, it would execute same logic, but _initialized = true; would be executed twice unnecessarily, right? However, it seems like cheaper than the previous one which has a one more variable and related additional instructions? Isn't it?

Related

Exponential backoff in Kotlin with RxJava2

I am trying to do an exponential retry for a request, so that if the request fails (i.e. your internet is down) the app retries endlessly until it works (for the amount of time the app is in the foreground)
I tried with this solution
public class RetryWithDelay implements Function<Observable<? extends Throwable>, Observable<?>> {
private final int maxRetries;
private final int retryDelayMillis;
private int retryCount;
public RetryWithDelay(final int maxRetries, final int retryDelayMillis) {
this.maxRetries = maxRetries;
this.retryDelayMillis = retryDelayMillis;
this.retryCount = 0;
}
#Override
public Observable<?> apply(final Observable<? extends Throwable> attempts) {
return attempts
.flatMap(new Function<Throwable, Observable<?>>() {
#Override
public Observable<?> apply(final Throwable throwable) {
if (++retryCount < maxRetries) {
// When this Observable calls onNext, the original
// Observable will be retried (i.e. re-subscribed).
return Observable.timer(retryDelayMillis,
TimeUnit.MILLISECONDS);
}
// Max retries hit. Just pass the error along.
return Observable.error(throwable);
}
});
}
}
But when I try to convert this to kotlin it says Function only takes one generic parameter.
I copy-pasted the Java code into IntelliJ and it did half the work for me:
import java.util.concurrent.TimeUnit
import io.reactivex.functions.Function
import io.reactivex.*
class RetryWithDelay(private val maxRetries: Int, private val retryDelayMillis: Long) : Function<Observable<Throwable>, Observable<Long>> {
override fun apply(attempts: Observable<Throwable>): Observable<Long> {
return attempts
.flatMap(object : Function<Throwable, Observable<Long>> {
private var retryCount: Int = 0
override fun apply(throwable: Throwable): Observable<Long> {
return if (++retryCount < maxRetries) {
// When this Observable calls onNext, the original
// Observable will be retried (i.e. re-subscribed).
Observable.timer(retryDelayMillis,
TimeUnit.MILLISECONDS)
} else Observable.error<Long>(throwable)
// Max retries hit. Just pass the error along.
}
})
}
}
Note that the retryCount has been moved into the inner flatMap so that it is not shared between multiple Observers.

What is the reason for twitter4j.StreamListner IllegalAccessError in Kotlin?

When implementing a twitter4j.StatusListner in Kotlin, I get the following IllegalAccessError and associated stack trace:
Exception in thread "main" java.lang.IllegalAccessError: tried to access class twitter4j.StreamListener from class rxkotlin.rxextensions.TwitterExampleKt$observe$1
at rxkotlin.rxextensions.TwitterExampleKt$observe$1.subscribe(TwitterExample.kt:50)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:10700)
at io.reactivex.Observable.subscribe(Observable.java:10686)
at io.reactivex.Observable.subscribe(Observable.java:10615)
at rxkotlin.rxextensions.TwitterExampleKt.main(TwitterExample.kt:8)
Produced by the following code:
val twitterStream = TwitterStreamFactory().instance
// See https://stackoverflow.com/questions/37672023/how-to-create-an-instance-of-anonymous-interface-in-kotlin/37672334
twitterStream.addListener(object : StatusListener {
override fun onStatus(status: Status?) {
if (emitter.isDisposed) {
twitterStream.shutdown()
} else {
emitter.onNext(status)
}
}
override fun onException(e: Exception?) {
if (emitter.isDisposed) {
twitterStream.shutdown()
} else {
emitter.onError(e)
}
}
// Other overrides.
})
emitter.setCancellable { twitterStream::shutdown }
If I don't use Rx, it makes the exception a bit simpler:
twitterStream.addListener(object: twitter4j.StatusListener {
override fun onStatus(status: Status) { println("Status: {$status}") }
override fun onException(ex: Exception) { println("Error callback: $ex") }
// Other overrides.
})
Exception in thread "main" java.lang.IllegalAccessError: tried to access class twitter4j.StreamListener from class rxkotlin.rxextensions.TwitterExampleKt
at rxkotlin.rxextensions.TwitterExampleKt.main(TwitterExample.kt:14)
However, if I implement a Java wrapper function, no error is thrown and the behaviour is as expected:
Wrapper -
public class Twitter4JHelper {
public static void addStatusListner(TwitterStream stream, StatusListener listner) {
stream.addListener(listner);
}
}
Revised implementation -
val twitterStream = TwitterStreamFactory().instance
val listner = object: StatusListener {
override fun onStatus(status: Status?) {
if (emitter.isDisposed) {
twitterStream.shutdown()
} else {
emitter.onNext(status)
}
}
override fun onException(e: Exception?) {
if (emitter.isDisposed) {
twitterStream.shutdown()
} else {
emitter.onError(e)
}
}
// Other overrides.
}
Twitter4JHelper.addStatusListner(twitterStream, listner)
emitter.setCancellable { twitterStream::shutdown }
This revised solution comes from a blog post, which I think tries to explain the cause but Google translate is not being my friend. What is causing the IllegalAccessError? Is there a purely Kotlin based solution, or will I have to live with this workaround?
Yep that's not going to work.
addListener method takes a StreamListener param and StreamListener is non-public (package private). I would definitely raise a bug against Kotlin compiler for this.
The code Kotlin compiler generates is:
TwitterStream twitterStream = (new TwitterStreamFactory()).getInstance();
twitterStream.addListener((StreamListener)(new StatusListener() {
// ..overrides ...
}));
StatusListener already implements StreamListener so I don't see why the cast is required.
I worked around this by using a java utility class:
public class T4JCompat {
public static void addStatusListener(TwitterStream stream, StatusListener listener) {
stream.addListener(listener);
}
public static void removeStatusListener(TwitterStream stream, StatusListener listener) {
stream.removeListener(listener);
}
}
You can call these methods from Kotlin and things work as expected.

Access members of outer class in TypeScript

Since TypeScript 1.6, we can easily create inner classes with class expressions. In other OOP-centric languages like Java, inner classes can access members of the outer class, even private ones.
This behavior is similar to concept of closures, where function could access variables from the scope in which it was defined.
Why I can't achieve this in TypeScript? Does specification of classes in ECMAScript 2015 plays role here?
Code that presents expected behavior:
class OuterClass {
private outerField = 1337;
public InnerClass = class {
public accessOuter() {
return this.outerField; // outerField not defined
}
}
}
var outer = new OuterClass();
var inner = new outer.InnerClass();
var win = inner.accessOuter();
It's easier to understand why you can't do that if you look at the compiled javascript of your code:
var OuterClass = (function () {
function OuterClass() {
this.outerField = 1337;
this.InnerClass = (function () {
function class_1() {
}
class_1.prototype.accessOuter = function () {
return this.outerField; // outerField not defined
};
return class_1;
}());
}
return OuterClass;
}());
As you can see, outerField is defined as a member of OuterClass like so:
this.outerField = 1337;
When you try to access it in your InnerClass you do:
return this.outerField;
But the this here is the instance of class_1 and not OuterClass so there's no outerField in this.
Also, you have no access from the inner class to the instance of the outer class.
The way this is solved in java is like so:
class OuterClass {
private int outerField = 1337;
public class InnerClass {
public int accessOuter() {
return OuterClass.this.outerField;
}
}
}
But there's no equivalent to OuterClass.this.outerField in typescript/javascript.
Look at typescript inner classes more like static inner classes in java, but here too you'll only be able to access public properties:
class OuterClass {
public static outerField = 1337; // has to be public
public InnerClass = class {
public accessOuter() {
return OuterClass.outerField;
}
}
}
You can pass an instance of the outer class to the inner class:
class OuterClass {
public outerField = 1337;
public InnerClass = class {
constructor(private parent: OuterClass) {}
public accessOuter() {
return this.parent.outerField;
}
}
}
But again, you'll need to have outerField public.
Edit
In case you want to achieve something that will simulate the needed behavior (that is, the inner class instance will have access to a private outer class members), then you can do something like this:
interface OuterClassProxy {
outerField: number;
}
interface IInnerClass {}
class OuterClass {
private outerField = 1337;
static InnerClass = class implements IInnerClass {
constructor(private parent: OuterClassProxy) {}
public accessOuter() {
return this.parent.outerField;
}
}
public createInnerClass(): IInnerClass {
let outerClassInstance = this;
return new OuterClass.InnerClass({
get outerField(): number {
return outerClassInstance.outerField;
},
set outerField(value: number) {
outerClassInstance.outerField = value;
}
});
}
}
It's quite a lot of work, but it will do it.
#Nitzan 's answer is great. I just wanted to add that I came up with this recently, maybe it helps:
class Outer {
constructor() {
this.val = 1337;
}
get Inner() {
let Outer = this;
return class {
accessVal() { return Outer.val; }
}
}
}
new (new Outer()).Inner().accessVal(); // 1337
Here is the correct way to do this in Typescript:
class OuterClass {
private outerField = 1337;
get InnerClass() {
const thatOuterField = this.outerField // <-- Notice this addition
return class {
public accessOuter() {
return thatOuterField; // outerField not defined
}
}
}
}
let outer = new OuterClass();
let inner = new outer.InnerClass();
let win = inner.accessOuter();
alert(win); // test works!
No need for anything convoluted.
This one did not work so bad for me:
function use<T>(value: T) {return new class {with<U>(f: (value: T) => U) {return f(value)}}}
class OuterClass {
private outerField = 1337;
InnerClass = use(this).with(outerThis => class {
accessOuter() {
return outerThis.outerField; // outerField not defined
}
}
}
const outer = new OuterClass()
const inner = new outer.InnerClass()
const win = inner.accessOuter()
console.log(win)

How to achieve simple OOP in Solidity?

Code:
contract A
{
uint public foo;
function A(uint _foo)
{
foo = _foo;
}
}
contract B
{
uint bar;
function B()
{
A a = new A(42);
bar = a.foo;
}
}
Compile Error
Test:18:15: Error: Type function () returns (uint256) is not implicitly convertible to expected type uint256.
bar = a.foo;
^---^
How can I read public variables of a contract in another?
contract A
{
uint public foo;
function A(uint _foo)
{
foo = _foo;
}
}
contract B
{
uint bar;
function B()
{
A a = new A(42);
bar = a.foo();
}
}
bar = a.foo(); instead of bar = a.foo; ...

Method and mock with same class

I have class with 2 methods
class A
{
void Fun()
{
if(FunRet()>0){///} else {///}
}
int FunRet()
{ return 4;}
};
I want to test Fun() method depend on what FunRet returns. So i want to mock FunRet.
I rather don't want make FunRet as virtual. How I can do that?
You can inject intra-class dependencies. In this case, make Fun accept a value instead of computing it:
class A
{
void Fun(int x)
{
if(x>0){///} else {///}
}
int FunRet()
{ return 4;}
};
Then your tests can pass arbitrary values into Fun(). If you need to enforce correct use, write a public version to expose in your API and a private version for testing:
class A {
public:
void Fun() { return Fun(FunRet()); }
private:
void Fun(int x); // for testing.
};
You could extract the Fun method into a calculator class that implements an interface. You should pass an instance of that interface to class A at constructor.
In testing you could have other classes implementing that interface, that return other values.
This method also have the big advantage, that you seperate the concerns of calculating a value and using the calculated value.
class A {
public:
A (IFunCalc calc) { m_calc = calc; }
void Fun { if calc.FunRet() > 4 ... }
private:
IFunCalc m_calc;
}
class FunCalc : IFunCulc {
public:
int FunRet { return 4; }
}
class FunCalc4Test : IFunCalc {
public:
int FunRet { return 27; }
}
I think you're missing the this pointer.
... if ( this->FunRet() > 0 ) { ...
If you use dependency injection and template your object under test, you can use mock objects without having to use virtual functions.
class AParameters
{
public:
int FunRet()
{ return 4;}
};
class MockAParameters
{
public:
MOCK_METHOD0(FunRet, int());
};
template<class Parameters>
class AImpl
{
public:
AImpl(Parameters& parameters):parameters(parameters){}
void Fun()
{
if(parameters.FunRet()>0){///} else {///}
}
private:
Parameters& parameters;
};
typedef AImpl<AParameters> A;
typedef AImpl<MockAParameters> ATestObject;
void Test::funUsesFunRet()
{
MockAParameters params;
EXPECT_CALL(params, FunRet());
ATestObject object(params);
object.Fun();
}
I believe FunRet is an internal implementation detail of Fun. As a result, Fun does not need to be tested in isolation from FunRet. Just test Fun and don't worry about the fact it calls FunRet.