Skip to content

Commit 5b78aef

Browse files
naveen-imtbholiman
andauthored
signer/core: extended support for EIP-712 array types (#30620)
This change updates the EIP-712 implementation to resolve [#30619](#30619). The test cases have been repurposed from the ethers.js [repository](https://github.com/ethers-io/ethers.js/blob/main/testcases/typed-data.json.gz), but have been updated to remove tests that don't have a valid domain separator; EIP-712 messages without a domain separator are not supported by geth. --------- Co-authored-by: Martin Holst Swende <[email protected]>
1 parent a6037d0 commit 5b78aef

File tree

4 files changed

+6272
-71
lines changed

4 files changed

+6272
-71
lines changed

signer/core/apitypes/signed_data_internal_test.go

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ package apitypes
1818

1919
import (
2020
"bytes"
21+
"encoding/json"
22+
"fmt"
2123
"math/big"
24+
"os"
2225
"testing"
2326

2427
"github.com/ethereum/go-ethereum/common"
2528
"github.com/ethereum/go-ethereum/common/hexutil"
2629
"github.com/ethereum/go-ethereum/common/math"
30+
"github.com/ethereum/go-ethereum/crypto"
31+
"github.com/stretchr/testify/assert"
32+
"github.com/stretchr/testify/require"
2733
)
2834

2935
func TestBytesPadding(t *testing.T) {
@@ -244,45 +250,42 @@ func TestConvertAddressDataToSlice(t *testing.T) {
244250
func TestTypedDataArrayValidate(t *testing.T) {
245251
t.Parallel()
246252

247-
typedData := TypedData{
248-
Types: Types{
249-
"BulkOrder": []Type{
250-
// Should be able to accept fixed size arrays
251-
{Name: "tree", Type: "OrderComponents[2][2]"},
252-
},
253-
"OrderComponents": []Type{
254-
{Name: "offerer", Type: "address"},
255-
{Name: "amount", Type: "uint8"},
256-
},
257-
"EIP712Domain": []Type{
258-
{Name: "name", Type: "string"},
259-
{Name: "version", Type: "string"},
260-
{Name: "chainId", Type: "uint8"},
261-
{Name: "verifyingContract", Type: "address"},
262-
},
263-
},
264-
PrimaryType: "BulkOrder",
265-
Domain: TypedDataDomain{
266-
VerifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
267-
},
268-
Message: TypedDataMessage{},
253+
type testDataInput struct {
254+
Name string `json:"name"`
255+
Domain TypedDataDomain `json:"domain"`
256+
PrimaryType string `json:"primaryType"`
257+
Types Types `json:"types"`
258+
Message TypedDataMessage `json:"data"`
259+
Digest string `json:"digest"`
269260
}
261+
fc, err := os.ReadFile("./testdata/typed-data.json")
262+
require.NoError(t, err, "error reading test data file")
270263

271-
if err := typedData.validate(); err != nil {
272-
t.Errorf("expected typed data to pass validation, got: %v", err)
273-
}
264+
var tests []testDataInput
265+
err = json.Unmarshal(fc, &tests)
266+
require.NoError(t, err, "error unmarshalling test data file contents")
274267

275-
// Should be able to accept dynamic arrays
276-
typedData.Types["BulkOrder"][0].Type = "OrderComponents[]"
268+
for _, tc := range tests {
269+
t.Run(tc.Name, func(t *testing.T) {
270+
t.Parallel()
277271

278-
if err := typedData.validate(); err != nil {
279-
t.Errorf("expected typed data to pass validation, got: %v", err)
280-
}
272+
td := TypedData{
273+
Types: tc.Types,
274+
PrimaryType: tc.PrimaryType,
275+
Domain: tc.Domain,
276+
Message: tc.Message,
277+
}
278+
279+
domainSeparator, tErr := td.HashStruct("EIP712Domain", td.Domain.Map())
280+
assert.NoError(t, tErr, "failed to hash domain separator: %v", tErr)
281+
282+
messageHash, tErr := td.HashStruct(td.PrimaryType, td.Message)
283+
assert.NoError(t, tErr, "failed to hash message: %v", tErr)
281284

282-
// Should be able to accept standard types
283-
typedData.Types["BulkOrder"][0].Type = "OrderComponents"
285+
digest := crypto.Keccak256Hash([]byte(fmt.Sprintf("%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash))))
286+
assert.Equal(t, tc.Digest, digest.String(), "digest doesn't not match")
284287

285-
if err := typedData.validate(); err != nil {
286-
t.Errorf("expected typed data to pass validation, got: %v", err)
288+
assert.NoError(t, td.validate(), "validation failed", tErr)
289+
})
287290
}
288291
}

0 commit comments

Comments
 (0)