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

Translate CW20 events into EVM events in shell receipts #1748

Merged
merged 7 commits into from
Jul 2, 2024
Merged

Conversation

codchen
Copy link
Collaborator

@codchen codchen commented Jun 27, 2024

Describe your changes and provide context

Add a post-DeliverTx hook that captures any relevant CW20 event and translate it into a corresponding ERC20 event. If a receipt already exists for that transaction (e.g. an EVM tx that called a CW20 contract via precompile), the translated event will be appended to the existing receipt and the bloom will be updated. Otherwise, a shell receipt will be created.

Testing performed to validate your change

unit tests

@@ -224,7 +224,7 @@
} else {
coinbase = am.keeper.AccountKeeper().GetModuleAddress(authtypes.FeeCollectorName)
}
evmTxDeferredInfoList := am.keeper.GetEVMTxDeferredInfo(ctx)
evmTxDeferredInfoList := am.keeper.GetAllEVMTxDeferredInfo(ctx)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods Warning

path flow from Begin/EndBlock to a panic call
path flow from Begin/EndBlock to a panic call
@codchen codchen force-pushed the use-transient-store-for-evm-deferred branch from 888db56 to 9902e71 Compare June 28, 2024 01:25
Base automatically changed from use-transient-store-for-evm-deferred to main June 28, 2024 02:14
Copy link

codecov bot commented Jun 28, 2024

Codecov Report

Attention: Patch coverage is 66.66667% with 58 lines in your changes missing coverage. Please review.

Project coverage is 60.79%. Comparing base (d25456d) to head (077d09f).
Report is 4 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1748      +/-   ##
==========================================
- Coverage   60.81%   60.79%   -0.03%     
==========================================
  Files         373      374       +1     
  Lines       27116    27300     +184     
==========================================
+ Hits        16491    16596     +105     
- Misses       9518     9581      +63     
- Partials     1107     1123      +16     
Files Coverage Δ
app/app.go 66.08% <100.00%> (-0.16%) ⬇️
x/evm/module.go 55.55% <100.00%> (-0.33%) ⬇️
x/dex/utils/context.go 0.00% <0.00%> (ø)
precompiles/wasmd/wasmd.go 59.55% <62.50%> (-0.17%) ⬇️
x/evm/keeper/receipt.go 50.74% <0.00%> (-9.97%) ⬇️
x/evm/keeper/deferred.go 57.89% <7.14%> (ø)
app/receipt.go 78.10% <78.10%> (ø)

... and 2 files with indirect coverage changes

Copy link
Contributor

@stevenlanders stevenlanders left a comment

Choose a reason for hiding this comment

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

Had some question - looks good to me.

@@ -1,5 +1,5 @@
The source files are under contracts/src. The artifacts should be updated whenever the source files change. To update run the following (with NativeSeiTokensERC20 as an example):
- `solc --overwrite @openzeppelin=contracts/lib/openzeppelin-contracts --bin -o x/evm/artifacts/cw721 contracts/src/CW721ERC721Pointer.sol`
- `solc --overwrite @openzeppelin=contracts/lib/openzeppelin-contracts --bin -o x/evm/artifacts/cw20 contracts/src/CW721ERC721Pointer.sol`
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 contract also be updated to CW20ERC20Pointer.sol?

@@ -63,3 +63,15 @@ func (k *Keeper) AppendToEvmTxDeferredInfo(ctx sdk.Context, bloom ethtypes.Bloom
}
prefix.NewStore(ctx.TransientStore(k.transientStoreKey), types.DeferredInfoPrefix).Set(key, bz)
}

func (k *Keeper) GetEVMTxDeferredInfo(ctx sdk.Context) *types.DeferredInfo {
Copy link
Contributor

Choose a reason for hiding this comment

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

side thought: It can sometimes be nice sdk-wise to have signatures that return *pointer, bool where the bool represents found

}
// check if there is a ERC20 pointer to contractAddr
pointerAddr, _, exists := app.EvmKeeper.GetERC20CW20Pointer(ctx, contractAddr)
if exists {
Copy link
Contributor

Choose a reason for hiding this comment

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

i'd suggest doing a if !exists { continue } to avoid the indentation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we can't continue here because we'd have another branch for 721 https://github.com/sei-protocol/sei-chain/pull/1750/files#diff-8810d2793d992ba6de31afd91265ef3facc0612669de567b51dc1d8d029cf22fR104 I refactored this part into a func to avoid the big indentation instead

app/receipt.go Outdated
return amountInt.BigInt()
}
}
return big.NewInt(0)
Copy link
Contributor

Choose a reason for hiding this comment

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

is it true that the default amount should be zero (vs. nil/not-existing?). I'd also suggest returning early on !found and !ok to keep the indentations down

Copy link
Contributor

Choose a reason for hiding this comment

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

(I like the GetAttributeValue approach of having the boolean to indicate found)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

updated

if found {
seiAddr, err := sdk.AccAddressFromBech32(addrStr)
if err == nil {
evmAddr := app.EvmKeeper.GetEVMAddressOrDefault(ctx, seiAddr)
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it will, but just confirming: this would work on a past block as well (ctx's height is honored here)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah all the states are accessed via ctx which will be versioned

app/receipt.go Outdated
[]byte(fmt.Sprintf("{\"allowance\":{\"owner\":\"%s\",\"spender\":\"%s\"}}", ownerStr, spenderStr)),
)
if err != nil {
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

is this err something that means a safe 'was not found' situation (or is it worse than that?) I wonder if it should log?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we probably don't want a log here since it simply indicates that the contract does not adhere to cw20 (which is bad from the contract's perspective, but kind of neutral from chain's perspective)

app/receipt.go Outdated
}
allowanceResponse := &AllowanceResponse{}
if err := json.Unmarshal(res, allowanceResponse); err != nil {
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we'd want a log for this one, or maybe it's a worse situation and should bail/panic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ditto

topics: [ethers.id("Transfer(address,address,uint256)")]
};
const logs = await ethers.provider.getLogs(filter);
expect(logs.length).to.equal(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

it may be good just to assert the expected properties of that log (just to make sure the addresses are right, and the amounts are in the right unit)

_ = app.EvmKeeper.SetTransientReceipt(ctx, txHash, r)
} else {
bloom = ethtypes.CreateBloom(ethtypes.Receipts{&ethtypes.Receipt{Logs: logs}})
receipt := &evmtypes.Receipt{
Copy link
Contributor

Choose a reason for hiding this comment

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

is there some indicator or flag so that we can somehow optionally include/exclude these events from a result?

@codchen codchen force-pushed the fake-receipt branch 3 times, most recently from 9179bc6 to 086b9c4 Compare July 2, 2024 03:20
@codchen codchen merged commit f9be5b2 into main Jul 2, 2024
49 checks passed
@codchen codchen deleted the fake-receipt branch July 2, 2024 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants