Skip to content

Commit

Permalink
more test
Browse files Browse the repository at this point in the history
  • Loading branch information
codchen authored and philipsu522 committed Nov 15, 2024
1 parent bd74d7a commit e035808
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 18 deletions.
48 changes: 32 additions & 16 deletions app/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func (app *App) AddCosmosEventsToEVMReceiptIfApplicable(ctx sdk.Context, tx sdk.
return
}
logs := []*ethtypes.Log{}
ownerReplacements := map[uint]common.Hash{}
// Note: txs with a very large number of WASM events may run out of gas due to
// additional gas consumption from EVM receipt generation and event translation
wasmToEvmEventGasLimit := app.EvmKeeper.GetDeliverTxHookWasmGasLimit(ctx.WithGasMeter(sdk.NewInfiniteGasMeter(1, 1)))
Expand All @@ -60,10 +61,13 @@ func (app *App) AddCosmosEventsToEVMReceiptIfApplicable(ctx sdk.Context, tx sdk.
// check if there is a ERC721 pointer to contract Addr
pointerAddr, _, exists = app.EvmKeeper.GetERC721CW721Pointer(wasmToEvmEventCtx, contractAddr)
if exists {
log, eligible := app.translateCW721Event(wasmToEvmEventCtx, wasmEvent, pointerAddr, contractAddr, response)
log, realOwner, eligible := app.translateCW721Event(wasmToEvmEventCtx, wasmEvent, pointerAddr, contractAddr, response)
if eligible {
log.Index = uint(len(logs))
logs = append(logs, log)
if (realOwner != common.Hash{}) {
ownerReplacements[log.Index] = realOwner
}
}
continue
}
Expand All @@ -77,15 +81,22 @@ func (app *App) AddCosmosEventsToEVMReceiptIfApplicable(ctx sdk.Context, tx sdk.
}
var bloom ethtypes.Bloom
if r, err := app.EvmKeeper.GetTransientReceipt(wasmToEvmEventCtx, txHash); err == nil && r != nil {
existingLogCnt := len(r.Logs)
r.Logs = append(r.Logs, utils.Map(logs, evmkeeper.ConvertSyntheticEthLog)...)
for i, l := range r.Logs {
l.Index = uint32(i)
}
bloom = ethtypes.CreateBloom(ethtypes.Receipts{&ethtypes.Receipt{Logs: evmkeeper.GetLogsForTx(r)}})
r.LogsBloom = bloom[:]
for i, o := range ownerReplacements {
r.Logs[existingLogCnt+int(i)].Topics[1] = o.Hex()
}
_ = app.EvmKeeper.SetTransientReceipt(wasmToEvmEventCtx, txHash, r)
} else {
bloom = ethtypes.CreateBloom(ethtypes.Receipts{&ethtypes.Receipt{Logs: logs}})
for i, o := range ownerReplacements {
logs[int(i)].Topics[1] = o
}
receipt := &evmtypes.Receipt{
TxType: ShellEVMTxType,
TxHashHex: txHash.Hex(),
Expand Down Expand Up @@ -173,19 +184,24 @@ func (app *App) translateCW20Event(ctx sdk.Context, wasmEvent abci.Event, pointe
return nil, false
}

func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, pointerAddr common.Address, contractAddr string, response sdk.DeliverTxHookInput) (*ethtypes.Log, bool) {
func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, pointerAddr common.Address, contractAddr string, response sdk.DeliverTxHookInput) (*ethtypes.Log, common.Hash, bool) {
action, found := GetAttributeValue(wasmEvent, "action")
if !found {
return nil, false
return nil, common.Hash{}, false
}
var topics []common.Hash
switch action {
case "transfer_nft", "send_nft", "burn":
tokenID := GetTokenIDAttribute(wasmEvent)
if tokenID == nil {
return nil, false
return nil, common.Hash{}, false
}
sender := app.GetEvmAddressAttribute(ctx, wasmEvent, "sender")
sender := common.Hash{}
// unfortunately CW721 transfer events differ from ERC721 transfer events
// in that CW721 include sender (which can be different than owner) whereas
// ERC721 always include owner. The following logic refer to the owner
// event emitted before the transfer and use that instead to populate the
// synthetic ERC721 event.
ownerEvents := GetEventsOfType(response, wasmtypes.EventTypeCW721PreTransferOwner)
for _, ownerEvent := range ownerEvents {
if len(ownerEvent.Attributes) != 3 {
Expand All @@ -210,19 +226,19 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
}
topics = []common.Hash{
ERC721TransferTopic,
sender,
app.GetEvmAddressAttribute(ctx, wasmEvent, "sender"),
app.GetEvmAddressAttribute(ctx, wasmEvent, "recipient"),
common.BigToHash(tokenID),
}
return &ethtypes.Log{
Address: pointerAddr,
Topics: topics,
Data: EmptyHash.Bytes(),
}, true
}, sender, true
case "mint":
tokenID := GetTokenIDAttribute(wasmEvent)
if tokenID == nil {
return nil, false
return nil, common.Hash{}, false
}
topics = []common.Hash{
ERC721TransferTopic,
Expand All @@ -234,11 +250,11 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
Address: pointerAddr,
Topics: topics,
Data: EmptyHash.Bytes(),
}, true
}, common.Hash{}, true
case "approve":
tokenID := GetTokenIDAttribute(wasmEvent)
if tokenID == nil {
return nil, false
return nil, common.Hash{}, false
}
topics = []common.Hash{
ERC721ApprovalTopic,
Expand All @@ -250,11 +266,11 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
Address: pointerAddr,
Topics: topics,
Data: EmptyHash.Bytes(),
}, true
}, common.Hash{}, true
case "revoke":
tokenID := GetTokenIDAttribute(wasmEvent)
if tokenID == nil {
return nil, false
return nil, common.Hash{}, false
}
topics = []common.Hash{
ERC721ApprovalTopic,
Expand All @@ -266,7 +282,7 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
Address: pointerAddr,
Topics: topics,
Data: EmptyHash.Bytes(),
}, true
}, common.Hash{}, true
case "approve_all":
topics = []common.Hash{
ERC721ApproveAllTopic,
Expand All @@ -277,7 +293,7 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
Address: pointerAddr,
Topics: topics,
Data: TrueHash.Bytes(),
}, true
}, common.Hash{}, true
case "revoke_all":
topics = []common.Hash{
ERC721ApproveAllTopic,
Expand All @@ -288,9 +304,9 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
Address: pointerAddr,
Topics: topics,
Data: EmptyHash.Bytes(),
}, true
}, common.Hash{}, true
}
return nil, false
return nil, common.Hash{}, false
}

func (app *App) GetEvmAddressAttribute(ctx sdk.Context, event abci.Event, attribute string) common.Hash {
Expand Down
53 changes: 51 additions & 2 deletions app/receipt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,10 @@ func TestEvmEventsForCw721(t *testing.T) {
require.True(t, found)
require.Equal(t, common.HexToHash("0x1").Bytes(), receipt.Logs[0].Data)

// burn on behalf
payload = []byte("{\"burn\":{\"token_id\":\"2\"}}")
// transfer on behalf
k.BankKeeper().MintCoins(ctx, "evm", amt)
k.BankKeeper().SendCoinsFromModuleToAccount(ctx, "evm", recipient, amt)
payload = []byte(fmt.Sprintf("{\"transfer_nft\":{\"token_id\":\"2\",\"recipient\":\"%s\"}}", recipient.String()))
msg = &wasmtypes.MsgExecuteContract{
Sender: recipient.String(),
Contract: contractAddr.String(),
Expand Down Expand Up @@ -354,6 +354,55 @@ func TestEvmEventsForCw721(t *testing.T) {
require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000002", tokenIdHash)
require.Equal(t, common.HexToHash("0x0").Bytes(), receipt.Logs[0].Data)

// transfer back
payload = []byte(fmt.Sprintf("{\"transfer_nft\":{\"token_id\":\"2\",\"recipient\":\"%s\"}}", creator.String()))
msg = &wasmtypes.MsgExecuteContract{
Sender: recipient.String(),
Contract: contractAddr.String(),
Msg: payload,
}
txBuilder = testkeeper.EVMTestApp.GetTxConfig().NewTxBuilder()
txBuilder.SetMsgs(msg)
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000000))))
txBuilder.SetGasLimit(300000)
tx = signTx(txBuilder, privKeyRecipient, k.AccountKeeper().GetAccount(ctx, recipient))
txbz, err = testkeeper.EVMTestApp.GetTxConfig().TxEncoder()(tx)
require.Nil(t, err)
sum = sha256.Sum256(txbz)
res = testkeeper.EVMTestApp.DeliverTx(ctx.WithEventManager(sdk.NewEventManager()), abci.RequestDeliverTx{Tx: txbz}, tx, sum)
require.Equal(t, uint32(0), res.Code)

// burn on behalf
payload = []byte("{\"burn\":{\"token_id\":\"2\"}}")
msg = &wasmtypes.MsgExecuteContract{
Sender: recipient.String(),
Contract: contractAddr.String(),
Msg: payload,
}
txBuilder = testkeeper.EVMTestApp.GetTxConfig().NewTxBuilder()
txBuilder.SetMsgs(msg)
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000000))))
txBuilder.SetGasLimit(300000)
tx = signTx(txBuilder, privKeyRecipient, k.AccountKeeper().GetAccount(ctx, recipient))
txbz, err = testkeeper.EVMTestApp.GetTxConfig().TxEncoder()(tx)
require.Nil(t, err)
sum = sha256.Sum256(txbz)
res = testkeeper.EVMTestApp.DeliverTx(ctx.WithEventManager(sdk.NewEventManager()), abci.RequestDeliverTx{Tx: txbz}, tx, sum)
require.Equal(t, uint32(0), res.Code)
receipt, err = testkeeper.EVMTestApp.EvmKeeper.GetTransientReceipt(ctx, common.BytesToHash(sum[:]))
require.Nil(t, err)
require.Equal(t, 1, len(receipt.Logs))
require.NotEmpty(t, receipt.LogsBloom)
require.Equal(t, mockPointerAddr.Hex(), receipt.Logs[0].Address)
require.Equal(t, uint32(0), receipt.Logs[0].Index)
ownerHash = receipt.Logs[0].Topics[1]
// make sure that the owner is set correctly to the creator, not the spender.
creatorEvmAddr = testkeeper.EVMTestApp.EvmKeeper.GetEVMAddressOrDefault(ctx, creator)
require.Equal(t, common.BytesToHash(creatorEvmAddr[:]).Hex(), ownerHash)
tokenIdHash = receipt.Logs[0].Topics[3]
require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000002", tokenIdHash)
require.Equal(t, common.HexToHash("0x0").Bytes(), receipt.Logs[0].Data)

// revoke all
payload = []byte(fmt.Sprintf("{\"revoke_all\":{\"operator\":\"%s\"}}", recipient.String()))
msg = &wasmtypes.MsgExecuteContract{
Expand Down

0 comments on commit e035808

Please sign in to comment.