-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(x/auth): v2 adaptable tx instead of double decode (#15910)
- Loading branch information
1 parent
1179285
commit 00b78fa
Showing
15 changed files
with
222 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package signing | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"google.golang.org/protobuf/types/known/anypb" | ||
|
||
txsigning "cosmossdk.io/x/tx/signing" | ||
codectypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/cosmos/cosmos-sdk/types/tx/signing" | ||
) | ||
|
||
// V2AdaptableTx is an interface that wraps the GetSigningTxData method. | ||
// GetSigningTxData returns an x/tx/signing.TxData representation of a transaction for use in signing | ||
// interoperability with x/tx. | ||
type V2AdaptableTx interface { | ||
GetSigningTxData() txsigning.TxData | ||
} | ||
|
||
// GetSignBytesAdapter returns the sign bytes for a given transaction and sign mode. It accepts the arguments expected | ||
// for signing in x/auth/tx and converts them to the arguments expected by the txsigning.HandlerMap, then applies | ||
// HandlerMap.GetSignBytes to get the sign bytes. | ||
func GetSignBytesAdapter( | ||
ctx context.Context, | ||
handlerMap *txsigning.HandlerMap, | ||
mode signing.SignMode, | ||
signerData SignerData, | ||
tx sdk.Tx, | ||
) ([]byte, error) { | ||
adaptableTx, ok := tx.(V2AdaptableTx) | ||
if !ok { | ||
return nil, fmt.Errorf("expected tx to be V2AdaptableTx, got %T", tx) | ||
} | ||
txData := adaptableTx.GetSigningTxData() | ||
|
||
txSignMode, err := internalSignModeToAPI(mode) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
anyPk, err := codectypes.NewAnyWithValue(signerData.PubKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
txSignerData := txsigning.SignerData{ | ||
ChainID: signerData.ChainID, | ||
AccountNumber: signerData.AccountNumber, | ||
Sequence: signerData.Sequence, | ||
Address: signerData.Address, | ||
PubKey: &anypb.Any{ | ||
TypeUrl: anyPk.TypeUrl, | ||
Value: anyPk.Value, | ||
}, | ||
} | ||
// Generate the bytes to be signed. | ||
return handlerMap.GetSignBytes(ctx, txSignMode, txSignerData, txData) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package tx | ||
|
||
import ( | ||
"google.golang.org/protobuf/types/known/anypb" | ||
|
||
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" | ||
multisigv1beta1 "cosmossdk.io/api/cosmos/crypto/multisig/v1beta1" | ||
signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" | ||
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1" | ||
txsigning "cosmossdk.io/x/tx/signing" | ||
"github.com/cosmos/cosmos-sdk/types/tx" | ||
) | ||
|
||
// GetSigningTxData returns an x/tx/signing.TxData representation of a transaction for use in the signing | ||
// API defined in x/tx. | ||
func (w *wrapper) GetSigningTxData() txsigning.TxData { | ||
body := w.tx.Body | ||
authInfo := w.tx.AuthInfo | ||
|
||
msgs := make([]*anypb.Any, len(body.Messages)) | ||
for i, msg := range body.Messages { | ||
msgs[i] = &anypb.Any{ | ||
TypeUrl: msg.TypeUrl, | ||
Value: msg.Value, | ||
} | ||
} | ||
|
||
extOptions := make([]*anypb.Any, len(body.ExtensionOptions)) | ||
for i, extOption := range body.ExtensionOptions { | ||
extOptions[i] = &anypb.Any{ | ||
TypeUrl: extOption.TypeUrl, | ||
Value: extOption.Value, | ||
} | ||
} | ||
|
||
nonCriticalExtOptions := make([]*anypb.Any, len(body.NonCriticalExtensionOptions)) | ||
for i, extOption := range body.NonCriticalExtensionOptions { | ||
nonCriticalExtOptions[i] = &anypb.Any{ | ||
TypeUrl: extOption.TypeUrl, | ||
Value: extOption.Value, | ||
} | ||
} | ||
|
||
feeCoins := authInfo.Fee.Amount | ||
feeAmount := make([]*basev1beta1.Coin, len(feeCoins)) | ||
for i, coin := range feeCoins { | ||
feeAmount[i] = &basev1beta1.Coin{ | ||
Denom: coin.Denom, | ||
Amount: coin.Amount.String(), | ||
} | ||
} | ||
|
||
var txTip *txv1beta1.Tip | ||
tip := authInfo.Tip | ||
if tip != nil { | ||
tipCoins := tip.GetAmount() | ||
tipAmount := make([]*basev1beta1.Coin, len(tipCoins)) | ||
for i, coin := range tipCoins { | ||
tipAmount[i] = &basev1beta1.Coin{ | ||
Denom: coin.Denom, | ||
Amount: coin.Amount.String(), | ||
} | ||
} | ||
txTip = &txv1beta1.Tip{ | ||
Amount: tipAmount, | ||
Tipper: tip.Tipper, | ||
} | ||
} | ||
|
||
txSignerInfos := make([]*txv1beta1.SignerInfo, len(authInfo.SignerInfos)) | ||
for i, signerInfo := range authInfo.SignerInfos { | ||
modeInfo := &txv1beta1.ModeInfo{} | ||
adaptModeInfo(signerInfo.ModeInfo, modeInfo) | ||
txSignerInfo := &txv1beta1.SignerInfo{ | ||
PublicKey: &anypb.Any{ | ||
TypeUrl: signerInfo.PublicKey.TypeUrl, | ||
Value: signerInfo.PublicKey.Value, | ||
}, | ||
Sequence: signerInfo.Sequence, | ||
ModeInfo: modeInfo, | ||
} | ||
txSignerInfos[i] = txSignerInfo | ||
} | ||
|
||
txAuthInfo := &txv1beta1.AuthInfo{ | ||
SignerInfos: txSignerInfos, | ||
Fee: &txv1beta1.Fee{ | ||
Amount: feeAmount, | ||
GasLimit: authInfo.Fee.GasLimit, | ||
Payer: authInfo.Fee.Payer, | ||
Granter: authInfo.Fee.Granter, | ||
}, | ||
Tip: txTip, | ||
} | ||
|
||
txBody := &txv1beta1.TxBody{ | ||
Messages: msgs, | ||
Memo: body.Memo, | ||
TimeoutHeight: body.TimeoutHeight, | ||
ExtensionOptions: extOptions, | ||
NonCriticalExtensionOptions: nonCriticalExtOptions, | ||
} | ||
txData := txsigning.TxData{ | ||
AuthInfo: txAuthInfo, | ||
AuthInfoBytes: w.getAuthInfoBytes(), | ||
Body: txBody, | ||
BodyBytes: w.getBodyBytes(), | ||
} | ||
return txData | ||
} | ||
|
||
func adaptModeInfo(legacy *tx.ModeInfo, res *txv1beta1.ModeInfo) { | ||
// handle nil modeInfo. this is permissible through the code path: | ||
// https://github.com/cosmos/cosmos-sdk/blob/4a6a1e3cb8de459891cb0495052589673d14ef51/x/auth/tx/builder.go#L295 | ||
// -> https://github.com/cosmos/cosmos-sdk/blob/b7841e3a76a38d069c1b9cb3d48368f7a67e9c26/x/auth/tx/sigs.go#L15-L17 | ||
// when signature.Data is nil. | ||
if legacy == nil { | ||
return | ||
} | ||
|
||
switch mi := legacy.Sum.(type) { | ||
case *tx.ModeInfo_Single_: | ||
res.Sum = &txv1beta1.ModeInfo_Single_{ | ||
Single: &txv1beta1.ModeInfo_Single{ | ||
Mode: signingv1beta1.SignMode(legacy.GetSingle().Mode), | ||
}, | ||
} | ||
case *tx.ModeInfo_Multi_: | ||
multiModeInfos := legacy.GetMulti().ModeInfos | ||
modeInfos := make([]*txv1beta1.ModeInfo, len(multiModeInfos)) | ||
for _, modeInfo := range multiModeInfos { | ||
adaptModeInfo(modeInfo, &txv1beta1.ModeInfo{}) | ||
} | ||
res.Sum = &txv1beta1.ModeInfo_Multi_{ | ||
Multi: &txv1beta1.ModeInfo_Multi{ | ||
Bitarray: &multisigv1beta1.CompactBitArray{ | ||
Elems: mi.Multi.Bitarray.Elems, | ||
ExtraBitsStored: mi.Multi.Bitarray.ExtraBitsStored, | ||
}, | ||
ModeInfos: modeInfos, | ||
}, | ||
} | ||
} | ||
} |
Oops, something went wrong.