-
Notifications
You must be signed in to change notification settings - Fork 10
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
[WIP]feat: introduce 2-phases aggregation #318
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -32,7 +32,7 @@ func (mpd MinGasPriceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate | |||||||||
return ctx, errorsmod.Wrapf(errortypes.ErrInvalidType, "invalid transaction type %T, expected sdk.FeeTx", tx) | ||||||||||
} | ||||||||||
|
||||||||||
if anteutils.IsOracleCreatePriceTx(tx) { | ||||||||||
if _, ok, _ := anteutils.OracleCreatePriceTx(tx); ok { | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Handle potential error from OracleCreatePriceTx Similar to the change in context.go, the function call has been updated to use Properly handle the error instead of ignoring it: - if _, ok, _ := anteutils.OracleCreatePriceTx(tx); ok {
+ if _, ok, err := anteutils.OracleCreatePriceTx(tx); err != nil {
+ return ctx, errorsmod.Wrapf(errortypes.ErrInvalidTxType, "failed to check oracle tx: %s", err.Error())
+ } else if ok { This will improve error reporting and debugging in case the oracle transaction parsing fails. 📝 Committable suggestion
Suggested change
|
||||||||||
return next(ctx, tx, simulate) | ||||||||||
} | ||||||||||
|
||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package cosmos | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/imua-xyz/imuachain/app/ante/utils" | ||
) | ||
|
||
type OracleTwoPhasesDecorator struct { | ||
ok utils.OracleKeeper | ||
} | ||
|
||
func NewOracleTwoPhasesDecorator(oracleKeeper utils.OracleKeeper) OracleTwoPhasesDecorator { | ||
return OracleTwoPhasesDecorator{ | ||
ok: oracleKeeper, | ||
} | ||
} | ||
|
||
func (otpd OracleTwoPhasesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { | ||
msgs, _, isRawData := utils.OracleCreatePriceTx(tx) | ||
if isRawData { | ||
pieceWithProof, ok := otpd.ok.GetPieceWithProof(msgs[0]) | ||
// valid failed when getting pieceWithProof | ||
if !ok { | ||
return ctx, errors.New("failed to valid and get pieceWithProof with a tx with oracle rawData") | ||
} | ||
proofPath := otpd.ok.MinimalProofPathByIndex(msgs[0].FeederID, uint32(pieceWithProof.Index)) | ||
if len(proofPath) != int(pieceWithProof.ProofSize()) { | ||
return ctx, fmt.Errorf("rawData proofPath size not match, expected:%d, got:%d", len(proofPath), pieceWithProof.ProofSize()) | ||
} | ||
// the proofPath need to be exactly the same of both value and order | ||
for i, index := range proofPath { | ||
if pieceWithProof.Proof[i].Index != index { | ||
return ctx, fmt.Errorf("rawData proofPath didn't include necessary index on position:%d of path:%d", i, index) | ||
} | ||
} | ||
} | ||
|
||
return next(ctx, tx, simulate) | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -38,9 +38,12 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim | |||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Skip gas consumption if tx is an OracleCreatePriceTx | ||||||||||||||||||||||||||||||||||||
if anteutils.IsOracleCreatePriceTx(tx) { | ||||||||||||||||||||||||||||||||||||
if len(ctx.TxBytes()) > anteutils.TxSizeLimit { | ||||||||||||||||||||||||||||||||||||
return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx has exceeds size limit, limit:%d, got:%d", anteutils.TxSizeLimit, len(ctx.TxBytes())) | ||||||||||||||||||||||||||||||||||||
if _, isOracle, isRawData := anteutils.OracleCreatePriceTx(tx); isOracle { | ||||||||||||||||||||||||||||||||||||
if isRawData && len(ctx.TxBytes()) > anteutils.TxSizeLimitOracleRawData { | ||||||||||||||||||||||||||||||||||||
return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx exceeds size limit, limit:%d, got:%d", anteutils.TxSizeLimitOracleRawData, len(ctx.TxBytes())) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
if len(ctx.TxBytes()) > anteutils.TxSizeLimitOraclePrice { | ||||||||||||||||||||||||||||||||||||
return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx with rawdata exceeds size limit, limit:%d, got:%d", anteutils.TxSizeLimitOraclePrice, len(ctx.TxBytes())) | ||||||||||||||||||||||||||||||||||||
Comment on lines
+41
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix non-exclusive condition checks and clarify error messages. The current logic always checks the raw-data size limit first, then the general oracle limit, regardless of whether if _, isOracle, isRawData := anteutils.OracleCreatePriceTx(tx); isOracle {
- if isRawData && len(ctx.TxBytes()) > anteutils.TxSizeLimitOracleRawData {
- return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx exceeds size limit, limit:%d, got:%d", anteutils.TxSizeLimitOracleRawData, len(ctx.TxBytes()))
- }
- if len(ctx.TxBytes()) > anteutils.TxSizeLimitOraclePrice {
- return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx with rawdata exceeds size limit, limit:%d, got:%d", anteutils.TxSizeLimitOraclePrice, len(ctx.TxBytes()))
- }
+ if isRawData {
+ if len(ctx.TxBytes()) > anteutils.TxSizeLimitOracleRawData {
+ return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx with raw data exceeds limit, limit:%d, got:%d", anteutils.TxSizeLimitOracleRawData, len(ctx.TxBytes()))
+ }
+ } else {
+ if len(ctx.TxBytes()) > anteutils.TxSizeLimitOraclePrice {
+ return ctx, sdkerrors.ErrTxTooLarge.Wrapf("oracle create-price tx exceeds limit, limit:%d, got:%d", anteutils.TxSizeLimitOraclePrice, len(ctx.TxBytes()))
+ }
+ }
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return next(ctx, tx, simulate) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -30,7 +30,7 @@ func NewGasWantedDecorator( | |||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
func (gwd GasWantedDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { | ||||||||||||||||||
if anteutils.IsOracleCreatePriceTx(tx) { | ||||||||||||||||||
if _, ok, _ := anteutils.OracleCreatePriceTx(tx); ok { | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Document the new return values. The code now unpacks multiple return values from - if _, ok, _ := anteutils.OracleCreatePriceTx(tx); ok {
+ // OracleCreatePriceTx returns (rawDataIndicator, isOracleCreatePriceTx, error)
+ // We only need to check if it's an Oracle Create Price transaction
+ if _, ok, _ := anteutils.OracleCreatePriceTx(tx); ok { 📝 Committable suggestion
Suggested change
🛠️ Refactor suggestion Handle potential errors from OracleCreatePriceTx. The third return value (error) from - if _, ok, _ := anteutils.OracleCreatePriceTx(tx); ok {
+ if _, ok, err := anteutils.OracleCreatePriceTx(tx); err != nil {
+ return ctx, errorsmod.Wrapf(err, "failed to determine if transaction is Oracle Create Price tx")
+ } else if ok { 📝 Committable suggestion
Suggested change
|
||||||||||||||||||
return next(ctx, tx, simulate) | ||||||||||||||||||
} | ||||||||||||||||||
evmParams := gwd.evmKeeper.GetParams(ctx) | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,7 @@ func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler { | |
cosmosante.NewIncrementSequenceDecorator(options.AccountKeeper, options.OracleKeeper), | ||
ibcante.NewRedundantRelayDecorator(options.IBCKeeper), | ||
evmante.NewGasWantedDecorator(options.EvmKeeper, options.FeeMarketKeeper), | ||
cosmosante.NewOracleTwoPhasesDecorator(options.OracleKeeper), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent ❓ Verification inconclusiveAdded Oracle Two Phases decorator to ante handler chain The Please ensure that this decorator is tested with different transaction types to verify it only processes relevant oracle transactions and doesn't affect other transaction flows. 🏁 Script executed: #!/bin/bash
# Check for tests of the OracleTwoPhasesDecorator
rg -i "test.*OracleTwoPhasesDecorator" --type go Length of output: 50 Please re-run this script to check if test files are validating the behavior of the new Oracle Two Phases decorator. If no tests are found, it is recommended to add tests that verify the decorator only processes relevant oracle transactions and leaves other transaction flows unaffected. 🏁 Script executed: #!/bin/bash
# Search for any references to OracleTwoPhasesDecorator in Go test files to verify test coverage
rg -i "OracleTwoPhasesDecorator" --type go --glob "*_test.go" Length of output: 61 Decorator added correctly but missing test coverage for OracleTwoPhasesDecorator
|
||
) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,17 +6,32 @@ import ( | |
) | ||
|
||
// TxSizeLimit limits max size of a create-price tx, this is calculated based on one nativeTokenbalance message of worst case(max size), which will need 576 bytes for balance update | ||
const TxSizeLimit = 1000 | ||
// 48*1024+5*32+6*4 +... TODO(leonz): ensure the proto cost, now use a fixed 200B | ||
const ( | ||
TxSizeLimitOraclePrice = 49600 | ||
TxSizeLimitOracleRawData = 200 | ||
) | ||
Comment on lines
+9
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainConstants need finalization. The comment indicates that the proto cost calculation for 🏁 Script executed: #!/bin/bash
# Check for usages of these constants to understand potential impact
rg -A 2 "TxSizeLimitOraclePrice|TxSizeLimitOracleRawData" Length of output: 958 Finalize Proto Cost Calculation for Oracle Constants The constant
|
||
|
||
func IsOracleCreatePriceTx(tx sdk.Tx) bool { | ||
// TODO(leonz): return additional error info | ||
func OracleCreatePriceTx(tx sdk.Tx) (msgsO []*oracletypes.MsgCreatePrice, validOracle, validRawData bool) { | ||
msgs := tx.GetMsgs() | ||
if len(msgs) == 0 { | ||
return false | ||
return nil, false, false | ||
} | ||
msgsO = make([]*oracletypes.MsgCreatePrice, 0, len(msgs)) | ||
for _, msg := range msgs { | ||
if _, ok := msg.(*oracletypes.MsgCreatePrice); !ok { | ||
return false | ||
msgO, ok := msg.(*oracletypes.MsgCreatePrice) | ||
if !ok { | ||
return nil, false, false | ||
} | ||
if msgO.IsPhaseTwo() { | ||
if len(msgs) > 1 { | ||
return nil, false, false | ||
} | ||
msgsO = append(msgsO, msgO) | ||
return msgsO, true, true | ||
} | ||
msgsO = append(msgsO, msgO) | ||
} | ||
return true | ||
return msgsO, true, false | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,7 +105,6 @@ import ( | |
"github.com/cosmos/cosmos-sdk/store/streaming" | ||
storetypes "github.com/cosmos/cosmos-sdk/store/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/cosmos/cosmos-sdk/types/mempool" | ||
"github.com/cosmos/cosmos-sdk/types/module" | ||
"github.com/cosmos/cosmos-sdk/version" | ||
srvflags "github.com/evmos/evmos/v16/server/flags" | ||
|
@@ -354,7 +353,7 @@ type ImuachainApp struct { | |
OperatorKeeper operatorKeeper.Keeper | ||
ImSlashKeeper slashKeeper.Keeper | ||
AVSManagerKeeper avsManagerKeeper.Keeper | ||
OracleKeeper oracleKeeper.Keeper | ||
OracleKeeper *oracleKeeper.Keeper | ||
ImmintKeeper immintkeeper.Keeper | ||
DistrKeeper distrkeeper.Keeper | ||
|
||
|
@@ -394,10 +393,10 @@ func NewImuachainApp( | |
|
||
eip712.SetEncodingConfig(encodingConfig) | ||
|
||
var oKeeper *oracleKeeper.Keeper | ||
// Setup Mempool and Proposal Handlers | ||
baseAppOptions = append(baseAppOptions, func(app *baseapp.BaseApp) { | ||
// NOTE: we use a NoOpMempool here, for oracle create-price, it works fine since we have set a infinitgasmeterwithlimit in the ante handler to avoid the out-of-gas error no matter what the amount/gas is set by tx builder, and we set the highest priority for oracle create-price txs to work properly with tendermint mempool to make sure oracle creat-prie tx will be included in the mempool if received. And if we want to use some other application mempool, we need to take care of the gas limit and gas price in the oracle create-price txs.(we don't need to bother this since tendermint mempool use gasMeter.limit() instead of tx.Gas()) | ||
mempool := mempool.NoOpMempool{} | ||
mempool := NewImuaMempool(oKeeper, encodingConfig.TxConfig.TxDecoder()) | ||
app.SetMempool(mempool) | ||
Comment on lines
+396
to
400
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainPotential initialization issue with forward reference. The variable
This would make the code more robust and easier to follow. 🏁 Script executed: #!/bin/bash
# Check how oKeeper is used before its initialization
rg -n "oKeeper" app/app.go | sort -n Length of output: 186 Attention: Resolve Forward Initialization Issue with The variable Recommendations:
These adjustments will make the code more robust and easier to follow. |
||
handler := baseapp.NewDefaultProposalHandler(mempool, app) | ||
app.SetPrepareProposal(handler.PrepareProposalHandler()) | ||
|
@@ -462,6 +461,7 @@ func NewImuachainApp( | |
keys: keys, | ||
tkeys: tkeys, | ||
memKeys: memKeys, | ||
OracleKeeper: oKeeper, | ||
} | ||
|
||
// init params keeper and subspaces | ||
|
@@ -544,7 +544,7 @@ func NewImuachainApp( | |
|
||
// asset and client chain registry. | ||
app.AssetsKeeper = assetsKeeper.NewKeeper( | ||
keys[assetsTypes.StoreKey], appCodec, &app.OracleKeeper, app.AccountKeeper, | ||
keys[assetsTypes.StoreKey], appCodec, app.OracleKeeper, app.AccountKeeper, | ||
app.BankKeeper, &app.DelegationKeeper, authAddrString, | ||
) | ||
|
||
|
@@ -582,7 +582,7 @@ func NewImuachainApp( | |
) | ||
|
||
// x/oracle is not fully integrated (or enabled) but allows for exchange rates to be added. | ||
app.OracleKeeper = oracleKeeper.NewKeeper( | ||
*app.OracleKeeper = oracleKeeper.NewKeeper( | ||
appCodec, keys[oracleTypes.StoreKey], memKeys[oracleTypes.MemStoreKey], | ||
app.GetSubspace(oracleTypes.ModuleName), app.StakingKeeper, | ||
&app.DelegationKeeper, &app.AssetsKeeper, authAddrString, | ||
|
@@ -696,7 +696,7 @@ func NewImuachainApp( | |
keys[operatorTypes.StoreKey], appCodec, | ||
app.AssetsKeeper, | ||
&app.DelegationKeeper, // intentionally a pointer, since not yet initialized. | ||
&app.OracleKeeper, | ||
app.OracleKeeper, | ||
&app.AVSManagerKeeper, | ||
&app.StakingKeeper, | ||
delegationTypes.VirtualSlashKeeper{}, | ||
|
@@ -904,7 +904,7 @@ func NewImuachainApp( | |
reward.NewAppModule(appCodec, app.RewardKeeper), | ||
imslash.NewAppModule(appCodec, app.ImSlashKeeper), | ||
avs.NewAppModule(appCodec, app.AVSManagerKeeper), | ||
oracle.NewAppModule(appCodec, app.OracleKeeper, app.AccountKeeper, app.BankKeeper), | ||
oracle.NewAppModule(appCodec, *app.OracleKeeper, app.AccountKeeper, app.BankKeeper), | ||
distr.NewAppModule(appCodec, app.DistrKeeper), | ||
) | ||
|
||
|
@@ -1106,6 +1106,7 @@ func NewImuachainApp( | |
func (app *ImuachainApp) Name() string { return app.BaseApp.Name() } | ||
|
||
func (app *ImuachainApp) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64) { | ||
app.OracleKeeper.GetPieceWithProof(nil) | ||
options := ante.HandlerOptions{ | ||
Cdc: app.appCodec, | ||
AccountKeeper: app.AccountKeeper, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor OracleCreatePriceTx function call to properly handle the error
The function call has been updated to use
anteutils.OracleCreatePriceTx(tx)
which now returns multiple values including an error, but the error is being discarded with_
.Consider handling the error properly rather than ignoring it, especially since this code is part of the critical transaction handling path:
📝 Committable suggestion