signer/core: don't require capital lettered reference types (#26462)
This commit is contained in:
parent
50e65392aa
commit
4f4a25d79f
|
@ -27,8 +27,6 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
@ -38,7 +36,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Z](\w*)(\[\])?$`)
|
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\])?$`)
|
||||||
|
|
||||||
type ValidationInfo struct {
|
type ValidationInfo struct {
|
||||||
Typ string `json:"type"`
|
Typ string `json:"type"`
|
||||||
|
@ -224,15 +222,6 @@ func (t *Type) typeName() string {
|
||||||
return t.Type
|
return t.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) isReferenceType() bool {
|
|
||||||
if len(t.Type) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// Reference types must have a leading uppercase character
|
|
||||||
r, _ := utf8.DecodeRuneInString(t.Type)
|
|
||||||
return unicode.IsUpper(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Types map[string][]Type
|
type Types map[string][]Type
|
||||||
|
|
||||||
type TypePriority struct {
|
type TypePriority struct {
|
||||||
|
@ -731,16 +720,16 @@ func (t Types) validate() error {
|
||||||
if typeKey == typeObj.Type {
|
if typeKey == typeObj.Type {
|
||||||
return fmt.Errorf("type %q cannot reference itself", typeObj.Type)
|
return fmt.Errorf("type %q cannot reference itself", typeObj.Type)
|
||||||
}
|
}
|
||||||
if typeObj.isReferenceType() {
|
if isPrimitiveTypeValid(typeObj.Type) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Must be reference type
|
||||||
if _, exist := t[typeObj.typeName()]; !exist {
|
if _, exist := t[typeObj.typeName()]; !exist {
|
||||||
return fmt.Errorf("reference type %q is undefined", typeObj.Type)
|
return fmt.Errorf("reference type %q is undefined", typeObj.Type)
|
||||||
}
|
}
|
||||||
if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) {
|
if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) {
|
||||||
return fmt.Errorf("unknown reference type %q", typeObj.Type)
|
return fmt.Errorf("unknown reference type %q", typeObj.Type)
|
||||||
}
|
}
|
||||||
} else if !isPrimitiveTypeValid(typeObj.Type) {
|
|
||||||
return fmt.Errorf("unknown type %q", typeObj.Type)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -848,3 +848,153 @@ func TestGnosisSafe(t *testing.T) {
|
||||||
t.Fatal("expected equality")
|
t.Fatal("expected equality")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var complexTypedDataLCRefType = `
|
||||||
|
{
|
||||||
|
"types": {
|
||||||
|
"EIP712Domain": [
|
||||||
|
{
|
||||||
|
"name": "chainId",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "verifyingContract",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Action": [
|
||||||
|
{
|
||||||
|
"name": "action",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "params",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cCell": [
|
||||||
|
{
|
||||||
|
"name": "capacity",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lock",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "data",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "extraData",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Transaction": [
|
||||||
|
{
|
||||||
|
"name": "DAS_MESSAGE",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inputsCapacity",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "outputsCapacity",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fee",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "action",
|
||||||
|
"type": "Action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inputs",
|
||||||
|
"type": "cCell[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "outputs",
|
||||||
|
"type": "cCell[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "digest",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primaryType": "Transaction",
|
||||||
|
"domain": {
|
||||||
|
"chainId": "56",
|
||||||
|
"name": "da.systems",
|
||||||
|
"verifyingContract": "0x0000000000000000000000000000000020210722",
|
||||||
|
"version": "1"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"DAS_MESSAGE": "SELL mobcion.bit FOR 100000 CKB",
|
||||||
|
"inputsCapacity": "1216.9999 CKB",
|
||||||
|
"outputsCapacity": "1216.9998 CKB",
|
||||||
|
"fee": "0.0001 CKB",
|
||||||
|
"digest": "0x53a6c0f19ec281604607f5d6817e442082ad1882bef0df64d84d3810dae561eb",
|
||||||
|
"action": {
|
||||||
|
"action": "start_account_sale",
|
||||||
|
"params": "0x00"
|
||||||
|
},
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"capacity": "218 CKB",
|
||||||
|
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
|
||||||
|
"type": "account-cell-type,0x01,0x",
|
||||||
|
"data": "{ account: mobcion.bit, expired_at: 1670913958 }",
|
||||||
|
"extraData": "{ status: 0, records_hash: 0x55478d76900611eb079b22088081124ed6c8bae21a05dd1a0d197efcc7c114ce }"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"capacity": "218 CKB",
|
||||||
|
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
|
||||||
|
"type": "account-cell-type,0x01,0x",
|
||||||
|
"data": "{ account: mobcion.bit, expired_at: 1670913958 }",
|
||||||
|
"extraData": "{ status: 1, records_hash: 0x55478d76900611eb079b22088081124ed6c8bae21a05dd1a0d197efcc7c114ce }"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"capacity": "201 CKB",
|
||||||
|
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
|
||||||
|
"type": "account-sale-cell-type,0x01,0x",
|
||||||
|
"data": "0x1209460ef3cb5f1c68ed2c43a3e020eec2d9de6e...",
|
||||||
|
"extraData": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestComplexTypedDataWithLowercaseReftype(t *testing.T) {
|
||||||
|
var td apitypes.TypedData
|
||||||
|
err := json.Unmarshal([]byte(complexTypedDataLCRefType), &td)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unmarshalling failed '%v'", err)
|
||||||
|
}
|
||||||
|
_, sighash, err := sign(td)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
expSigHash := common.FromHex("0x49191f910874f0148597204d9076af128d4694a7c4b714f1ccff330b87207bff")
|
||||||
|
if !bytes.Equal(expSigHash, sighash) {
|
||||||
|
t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue