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

server/asset/eth: refactor coins #1397

Merged
merged 3 commits into from
Jan 12, 2022

Conversation

buck54321
Copy link
Member

Separate swapCoin from redeemCoin. Switch (*rpcclient).swap method to
return a *dexeth.SwapState.

@buck54321 buck54321 force-pushed the erc20-coiner-refactor branch from 40b0d90 to 699e2d1 Compare January 8, 2022 12:13
Comment on lines 134 to 125
vGwei := new(big.Int).Div(v, BigGweiFactor)
if vGwei.IsUint64() {
return vGwei.Uint64()
}
Copy link
Member

@chappjc chappjc Jan 9, 2022

Choose a reason for hiding this comment

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

We have a lot of redundancy with these helpers.

  • server/asset/eth/common.go has ToGwei helpers that can be removed. Also that one is bizarrely used in client (ExchangeWallet) never mind this one, I was looking at an old commit.
  • dex/networks/eth/common.co has ToGwei and ToWei

Also, the docs on this function say GweiToWei instead of WeiToGwei.

Copy link
Member

Choose a reason for hiding this comment

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

Two things I was trying to avoid with the ToGwei.

  • A package level BigGweiFactor. This is mutable. Is this safe? For one a consumer could accidentally mutate it. big isn't the easiest package to use imo. Whenever you have a := b.Add(c, d ) you might not expect b to change here, because we just want to add c and d, but b is set to those and returned as a. Also, could an asset that is not one of ours be added that maliciously changes this? I'm not sure if that is something we are worried about, but imo starting with a constant, or at least not exporting it, is safer.

As an example, add this test to the top of eth_test.go and another test will fail:

func TestMutate(t *testing.T) {
	fmt.Println("**************")
	fmt.Println(dexeth.BigGweiFactor)
	c := big.NewInt(2)
	d := big.NewInt(3)
	a := dexeth.BigGweiFactor.Add(c, d)
	fmt.Printf("%p %p\n", a, dexeth.BigGweiFactor)
	fmt.Println(dexeth.BigGweiFactor)
}
  • A big.Int may not fit into a uint64. It could be too large or negative. It would be unexpected, but have untested consequences. Should we at least panic?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call on the BigGweiFactor.

  • A big.Int may not fit into a uint64.

That's the purpose of both ToGwei and the new IsUnit64 check in WeiToGwei. Which brings us back to @chappjc's original observation

We have a lot of redundancy with these helpers.

I have no problem having both ToGwei and WeiToGwei, the choice of which depends on if we want 1) to explicitly check for overflow/sign errors, or 2) just fall back to zero when not suitable for uint64. WeiToGwei clearly has some syntactic advantage, but whether it's appropriate needs to be considered in context.

I do think we should rename ToGwei.


bn, err := c.backend.node.blockNumber(c.backend.rpcCtx)
func (c *redeemCoin) Confirmations(ctx context.Context) (int64, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we ever check redeem confs? I'm drawing a blank on this for some reason

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so. I put added a TODO in the (*Backend).newRedeemCoin docs about it.

Comment on lines 134 to 125
vGwei := new(big.Int).Div(v, BigGweiFactor)
if vGwei.IsUint64() {
return vGwei.Uint64()
}
Copy link
Member

Choose a reason for hiding this comment

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

Two things I was trying to avoid with the ToGwei.

  • A package level BigGweiFactor. This is mutable. Is this safe? For one a consumer could accidentally mutate it. big isn't the easiest package to use imo. Whenever you have a := b.Add(c, d ) you might not expect b to change here, because we just want to add c and d, but b is set to those and returned as a. Also, could an asset that is not one of ours be added that maliciously changes this? I'm not sure if that is something we are worried about, but imo starting with a constant, or at least not exporting it, is safer.

As an example, add this test to the top of eth_test.go and another test will fail:

func TestMutate(t *testing.T) {
	fmt.Println("**************")
	fmt.Println(dexeth.BigGweiFactor)
	c := big.NewInt(2)
	d := big.NewInt(3)
	a := dexeth.BigGweiFactor.Add(c, d)
	fmt.Printf("%p %p\n", a, dexeth.BigGweiFactor)
	fmt.Println(dexeth.BigGweiFactor)
}
  • A big.Int may not fit into a uint64. It could be too large or negative. It would be unexpected, but have untested consequences. Should we at least panic?

Comment on lines -83 to -88
txdata := tx.Data()
// Transactions that call contract functions must have extra data.
if len(txdata) == 0 {
return nil, errors.New("tx calling contract function has no extra data")
}

Copy link
Member

Choose a reason for hiding this comment

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

Was this check not accurate? I thought it was a good way to fail fast.

Copy link
Member Author

Choose a reason for hiding this comment

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

baseCoin is more generalized. The txdata length check is now performed (via ParseInitiateData) in newSwapCoin immediately after the baseCoin is created.

Comment on lines -150 to -153
// For redemptions, the transaction should move no value.
if sct == sctRedeem && value != 0 {
return nil, fmt.Errorf("expected swapCoin value of zero for redeem but got: %d", value)
}
Copy link
Member

Choose a reason for hiding this comment

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

This check removed. Not needed? Any redeem tx with a value should fail to redeem because the solidity redeem function is not marked payable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Value is now being checked (to a tighter standard) in newSwapCoin.

Copy link
Member

Choose a reason for hiding this comment

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

Isn't that for inits, I mean redeems should be 0 value.

if err != nil {
return 0, fmt.Errorf("unable to fetch block number: %v", err)
}
return int64(bn - swap.InitBlockNumber.Uint64()), nil
return int64(bn - swap.BlockHeight + 1), nil
Copy link
Member

Choose a reason for hiding this comment

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

eek good catch

Copy link
Member

@chappjc chappjc left a comment

Choose a reason for hiding this comment

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

LGTM, just a conflict to resolve.

Separate swapCoin from redeemCoin. Switch (*rpcclient).swap method to
return a *dexeth.SwapState.
@buck54321 buck54321 force-pushed the erc20-coiner-refactor branch from 64dc3ae to d597dc5 Compare January 11, 2022 23:44
@chappjc chappjc merged commit 8be5846 into decred:master Jan 12, 2022
@chappjc chappjc added this to the 0.5 milestone Apr 21, 2022
@chappjc chappjc added the ETH label Aug 26, 2022
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.

3 participants