Skip to content

Commit

Permalink
Merge branch 'feature/firehose-tracer' into release/firehose
Browse files Browse the repository at this point in the history
# Conflicts:
#	evmrpc/config.go
#	evmrpc/config_test.go
#	precompiles/bank/bank.go
#	precompiles/wasmd/wasmd.go
#	x/evm/keeper/msg_server.go
#	x/evm/module.go
  • Loading branch information
maoueh committed May 27, 2024
2 parents e6bdc65 + ad9f914 commit 16f73c4
Show file tree
Hide file tree
Showing 167 changed files with 8,876 additions and 1,762 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,12 @@ jobs:
{
name: "EVM Module",
scripts: [
"python3 integration_test/scripts/runner.py integration_test/evm_module/hardhat_test.yaml",
"./integration_test/evm_module/scripts/evm_tests.sh",
]
},
{
name: "EVM Interoperability",
scripts: [
"python3 integration_test/scripts/runner.py integration_test/evm_module/hardhat_test.yaml",
"./integration_test/evm_module/scripts/evm_interoperability_tests.sh"
]
},
Expand Down
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ linters:
disable-all: true
enable:
- bodyclose
- deadcode
# - depguard ## see https://github.com/golangci/golangci-lint/issues/3906
- dogsled
- exportloopref
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ Ref: https://keepachangelog.com/en/1.0.0/
-->

# Changelog
## v5.5.2
sei-chain
* [#1685](https://github.com/sei-protocol/sei-chain/pull/1685) Add EVM support to v5.5.2
## v5.4.0
sei-chain
* [#1671](https://github.com/sei-protocol/sei-chain/pull/1671) Update and fixes to ERC721 contract
* [#1672](https://github.com/sei-protocol/sei-chain/pull/1672) Add sei_getCosmosTx endpoint
* [#1669](https://github.com/sei-protocol/sei-chain/pull/1669) Add ERC/CW 2981 in pointe
* [#1668](https://github.com/sei-protocol/sei-chain/pull/1673) Bring CW721 pointer contract up to spec
* [#1662](https://github.com/sei-protocol/sei-chain/pull/1662) Add memo support to ibc compiles
* [#1661](https://github.com/sei-protocol/sei-chain/pull/1661) Do not modify original value passed in executeBatch call

sei-cosmos
*[#505](https://github.com/sei-protocol/sei-cosmos/pull/505) Fix export genesis for historical height
*[#506](https://github.com/sei-protocol/sei-cosmos/pull/506) Allow reading pairs in changeset before flush

sei-wasmd
*[#50](https://github.com/sei-protocol/sei-wasmd/pull/50) Changes to fix runtime gas and add paramsKeeper to wasmKeeper for query gas multiplier

## v5.2.0
sei-chain
* [#1621](https://github.com/sei-protocol/sei-chain/pull/1621) Add websocket metrics
Expand Down
2 changes: 1 addition & 1 deletion app/antedecorators/gasless.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func IsTxGasless(tx sdk.Tx, ctx sdk.Context, oracleKeeper oraclekeeper.Keeper) (
}

func dexPlaceOrdersIsGasless(_ *dextypes.MsgPlaceOrders) bool {
return true
return false
}

// WhitelistedGaslessCancellationAddrs TODO: migrate this into params state
Expand Down
59 changes: 0 additions & 59 deletions app/antedecorators/gasless_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"testing"

"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/accesscontrol"
"github.com/cosmos/cosmos-sdk/x/staking"
Expand All @@ -14,9 +13,7 @@ import (
oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"
)

var output = ""
Expand Down Expand Up @@ -112,53 +109,6 @@ func CallGaslessDecoratorWithMsg(ctx sdk.Context, msg sdk.Msg, oracleKeeper orac
return err
}

func TestGaslessDecorator(t *testing.T) {
output = ""
anteDecorators := []sdk.AnteFullDecorator{
FakeAnteDecoratorOne{},
antedecorators.NewGaslessDecorator([]sdk.AnteFullDecorator{FakeAnteDecoratorTwo{}}, oraclekeeper.Keeper{}),
FakeAnteDecoratorThree{},
}
chainedHandler, depGen := sdk.ChainAnteDecorators(anteDecorators...)

db := tmdb.NewMemDB()
stateStore := store.NewCommitMultiStore(db)
ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())

// normal tx (not gasless)
_, err := chainedHandler(ctx, FakeTx{}, false)
require.NoError(t, err)
require.Equal(t, "onetwothree", output)
_, err = depGen([]accesscontrol.AccessOperation{}, FakeTx{}, 1)
require.NoError(t, err)
require.Equal(t, "onetwothree", outputDeps)

// gasless tx (deliverTx) -> wrapped should still be run
output = ""
outputDeps = ""
_, err = chainedHandler(ctx, FakeTx{
FakeMsgs: []sdk.Msg{&types.MsgPlaceOrders{}},
Gas: 100,
}, false)
require.NoError(t, err)
require.Equal(t, "onetwothree", output)
_, err = depGen([]accesscontrol.AccessOperation{}, FakeTx{}, 1)
require.NoError(t, err)
require.Equal(t, "onetwothree", outputDeps)

// gasless tx (checkTx) -> wrapped should not be run
output = ""
outputDeps = ""
_, err = chainedHandler(ctx.WithIsCheckTx(true), FakeTx{
FakeMsgs: []sdk.Msg{&types.MsgPlaceOrders{}},
}, false)
require.NoError(t, err)
require.Equal(t, "onethree", output)
_, err = depGen([]accesscontrol.AccessOperation{}, FakeTx{}, 1)
require.NoError(t, err)
require.Equal(t, "onetwothree", outputDeps)
}

func TestOracleVoteGasless(t *testing.T) {
input := oraclekeeper.CreateTestInput(t)

Expand Down Expand Up @@ -200,15 +150,6 @@ func TestOracleVoteGasless(t *testing.T) {
require.True(t, gasless)
}

func TestDexPlaceOrderGasless(t *testing.T) {
// this needs to be updated if its changed from constant true
// reset gasless
gasless = true
err := CallGaslessDecoratorWithMsg(sdk.NewContext(nil, tmproto.Header{}, false, nil).WithIsCheckTx(true), &types.MsgPlaceOrders{}, oraclekeeper.Keeper{})
require.NoError(t, err)
require.True(t, gasless)
}

func TestDexCancelOrderGasless(t *testing.T) {
addr1 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
addr2 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
Expand Down
16 changes: 11 additions & 5 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ func New(
app.WasmKeeper = wasm.NewKeeper(
appCodec,
keys[wasm.StoreKey],
app.ParamsKeeper,
app.GetSubspace(wasm.ModuleName),
app.AccountKeeper,
app.BankKeeper,
Expand All @@ -597,7 +598,7 @@ func New(

app.EvmKeeper = *evmkeeper.NewKeeper(keys[evmtypes.StoreKey], memKeys[evmtypes.MemStoreKey],
app.GetSubspace(evmtypes.ModuleName), app.BankKeeper, &app.AccountKeeper, &app.StakingKeeper,
app.TransferKeeper, wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper))
app.TransferKeeper, wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper), &app.WasmKeeper)
app.evmRPCConfig, err = evmrpc.ReadConfig(appOpts)
if err != nil {
panic(fmt.Sprintf("error reading EVM config due to %s", err))
Expand Down Expand Up @@ -683,6 +684,9 @@ func New(
app.DistrKeeper,
app.OracleKeeper,
app.TransferKeeper,
app.IBCKeeper.ClientKeeper,
app.IBCKeeper.ConnectionKeeper,
app.IBCKeeper.ChannelKeeper,
); err != nil {
panic(err)
}
Expand Down Expand Up @@ -1019,7 +1023,7 @@ func (app *App) SetStoreUpgradeHandlers() {
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
}

if upgradeInfo.Name == "v5.1.0" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
if (upgradeInfo.Name == "v5.1.0" || upgradeInfo.Name == "v5.5.2") && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := storetypes.StoreUpgrades{
Added: []string{evmtypes.StoreKey},
}
Expand Down Expand Up @@ -1139,7 +1143,8 @@ func (app *App) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock)
if app.EvmKeeper.EthReplayConfig.Enabled || app.EvmKeeper.EthBlockTestConfig.Enabled {
return &abci.ResponseFinalizeBlock{}, nil
}
appHash := app.WriteStateToCommitAndGetWorkingHash()
app.WriteState()
appHash := app.GetWorkingHash()
resp := app.getFinalizeBlockResponse(appHash, app.optimisticProcessingInfo.Events, app.optimisticProcessingInfo.TxRes, app.optimisticProcessingInfo.EndBlockResp)
return &resp, nil
}
Expand All @@ -1154,7 +1159,8 @@ func (app *App) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock)
if app.EvmKeeper.EthReplayConfig.Enabled || app.EvmKeeper.EthBlockTestConfig.Enabled {
return &abci.ResponseFinalizeBlock{}, nil
}
appHash := app.WriteStateToCommitAndGetWorkingHash()
app.WriteState()
appHash := app.GetWorkingHash()
resp := app.getFinalizeBlockResponse(appHash, events, txResults, endBlockResp)
return &resp, nil
}
Expand Down Expand Up @@ -1784,7 +1790,7 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) {
app.Logger().Error(fmt.Sprintf("failed to create query context for EVM; using latest context instead: %v+", err.Error()))
return app.GetCheckCtx()
}
return ctx
return ctx.WithIsEVM(true)
}
if app.evmRPCConfig.HTTPEnabled {
evmHTTPServer, err := evmrpc.NewEVMHTTPServer(app.Logger(), app.evmRPCConfig, clientCtx.Client, &app.EvmKeeper, ctxProvider, app.encodingConfig.TxConfig, DefaultNodeHome)
Expand Down
7 changes: 7 additions & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ var upgradesList = []string{
"v5.0.1",
"v5.1.0",
"v5.2.0",
"v5.2.1",
"v5.2.2",
"v5.3.0",
"v5.4.0",
"v5.5.0",
"v5.5.1",
"v5.5.2",
}

// if there is an override list, use that instead, for integration tests
Expand Down
1 change: 1 addition & 0 deletions cmd/seid/cmd/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ $ %s debug dump-iavl 12345
return cmd
}

//nolint:gosec
func dumpIavlCmdHandler(cmd *cobra.Command, args []string) error {
var err error
home, err := os.UserHomeDir()
Expand Down
88 changes: 82 additions & 6 deletions contracts/src/CW721ERC721Pointer.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma solidity ^0.8.12;

import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IWasmd} from "./precompiles/IWasmd.sol";
import {IJson} from "./precompiles/IJson.sol";
import {IAddr} from "./precompiles/IAddr.sol";

contract CW721ERC721Pointer is ERC721 {
contract CW721ERC721Pointer is ERC721,ERC2981 {

address constant WASMD_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000001002;
address constant JSON_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000001003;
Expand All @@ -19,23 +21,53 @@ contract CW721ERC721Pointer is ERC721 {
IJson public JsonPrecompile;
IAddr public AddrPrecompile;

error NotImplementedOnCosmwasmContract(string method);
error NotImplemented(string method);

constructor(string memory Cw721Address_, string memory name_, string memory symbol_) ERC721(name_, symbol_) {
WasmdPrecompile = IWasmd(WASMD_PRECOMPILE_ADDRESS);
JsonPrecompile = IJson(JSON_PRECOMPILE_ADDRESS);
AddrPrecompile = IAddr(ADDR_PRECOMPILE_ADDRESS);
Cw721Address = Cw721Address_;
}

function supportsInterface(bytes4 interfaceId) public pure override(ERC721, ERC2981) returns (bool) {
return
interfaceId == type(IERC2981).interfaceId ||
interfaceId == type(IERC165).interfaceId ||
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId;
}

// Queries
function balanceOf(address owner) public view override returns (uint256) {
if (owner == address(0)) {
revert ERC721InvalidOwner(address(0));
}
string memory ownerAddr = _formatPayload("owner", _doubleQuotes(AddrPrecompile.getSeiAddr(owner)));
string memory req = _curlyBrace(_formatPayload("tokens", _curlyBrace(ownerAddr)));
uint256 numTokens = 0;
string memory startAfter;
string memory qb = string.concat(
string.concat("\"limit\":1000,\"owner\":\"", AddrPrecompile.getSeiAddr(owner)),
"\""
);
bytes32 terminator = keccak256("{\"tokens\":[]}");

bytes[] memory tokens;
uint256 tokensLength;
string memory req = string.concat(string.concat("{\"tokens\":{", qb), "}}");
bytes memory response = WasmdPrecompile.query(Cw721Address, bytes(req));
bytes[] memory tokens = JsonPrecompile.extractAsBytesList(response, "tokens");
return tokens.length;
while (keccak256(response) != terminator) {
tokens = JsonPrecompile.extractAsBytesList(response, "tokens");
tokensLength = tokens.length;
numTokens += tokensLength;
startAfter = string.concat(",\"start_after\":", string(tokens[tokensLength-1]));
req = string.concat(
string.concat("{\"tokens\":{", string.concat(qb, startAfter)),
"}}"
);
response = WasmdPrecompile.query(Cw721Address, bytes(req));
}
return numTokens;
}

function ownerOf(uint256 tokenId) public view override returns (address) {
Expand Down Expand Up @@ -72,6 +104,26 @@ contract CW721ERC721Pointer is ERC721 {
return false;
}

// 2981
function royaltyInfo(uint256 tokenId, uint256 salePrice) public view override returns (address, uint256) {
bytes memory checkRoyaltyResponse = WasmdPrecompile.query(Cw721Address, bytes("{\"extension\":{\"msg\":{\"check_royalties\":{}}}}"));
bytes memory isRoyaltyImplemented = JsonPrecompile.extractAsBytes(checkRoyaltyResponse, "royalty_payments");
if (keccak256(isRoyaltyImplemented) != keccak256("true")) {
revert NotImplementedOnCosmwasmContract("royalty_info");
}
string memory tId = _formatPayload("token_id", _doubleQuotes(Strings.toString(tokenId)));
string memory sPrice = _formatPayload("sale_price", _doubleQuotes(Strings.toString(salePrice)));
string memory req = _curlyBrace(_formatPayload("royalty_info", _curlyBrace(_join(tId, sPrice, ","))));
string memory fullReq = _curlyBrace(_formatPayload("extension", _curlyBrace(_formatPayload("msg", req))));
bytes memory response = WasmdPrecompile.query(Cw721Address, bytes(fullReq));
bytes memory addr = JsonPrecompile.extractAsBytes(response, "address");
uint256 amt = JsonPrecompile.extractAsUint256(response, "royalty_amount");
if (addr.length == 0) {
return (address(0), amt);
}
return (AddrPrecompile.getEvmAddr(string(addr)), amt);
}

function tokenURI(uint256 tokenId) public view override returns (string memory) {
// revert if token isn't owned
ownerOf(tokenId);
Expand All @@ -82,6 +134,20 @@ contract CW721ERC721Pointer is ERC721 {
return string(uri);
}

// 721-Enumerable
function totalSupply() public view virtual returns (uint256) {
bytes memory response = WasmdPrecompile.query(Cw721Address, bytes("{\"num_tokens\":{}}"));
return JsonPrecompile.extractAsUint256(response, "count");
}

function tokenOfOwnerByIndex(address, uint256) public view virtual returns (uint256) {
revert NotImplemented("tokenOfOwnerByIndex");
}

function tokenByIndex(uint256) public view virtual returns (uint256) {
revert NotImplemented("tokenByIndex");
}

// Transactions
function transferFrom(address from, address to, uint256 tokenId) public override {
if (to == address(0)) {
Expand Down Expand Up @@ -126,6 +192,16 @@ contract CW721ERC721Pointer is ERC721 {
return ret;
}

function _queryContractInfo() internal view virtual returns (string memory, string memory) {
string memory req = _curlyBrace(_formatPayload("contract_info", "{}"));
bytes memory response = WasmdPrecompile.query(Cw721Address, bytes(req));
bytes memory respName = JsonPrecompile.extractAsBytes(response, "name");
bytes memory respSymbol = JsonPrecompile.extractAsBytes(response, "symbol");
string memory nameStr = string(respName);
string memory symbolStr = string(respSymbol);
return (nameStr, symbolStr);
}

function _formatPayload(string memory key, string memory value) internal pure returns (string memory) {
return _join(_doubleQuotes(key), value, ":");
}
Expand Down
Loading

0 comments on commit 16f73c4

Please sign in to comment.