Skip to content
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

release: prepare for release v0.2.1-alpha.1 #209

Merged
merged 3 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v0.2.1-alpha.1
This release enable the support of multiple messages for EIP712.

* [\#205](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/205) feat: support multiple messages for EIP712
* [\#206](https://github.com/bnb-chain/greenfield-cosmos-sdk/pull/206) fix: fix potential panic in tx simulation

## v0.2.1
This release is a hot fix release for v0.2.0.

Expand Down
386 changes: 222 additions & 164 deletions api/cosmos/tx/v1beta1/tx.pulsar.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/tx/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type Factory struct {
func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, error) {
signModeStr := clientCtx.SignModeStr

signMode := signing.SignMode_SIGN_MODE_UNSPECIFIED
signMode := signing.SignMode_SIGN_MODE_EIP_712
switch signModeStr {
case flags.SignModeDirect:
signMode = signing.SignMode_SIGN_MODE_DIRECT
Expand Down
5 changes: 5 additions & 0 deletions client/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func Paginate(numObjs, page, limit, defLimit int) (start, end int) {
start = (page - 1) * limit
end = limit + start

if end < start {
// check if this produces negative numbers, resulting in end < start
return -1, -1
}

if end >= numObjs {
end = numObjs
}
Expand Down
5 changes: 2 additions & 3 deletions proto/cosmos/tx/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ message SignDocDirectAux {
Tip tip = 6;
}

// SignDocEIP712 is the type used for generating sign bytes for
// SIGN_MODE_EIP_712.
// SignDocEIP712 is the type used for generating sign bytes for SIGN_MODE_EIP_712.
message SignDocEip712 {
// chain_id is the identifier of the chain this transaction targets.
// It prevents signed transactions from being used on another chain by an
Expand All @@ -117,7 +116,7 @@ message SignDocEip712 {
Fee fee = 4 [(gogoproto.nullable) = false];

// msg is the msg in the EIP712 transaction.
google.protobuf.Any msg = 5;
repeated google.protobuf.Any msgs = 5;

// timeout_height is the transaction's timeout height (if set).
uint64 timeout_height = 6 [(gogoproto.jsontag) = "timeout_height"];
Expand Down
189 changes: 95 additions & 94 deletions types/tx/tx.pb.go

Large diffs are not rendered by default.

166 changes: 93 additions & 73 deletions x/auth/tx/eip712.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ func GetMsgTypes(signerData signing.SignerData, tx sdk.Tx, typedChainID *big.Int
}

// construct the signDoc
msgAny, _ := codectypes.NewAnyWithValue(protoTx.GetMsgs()[0])
msgAnys := make([]*codectypes.Any, 0, len(protoTx.GetMsgs()))
for _, msg := range protoTx.GetMsgs() {
msgAny, _ := codectypes.NewAnyWithValue(msg)
msgAnys = append(msgAnys, msgAny)
}
signDoc := &types.SignDocEip712{
AccountNumber: signerData.AccountNumber,
Sequence: signerData.Sequence,
Expand All @@ -106,27 +110,71 @@ func GetMsgTypes(signerData signing.SignerData, tx sdk.Tx, typedChainID *big.Int
},
Memo: protoTx.GetMemo(),
Tip: protoTx.GetTip(),
Msg: msgAny,
Msgs: msgAnys,
}

// extract the msg types
msgTypes, err := extractMsgTypes(protoTx.GetMsgs()[0])
if err != nil {
return nil, nil, err
}

// patch the msg types to include `Tip` if it's not empty
if signDoc.Tip != nil {
msgTypes["Tx"] = []apitypes.Type{
msgTypes := apitypes.Types{
"EIP712Domain": {
{
Name: "name",
Type: "string",
},
{
Name: "version",
Type: "string",
},
{
Name: "chainId",
Type: "uint256",
},
{
Name: "verifyingContract",
Type: "string",
},
{
Name: "salt",
Type: "string",
},
},
"Tx": {
{Name: "account_number", Type: "uint256"},
{Name: "chain_id", Type: "uint256"},
{Name: "fee", Type: "Fee"},
{Name: "memo", Type: "string"},
{Name: "msg", Type: "Msg"},
{Name: "sequence", Type: "uint256"},
{Name: "timeout_height", Type: "uint256"},
{Name: "tip", Type: "Tip"},
},
"Fee": {
{Name: "amount", Type: "Coin[]"},
{Name: "gas_limit", Type: "uint256"},
{Name: "payer", Type: "string"},
{Name: "granter", Type: "string"},
},
"Coin": {
{Name: "denom", Type: "string"},
{Name: "amount", Type: "uint256"},
},
}
for i, msg := range protoTx.GetMsgs() {
tmpMsgTypes, err := extractMsgTypes(msg, i+1)
if err != nil {
return nil, nil, err
}

msgTypes["Tx"] = append(msgTypes["Tx"], apitypes.Type{
Name: fmt.Sprintf("msg%d", i+1),
Type: fmt.Sprintf("Msg%d", i+1),
})

for key, field := range tmpMsgTypes {
msgTypes[key] = field
}
}

// patch the msg types to include `Tip` if it's not empty
if signDoc.Tip != nil {
msgTypes["Tx"] = append(msgTypes["Tx"], apitypes.Type{Name: "tip", Type: "Tip"})
msgTypes["Tip"] = []apitypes.Type{
{Name: "amount", Type: "Coin[]"},
{Name: "tipper", Type: "string"},
Expand Down Expand Up @@ -177,8 +225,13 @@ func WrapTxToTypedData(
delete(txData, "tip")
}

// filling nil value and do other clean up
cleanTypesAndMsgValue(msgTypes, "Msg", txData["msg"].(map[string]interface{}))
// filling nil value and do the other clean up
msgData := txData["msgs"].([]interface{})
for i := range signDoc.GetMsgs() {
txData[fmt.Sprintf("msg%d", i+1)] = msgData[i]
cleanTypesAndMsgValue(msgTypes, fmt.Sprintf("Msg%d", i+1), msgData[i].(map[string]interface{}))
}
delete(txData, "msgs")

tempDomain := *domain
tempDomain.ChainId = math.NewHexOrDecimal256(int64(chainID))
Expand All @@ -192,55 +245,14 @@ func WrapTxToTypedData(
return typedData, nil
}

func extractMsgTypes(msg sdk.Msg) (apitypes.Types, error) {
func extractMsgTypes(msg sdk.Msg, index int) (apitypes.Types, error) {
rootTypes := apitypes.Types{
"EIP712Domain": {
{
Name: "name",
Type: "string",
},
{
Name: "version",
Type: "string",
},
{
Name: "chainId",
Type: "uint256",
},
{
Name: "verifyingContract",
Type: "string",
},
{
Name: "salt",
Type: "string",
},
},
"Tx": {
{Name: "account_number", Type: "uint256"},
{Name: "chain_id", Type: "uint256"},
{Name: "fee", Type: "Fee"},
{Name: "memo", Type: "string"},
{Name: "msg", Type: "Msg"},
{Name: "sequence", Type: "uint256"},
{Name: "timeout_height", Type: "uint256"},
},
"Fee": {
{Name: "amount", Type: "Coin[]"},
{Name: "gas_limit", Type: "uint256"},
{Name: "payer", Type: "string"},
{Name: "granter", Type: "string"},
},
"Coin": {
{Name: "denom", Type: "string"},
{Name: "amount", Type: "uint256"},
},
"Msg": {
fmt.Sprintf("Msg%d", index): {
{Name: "type", Type: "string"},
},
}

if err := walkFields(rootTypes, msg); err != nil {
if err := walkFields(rootTypes, msg, index); err != nil {
return nil, err
}

Expand All @@ -249,7 +261,7 @@ func extractMsgTypes(msg sdk.Msg) (apitypes.Types, error) {

const typeDefPrefix = "_"

func walkFields(typeMap apitypes.Types, in interface{}) (err error) {
func walkFields(typeMap apitypes.Types, in interface{}, index int) (err error) {
defer doRecover(&err)

t := reflect.TypeOf(in)
Expand All @@ -267,7 +279,7 @@ func walkFields(typeMap apitypes.Types, in interface{}) (err error) {
break
}

return traverseFields(typeMap, typeDefPrefix, t, v)
return traverseFields(typeMap, typeDefPrefix, index, t, v)
}

type anyWrapper struct {
Expand All @@ -278,6 +290,7 @@ type anyWrapper struct {
func traverseFields(
typeMap apitypes.Types,
prefix string,
index int,
t reflect.Type,
v reflect.Value,
) error {
Expand Down Expand Up @@ -349,12 +362,13 @@ func traverseFields(
}

if prefix == typeDefPrefix {
typeMap["Msg"] = append(typeMap["Msg"], apitypes.Type{
tag := fmt.Sprintf("Msg%d", index)
typeMap[tag] = append(typeMap[tag], apitypes.Type{
Name: fieldName,
Type: ethTyp,
})
} else {
typeDef := sanitizeTypedef(prefix)
typeDef := sanitizeTypedef(prefix, index)
typeMap[typeDef] = append(typeMap[typeDef], apitypes.Type{
Name: fieldName,
Type: ethTyp,
Expand All @@ -368,25 +382,26 @@ func traverseFields(
var fieldTypedef string

if isCollection {
fieldTypedef = sanitizeTypedef(fieldPrefix) + "[]"
fieldTypedef = sanitizeTypedef(fieldPrefix, index) + "[]"
} else {
fieldTypedef = sanitizeTypedef(fieldPrefix)
fieldTypedef = sanitizeTypedef(fieldPrefix, index)
}

if prefix == typeDefPrefix {
typeMap["Msg"] = append(typeMap["Msg"], apitypes.Type{
tag := fmt.Sprintf("Msg%d", index)
typeMap[tag] = append(typeMap[tag], apitypes.Type{
Name: fieldName,
Type: fieldTypedef,
})
} else {
typeDef := sanitizeTypedef(prefix)
typeDef := sanitizeTypedef(prefix, index)
typeMap[typeDef] = append(typeMap[typeDef], apitypes.Type{
Name: fieldName,
Type: fieldTypedef,
})
}

if err := traverseFields(typeMap, fieldPrefix, fieldType, field); err != nil {
if err := traverseFields(typeMap, fieldPrefix, index, fieldType, field); err != nil {
return err
}
continue
Expand Down Expand Up @@ -443,17 +458,22 @@ func cleanTypesAndMsgValue(typedData apitypes.Types, primaryType string, msgValu
newValue["value"] = bz
newAnySet[i] = newValue
}
msgValue[encName] = newAnySet
msgValue[encName[:len(encName)-3]] = newAnySet
typedData[primaryType][i].Name = encName[:len(encName)-3]
typedData[primaryType][i].Type = "TypeAny[]"
delete(typedData, encType[:len(encType)-2])
} else {
anyValue := msgValue[encName[:len(encName)-3]].(map[string]interface{})
newValue := make(map[string]interface{})
bz, _ := json.Marshal(anyValue)
newValue["type"] = anyValue["@type"]
newValue["value"] = bz
msgValue[encName] = newValue
msgValue[encName[:len(encName)-3]] = newValue
typedData[primaryType][i].Name = encName[:len(encName)-3]
typedData[primaryType][i].Type = "TypeAny"
delete(typedData, encType)
}
typedData[encType] = anyApiTypes
delete(msgValue, encName[:len(encName)-3])
typedData["TypeAny"] = anyApiTypes
continue
}
encValue := msgValue[encName]
Expand Down Expand Up @@ -564,14 +584,14 @@ func unwrapField(fieldType reflect.Type, field reflect.Value, fieldName string)
//
// this is needed for Geth's own signing code which doesn't
// tolerate complex type names
func sanitizeTypedef(str string) string {
func sanitizeTypedef(str string, index int) string {
buf := new(bytes.Buffer)
parts := strings.Split(str, ".")
caser := cases.Title(language.English, cases.NoLower)

for _, part := range parts {
if part == "_" {
buf.WriteString("Type")
buf.WriteString(fmt.Sprintf("TypeMsg%d", index))
continue
}

Expand Down
Loading