mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
CORE-2543 Investigate geth fork
This commit is contained in:
parent
9fd3f8a0dd
commit
c16b1a357b
6 changed files with 2551 additions and 6352 deletions
|
|
@ -734,7 +734,7 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
|
|||
"to": msg.To,
|
||||
}
|
||||
if len(msg.Data) > 0 {
|
||||
arg["input"] = hexutil.Bytes(msg.Data)
|
||||
arg["data"] = hexutil.Bytes(msg.Data)
|
||||
}
|
||||
if msg.Value != nil {
|
||||
arg["value"] = (*hexutil.Big)(msg.Value)
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
|
|||
"to": msg.To,
|
||||
}
|
||||
if len(msg.Data) > 0 {
|
||||
arg["input"] = hexutil.Bytes(msg.Data)
|
||||
arg["data"] = hexutil.Bytes(msg.Data)
|
||||
}
|
||||
if msg.Value != nil {
|
||||
arg["value"] = (*hexutil.Big)(msg.Value)
|
||||
|
|
|
|||
|
|
@ -250,31 +250,28 @@ func TestConvertAddressDataToSlice(t *testing.T) {
|
|||
func TestTypedDataArrayValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testDataInput struct {
|
||||
type TestDataInput struct {
|
||||
Name string `json:"name"`
|
||||
Domain TypedDataDomain `json:"domain"`
|
||||
PrimaryType string `json:"primaryType"`
|
||||
Types Types `json:"types"`
|
||||
Message TypedDataMessage `json:"data"`
|
||||
TypedData TypedData `json:"typedData"`
|
||||
DomainHash string `json:"domainHash"`
|
||||
MessageHash string `json:"messageHash"`
|
||||
Digest string `json:"digest"`
|
||||
}
|
||||
|
||||
fc, err := os.ReadFile("./testdata/typed-data.json")
|
||||
require.NoError(t, err, "error reading test data file")
|
||||
|
||||
var tests []testDataInput
|
||||
var tests []TestDataInput
|
||||
err = json.Unmarshal(fc, &tests)
|
||||
require.NoError(t, err, "error unmarshalling test data file contents")
|
||||
|
||||
for _, tc := range tests {
|
||||
for _, tt := range tests {
|
||||
tc := tt
|
||||
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
td := TypedData{
|
||||
Types: tc.Types,
|
||||
PrimaryType: tc.PrimaryType,
|
||||
Domain: tc.Domain,
|
||||
Message: tc.Message,
|
||||
}
|
||||
td := tc.TypedData
|
||||
|
||||
domainSeparator, tErr := td.HashStruct("EIP712Domain", td.Domain.Map())
|
||||
assert.NoError(t, tErr, "failed to hash domain separator: %v", tErr)
|
||||
|
|
@ -282,10 +279,13 @@ func TestTypedDataArrayValidate(t *testing.T) {
|
|||
messageHash, tErr := td.HashStruct(td.PrimaryType, td.Message)
|
||||
assert.NoError(t, tErr, "failed to hash message: %v", tErr)
|
||||
|
||||
digest := crypto.Keccak256Hash(fmt.Appendf(nil, "%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash)))
|
||||
assert.Equal(t, tc.Digest, digest.String(), "digest doesn't not match")
|
||||
digest := crypto.Keccak256Hash([]byte(fmt.Sprintf("%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash))))
|
||||
|
||||
assert.NoError(t, td.validate(), "validation failed", tErr)
|
||||
assert.Equal(t, tc.Digest, digest.String(), "digest doesn't not match")
|
||||
assert.Equal(t, tc.DomainHash, domainSeparator.String(), "domain separator hashes do not match")
|
||||
assert.Equal(t, tc.MessageHash, messageHash.String(), "message hashes do not match")
|
||||
|
||||
assert.NoError(t, td.validate(), "expected typed data to pass validation, got: %v", tErr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7922
signer/core/apitypes/testdata/typed-data.json
vendored
7922
signer/core/apitypes/testdata/typed-data.json
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -18,14 +18,12 @@ package apitypes
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -36,8 +34,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\d*\])*$`)
|
||||
|
|
@ -66,10 +62,10 @@ func (vs *ValidationMessages) Info(msg string) {
|
|||
vs.Messages = append(vs.Messages, ValidationInfo{INFO, msg})
|
||||
}
|
||||
|
||||
// GetWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present
|
||||
func (vs *ValidationMessages) GetWarnings() error {
|
||||
// getWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present
|
||||
func (v *ValidationMessages) GetWarnings() error {
|
||||
var messages []string
|
||||
for _, msg := range vs.Messages {
|
||||
for _, msg := range v.Messages {
|
||||
if msg.Typ == WARN || msg.Typ == CRIT {
|
||||
messages = append(messages, msg.Message)
|
||||
}
|
||||
|
|
@ -96,21 +92,12 @@ type SendTxArgs struct {
|
|||
// We accept "data" and "input" for backwards-compatibility reasons.
|
||||
// "input" is the newer name and should be preferred by clients.
|
||||
// Issue detail: https://github.com/ethereum/go-ethereum/issues/15628
|
||||
Data *hexutil.Bytes `json:"data,omitempty"`
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input,omitempty"`
|
||||
|
||||
// For non-legacy transactions
|
||||
AccessList *types.AccessList `json:"accessList,omitempty"`
|
||||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
|
||||
// For BlobTxType
|
||||
BlobFeeCap *hexutil.Big `json:"maxFeePerBlobGas,omitempty"`
|
||||
BlobHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
|
||||
|
||||
// For BlobTxType transactions with blob sidecar
|
||||
Blobs []kzg4844.Blob `json:"blobs,omitempty"`
|
||||
Commitments []kzg4844.Commitment `json:"commitments,omitempty"`
|
||||
Proofs []kzg4844.Proof `json:"proofs,omitempty"`
|
||||
}
|
||||
|
||||
func (args SendTxArgs) String() string {
|
||||
|
|
@ -121,56 +108,24 @@ func (args SendTxArgs) String() string {
|
|||
return err.Error()
|
||||
}
|
||||
|
||||
// data retrieves the transaction calldata. Input field is preferred.
|
||||
func (args *SendTxArgs) data() []byte {
|
||||
if args.Input != nil {
|
||||
return *args.Input
|
||||
}
|
||||
if args.Data != nil {
|
||||
return *args.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToTransaction converts the arguments to a transaction.
|
||||
func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) {
|
||||
func (args *SendTxArgs) ToTransaction() *types.Transaction {
|
||||
// Add the To-field, if specified
|
||||
var to *common.Address
|
||||
if args.To != nil {
|
||||
dstAddr := args.To.Address()
|
||||
to = &dstAddr
|
||||
}
|
||||
if err := args.validateTxSidecar(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data types.TxData
|
||||
switch {
|
||||
case args.BlobHashes != nil:
|
||||
al := types.AccessList{}
|
||||
if args.AccessList != nil {
|
||||
al = *args.AccessList
|
||||
}
|
||||
data = &types.BlobTx{
|
||||
To: *to,
|
||||
ChainID: uint256.MustFromBig((*big.Int)(args.ChainID)),
|
||||
Nonce: uint64(args.Nonce),
|
||||
Gas: uint64(args.Gas),
|
||||
GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)),
|
||||
GasTipCap: uint256.MustFromBig((*big.Int)(args.MaxPriorityFeePerGas)),
|
||||
Value: uint256.MustFromBig((*big.Int)(&args.Value)),
|
||||
Data: args.data(),
|
||||
AccessList: al,
|
||||
BlobHashes: args.BlobHashes,
|
||||
BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)),
|
||||
}
|
||||
if args.Blobs != nil {
|
||||
data.(*types.BlobTx).Sidecar = &types.BlobTxSidecar{
|
||||
Blobs: args.Blobs,
|
||||
Commitments: args.Commitments,
|
||||
Proofs: args.Proofs,
|
||||
}
|
||||
|
||||
var input []byte
|
||||
if args.Input != nil {
|
||||
input = *args.Input
|
||||
} else if args.Data != nil {
|
||||
input = *args.Data
|
||||
}
|
||||
|
||||
var data types.TxData
|
||||
switch {
|
||||
case args.MaxFeePerGas != nil:
|
||||
al := types.AccessList{}
|
||||
if args.AccessList != nil {
|
||||
|
|
@ -184,7 +139,7 @@ func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) {
|
|||
GasFeeCap: (*big.Int)(args.MaxFeePerGas),
|
||||
GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas),
|
||||
Value: (*big.Int)(&args.Value),
|
||||
Data: args.data(),
|
||||
Data: input,
|
||||
AccessList: al,
|
||||
}
|
||||
case args.AccessList != nil:
|
||||
|
|
@ -195,7 +150,7 @@ func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) {
|
|||
Gas: uint64(args.Gas),
|
||||
GasPrice: (*big.Int)(args.GasPrice),
|
||||
Value: (*big.Int)(&args.Value),
|
||||
Data: args.data(),
|
||||
Data: input,
|
||||
AccessList: *args.AccessList,
|
||||
}
|
||||
default:
|
||||
|
|
@ -205,81 +160,10 @@ func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) {
|
|||
Gas: uint64(args.Gas),
|
||||
GasPrice: (*big.Int)(args.GasPrice),
|
||||
Value: (*big.Int)(&args.Value),
|
||||
Data: args.data(),
|
||||
Data: input,
|
||||
}
|
||||
}
|
||||
|
||||
return types.NewTx(data), nil
|
||||
}
|
||||
|
||||
// validateTxSidecar validates blob data, if present
|
||||
func (args *SendTxArgs) validateTxSidecar() error {
|
||||
// No blobs, we're done.
|
||||
if args.Blobs == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := len(args.Blobs)
|
||||
// Assume user provides either only blobs (w/o hashes), or
|
||||
// blobs together with commitments and proofs.
|
||||
if args.Commitments == nil && args.Proofs != nil {
|
||||
return errors.New(`blob proofs provided while commitments were not`)
|
||||
} else if args.Commitments != nil && args.Proofs == nil {
|
||||
return errors.New(`blob commitments provided while proofs were not`)
|
||||
}
|
||||
|
||||
// len(blobs) == len(commitments) == len(proofs) == len(hashes)
|
||||
if args.Commitments != nil && len(args.Commitments) != n {
|
||||
return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n)
|
||||
}
|
||||
if args.Proofs != nil && len(args.Proofs) != n {
|
||||
return fmt.Errorf("number of blobs and proofs mismatch (have=%d, want=%d)", len(args.Proofs), n)
|
||||
}
|
||||
if args.BlobHashes != nil && len(args.BlobHashes) != n {
|
||||
return fmt.Errorf("number of blobs and hashes mismatch (have=%d, want=%d)", len(args.BlobHashes), n)
|
||||
}
|
||||
|
||||
if args.Commitments == nil {
|
||||
// Generate commitment and proof.
|
||||
commitments := make([]kzg4844.Commitment, n)
|
||||
proofs := make([]kzg4844.Proof, n)
|
||||
for i, b := range args.Blobs {
|
||||
c, err := kzg4844.BlobToCommitment(&b)
|
||||
if err != nil {
|
||||
return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err)
|
||||
}
|
||||
commitments[i] = c
|
||||
p, err := kzg4844.ComputeBlobProof(&b, c)
|
||||
if err != nil {
|
||||
return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err)
|
||||
}
|
||||
proofs[i] = p
|
||||
}
|
||||
args.Commitments = commitments
|
||||
args.Proofs = proofs
|
||||
} else {
|
||||
for i, b := range args.Blobs {
|
||||
if err := kzg4844.VerifyBlobProof(&b, args.Commitments[i], args.Proofs[i]); err != nil {
|
||||
return fmt.Errorf("failed to verify blob proof: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hashes := make([]common.Hash, n)
|
||||
hasher := sha256.New()
|
||||
for i, c := range args.Commitments {
|
||||
hashes[i] = kzg4844.CalcBlobHashV1(hasher, &c)
|
||||
}
|
||||
if args.BlobHashes != nil {
|
||||
for i, h := range hashes {
|
||||
if h != args.BlobHashes[i] {
|
||||
return fmt.Errorf("blob hash verification failed (have=%s, want=%s)", args.BlobHashes[i], h)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args.BlobHashes = hashes
|
||||
}
|
||||
return nil
|
||||
return types.NewTx(data)
|
||||
}
|
||||
|
||||
type SigFormat struct {
|
||||
|
|
@ -325,11 +209,9 @@ type Type struct {
|
|||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// isArray returns true if the type is a fixed or variable sized array.
|
||||
// This method may return false positives, in case the Type is not a valid
|
||||
// expression, e.g. "fooo[[[[".
|
||||
// isArray returns true if the type is a fixed or variable sized array
|
||||
func (t *Type) isArray() bool {
|
||||
return strings.IndexByte(t.Type, '[') > 0
|
||||
return len(strings.Split(t.Type, "[")) > 1
|
||||
}
|
||||
|
||||
// typeName returns the canonical name of the type. If the type is 'Person[]' or 'Person[2]', then
|
||||
|
|
@ -387,8 +269,16 @@ func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage
|
|||
// Dependencies returns an array of custom types ordered by their hierarchical reference tree
|
||||
func (typedData *TypedData) Dependencies(primaryType string, found []string) []string {
|
||||
primaryType = strings.Split(primaryType, "[")[0]
|
||||
includes := func(arr []string, str string) bool {
|
||||
for _, obj := range arr {
|
||||
if obj == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if slices.Contains(found, primaryType) {
|
||||
if includes(found, primaryType) {
|
||||
return found
|
||||
}
|
||||
if typedData.Types[primaryType] == nil {
|
||||
|
|
@ -397,7 +287,7 @@ func (typedData *TypedData) Dependencies(primaryType string, found []string) []s
|
|||
found = append(found, primaryType)
|
||||
for _, field := range typedData.Types[primaryType] {
|
||||
for _, dep := range typedData.Dependencies(field.Type, found) {
|
||||
if !slices.Contains(found, dep) {
|
||||
if !includes(found, dep) {
|
||||
found = append(found, dep)
|
||||
}
|
||||
}
|
||||
|
|
@ -464,9 +354,9 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter
|
|||
encType := field.Type
|
||||
encValue := data[field.Name]
|
||||
if encType[len(encType)-1:] == "]" {
|
||||
encodedData, err := typedData.encodeArrayValue(encValue, encType, depth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
encodedData, encErr := typedData.encodeArrayValue(encValue, encType, depth)
|
||||
if encErr != nil {
|
||||
return nil, encErr
|
||||
}
|
||||
buffer.Write(encodedData)
|
||||
} else if typedData.Types[field.Type] != nil {
|
||||
|
|
@ -496,23 +386,14 @@ func (typedData *TypedData) encodeArrayValue(encValue interface{}, encType strin
|
|||
return nil, dataMismatchError(encType, encValue)
|
||||
}
|
||||
|
||||
arrayBuffer := new(bytes.Buffer)
|
||||
arrayBuffer := bytes.Buffer{}
|
||||
parsedType := strings.Split(encType, "[")[0]
|
||||
for _, item := range arrayValue {
|
||||
if reflect.TypeOf(item).Kind() == reflect.Slice ||
|
||||
reflect.TypeOf(item).Kind() == reflect.Array {
|
||||
var (
|
||||
encodedData hexutil.Bytes
|
||||
err error
|
||||
)
|
||||
if reflect.TypeOf(item).Elem().Kind() == reflect.Uint8 {
|
||||
// the item type is bytes. encode the bytes array directly instead of recursing.
|
||||
encodedData, err = typedData.EncodePrimitiveValue(parsedType, item, depth+1)
|
||||
} else {
|
||||
encodedData, err = typedData.encodeArrayValue(item, parsedType, depth+1)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
encodedData, encErr := typedData.encodeArrayValue(item, parsedType, depth+1)
|
||||
if encErr != nil {
|
||||
return nil, encErr
|
||||
}
|
||||
arrayBuffer.Write(encodedData)
|
||||
} else {
|
||||
|
|
@ -521,16 +402,16 @@ func (typedData *TypedData) encodeArrayValue(encValue interface{}, encType strin
|
|||
if !ok {
|
||||
return nil, dataMismatchError(parsedType, item)
|
||||
}
|
||||
encodedData, err := typedData.EncodeData(parsedType, mapValue, depth+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
encodedData, encErr := typedData.EncodeData(parsedType, mapValue, depth+1)
|
||||
if encErr != nil {
|
||||
return nil, encErr
|
||||
}
|
||||
digest := crypto.Keccak256(encodedData)
|
||||
arrayBuffer.Write(digest)
|
||||
} else {
|
||||
bytesValue, err := typedData.EncodePrimitiveValue(parsedType, item, depth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
bytesValue, encErr := typedData.EncodePrimitiveValue(parsedType, item, depth)
|
||||
if encErr != nil {
|
||||
return nil, encErr
|
||||
}
|
||||
arrayBuffer.Write(bytesValue)
|
||||
}
|
||||
|
|
@ -685,7 +566,7 @@ func (typedData *TypedData) EncodePrimitiveValue(encType string, encValue interf
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return math.U256Bytes(new(big.Int).Set(b)), nil
|
||||
return math.U256Bytes(b), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unrecognized type '%s'", encType)
|
||||
}
|
||||
|
|
@ -838,11 +719,11 @@ func formatPrimitiveValue(encType string, encValue interface{}) (string, error)
|
|||
return "", fmt.Errorf("unhandled type %v", encType)
|
||||
}
|
||||
|
||||
// validate checks if the types object is conformant to the specs
|
||||
// Validate checks if the types object is conformant to the specs
|
||||
func (t Types) validate() error {
|
||||
for typeKey, typeArr := range t {
|
||||
if len(typeKey) == 0 {
|
||||
return errors.New("empty type key")
|
||||
return fmt.Errorf("empty type key")
|
||||
}
|
||||
for i, typeObj := range typeArr {
|
||||
if len(typeObj.Type) == 0 {
|
||||
|
|
@ -869,36 +750,34 @@ func (t Types) validate() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var validPrimitiveTypes = map[string]struct{}{}
|
||||
|
||||
// build the set of valid primitive types
|
||||
func init() {
|
||||
// Types those are trivially valid
|
||||
for _, t := range []string{
|
||||
"address", "address[]", "bool", "bool[]", "string", "string[]",
|
||||
"bytes", "bytes[]", "int", "int[]", "uint", "uint[]",
|
||||
} {
|
||||
validPrimitiveTypes[t] = struct{}{}
|
||||
// Checks if the primitive value is valid
|
||||
func isPrimitiveTypeValid(primitiveType string) bool {
|
||||
primitiveType = strings.Split(primitiveType, "[")[0]
|
||||
if primitiveType == "address" ||
|
||||
primitiveType == "bool" ||
|
||||
primitiveType == "string" ||
|
||||
primitiveType == "bytes" ||
|
||||
primitiveType == "int" ||
|
||||
primitiveType == "uint" {
|
||||
return true
|
||||
}
|
||||
// For 'bytesN', 'bytesN[]', we allow N from 1 to 32
|
||||
for n := 1; n <= 32; n++ {
|
||||
validPrimitiveTypes[fmt.Sprintf("bytes%d", n)] = struct{}{}
|
||||
validPrimitiveTypes[fmt.Sprintf("bytes%d[]", n)] = struct{}{}
|
||||
// e.g. 'bytes28' or 'bytes28[]'
|
||||
if primitiveType == fmt.Sprintf("bytes%d", n) || primitiveType == fmt.Sprintf("bytes%d[]", n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// For 'intN','intN[]' and 'uintN','uintN[]' we allow N in increments of 8, from 8 up to 256
|
||||
for n := 8; n <= 256; n += 8 {
|
||||
validPrimitiveTypes[fmt.Sprintf("int%d", n)] = struct{}{}
|
||||
validPrimitiveTypes[fmt.Sprintf("int%d[]", n)] = struct{}{}
|
||||
validPrimitiveTypes[fmt.Sprintf("uint%d", n)] = struct{}{}
|
||||
validPrimitiveTypes[fmt.Sprintf("uint%d[]", n)] = struct{}{}
|
||||
if primitiveType == fmt.Sprintf("int%d", n) || primitiveType == fmt.Sprintf("int%d[]", n) {
|
||||
return true
|
||||
}
|
||||
if primitiveType == fmt.Sprintf("uint%d", n) || primitiveType == fmt.Sprintf("uint%d[]", n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the primitive value is valid
|
||||
func isPrimitiveTypeValid(primitiveType string) bool {
|
||||
input := strings.Split(primitiveType, "[")[0]
|
||||
_, ok := validPrimitiveTypes[input]
|
||||
return ok
|
||||
return false
|
||||
}
|
||||
|
||||
// validate checks if the given domain is valid, i.e. contains at least
|
||||
|
|
|
|||
|
|
@ -16,16 +16,7 @@
|
|||
|
||||
package apitypes
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
import "testing"
|
||||
|
||||
func TestIsPrimitive(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
|
@ -50,99 +41,6 @@ func TestIsPrimitive(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTxArgs(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
data []byte
|
||||
want common.Hash
|
||||
wantType uint8
|
||||
}{
|
||||
{
|
||||
data: []byte(`{"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","accessList":[],"blobVersionedHashes":["0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014"],"chainId":"0x7","gas":"0x124f8","gasPrice":"0x693d4ca8","input":"0x","maxFeePerBlobGas":"0x3b9aca00","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","nonce":"0x0","r":"0x2a922afc784d07e98012da29f2f37cae1f73eda78aa8805d3df6ee5dbb41ec1","s":"0x4f1f75ae6bcdf4970b4f305da1a15d8c5ddb21f555444beab77c9af2baab14","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","type":"0x1","v":"0x0","value":"0x0","yParity":"0x0"}`),
|
||||
want: common.HexToHash("0x7d53234acc11ac5b5948632c901a944694e228795782f511887d36fd76ff15c4"),
|
||||
wantType: types.BlobTxType,
|
||||
},
|
||||
{
|
||||
// on input, we don't read the type, but infer the type from the arguments present
|
||||
data: []byte(`{"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","accessList":[],"chainId":"0x7","gas":"0x124f8","gasPrice":"0x693d4ca8","input":"0x","maxFeePerBlobGas":"0x3b9aca00","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","nonce":"0x0","r":"0x2a922afc784d07e98012da29f2f37cae1f73eda78aa8805d3df6ee5dbb41ec1","s":"0x4f1f75ae6bcdf4970b4f305da1a15d8c5ddb21f555444beab77c9af2baab14","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","type":"0x12","v":"0x0","value":"0x0","yParity":"0x0"}`),
|
||||
want: common.HexToHash("0x7919e2b0b9b543cb87a137b6ff66491ec7ae937cb88d3c29db4d9b28073dce53"),
|
||||
wantType: types.DynamicFeeTxType,
|
||||
},
|
||||
} {
|
||||
var txArgs SendTxArgs
|
||||
if err := json.Unmarshal(tc.data, &txArgs); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx, err := txArgs.ToTransaction()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if have := tx.Type(); have != tc.wantType {
|
||||
t.Errorf("test %d, have type %d, want type %d", i, have, tc.wantType)
|
||||
}
|
||||
if have := tx.Hash(); have != tc.want {
|
||||
t.Errorf("test %d: have %v, want %v", i, have, tc.want)
|
||||
}
|
||||
d2, err := json.Marshal(txArgs)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var txArgs2 SendTxArgs
|
||||
if err := json.Unmarshal(d2, &txArgs2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx1, _ := txArgs.ToTransaction()
|
||||
tx2, _ := txArgs2.ToTransaction()
|
||||
if have, want := tx1.Hash(), tx2.Hash(); have != want {
|
||||
t.Errorf("test %d: have %v, want %v", i, have, want)
|
||||
}
|
||||
}
|
||||
/*
|
||||
End to end testing:
|
||||
|
||||
$ go run ./cmd/clef --advanced --suppress-bootwarn
|
||||
|
||||
$ go run ./cmd/geth --nodiscover --maxpeers 0 --signer /home/user/.clef/clef.ipc console
|
||||
|
||||
> tx={"from":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","to":"0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425","gas":"0x124f8","maxFeePerGas":"0x6fc23ac00","maxPriorityFeePerGas":"0x3b9aca00","value":"0x0","nonce":"0x0","input":"0x","accessList":[],"maxFeePerBlobGas":"0x3b9aca00","blobVersionedHashes":["0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014"]}
|
||||
> eth.signTransaction(tx)
|
||||
*/
|
||||
}
|
||||
|
||||
func TestBlobTxs(t *testing.T) {
|
||||
blob := kzg4844.Blob{0x1}
|
||||
commitment, err := kzg4844.BlobToCommitment(&blob)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
proof, err := kzg4844.ComputeBlobProof(&blob, commitment)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
hash := kzg4844.CalcBlobHashV1(sha256.New(), &commitment)
|
||||
b := &types.BlobTx{
|
||||
ChainID: uint256.NewInt(6),
|
||||
Nonce: 8,
|
||||
GasTipCap: uint256.NewInt(500),
|
||||
GasFeeCap: uint256.NewInt(600),
|
||||
Gas: 21000,
|
||||
BlobFeeCap: uint256.NewInt(700),
|
||||
BlobHashes: []common.Hash{hash},
|
||||
Value: uint256.NewInt(100),
|
||||
Sidecar: &types.BlobTxSidecar{
|
||||
Blobs: []kzg4844.Blob{blob},
|
||||
Commitments: []kzg4844.Commitment{commitment},
|
||||
Proofs: []kzg4844.Proof{proof},
|
||||
},
|
||||
}
|
||||
tx := types.NewTx(b)
|
||||
data, err := json.Marshal(tx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("tx %v", string(data))
|
||||
}
|
||||
|
||||
func TestType_IsArray(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Expected positives
|
||||
|
|
@ -229,7 +127,7 @@ func TestType_TypeName(t *testing.T) {
|
|||
},
|
||||
} {
|
||||
if tc.Input.typeName() != tc.Expected {
|
||||
t.Errorf("test %d: expected typeName value of '%v' but got '%v'", i, tc.Expected, tc.Input)
|
||||
t.Errorf("test %d: expected typeName value of '%v' to be '%v'", i, tc.Input, tc.Expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue