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

fix: eth: use the correct tipset for Eth APIs #10462

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Stebalien
Copy link
Member

@Stebalien Stebalien commented Mar 13, 2023

Related Issues

fixes #10357

Proposed Changes

Many of our "state" methods look at the tipset's parent state. However, Eth APIs expect the current tipset. We had sort-of fixed this for balances, but nothing else.

This patch alters most Eth APIs to use the following tipset as their base instead of the requested tipset. This is now possible because the pending tipset is no longer allowed.

NOTE: this patch also adds "pending" support back to EthGetTransactionCount. I expect we actually need this...

Checklist

Before you mark the PR ready for review, please make sure that:

  • Commits have a clear commit message.
  • PR title is in the form of of <PR type>: <area>: <change being made>
    • example: fix: mempool: Introduce a cache for valid signatures
    • PR type: fix, feat, build, chore, ci, docs, perf, refactor, revert, style, test
    • area, e.g. api, chain, state, market, mempool, multisig, networking, paych, proving, sealing, wallet, deps
  • New features have usage guidelines and / or documentation updates in
  • Tests exist for new functionality or change in behavior
  • CI is green

@Stebalien Stebalien requested a review from a team as a code owner March 13, 2023 21:07
@Stebalien Stebalien force-pushed the steb/eth-tipset-after branch from 928b1a7 to 276afdb Compare March 13, 2023 21:11
@Stebalien
Copy link
Member Author

This'll need a couple of tests but I wanted to get this up.

// blkParamToTipsetAfter returns the next non-nil tipset after the given block param.
func (a *EthModule) blkParamToTipsetAfter(ctx context.Context, blkParam string) (*types.TipSet, error) {
switch blkParam {
case "earliest", "pending":
Copy link
Member Author

Choose a reason for hiding this comment

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

Alternatively, we can reject "pending" in some specific cases, rather than allow it in some specific cases.

@Stebalien Stebalien marked this pull request as draft April 25, 2023 16:35
Many of our "state" methods look at the tipset's _parent_ state.
However, Eth APIs expect the current tipset. We had sort-of fixed this
for balances, but nothing else.

This patch alters _most_ Eth APIs to use the following tipset as their
base instead of the requested tipset.
@Stebalien Stebalien force-pushed the steb/eth-tipset-after branch from 276afdb to 408e01d Compare August 24, 2023 16:37
@@ -274,6 +282,7 @@ func (a *EthModule) getTipsetByEthBlockNumberOrHash(ctx context.Context, blkPara
}

if blkParam.BlockHash != nil {
// TODO
Copy link
Member Author

Choose a reason for hiding this comment

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

We don't have a fast way to implement this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Specifically, we don't have a fast way to implement this if the requested block is not on the main chain.

return 0, err
}
if !consensus.IsValidForSending(nv, actor) {
return 0, xerrors.Errorf("cannot lookup pending transaction count for non-accounts")
Copy link
Member Author

Choose a reason for hiding this comment

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

We could support this. But we'd need to call TipSetState which may compute the state.

@@ -709,17 +739,13 @@ func (a *EthModule) EthGetBalance(ctx context.Context, address ethtypes.EthAddre
return ethtypes.EthBigInt{}, err
}

ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
// TODO: Consider supporting pending balance?
Copy link
Member Author

Choose a reason for hiding this comment

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

So, we were supporting "pending" balances. What will this break?

Copy link
Member Author

Choose a reason for hiding this comment

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

We were also randomly computing the tipset state. So maybe that's not an issue?

  • It will be cached.
  • We no longer have a hard parallelism limit like we did before.
  • We "lock" so we won't compute it multiple times in parallel.

return nil, xerrors.Errorf("getting parent tipset: %w", err)
}
}
res, err := a.StateManager.CallWithGas(ctx, msg, []types.ChainMsg{}, ts, false)
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'm not sure why we were retrying at different heights. We should just bail in this case.

@@ -1176,7 +1187,7 @@ func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam e
return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err)
}

ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam, true)
Copy link
Member Author

Choose a reason for hiding this comment

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

This "removes" support for applying on-top-of the "pending" tipset.

@@ -613,7 +643,7 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress,
}

func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam ethtypes.EthBlockNumberOrHash) (ethtypes.EthBytes, error) {
ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam, true)
Copy link
Member Author

Choose a reason for hiding this comment

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

This used to be incorrect at the pending tipset, now it will error.

@@ -534,7 +564,7 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress,
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
}

ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam)
ts, err := a.getTipsetByEthBlockNumberOrHash(ctx, blkParam, true)
Copy link
Member Author

Choose a reason for hiding this comment

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

This used to be incorrect at the pending tipset, now it will error.

@Stebalien
Copy link
Member Author

So, the real question is: Do we want to do it this way? Or do we want to actually support "pending" by, e.g., computing the tipset state.

Computing the tipset state used to be a huge issue... but:

  1. Tipset computation time is now sane again.
  2. The results will be cached and computed at most once and only for "pending".

@Stebalien
Copy link
Member Author

Ok, some discussion has been had:

  1. We should correctly support "pending" wherever possible. That means calling TipSetState extensively to compute the tipset state. Luckily, this will be cached much of the time.
  2. I have no good ideas on what to do about ethCall in general. The current logic (once we remove the "don't apply messages from the current tipset" feature) is, in fact, the "most correct". But it's slow.

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

Successfully merging this pull request may close these issues.

EthGetTransactionCount ignores input
1 participant