Skip to content

Commit

Permalink
Merge PR :RLP encode is not allowed until venus height (#1407)
Browse files Browse the repository at this point in the history
* RLP encode is not allowed until venus height

* add optional heights paramter in sdk.TxDecoder

* update rpc

* update HigherThanVenus

* txpool is not allowed until venus height

* update global height when restarting the node

Co-authored-by: KamiD <[email protected]>
  • Loading branch information
yann-sjtu and KamiD authored Jan 10, 2022
1 parent 3bf6499 commit 47920a4
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 47 deletions.
18 changes: 15 additions & 3 deletions app/rpc/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ func (b *EthermintBackend) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.L
// PendingTransactions returns the transactions that are in the transaction pool
// and have a from address that is one of the accounts this node manages.
func (b *EthermintBackend) PendingTransactions() ([]*rpctypes.Transaction, error) {
info, err := b.clientCtx.Client.BlockchainInfo(0, 0)
if err != nil {
return nil, err
}
pendingTxs, err := b.clientCtx.Client.UnconfirmedTxs(-1)
if err != nil {
return nil, err
Expand All @@ -249,7 +253,7 @@ func (b *EthermintBackend) PendingTransactions() ([]*rpctypes.Transaction, error
}

// TODO: check signer and reference against accounts the node manages
rpcTx, err := rpctypes.NewTransaction(ethTx, common.BytesToHash(tx.Hash(b.clientCtx.Height)), common.Hash{}, 0, 0)
rpcTx, err := rpctypes.NewTransaction(ethTx, common.BytesToHash(tx.Hash(info.LastHeight)), common.Hash{}, 0, 0)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -277,6 +281,10 @@ func (b *EthermintBackend) UserPendingTransactionsCnt(address string) (int, erro
}

func (b *EthermintBackend) UserPendingTransactions(address string, limit int) ([]*rpctypes.Transaction, error) {
info, err := b.clientCtx.Client.BlockchainInfo(0, 0)
if err != nil {
return nil, err
}
result, err := b.clientCtx.Client.UserUnconfirmedTxs(address, limit)
if err != nil {
return nil, err
Expand All @@ -290,7 +298,7 @@ func (b *EthermintBackend) UserPendingTransactions(address string, limit int) ([
}

// TODO: check signer and reference against accounts the node manages
rpcTx, err := rpctypes.NewTransaction(ethTx, common.BytesToHash(tx.Hash(b.clientCtx.Height)), common.Hash{}, 0, 0)
rpcTx, err := rpctypes.NewTransaction(ethTx, common.BytesToHash(tx.Hash(info.LastHeight)), common.Hash{}, 0, 0)
if err != nil {
return nil, err
}
Expand All @@ -312,6 +320,10 @@ func (b *EthermintBackend) PendingAddressList() ([]string, error) {
// PendingTransactions returns the transaction that is in the transaction pool
// and have a from address that is one of the accounts this node manages.
func (b *EthermintBackend) PendingTransactionsByHash(target common.Hash) (*rpctypes.Transaction, error) {
info, err := b.clientCtx.Client.BlockchainInfo(0, 0)
if err != nil {
return nil, err
}
pendingTx, err := b.clientCtx.Client.GetUnconfirmedTxByHash(target)
if err != nil {
return nil, err
Expand All @@ -321,7 +333,7 @@ func (b *EthermintBackend) PendingTransactionsByHash(target common.Hash) (*rpcty
// ignore non Ethermint EVM transactions
return nil, err
}
rpcTx, err := rpctypes.NewTransaction(ethTx, common.BytesToHash(pendingTx.Hash(b.clientCtx.Height)), common.Hash{}, 0, 0)
rpcTx, err := rpctypes.NewTransaction(ethTx, common.BytesToHash(pendingTx.Hash(info.LastHeight)), common.Hash{}, 0, 0)
if err != nil {
return nil, err
}
Expand Down
25 changes: 22 additions & 3 deletions app/rpc/namespaces/eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,10 @@ func (api *PublicEthereumAPI) SendTransaction(args rpctypes.SendTxArgs) (common.
defer monitor.OnEnd("args", args)
// TODO: Change this functionality to find an unlocked account by address

height, err := api.BlockNumber()
if err != nil {
return common.Hash{}, err
}
key, exist := rpctypes.GetKeyByAddress(api.keys, *args.From)
if !exist {
api.logger.Debug("failed to find key in keyring", "key", args.From)
Expand Down Expand Up @@ -700,7 +704,12 @@ func (api *PublicEthereumAPI) SendTransaction(args rpctypes.SendTxArgs) (common.
return common.Hash{}, err
}

txEncoder := authclient.GetTxEncoder(nil, authclient.WithEthereumTx())
var txEncoder sdk.TxEncoder
if tmtypes.HigherThanVenus(int64(height)) {
txEncoder = authclient.GetTxEncoder(nil, authclient.WithEthereumTx())
} else {
txEncoder = authclient.GetTxEncoder(api.clientCtx.Codec)
}

// Encode transaction by RLP encoder
txBytes, err := txEncoder(tx)
Expand All @@ -709,7 +718,7 @@ func (api *PublicEthereumAPI) SendTransaction(args rpctypes.SendTxArgs) (common.
}

// send chanData to txPool
if api.txPool != nil {
if tmtypes.HigherThanVenus(int64(height)) && api.txPool != nil {
return broadcastTxByTxPool(api, tx, txBytes)
}

Expand All @@ -732,6 +741,10 @@ func (api *PublicEthereumAPI) SendTransaction(args rpctypes.SendTxArgs) (common.
func (api *PublicEthereumAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
monitor := monitor.GetMonitor("eth_sendRawTransaction", api.logger, api.Metrics).OnBegin()
defer monitor.OnEnd("data", data)
height, err := api.BlockNumber()
if err != nil {
return common.Hash{}, err
}
tx := new(evmtypes.MsgEthereumTx)

// RLP decode raw transaction bytes
Expand All @@ -741,9 +754,15 @@ func (api *PublicEthereumAPI) SendRawTransaction(data hexutil.Bytes) (common.Has
}

txBytes := data
if !tmtypes.HigherThanVenus(int64(height)) {
txBytes, err = authclient.GetTxEncoder(api.clientCtx.Codec)(tx)
if err != nil {
return common.Hash{}, err
}
}

// send chanData to txPool
if api.txPool != nil {
if tmtypes.HigherThanVenus(int64(height)) && api.txPool != nil {
return broadcastTxByTxPool(api, tx, txBytes)
}

Expand Down
6 changes: 5 additions & 1 deletion app/rpc/namespaces/eth/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func (pool *TxPool) initDB(api *PublicEthereumAPI) error {
}

func broadcastTxByTxPool(api *PublicEthereumAPI, tx *evmtypes.MsgEthereumTx, txBytes []byte) (common.Hash, error) {
info, err := api.clientCtx.Client.BlockchainInfo(0, 0)
if err != nil {
return common.Hash{}, err
}
// Get sender address
chainIDEpoch, err := ethermint.ParseChainID(api.clientCtx.ChainID)
if err != nil {
Expand All @@ -139,7 +143,7 @@ func broadcastTxByTxPool(api *PublicEthereumAPI, tx *evmtypes.MsgEthereumTx, txB
return common.Hash{}, err
}

return common.BytesToHash(types.Tx(txBytes).Hash(api.clientCtx.Height)), nil
return common.BytesToHash(types.Tx(txBytes).Hash(info.LastHeight)), nil
}

func (pool *TxPool) CacheAndBroadcastTx(api *PublicEthereumAPI, address common.Address, tx *evmtypes.MsgEthereumTx) error {
Expand Down
2 changes: 1 addition & 1 deletion libs/cosmos-sdk/baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc
// will contain releveant error information. Regardless of tx execution outcome,
// the ResponseCheckTx will contain relevant gas execution context.
func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
tx, err := app.txDecoder(req.Tx)
tx, err := app.txDecoder(req.Tx, app.Info(abci.RequestInfo{}).LastBlockHeight)
if err != nil {
return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace)
}
Expand Down
2 changes: 1 addition & 1 deletion libs/cosmos-sdk/baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ func (msg msgCounter2) ValidateBasic() error {

// amino decode
func testTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
return func(txBytes []byte, _ ...int64) (sdk.Tx, error) {
var tx txTest
if len(txBytes) == 0 {
return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty")
Expand Down
2 changes: 1 addition & 1 deletion libs/cosmos-sdk/server/mock/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (tx kvstoreTx) GetTxFnSignatureInfo() ([]byte, int) {

// takes raw transaction bytes and decodes them into an sdk.Tx. An sdk.Tx has
// all the signatures and can be used to authenticate.
func decodeTx(txBytes []byte) (sdk.Tx, error) {
func decodeTx(txBytes []byte, _ ...int64) (sdk.Tx, error) {
var tx sdk.Tx

split := bytes.Split(txBytes, []byte("="))
Expand Down
5 changes: 4 additions & 1 deletion libs/cosmos-sdk/server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
sdk "github.com/okex/exchain/libs/cosmos-sdk/types"
"github.com/okex/exchain/libs/system"
"github.com/okex/exchain/libs/tendermint/global"
"github.com/okex/exchain/libs/tendermint/libs/log"
"os"
"runtime/pprof"
Expand Down Expand Up @@ -296,6 +297,8 @@ func startInProcess(ctx *Context, cdc *codec.Codec, appCreator AppCreator, appSt
return nil, err
}

global.SetGlobalHeight(tmNode.ConsensusState().Height)

app.SetOption(abci.RequestSetOption{
Key: "CheckChainID",
Value: tmNode.ConsensusState().GetState().ChainID,
Expand All @@ -304,7 +307,7 @@ func startInProcess(ctx *Context, cdc *codec.Codec, appCreator AppCreator, appSt
ctx.Logger.Info("startInProcess",
"ConsensusStateChainID", tmNode.ConsensusState().GetState().ChainID,
"GenesisDocChainID", tmNode.GenesisDoc().ChainID,
)
)
if err := tmNode.Start(); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion libs/cosmos-sdk/types/tx_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type Tx interface {
//__________________________________________________________

// TxDecoder unmarshals transaction bytes
type TxDecoder func(txBytes []byte) (Tx, error)
type TxDecoder func(txBytes []byte, height ...int64) (Tx, error)

// TxEncoder marshals transaction to bytes
type TxEncoder func(tx Tx) ([]byte, error)
Expand Down
5 changes: 4 additions & 1 deletion libs/cosmos-sdk/x/auth/types/stdtx.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,10 @@ type StdSignature struct {

// DefaultTxDecoder logic for standard transaction decoding
func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
return func(txBytes []byte, heights ...int64) (sdk.Tx, error) {
if len(heights) > 0 {
return nil, fmt.Errorf("too many height parameters")
}
var tx = StdTx{}

if len(txBytes) == 0 {
Expand Down
15 changes: 15 additions & 0 deletions libs/tendermint/global/height.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package global

import "sync/atomic"

var lastCommittedHeight int64

// SetGlobalHeight sets lastCommittedHeight safely.
func SetGlobalHeight(height int64) {
atomic.StoreInt64(&lastCommittedHeight, height)
}

// GetGlobalHeight gets lastCommittedHeight safely.
func GetGlobalHeight() int64 {
return atomic.LoadInt64(&lastCommittedHeight)
}
33 changes: 17 additions & 16 deletions libs/tendermint/state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package state

import (
"fmt"
"github.com/okex/exchain/libs/tendermint/global"
"github.com/okex/exchain/libs/tendermint/libs/automation"
"time"

Expand Down Expand Up @@ -38,7 +39,7 @@ type BlockExecutor struct {
mempool mempl.Mempool
evpool EvidencePool

logger log.Logger
logger log.Logger
metrics *Metrics
isAsync bool

Expand All @@ -50,7 +51,6 @@ type BlockExecutor struct {
isFastSync bool
}


type BlockExecutorOption func(executor *BlockExecutor)

func BlockExecutorWithMetrics(metrics *Metrics) BlockExecutorOption {
Expand All @@ -70,16 +70,16 @@ func NewBlockExecutor(
options ...BlockExecutorOption,
) *BlockExecutor {
res := &BlockExecutor{
db: db,
proxyApp: proxyApp,
eventBus: types.NopEventBus{},
mempool: mempool,
evpool: evpool,
logger: logger,
metrics: NopMetrics(),
isAsync: viper.GetBool(FlagParalleledTx),
prerunCtx: newPrerunContex(logger),
deltaContext: newDeltaContext(logger),
db: db,
proxyApp: proxyApp,
eventBus: types.NopEventBus{},
mempool: mempool,
evpool: evpool,
logger: logger,
metrics: NopMetrics(),
isAsync: viper.GetBool(FlagParalleledTx),
prerunCtx: newPrerunContex(logger),
deltaContext: newDeltaContext(logger),
}

for _, option := range options {
Expand Down Expand Up @@ -235,6 +235,7 @@ func (blockExec *BlockExecutor) ApplyBlock(
if err != nil {
return state, 0, fmt.Errorf("commit failed for application: %v", err)
}
global.SetGlobalHeight(block.Height)

trc.Pin("evpool")
// Update evpool with the block and state.
Expand Down Expand Up @@ -298,6 +299,7 @@ func (blockExec *BlockExecutor) runAbci(block *types.Block, delta *types.Deltas)

return abciResponses, err
}

// Commit locks the mempool, runs the ABCI Commit message, and updates the
// mempool.
// It returns the result of calling abci.Commit (the AppHash) and the height to retain (if any).
Expand Down Expand Up @@ -664,9 +666,9 @@ func ExecCommitBlock(
) ([]byte, error) {

ctx := &executionTask{
logger: logger,
block: block,
db: stateDB,
logger: logger,
block: block,
db: stateDB,
proxyApp: appConnConsensus,
}

Expand All @@ -684,4 +686,3 @@ func ExecCommitBlock(
// ResponseCommit has no error or log, just data
return res.Data, nil
}

23 changes: 11 additions & 12 deletions libs/tendermint/types/milestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,26 @@ import (
// 3. BankTransferBlock

var (
MILESTONE_GENESIS_HEIGHT string
genesisHeight int64
MILESTONE_GENESIS_HEIGHT string
genesisHeight int64

MILESTONE_MERCURY_HEIGHT string
milestoneMercuryHeight int64
MILESTONE_MERCURY_HEIGHT string
milestoneMercuryHeight int64

MILESTONE_VENUS_HEIGHT string
milestoneVenusHeight int64
MILESTONE_VENUS_HEIGHT string
milestoneVenusHeight int64

once sync.Once
once sync.Once
)

func init() {
once.Do(func() {
genesisHeight = string2number(MILESTONE_GENESIS_HEIGHT)
genesisHeight = string2number(MILESTONE_GENESIS_HEIGHT)
milestoneMercuryHeight = string2number(MILESTONE_MERCURY_HEIGHT)
milestoneVenusHeight = string2number(MILESTONE_VENUS_HEIGHT)
milestoneVenusHeight = string2number(MILESTONE_VENUS_HEIGHT)
})
}


func string2number(input string) int64 {
if len(input) == 0 {
input = "0"
Expand All @@ -56,7 +55,7 @@ func HigherThanVenus(height int64) bool {
if milestoneVenusHeight == 0 {
return false
}
return height > milestoneVenusHeight
return height >= milestoneVenusHeight
}

// 2322600 is mainnet GenesisHeight
Expand All @@ -79,4 +78,4 @@ func GetVenusHeight() int64 {

func GetMercuryHeight() int64 {
return milestoneMercuryHeight
}
}
Loading

0 comments on commit 47920a4

Please sign in to comment.