diff --git a/cmd/chain-receipts/main.go b/cmd/chain-receipts/main.go index 92d77721..50e6e7a5 100644 --- a/cmd/chain-receipts/main.go +++ b/cmd/chain-receipts/main.go @@ -100,12 +100,10 @@ func listener(provider *ethrpc.Provider, monitorOptions ethmonitor.Options, rece // Find specific meta transaction -- note: this is not the "transaction hash", // this is a sub-transaction where the id is emitted as an event. FilterMetaTransactionID := func(metaTxnID ethkit.Hash) ethreceipts.FilterQuery { - return ethreceipts.FilterLogs(func(logs []*types.Log) bool { + return ethreceipts.FilterLogs(func(logs []types.Log) bool { for _, log := range logs { - isTxExecuted := IsTxExecutedEvent(log, metaTxnID) - isTxFailed := IsTxFailedEvent(log, metaTxnID) - if isTxExecuted || isTxFailed { - // found the sequence meta txn + // found the sequence meta txn + if IsTxExecutedEvent(log, metaTxnID) || IsTxFailedEvent(log, metaTxnID) { return true } } @@ -116,7 +114,7 @@ func listener(provider *ethrpc.Provider, monitorOptions ethmonitor.Options, rece // Find any Sequence meta txns FilterMetaTransactionAny := func() ethreceipts.FilterQuery { - return ethreceipts.FilterLogs(func(logs []*types.Log) bool { + return ethreceipts.FilterLogs(func(logs []types.Log) bool { foundNonceEvent := false for _, log := range logs { if len(log.Topics) > 0 && log.Topics[0] == NonceChangeEventSig { @@ -208,13 +206,13 @@ func MustEncodeSig(str string) common.Hash { return crypto.Keccak256Hash([]byte(str)) } -func IsTxExecutedEvent(log *types.Log, hash common.Hash) bool { +func IsTxExecutedEvent(log types.Log, hash common.Hash) bool { return len(log.Topics) == 0 && len(log.Data) == 32 && bytes.Equal(log.Data, hash[:]) } -func IsTxFailedEvent(log *types.Log, hash common.Hash) bool { +func IsTxFailedEvent(log types.Log, hash common.Hash) bool { return len(log.Topics) == 1 && log.Topics[0] == TxFailedEventSig && bytes.HasPrefix(log.Data, hash[:]) diff --git a/cmd/chain-watch/main.go b/cmd/chain-watch/main.go index d7e59aeb..8cf26024 100644 --- a/cmd/chain-watch/main.go +++ b/cmd/chain-watch/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "encoding/json" "fmt" "log" "math/big" @@ -13,7 +12,10 @@ import ( "github.com/0xsequence/ethkit/ethmonitor" "github.com/0xsequence/ethkit/ethrpc" + "github.com/bytedance/sonic" + "github.com/0xsequence/ethkit/util" + rediscache "github.com/goware/cachestore-redis" cachestore "github.com/goware/cachestore2" "github.com/goware/logger" @@ -201,7 +203,7 @@ func chainWatch(provider *ethrpc.Provider, monitorOptions ethmonitor.Options) (* // of objects, one after another. // Or... we can write [event1, event2,event3],[event,event5],[event6],... // to the disk, and this would be fine too. - d, _ := json.Marshal(events) + d, _ := sonic.ConfigFastest.Marshal(events) writeToFile(snapshotFile, d) } diff --git a/cmd/ethkit/block.go b/cmd/ethkit/block.go index e5ffdc15..5fe0b9a9 100644 --- a/cmd/ethkit/block.go +++ b/cmd/ethkit/block.go @@ -172,7 +172,7 @@ func NewHeader(b *types.Block) *Header { WithdrawalsHash: b.Header().WithdrawalsHash, Size: b.Header().Size(), // TotalDifficulty: b.Difficulty(), - TransactionsHash: TransactionsHash(*b), + TransactionsHash: TransactionsHash(b), } } @@ -188,7 +188,7 @@ func (h *Header) String() string { } // TransactionsHash returns a list of transaction hash starting from a list of transactions contained in a block. -func TransactionsHash(block types.Block) []common.Hash { +func TransactionsHash(block *types.Block) []common.Hash { txsh := make([]common.Hash, len(block.Transactions())) for i, tx := range block.Transactions() { diff --git a/cmd/ethkit/print.go b/cmd/ethkit/print.go index 3f362ecd..935bb6cd 100644 --- a/cmd/ethkit/print.go +++ b/cmd/ethkit/print.go @@ -4,12 +4,13 @@ import ( "bytes" "encoding/base64" "encoding/hex" - "encoding/json" "fmt" "reflect" "strconv" "strings" "text/tabwriter" + + "github.com/bytedance/sonic" ) type printableFormat struct { @@ -29,7 +30,7 @@ type Printable map[string]any // PrettyJSON prints an object in "prettified" JSON format func PrettyJSON(toJSON any) (*string, error) { - b, err := json.MarshalIndent(toJSON, "", " ") + b, err := sonic.ConfigFastest.MarshalIndent(toJSON, "", " ") if err != nil { return nil, err } @@ -45,11 +46,11 @@ func PrettyJSON(toJSON any) (*string, error) { // FromStruct converts a struct into a Printable using, when available, JSON field names as keys func (p *Printable) FromStruct(input any) error { - bytes, err := json.Marshal(input) + bytes, err := sonic.ConfigFastest.Marshal(input) if err != nil { return err } - if err := json.Unmarshal(bytes, &p); err != nil { + if err := sonic.ConfigFastest.Unmarshal(bytes, &p); err != nil { return err } diff --git a/cmd/ethkit/wallet.go b/cmd/ethkit/wallet.go index 967396e4..b5f01eaf 100644 --- a/cmd/ethkit/wallet.go +++ b/cmd/ethkit/wallet.go @@ -2,7 +2,6 @@ package main import ( "bufio" - "encoding/json" "errors" "fmt" "log" @@ -13,8 +12,10 @@ import ( "github.com/0xsequence/ethkit/ethwallet" "github.com/0xsequence/ethkit/go-ethereum/accounts/keystore" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/bytedance/sonic" + "github.com/spf13/cobra" - "golang.org/x/crypto/ssh/terminal" + "golang.org/x/term" ) func init() { @@ -90,7 +91,7 @@ func (c *wallet) Run(cmd *cobra.Command, args []string) { log.Fatal(err) } keyFile := walletKeyFile{} - err = json.Unmarshal(data, &keyFile) + err = sonic.ConfigFastest.Unmarshal(data, &keyFile) if err != nil { log.Fatal(err) } @@ -219,7 +220,7 @@ func (c *wallet) createNew() error { Client: fmt.Sprintf("ethkit/%s - github.com/0xsequence/ethkit", VERSION), } - data, err := json.MarshalIndent(keyFile, "", " ") + data, err := sonic.ConfigFastest.MarshalIndent(keyFile, "", " ") if err != nil { return err } @@ -261,7 +262,7 @@ func fileExists(filename string) bool { func readSecretInput(prompt string) ([]byte, error) { fmt.Print(prompt) - password, err := terminal.ReadPassword(int(syscall.Stdin)) + password, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { return nil, err } diff --git a/ethartifact/ethartifact.go b/ethartifact/ethartifact.go index cef31707..1095c929 100644 --- a/ethartifact/ethartifact.go +++ b/ethartifact/ethartifact.go @@ -8,6 +8,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/accounts/abi" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/bytedance/sonic" ) type Artifact struct { @@ -27,7 +28,7 @@ func (a Artifact) Decode(result interface{}, method string, data []byte) error { func ParseArtifactJSON(artifactJSON string) (Artifact, error) { var rawArtifact RawArtifact - err := json.Unmarshal([]byte(artifactJSON), &rawArtifact) + err := sonic.ConfigFastest.Unmarshal([]byte(artifactJSON), &rawArtifact) if err != nil { return Artifact{}, err } @@ -77,7 +78,7 @@ func ParseArtifactFile(path string) (RawArtifact, error) { } var artifact RawArtifact - err = json.Unmarshal(filedata, &artifact) + err = sonic.ConfigFastest.Unmarshal(filedata, &artifact) if err != nil { return RawArtifact{}, err } diff --git a/ethcoder/abi_helpers.go b/ethcoder/abi_helpers.go index 8a874246..79590109 100644 --- a/ethcoder/abi_helpers.go +++ b/ethcoder/abi_helpers.go @@ -1,7 +1,6 @@ package ethcoder import ( - "encoding/json" "errors" "fmt" "math/big" @@ -11,6 +10,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/accounts/abi" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) func ABIPackArguments(argTypes []string, argValues []interface{}) ([]byte, error) { @@ -459,7 +459,7 @@ func ABIUnmarshalStringValuesAny(argTypes []string, stringValues []any) ([]any, switch v := v.(type) { case string: // v is string array, ie. `["1","2","3"]` - err = json.Unmarshal([]byte(v), &stringValues) + err = sonic.ConfigFastest.Unmarshal([]byte(v), &stringValues) if err != nil { return nil, fmt.Errorf("ethcoder: value at position %d is invalid. failed to unmarshal json string array '%s'", i, v) } diff --git a/ethcoder/abi_test.go b/ethcoder/abi_test.go index fe061a01..b73c3864 100644 --- a/ethcoder/abi_test.go +++ b/ethcoder/abi_test.go @@ -1,7 +1,6 @@ package ethcoder import ( - "encoding/json" "math/big" "reflect" "testing" @@ -9,6 +8,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/accounts/abi" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -560,10 +561,10 @@ func TestEncodeContractCall(t *testing.T) { // Args: []any{"mundo"}, // } - // net1jsn, err := json.Marshal(nestedEncodeType1) + // net1jsn, err := sonic.ConfigFastest.Marshal(nestedEncodeType1) // require.Nil(t, err) - // net2jsn, err := json.Marshal(nestedEncodeType2) + // net2jsn, err := sonic.ConfigFastest.Marshal(nestedEncodeType2) // require.Nil(t, err) t.Run("nested transferFrom, not named", func(t *testing.T) { @@ -653,7 +654,7 @@ func TestEncodeContractCall(t *testing.T) { }` var contractCall ContractCallDef - err := json.Unmarshal([]byte(jsonContractCall), &contractCall) + err := sonic.ConfigFastest.Unmarshal([]byte(jsonContractCall), &contractCall) require.NoError(t, err) res, err := EncodeContractCall(contractCall) @@ -670,7 +671,7 @@ func TestEncodeContractCall(t *testing.T) { }` var contractCall ContractCallDef - err := json.Unmarshal([]byte(jsonContractCall), &contractCall) + err := sonic.ConfigFastest.Unmarshal([]byte(jsonContractCall), &contractCall) require.NoError(t, err) res, err := EncodeContractCall(contractCall) @@ -687,7 +688,7 @@ func TestEncodeContractCall(t *testing.T) { }` var contractCall ContractCallDef - err := json.Unmarshal([]byte(jsonContractCall), &contractCall) + err := sonic.ConfigFastest.Unmarshal([]byte(jsonContractCall), &contractCall) require.NoError(t, err) res, err := EncodeContractCall(contractCall) diff --git a/ethcoder/ethcoder.go b/ethcoder/ethcoder.go index 0487449f..dad89634 100644 --- a/ethcoder/ethcoder.go +++ b/ethcoder/ethcoder.go @@ -12,9 +12,7 @@ func BytesToBytes32(slice []byte) [32]byte { } func PaddedAddress(address string) string { - if strings.HasPrefix(address, "0x") { - address = address[2:] - } + address = strings.TrimPrefix(address, "0x") if len(address) < 64 { address = strings.Repeat("0", 64-len(address)) + address } diff --git a/ethcoder/solidity_pack.go b/ethcoder/solidity_pack.go index 500ae866..cd2f561f 100644 --- a/ethcoder/solidity_pack.go +++ b/ethcoder/solidity_pack.go @@ -163,7 +163,7 @@ func solidityArgumentPack(typ string, val interface{}, isArray bool) ([]byte, er return nil, fmt.Errorf("not a [%d]byte", size) } - v := make([]byte, size, size) + v := make([]byte, size) var ok bool for i := 0; i < int(size); i++ { v[i], ok = rv.Index(i).Interface().(byte) diff --git a/ethcoder/typed_data_json.go b/ethcoder/typed_data_json.go index 6d8645be..4f97a0e7 100644 --- a/ethcoder/typed_data_json.go +++ b/ethcoder/typed_data_json.go @@ -10,11 +10,12 @@ import ( "strings" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/bytedance/sonic" ) func TypedDataFromJSON(typedDataJSON string) (*TypedData, error) { var typedData TypedData - err := json.Unmarshal([]byte(typedDataJSON), &typedData) + err := sonic.ConfigFastest.Unmarshal([]byte(typedDataJSON), &typedData) if err != nil { return nil, err } @@ -34,7 +35,7 @@ func (t *TypedData) MarshalJSON() ([]byte, error) { return nil, err } - return json.Marshal(TypedDataJSON{ + return sonic.ConfigFastest.Marshal(TypedDataJSON{ Types: t.Types, PrimaryType: t.PrimaryType, Domain: t.Domain, @@ -130,7 +131,7 @@ func (t *TypedData) UnmarshalJSON(data []byte) error { } // Json decoder with json.Number support, so that we can decode big.Int values - dec := json.NewDecoder(bytes.NewReader(data)) + dec := sonic.ConfigFastest.NewDecoder(bytes.NewReader(data)) dec.UseNumber() var raw TypedDataRaw diff --git a/ethcoder/typed_data_test.go b/ethcoder/typed_data_test.go index 8ed67d94..a84a58e0 100644 --- a/ethcoder/typed_data_test.go +++ b/ethcoder/typed_data_test.go @@ -1,13 +1,14 @@ package ethcoder_test import ( - "encoding/json" "math/big" "testing" "github.com/0xsequence/ethkit/ethcoder" "github.com/0xsequence/ethkit/ethwallet" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/bytedance/sonic" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -207,7 +208,7 @@ func TestTypedDataFromJSON(t *testing.T) { require.True(t, valid) // test MarshalJSON by encoding, then comparing digests - jsonOut, err := json.Marshal(typedData) + jsonOut, err := sonic.ConfigFastest.Marshal(typedData) require.NoError(t, err) typedData2, err := ethcoder.TypedDataFromJSON(string(jsonOut)) @@ -307,7 +308,7 @@ func TestTypedDataFromJSONPart2(t *testing.T) { require.True(t, valid) // test MarshalJSON by encoding, then comparing digests - jsonOut, err := json.Marshal(typedData) + jsonOut, err := sonic.ConfigFastest.Marshal(typedData) require.NoError(t, err) typedData2, err := ethcoder.TypedDataFromJSON(string(jsonOut)) @@ -381,7 +382,7 @@ func TestTypedDataFromJSONPart3(t *testing.T) { require.True(t, valid) // test MarshalJSON by encoding, then comparing digests - jsonOut, err := json.Marshal(typedData) + jsonOut, err := sonic.ConfigFastest.Marshal(typedData) require.NoError(t, err) typedData2, err := ethcoder.TypedDataFromJSON(string(jsonOut)) @@ -454,7 +455,7 @@ func TestTypedDataFromJSONPart4(t *testing.T) { require.True(t, valid) // test MarshalJSON by encoding, then comparing digests - jsonOut, err := json.Marshal(typedData) + jsonOut, err := sonic.ConfigFastest.Marshal(typedData) require.NoError(t, err) typedData2, err := ethcoder.TypedDataFromJSON(string(jsonOut)) @@ -525,7 +526,7 @@ func TestTypedDataFromJSONPart5(t *testing.T) { require.True(t, valid) // test MarshalJSON by encoding, then comparing digests - jsonOut, err := json.Marshal(typedData) + jsonOut, err := sonic.ConfigFastest.Marshal(typedData) require.NoError(t, err) typedData2, err := ethcoder.TypedDataFromJSON(string(jsonOut)) @@ -718,7 +719,7 @@ func TestTypedDataFromJSONPart6(t *testing.T) { require.True(t, valid) // test MarshalJSON by encoding, then comparing digests - jsonOut, err := json.Marshal(typedData) + jsonOut, err := sonic.ConfigFastest.Marshal(typedData) require.NoError(t, err) typedData2, err := ethcoder.TypedDataFromJSON(string(jsonOut)) diff --git a/ethmonitor/bootstrap.go b/ethmonitor/bootstrap.go index c4c28f6d..1bb13b74 100644 --- a/ethmonitor/bootstrap.go +++ b/ethmonitor/bootstrap.go @@ -1,10 +1,10 @@ package ethmonitor import ( - "encoding/json" "fmt" "github.com/0xsequence/ethkit/go-ethereum/core/types" + "github.com/bytedance/sonic" ) // BootstrapFromBlocks will bootstrap the ethmonitor canonical chain from input blocks, @@ -18,7 +18,7 @@ func (c *Chain) BootstrapFromBlocks(blocks []*Block) error { // that you use BootstrapFromBlocks and handle constructing block events outside of ethmonitor. func (c *Chain) BootstrapFromBlocksJSON(data []byte) error { var blocks Blocks - err := json.Unmarshal(data, &blocks) + err := sonic.ConfigFastest.Unmarshal(data, &blocks) if err != nil { return fmt.Errorf("ethmonitor: BootstrapFromBlocksJSON failed to unmarshal: %w", err) } @@ -67,7 +67,7 @@ func (c *Chain) Snapshot() ([]byte, error) { c.mu.Lock() defer c.mu.Unlock() - data, err := json.Marshal(c.blocks) + data, err := sonic.ConfigFastest.Marshal(c.blocks) if err != nil { return nil, err } @@ -83,7 +83,7 @@ type blockSnapshot struct { } func (b *Block) MarshalJSON() ([]byte, error) { - return json.Marshal(&blockSnapshot{ + return sonic.ConfigFastest.Marshal(&blockSnapshot{ Block: b.Block, Event: b.Event, Logs: b.Logs, @@ -93,7 +93,7 @@ func (b *Block) MarshalJSON() ([]byte, error) { func (b *Block) UnmarshalJSON(data []byte) error { var s *blockSnapshot - err := json.Unmarshal(data, &s) + err := sonic.ConfigFastest.Unmarshal(data, &s) if err != nil { return err } diff --git a/ethmonitor/ethmonitor.go b/ethmonitor/ethmonitor.go index f0f5f714..13aecdeb 100644 --- a/ethmonitor/ethmonitor.go +++ b/ethmonitor/ethmonitor.go @@ -2,7 +2,6 @@ package ethmonitor import ( "context" - "encoding/json" "errors" "fmt" "math/big" @@ -15,7 +14,10 @@ import ( "github.com/0xsequence/ethkit/go-ethereum" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/core/types" + "github.com/bytedance/sonic" + "github.com/0xsequence/ethkit/util" + "github.com/goware/breaker" cachestore "github.com/goware/cachestore2" "github.com/goware/calc" @@ -1227,7 +1229,7 @@ func (m *Monitor) unmarshalBlock(blockPayload []byte) (*types.Block, error) { func (m *Monitor) unmarshalLogs(logsPayload []byte) ([]types.Log, error) { var logs []types.Log - err := json.Unmarshal(logsPayload, &logs) + err := sonic.ConfigFastest.Unmarshal(logsPayload, &logs) if err != nil { return nil, err } diff --git a/ethreceipts/ethreceipts.go b/ethreceipts/ethreceipts.go index 95121edd..a0c8ec01 100644 --- a/ethreceipts/ethreceipts.go +++ b/ethreceipts/ethreceipts.go @@ -739,7 +739,7 @@ func (l *ReceiptsListener) processBlocks(blocks ethmonitor.Blocks, subscribers [ for i, txn := range block.Transactions() { txnLog, ok := logs[txn.Hash().Hex()] if !ok { - txnLog = []*types.Log{} + txnLog = []types.Log{} } receipts[i] = Receipt{ @@ -911,8 +911,8 @@ func collectOk[T any](in []T, oks []bool, okCond bool) []T { return out } -// func txnLogs(blockLogs []types.Log, txnHash ethkit.Hash) []*types.Log { -// txnLogs := []*types.Log{} +// func txnLogs(blockLogs []types.Log, txnHash ethkit.Hash) []types.Log { +// txnLogs := []types.Log{} // for i, log := range blockLogs { // if log.TxHash == txnHash { // log := log // copy @@ -925,29 +925,27 @@ func collectOk[T any](in []T, oks []bool, okCond bool) []T { // return txnLogs // } -func groupLogsByTransaction(logs []types.Log) map[string][]*types.Log { - var out = make(map[string][]*types.Log) +func groupLogsByTransaction(logs []types.Log) map[string][]types.Log { + var out = make(map[string][]types.Log) for _, log := range logs { log := log logTxHash := log.TxHash.Hex() outLogs, ok := out[logTxHash] if !ok { - outLogs = []*types.Log{} + outLogs = []types.Log{} } - outLogs = append(outLogs, &log) + outLogs = append(outLogs, log) out[logTxHash] = outLogs } return out } func blockLogsCount(numTxns int, logs []types.Log) uint { - var max uint = uint(numTxns) + blockCount := uint(numTxns) for _, log := range logs { - if log.TxIndex+1 > max { - max = log.TxIndex + 1 - } + blockCount = max(blockCount, log.TxIndex+1) } - return max + return blockCount } diff --git a/ethreceipts/ethreceipts_test.go b/ethreceipts/ethreceipts_test.go index f5946b00..d4a7b4b3 100644 --- a/ethreceipts/ethreceipts_test.go +++ b/ethreceipts/ethreceipts_test.go @@ -518,7 +518,7 @@ func TestReceiptsListenerERC20(t *testing.T) { // won't be found.. ethreceipts.FilterFrom(ethkit.Address{}).MaxWait(0).ID(8888), - // ethreceipts.FilterLogs(func(logs []*types.Log) bool { + // ethreceipts.FilterLogs(func(logs []types.Log) bool { // for _, log := range logs { // if log.Address == erc20Mock.Contract.Address { // return true diff --git a/ethreceipts/filterer.go b/ethreceipts/filterer.go index efe487e3..8647b5b0 100644 --- a/ethreceipts/filterer.go +++ b/ethreceipts/filterer.go @@ -60,7 +60,7 @@ func FilterTo(to ethkit.Address) FilterQuery { // Filter the logs of a transaction and search for an event log // from a specific contract address. func FilterLogContract(contractAddress ethkit.Address) FilterQuery { - return FilterLogs(func(logs []*types.Log) bool { + return FilterLogs(func(logs []types.Log) bool { for _, log := range logs { if log.Address == contractAddress { return true @@ -84,7 +84,7 @@ func FilterLogTopic(eventTopicHash ethkit.Hash) FilterQuery { } // Filter logs of a transaction -func FilterLogs(logFn func([]*types.Log) bool) FilterQuery { +func FilterLogs(logFn func([]types.Log) bool) FilterQuery { return &filter{ cond: FilterCond{ Logs: logFn, @@ -151,7 +151,7 @@ type FilterCond struct { From *ethkit.Address To *ethkit.Address LogTopic *ethkit.Hash // event signature topic hash - Logs func([]*types.Log) bool + Logs func([]types.Log) bool } type filter struct { diff --git a/ethreceipts/receipt.go b/ethreceipts/receipt.go index 802643fd..0a65a73b 100644 --- a/ethreceipts/receipt.go +++ b/ethreceipts/receipt.go @@ -17,7 +17,7 @@ type Receipt struct { transaction *types.Transaction message *core.Message // TODO: this intermediate type is lame.. with new ethrpc we can remove receipt *types.Receipt - logs []*types.Log + logs []types.Log } func (r *Receipt) Receipt() *types.Receipt { @@ -132,7 +132,7 @@ func (r *Receipt) GasUsed() uint64 { } } -func (r *Receipt) Logs() []*types.Log { +func (r *Receipt) Logs() []types.Log { if r.receipt != nil && len(r.receipt.Logs) > 0 { return r.receipt.Logs } else { diff --git a/ethrpc/batch.go b/ethrpc/batch.go index 6dff9054..f2ce6da3 100644 --- a/ethrpc/batch.go +++ b/ethrpc/batch.go @@ -1,23 +1,23 @@ package ethrpc import ( - "encoding/json" "fmt" "github.com/0xsequence/ethkit/ethrpc/jsonrpc" + "github.com/bytedance/sonic" ) type BatchCall []*Call func (b *BatchCall) MarshalJSON() ([]byte, error) { if len(*b) == 1 { - return json.Marshal((*b)[0].request) + return sonic.ConfigFastest.Marshal((*b)[0].request) } reqBody := make([]jsonrpc.Message, len(*b)) for i, r := range *b { reqBody[i] = r.request } - return json.Marshal(reqBody) + return sonic.ConfigFastest.Marshal(reqBody) } func (b *BatchCall) UnmarshalJSON(data []byte) error { @@ -30,7 +30,7 @@ func (b *BatchCall) UnmarshalJSON(data []byte) error { target = &results[0] } - if err := json.Unmarshal(data, target); err != nil { + if err := sonic.ConfigFastest.Unmarshal(data, target); err != nil { return fmt.Errorf("failed to unmarshal batch response: %w", err) } if len(results) > len(*b) { diff --git a/ethrpc/ethrpc.go b/ethrpc/ethrpc.go index edd75f74..e5f93463 100644 --- a/ethrpc/ethrpc.go +++ b/ethrpc/ethrpc.go @@ -20,6 +20,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/core/types" "github.com/0xsequence/ethkit/go-ethereum/rpc" + "github.com/bytedance/sonic" + "github.com/goware/breaker" "github.com/goware/logger" "github.com/goware/superr" @@ -160,7 +162,7 @@ func (p *Provider) Do(ctx context.Context, calls ...Call) ([]byte, error) { if (res.StatusCode < 200 || res.StatusCode > 299) && res.StatusCode != 401 { msg := jsonrpc.Message{} - if err := json.Unmarshal(body, &msg); err == nil && msg.Error != nil { + if err := sonic.ConfigFastest.Unmarshal(body, &msg); err == nil && msg.Error != nil { return body, superr.Wrap(ErrRequestFail, msg.Error) } details := any(body) @@ -170,7 +172,7 @@ func (p *Provider) Do(ctx context.Context, calls ...Call) ([]byte, error) { return body, superr.Wrap(ErrRequestFail, fmt.Errorf("non-200 response with status code: %d with body '%s'", res.StatusCode, details)) } - if err := json.Unmarshal(body, &batch); err != nil { + if err := sonic.ConfigFastest.Unmarshal(body, &batch); err != nil { if len(body) > 100 { body = body[:100] } diff --git a/ethrpc/jsonrpc.go b/ethrpc/jsonrpc.go index acba634a..e23d6686 100644 --- a/ethrpc/jsonrpc.go +++ b/ethrpc/jsonrpc.go @@ -8,6 +8,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) type Call struct { @@ -74,7 +75,7 @@ func (b CallBuilder[T]) Into(ret *T) Call { if b.intoFn != nil { return b.intoFn(message, ret, b.strictness) } - return json.Unmarshal(message, ret) + return sonic.ConfigFastest.Unmarshal(message, ret) }, } } @@ -137,7 +138,7 @@ func toCallArg(msg ethereum.CallMsg) any { func hexIntoBigInt(message json.RawMessage, ret **big.Int, strictness StrictnessLevel) error { var result hexutil.Big - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } *ret = (*big.Int)(&result) @@ -151,7 +152,7 @@ func hexIntoUint64(message json.RawMessage, ret *uint64, strictness StrictnessLe } var result hexutil.Uint64 - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } *ret = uint64(result) @@ -165,7 +166,7 @@ func hexIntoUint(message json.RawMessage, ret *uint, strictness StrictnessLevel) } var result hexutil.Uint - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } *ret = uint(result) @@ -174,7 +175,7 @@ func hexIntoUint(message json.RawMessage, ret *uint, strictness StrictnessLevel) func hexIntoBigUint64(message json.RawMessage, ret **big.Int, strictness StrictnessLevel) error { var result hexutil.Uint64 - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } *ret = big.NewInt(int64(result)) @@ -183,7 +184,7 @@ func hexIntoBigUint64(message json.RawMessage, ret **big.Int, strictness Strictn func hexIntoBytes(message json.RawMessage, ret *[]byte, strictness StrictnessLevel) error { var result hexutil.Bytes - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } *ret = result @@ -192,7 +193,7 @@ func hexIntoBytes(message json.RawMessage, ret *[]byte, strictness StrictnessLev func hexIntoHash(message json.RawMessage, ret *common.Hash, strictness StrictnessLevel) error { var result common.Hash - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } *ret = result diff --git a/ethrpc/methods.go b/ethrpc/methods.go index ac28d504..06809cb2 100644 --- a/ethrpc/methods.go +++ b/ethrpc/methods.go @@ -12,6 +12,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/core/types" "github.com/0xsequence/ethkit/go-ethereum/rpc" + "github.com/bytedance/sonic" ) func ChainID() CallBuilder[*big.Int] { @@ -130,7 +131,7 @@ func TransactionSender(tx *types.Transaction, block common.Hash, index uint) Cal Hash common.Hash From common.Address } - if err := json.Unmarshal(raw, &meta); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &meta); err != nil { return err } if meta.Hash == (common.Hash{}) || meta.Hash != tx.Hash() { @@ -163,7 +164,7 @@ func TransactionReceipt(txHash common.Hash) CallBuilder[*types.Receipt] { method: "eth_getTransactionReceipt", params: []any{txHash}, intoFn: func(raw json.RawMessage, receipt **types.Receipt, strictness StrictnessLevel) error { - err := json.Unmarshal(raw, receipt) + err := sonic.ConfigFastest.Unmarshal(raw, receipt) if err == nil && receipt == nil { return ethereum.NotFound } @@ -187,7 +188,7 @@ func NetworkID() CallBuilder[*big.Int] { verString string version = &big.Int{} ) - if err := json.Unmarshal(raw, &verString); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &verString); err != nil { return err } if _, ok := version.SetString(verString, 10); !ok { @@ -320,7 +321,7 @@ func ContractQuery(contractAddress common.Address, inputAbiExpr, outputAbiExpr s params: []any{toCallArg(msg), toBlockNumArg(nil)}, intoFn: func(message json.RawMessage, ret *[]string, strictness StrictnessLevel) error { var result hexutil.Bytes - if err := json.Unmarshal(message, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(message, &result); err != nil { return err } @@ -385,7 +386,7 @@ func FeeHistory(blockCount uint64, lastBlock *big.Int, rewardPercentiles []float params: []any{hexutil.Uint(blockCount), toBlockNumArg(lastBlock), rewardPercentiles}, intoFn: func(raw json.RawMessage, ret **ethereum.FeeHistory, strictness StrictnessLevel) error { var res feeHistoryResult - if err := json.Unmarshal(raw, &res); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &res); err != nil { return err } diff --git a/ethrpc/syncing.go b/ethrpc/syncing.go index 9a8070d4..da92fb24 100644 --- a/ethrpc/syncing.go +++ b/ethrpc/syncing.go @@ -5,6 +5,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) func intoSyncingProgress(raw json.RawMessage, ret **ethereum.SyncProgress, strictness StrictnessLevel) error { @@ -12,11 +13,11 @@ func intoSyncingProgress(raw json.RawMessage, ret **ethereum.SyncProgress, stric syncing bool p *rpcProgress ) - if err := json.Unmarshal(raw, &syncing); err == nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &syncing); err == nil { *ret = nil // bool is always false == not syncing return nil } - if err := json.Unmarshal(raw, &p); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &p); err != nil { return err } *ret = p.toSyncProgress() diff --git a/ethrpc/unmarshal.go b/ethrpc/unmarshal.go index 0786bdcb..78db4095 100644 --- a/ethrpc/unmarshal.go +++ b/ethrpc/unmarshal.go @@ -10,6 +10,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/core/types" + "github.com/bytedance/sonic" ) type rpcBlock struct { @@ -33,7 +34,7 @@ type txExtraInfo struct { } func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error { - err := json.Unmarshal(msg, &tx.tx) + err := sonic.ConfigFastest.Unmarshal(msg, &tx.tx) if err != nil { // for unsupported txn types, we don't completely fail, // ie. some chains like arbitrum nova will return a non-standard type @@ -55,14 +56,14 @@ func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error { } // in case of any other error, return the error - err = json.Unmarshal(msg, &tx.tx) + err = sonic.ConfigFastest.Unmarshal(msg, &tx.tx) if err != nil { return err } } } - err = json.Unmarshal(msg, &tx.txExtraInfo) + err = sonic.ConfigFastest.Unmarshal(msg, &tx.txExtraInfo) if err != nil { return err } @@ -77,7 +78,7 @@ func IntoJSONRawMessage(raw json.RawMessage, ret *json.RawMessage, strictness St func IntoHeader(raw json.RawMessage, ret **types.Header, strictness StrictnessLevel) error { var header *types.Header - if err := json.Unmarshal(raw, &header); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &header); err != nil { return err } if strictness == StrictnessLevel_Strict { @@ -97,13 +98,13 @@ func IntoBlock(raw json.RawMessage, ret **types.Block, strictness StrictnessLeve head *types.Header body rpcBlock ) - if err := json.Unmarshal(raw, &head); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &head); err != nil { return err } if head == nil { return ethereum.NotFound } - if err := json.Unmarshal(raw, &body); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &body); err != nil { return err } @@ -162,7 +163,7 @@ func IntoTransaction(raw json.RawMessage, tx **types.Transaction, strictness Str func IntoTransactionWithPending(raw json.RawMessage, tx **types.Transaction, pending *bool, strictness StrictnessLevel) error { var body *rpcTransaction - if err := json.Unmarshal(raw, &body); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &body); err != nil { return err } @@ -232,14 +233,14 @@ func (s *senderFromServer) SignatureValues(tx *types.Transaction, sig []byte) (R func resetVRS(msg []byte) ([]byte, error) { var m map[string]interface{} - err := json.Unmarshal(msg, &m) + err := sonic.ConfigFastest.Unmarshal(msg, &m) if err != nil { return nil, err } m["v"] = "0x0" m["r"] = "0x0" m["s"] = "0x0" - out, err := json.Marshal(m) + out, err := sonic.ConfigFastest.Marshal(m) if err != nil { return nil, err } diff --git a/ethtest/testchain.go b/ethtest/testchain.go index 4ac623cd..7d5fff24 100644 --- a/ethtest/testchain.go +++ b/ethtest/testchain.go @@ -2,7 +2,6 @@ package ethtest import ( "context" - "encoding/json" "fmt" "math/big" "os" @@ -19,6 +18,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/accounts/abi/bind" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/core/types" + "github.com/bytedance/sonic" ) type Testchain struct { @@ -339,7 +339,7 @@ func parseTestWalletMnemonic() (string, error) { Mnemonic string `json:"mnemonic"` } `json:"config"` } - err = json.Unmarshal(data, &dict) + err = sonic.ConfigFastest.Unmarshal(data, &dict) if err != nil { return "", fmt.Errorf("ParseTestWalletMnemonic, unmarshal: %w", err) } diff --git a/go-ethereum/accounts/abi/abi.go b/go-ethereum/accounts/abi/abi.go index fb840db1..a18a147b 100644 --- a/go-ethereum/accounts/abi/abi.go +++ b/go-ethereum/accounts/abi/abi.go @@ -18,7 +18,6 @@ package abi import ( "bytes" - "encoding/json" "errors" "fmt" "io" @@ -26,6 +25,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/bytedance/sonic" ) // The ABI holds information about a contract's context and available @@ -46,7 +46,7 @@ type ABI struct { // JSON returns a parsed ABI interface and error if it failed. func JSON(reader io.Reader) (ABI, error) { - dec := json.NewDecoder(reader) + dec := sonic.ConfigFastest.NewDecoder(reader) var abi ABI if err := dec.Decode(&abi); err != nil { @@ -134,7 +134,7 @@ func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) return args.UnpackIntoMap(v, data) } -// UnmarshalJSON implements json.Unmarshaler interface. +// UnmarshalJSON implements sonic.ConfigFastest.Unmarshaler interface. func (abi *ABI) UnmarshalJSON(data []byte) error { var fields []struct { Type string @@ -154,7 +154,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { // declared as anonymous. Anonymous bool } - if err := json.Unmarshal(data, &fields); err != nil { + if err := sonic.ConfigFastest.Unmarshal(data, &fields); err != nil { return err } abi.Methods = make(map[string]Method) diff --git a/go-ethereum/accounts/abi/argument.go b/go-ethereum/accounts/abi/argument.go index 227a088b..ecd50c1b 100644 --- a/go-ethereum/accounts/abi/argument.go +++ b/go-ethereum/accounts/abi/argument.go @@ -17,11 +17,12 @@ package abi import ( - "encoding/json" "errors" "fmt" "reflect" "strings" + + "github.com/bytedance/sonic" ) // Argument holds the name of the argument and the corresponding type. @@ -42,10 +43,10 @@ type ArgumentMarshaling struct { Indexed bool } -// UnmarshalJSON implements json.Unmarshaler interface. +// UnmarshalJSON implements sonic.ConfigFastest.Unmarshaler interface. func (argument *Argument) UnmarshalJSON(data []byte) error { var arg ArgumentMarshaling - err := json.Unmarshal(data, &arg) + err := sonic.ConfigFastest.Unmarshal(data, &arg) if err != nil { return fmt.Errorf("argument json err: %v", err) } diff --git a/go-ethereum/accounts/abi/event_test.go b/go-ethereum/accounts/abi/event_test.go index e2672152..fc8b7f87 100644 --- a/go-ethereum/accounts/abi/event_test.go +++ b/go-ethereum/accounts/abi/event_test.go @@ -19,7 +19,6 @@ package abi import ( "bytes" "encoding/hex" - "encoding/json" "math/big" "reflect" "strings" @@ -27,6 +26,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/bytedance/sonic" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -348,7 +349,7 @@ func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, ass data, err := hex.DecodeString(hexData) assert.NoError(err, "Hex data should be a correct hex-string") var e Event - assert.NoError(json.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI") + assert.NoError(sonic.ConfigFastest.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI") a := ABI{Events: map[string]Event{"e": e}} return a.UnpackIntoInterface(dest, "e", data) } diff --git a/go-ethereum/accounts/hd.go b/go-ethereum/accounts/hd.go index daca75eb..255a1142 100644 --- a/go-ethereum/accounts/hd.go +++ b/go-ethereum/accounts/hd.go @@ -17,12 +17,13 @@ package accounts import ( - "encoding/json" "errors" "fmt" "math" "math/big" "strings" + + "github.com/bytedance/sonic" ) // DefaultRootDerivationPath is the root path to which custom derivation endpoints @@ -137,14 +138,14 @@ func (path DerivationPath) String() string { // MarshalJSON turns a derivation path into its json-serialized string func (path DerivationPath) MarshalJSON() ([]byte, error) { - return json.Marshal(path.String()) + return sonic.ConfigFastest.Marshal(path.String()) } // UnmarshalJSON a json-serialized string back into a derivation path func (path *DerivationPath) UnmarshalJSON(b []byte) error { var dp string var err error - if err = json.Unmarshal(b, &dp); err != nil { + if err = sonic.ConfigFastest.Unmarshal(b, &dp); err != nil { return err } *path, err = ParseDerivationPath(dp) diff --git a/go-ethereum/accounts/keystore/account_cache.go b/go-ethereum/accounts/keystore/account_cache.go index 92842ba5..8fcab4ba 100644 --- a/go-ethereum/accounts/keystore/account_cache.go +++ b/go-ethereum/accounts/keystore/account_cache.go @@ -18,7 +18,6 @@ package keystore import ( "bufio" - "encoding/json" "fmt" "os" "path/filepath" @@ -31,6 +30,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/accounts" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/log" + "github.com/bytedance/sonic" + mapset "github.com/deckarep/golang-set/v2" ) @@ -265,7 +266,7 @@ func (ac *accountCache) scanAccounts() error { buf.Reset(fd) // Parse the address. key.Address = "" - err = json.NewDecoder(buf).Decode(&key) + err = sonic.ConfigFastest.NewDecoder(buf).Decode(&key) addr := common.HexToAddress(key.Address) switch { case err != nil: diff --git a/go-ethereum/accounts/keystore/key.go b/go-ethereum/accounts/keystore/key.go index d065c11b..6ceb9585 100644 --- a/go-ethereum/accounts/keystore/key.go +++ b/go-ethereum/accounts/keystore/key.go @@ -20,7 +20,6 @@ import ( "bytes" "crypto/ecdsa" "encoding/hex" - "encoding/json" "fmt" "io" "os" @@ -31,6 +30,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/accounts" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/bytedance/sonic" + "github.com/google/uuid" ) @@ -97,13 +98,13 @@ func (k *Key) MarshalJSON() (j []byte, err error) { k.Id.String(), version, } - j, err = json.Marshal(jStruct) + j, err = sonic.ConfigFastest.Marshal(jStruct) return j, err } func (k *Key) UnmarshalJSON(j []byte) (err error) { keyJSON := new(plainKeyJSON) - err = json.Unmarshal(j, &keyJSON) + err = sonic.ConfigFastest.Unmarshal(j, &keyJSON) if err != nil { return err } diff --git a/go-ethereum/accounts/keystore/passphrase.go b/go-ethereum/accounts/keystore/passphrase.go index 99533509..2cb914e7 100644 --- a/go-ethereum/accounts/keystore/passphrase.go +++ b/go-ethereum/accounts/keystore/passphrase.go @@ -31,7 +31,6 @@ import ( "crypto/rand" "crypto/sha256" "encoding/hex" - "encoding/json" "fmt" "io" "os" @@ -41,6 +40,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/math" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/bytedance/sonic" + "github.com/google/uuid" "golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/scrypt" @@ -193,14 +194,14 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { key.Id.String(), version, } - return json.Marshal(encryptedKeyJSONV3) + return sonic.ConfigFastest.Marshal(encryptedKeyJSONV3) } // DecryptKey decrypts a key from a json blob, returning the private key itself. func DecryptKey(keyjson []byte, auth string) (*Key, error) { // Parse the json into a simple map to fetch the key version m := make(map[string]interface{}) - if err := json.Unmarshal(keyjson, &m); err != nil { + if err := sonic.ConfigFastest.Unmarshal(keyjson, &m); err != nil { return nil, err } // Depending on the version try to parse one way or another @@ -210,13 +211,13 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { ) if version, ok := m["version"].(string); ok && version == "1" { k := new(encryptedKeyJSONV1) - if err := json.Unmarshal(keyjson, k); err != nil { + if err := sonic.ConfigFastest.Unmarshal(keyjson, k); err != nil { return nil, err } keyBytes, keyId, err = decryptKeyV1(k, auth) } else { k := new(encryptedKeyJSONV3) - if err := json.Unmarshal(keyjson, k); err != nil { + if err := sonic.ConfigFastest.Unmarshal(keyjson, k); err != nil { return nil, err } keyBytes, keyId, err = decryptKeyV3(k, auth) diff --git a/go-ethereum/accounts/keystore/plain.go b/go-ethereum/accounts/keystore/plain.go index eeaf0fd9..6dc6bca8 100644 --- a/go-ethereum/accounts/keystore/plain.go +++ b/go-ethereum/accounts/keystore/plain.go @@ -17,12 +17,12 @@ package keystore import ( - "encoding/json" "fmt" "os" "path/filepath" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/bytedance/sonic" ) type keyStorePlain struct { @@ -36,7 +36,7 @@ func (ks keyStorePlain) GetKey(addr common.Address, filename, auth string) (*Key } defer fd.Close() key := new(Key) - if err := json.NewDecoder(fd).Decode(key); err != nil { + if err := sonic.ConfigFastest.NewDecoder(fd).Decode(key); err != nil { return nil, err } if key.Address != addr { @@ -46,7 +46,7 @@ func (ks keyStorePlain) GetKey(addr common.Address, filename, auth string) (*Key } func (ks keyStorePlain) StoreKey(filename string, key *Key, auth string) error { - content, err := json.Marshal(key) + content, err := sonic.ConfigFastest.Marshal(key) if err != nil { return err } diff --git a/go-ethereum/accounts/keystore/presale.go b/go-ethereum/accounts/keystore/presale.go index e4e0a67e..bbebd7dd 100644 --- a/go-ethereum/accounts/keystore/presale.go +++ b/go-ethereum/accounts/keystore/presale.go @@ -21,12 +21,13 @@ import ( "crypto/cipher" "crypto/sha256" "encoding/hex" - "encoding/json" "errors" "fmt" "github.com/0xsequence/ethkit/go-ethereum/accounts" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/bytedance/sonic" + "github.com/google/uuid" "golang.org/x/crypto/pbkdf2" ) @@ -59,7 +60,7 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error Email string BtcAddr string }{} - err = json.Unmarshal(fileContent, &preSaleKeyStruct) + err = sonic.ConfigFastest.Unmarshal(fileContent, &preSaleKeyStruct) if err != nil { return nil, err } diff --git a/go-ethereum/accounts/url.go b/go-ethereum/accounts/url.go index 39b00e5b..64f1e454 100644 --- a/go-ethereum/accounts/url.go +++ b/go-ethereum/accounts/url.go @@ -17,10 +17,11 @@ package accounts import ( - "encoding/json" "errors" "fmt" "strings" + + "github.com/bytedance/sonic" ) // URL represents the canonical identification URL of a wallet or account. @@ -69,15 +70,15 @@ func (u URL) TerminalString() string { return url } -// MarshalJSON implements the json.Marshaller interface. +// MarshalJSON implements the sonic.ConfigFastest.Marshaller interface. func (u URL) MarshalJSON() ([]byte, error) { - return json.Marshal(u.String()) + return sonic.ConfigFastest.Marshal(u.String()) } // UnmarshalJSON parses url. func (u *URL) UnmarshalJSON(input []byte) error { var textURL string - err := json.Unmarshal(input, &textURL) + err := sonic.ConfigFastest.Unmarshal(input, &textURL) if err != nil { return err } diff --git a/go-ethereum/common/hexutil/json.go b/go-ethereum/common/hexutil/json.go index ce2d8cc6..27d11316 100644 --- a/go-ethereum/common/hexutil/json.go +++ b/go-ethereum/common/hexutil/json.go @@ -24,6 +24,7 @@ import ( "reflect" "strconv" + "github.com/0xsequence/ethkit/util" "github.com/holiman/uint256" ) @@ -47,6 +48,11 @@ func (b Bytes) MarshalText() ([]byte, error) { return result, nil } +// MarshalJSON implements json.Marshaler. +func (b Bytes) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Bytes) UnmarshalJSON(input []byte) error { if !isString(input) { @@ -159,6 +165,11 @@ func (b Big) MarshalText() ([]byte, error) { return []byte(EncodeBig((*big.Int)(&b))), nil } +// MarshalJSON implements json.Marshaler. +func (b Big) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Big) UnmarshalJSON(input []byte) error { if !isString(input) { @@ -238,6 +249,11 @@ func (b U256) MarshalText() ([]byte, error) { return []byte(u256.Hex()), nil } +// MarshalJSON implements json.Marshaler. +func (b U256) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *U256) UnmarshalJSON(input []byte) error { // The uint256.Int.UnmarshalJSON method accepts "dec", "0xhex"; we must be @@ -282,6 +298,11 @@ func (b Uint64) MarshalText() ([]byte, error) { return buf, nil } +// MarshalJSON implements json.Marshaler. +func (b Uint64) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Uint64) UnmarshalJSON(input []byte) error { if !isString(input) { @@ -343,6 +364,11 @@ func (b Uint) MarshalText() ([]byte, error) { return Uint64(b).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b Uint) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalJSON implements json.Unmarshaler. func (b *Uint) UnmarshalJSON(input []byte) error { if !isString(input) { diff --git a/go-ethereum/common/hexutil/json_example_test.go b/go-ethereum/common/hexutil/json_example_test.go index 87f955ca..1f85b7ba 100644 --- a/go-ethereum/common/hexutil/json_example_test.go +++ b/go-ethereum/common/hexutil/json_example_test.go @@ -17,10 +17,10 @@ package hexutil_test import ( - "encoding/json" "fmt" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) type MyType [5]byte @@ -35,8 +35,8 @@ func (v MyType) String() string { func ExampleUnmarshalFixedText() { var v1, v2 MyType - fmt.Println("v1 error:", json.Unmarshal([]byte(`"0x01"`), &v1)) - fmt.Println("v2 error:", json.Unmarshal([]byte(`"0x0101010101"`), &v2)) + fmt.Println("v1 error:", sonic.ConfigFastest.Unmarshal([]byte(`"0x01"`), &v1)) + fmt.Println("v2 error:", sonic.ConfigFastest.Unmarshal([]byte(`"0x0101010101"`), &v2)) fmt.Println("v2:", v2) // Output: // v1 error: hex string has length 2, want 10 for MyType diff --git a/go-ethereum/common/hexutil/json_test.go b/go-ethereum/common/hexutil/json_test.go index 7cca3009..67205867 100644 --- a/go-ethereum/common/hexutil/json_test.go +++ b/go-ethereum/common/hexutil/json_test.go @@ -19,11 +19,11 @@ package hexutil import ( "bytes" "encoding/hex" - "encoding/json" "errors" "math/big" "testing" + "github.com/bytedance/sonic" "github.com/holiman/uint256" ) @@ -86,7 +86,7 @@ var unmarshalBytesTests = []unmarshalTest{ func TestUnmarshalBytes(t *testing.T) { for _, test := range unmarshalBytesTests { var v Bytes - err := json.Unmarshal([]byte(test.input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(test.input), &v) if !checkError(t, test.input, err, test.wantErr) { continue } @@ -110,7 +110,7 @@ func BenchmarkUnmarshalBytes(b *testing.B) { func TestMarshalBytes(t *testing.T) { for _, test := range encodeBytesTests { in := test.input.([]byte) - out, err := json.Marshal(Bytes(in)) + out, err := sonic.ConfigFastest.Marshal(Bytes(in)) if err != nil { t.Errorf("%x: %v", in, err) continue @@ -167,7 +167,7 @@ var unmarshalBigTests = []unmarshalTest{ func TestUnmarshalBig(t *testing.T) { for _, test := range unmarshalBigTests { var v Big - err := json.Unmarshal([]byte(test.input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(test.input), &v) if !checkError(t, test.input, err, test.wantErr) { continue } @@ -219,7 +219,7 @@ var unmarshalU256Tests = []unmarshalTest{ func TestUnmarshalU256(t *testing.T) { for _, test := range unmarshalU256Tests { var v U256 - err := json.Unmarshal([]byte(test.input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(test.input), &v) if !checkError(t, test.input, err, test.wantErr) { continue } @@ -249,7 +249,7 @@ func BenchmarkUnmarshalBig(b *testing.B) { func TestMarshalBig(t *testing.T) { for _, test := range encodeBigTests { in := test.input.(*big.Int) - out, err := json.Marshal((*Big)(in)) + out, err := sonic.ConfigFastest.Marshal((*Big)(in)) if err != nil { t.Errorf("%d: %v", in, err) continue @@ -291,7 +291,7 @@ var unmarshalUint64Tests = []unmarshalTest{ func TestUnmarshalUint64(t *testing.T) { for _, test := range unmarshalUint64Tests { var v Uint64 - err := json.Unmarshal([]byte(test.input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(test.input), &v) if !checkError(t, test.input, err, test.wantErr) { continue } @@ -313,7 +313,7 @@ func BenchmarkUnmarshalUint64(b *testing.B) { func TestMarshalUint64(t *testing.T) { for _, test := range encodeUint64Tests { in := test.input.(uint64) - out, err := json.Marshal(Uint64(in)) + out, err := sonic.ConfigFastest.Marshal(Uint64(in)) if err != nil { t.Errorf("%d: %v", in, err) continue @@ -332,7 +332,7 @@ func TestMarshalUint64(t *testing.T) { func TestMarshalUint(t *testing.T) { for _, test := range encodeUintTests { in := test.input.(uint) - out, err := json.Marshal(Uint(in)) + out, err := sonic.ConfigFastest.Marshal(Uint(in)) if err != nil { t.Errorf("%d: %v", in, err) continue @@ -383,7 +383,7 @@ var unmarshalUintTests = []unmarshalTest{ func TestUnmarshalUint(t *testing.T) { for _, test := range unmarshalUintTests { var v Uint - err := json.Unmarshal([]byte(test.input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(test.input), &v) if uintBits == 32 && test.wantErr32bit != nil { checkError(t, test.input, err, test.wantErr32bit) continue diff --git a/go-ethereum/common/math/big.go b/go-ethereum/common/math/big.go index d9748d01..e4093b65 100644 --- a/go-ethereum/common/math/big.go +++ b/go-ethereum/common/math/big.go @@ -20,6 +20,8 @@ package math import ( "fmt" "math/big" + + "github.com/0xsequence/ethkit/util" ) // Various big integer limit values. @@ -49,7 +51,7 @@ func NewHexOrDecimal256(x int64) *HexOrDecimal256 { return &h } -// UnmarshalJSON implements json.Unmarshaler. +// UnmarshalJSON implements sonic.ConfigFastest.Unmarshaler. // // It is similar to UnmarshalText, but allows parsing real decimals too, not just // quoted decimal strings. @@ -78,6 +80,11 @@ func (i *HexOrDecimal256) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("%#x", (*big.Int)(i))), nil } +// MarshalJSON implements json.Marshaler. +func (i HexOrDecimal256) MarshalJSON() ([]byte, error) { + return util.QuoteString(&i) +} + // Decimal256 unmarshals big.Int as a decimal string. When unmarshalling, // it however accepts either "0x"-prefixed (hex encoded) or non-prefixed (decimal) type Decimal256 big.Int @@ -104,6 +111,11 @@ func (i *Decimal256) MarshalText() ([]byte, error) { return []byte(i.String()), nil } +// MarshalJSON implements json.Marshaler. +func (i Decimal256) MarshalJSON() ([]byte, error) { + return util.QuoteString(&i) +} + // String implements Stringer. func (i *Decimal256) String() string { if i == nil { diff --git a/go-ethereum/common/math/integer.go b/go-ethereum/common/math/integer.go index 82de96f9..2cb421a8 100644 --- a/go-ethereum/common/math/integer.go +++ b/go-ethereum/common/math/integer.go @@ -20,6 +20,8 @@ import ( "fmt" "math/bits" "strconv" + + "github.com/0xsequence/ethkit/util" ) // Integer limit values. @@ -41,7 +43,7 @@ const ( // HexOrDecimal64 marshals uint64 as hex or decimal. type HexOrDecimal64 uint64 -// UnmarshalJSON implements json.Unmarshaler. +// UnmarshalJSON implements sonic.ConfigFastest.Unmarshaler. // // It is similar to UnmarshalText, but allows parsing real decimals too, not just // quoted decimal strings. @@ -67,6 +69,11 @@ func (i HexOrDecimal64) MarshalText() ([]byte, error) { return []byte(fmt.Sprintf("%#x", uint64(i))), nil } +// MarshalJSON implements json.Marshaler. +func (i HexOrDecimal64) MarshalJSON() ([]byte, error) { + return util.QuoteString(i) +} + // ParseUint64 parses s as an integer in decimal or hexadecimal syntax. // Leading zeros are accepted. The empty string parses as zero. func ParseUint64(s string) (uint64, bool) { diff --git a/go-ethereum/common/test_utils.go b/go-ethereum/common/test_utils.go index 7a175412..ea071b17 100644 --- a/go-ethereum/common/test_utils.go +++ b/go-ethereum/common/test_utils.go @@ -20,6 +20,8 @@ import ( "encoding/json" "fmt" "os" + + "github.com/bytedance/sonic" ) // LoadJSON reads the given file and unmarshals its content. @@ -28,7 +30,7 @@ func LoadJSON(file string, val interface{}) error { if err != nil { return err } - if err := json.Unmarshal(content, val); err != nil { + if err := sonic.ConfigFastest.Unmarshal(content, val); err != nil { if syntaxerr, ok := err.(*json.SyntaxError); ok { line := findLine(content, syntaxerr.Offset) return fmt.Errorf("JSON syntax error at %v:%v: %v", file, line, err) diff --git a/go-ethereum/common/types.go b/go-ethereum/common/types.go index 1416884e..8a4b1949 100644 --- a/go-ethereum/common/types.go +++ b/go-ethereum/common/types.go @@ -30,6 +30,8 @@ import ( "strings" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" + "golang.org/x/crypto/sha3" ) @@ -142,6 +144,17 @@ func (h Hash) MarshalText() ([]byte, error) { return hexutil.Bytes(h[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (h Hash) MarshalJSON() ([]byte, error) { + raw, err := h.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil +} + // SetBytes sets the hash to the value of b. // If b is larger than len(h), b will be cropped from the left. func (h *Hash) SetBytes(b []byte) { @@ -204,7 +217,20 @@ func (h *UnprefixedHash) UnmarshalText(input []byte) error { // MarshalText encodes the hash as hex. func (h UnprefixedHash) MarshalText() ([]byte, error) { - return []byte(hex.EncodeToString(h[:])), nil + b := make([]byte, hex.EncodedLen(len(h))) + hex.Encode(b, h[:]) + return b, nil +} + +// MarshalJSON implements json.Marshaler. +func (h UnprefixedHash) MarshalJSON() ([]byte, error) { + raw, err := h.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil } /////////// Address @@ -323,11 +349,22 @@ func (a *Address) SetBytes(b []byte) { copy(a[AddressLength-len(b):], b) } -// MarshalText returns the hex representation of a. +// MarshalText returns the hex representation of the address. func (a Address) MarshalText() ([]byte, error) { return hexutil.Bytes(a[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (a Address) MarshalJSON() ([]byte, error) { + raw, err := a.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil +} + // UnmarshalText parses a hash in hex syntax. func (a *Address) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("Address", input, a[:]) @@ -381,7 +418,20 @@ func (a *UnprefixedAddress) UnmarshalText(input []byte) error { // MarshalText encodes the address as hex. func (a UnprefixedAddress) MarshalText() ([]byte, error) { - return []byte(hex.EncodeToString(a[:])), nil + b := make([]byte, hex.EncodedLen(len(a))) + hex.Encode(b, a[:]) + return b, nil +} + +// MarshalJSON implements json.Marshaler. +func (a UnprefixedAddress) MarshalJSON() ([]byte, error) { + raw, err := a.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil } // MixedcaseAddress retains the original string, which may or may not be @@ -410,15 +460,15 @@ func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error { if err := hexutil.UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil { return err } - return json.Unmarshal(input, &ma.original) + return sonic.ConfigFastest.Unmarshal(input, &ma.original) } // MarshalJSON marshals the original value func (ma MixedcaseAddress) MarshalJSON() ([]byte, error) { if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") { - return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:])) + return sonic.ConfigFastest.Marshal(fmt.Sprintf("0x%s", ma.original[2:])) } - return json.Marshal(fmt.Sprintf("0x%s", ma.original)) + return sonic.ConfigFastest.Marshal(fmt.Sprintf("0x%s", ma.original)) } // Address returns the address @@ -454,7 +504,7 @@ func (addr AddressEIP55) String() string { // MarshalJSON marshals the address in the manner of EIP55. func (addr AddressEIP55) MarshalJSON() ([]byte, error) { - return json.Marshal(addr.String()) + return sonic.ConfigFastest.Marshal(addr.String()) } type Decimal uint64 diff --git a/go-ethereum/common/types_test.go b/go-ethereum/common/types_test.go index 11247b11..93ca905c 100644 --- a/go-ethereum/common/types_test.go +++ b/go-ethereum/common/types_test.go @@ -19,7 +19,6 @@ package common import ( "bytes" "database/sql/driver" - "encoding/json" "fmt" "math" "math/big" @@ -27,6 +26,8 @@ import ( "strings" "testing" "time" + + "github.com/bytedance/sonic" ) func TestBytesConversion(t *testing.T) { @@ -81,7 +82,7 @@ func TestHashJsonValidation(t *testing.T) { for _, test := range tests { input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"` var v Hash - err := json.Unmarshal([]byte(input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(input), &v) if err == nil { if test.Error != "" { t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error) @@ -110,7 +111,7 @@ func TestAddressUnmarshalJSON(t *testing.T) { } for i, test := range tests { var v Address - err := json.Unmarshal([]byte(test.Input), &v) + err := sonic.ConfigFastest.Unmarshal([]byte(test.Input), &v) if err != nil && !test.ShouldErr { t.Errorf("test #%d: unexpected error: %v", i, err) } @@ -171,11 +172,11 @@ func TestMixedcaseAddressMarshal(t *testing.T) { if err != nil { t.Fatal(err) } - blob, err := json.Marshal(*addr) + blob, err := sonic.ConfigFastest.Marshal(*addr) if err != nil { t.Fatal(err) } - json.Unmarshal(blob, &output) + sonic.ConfigFastest.Unmarshal(blob, &output) if output != input { t.Fatal("Failed to marshal/unmarshal MixedcaseAddress object") } @@ -189,7 +190,7 @@ func TestMixedcaseAccount_Address(t *testing.T) { A MixedcaseAddress Valid bool } - if err := json.Unmarshal([]byte(`[ + if err := sonic.ConfigFastest.Unmarshal([]byte(`[ {"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, {"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true}, {"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, @@ -215,7 +216,7 @@ func TestMixedcaseAccount_Address(t *testing.T) { `["x1111111111111111111112222222222223333323"]`, // Missing 0 `["0xG111111111111111111112222222222223333323"]`, //Non-hex } { - if err := json.Unmarshal([]byte(r), &r2); err == nil { + if err := sonic.ConfigFastest.Unmarshal([]byte(r), &r2); err == nil { t.Errorf("Expected failure, input %v", r) } } @@ -578,7 +579,7 @@ func TestAddressEIP55(t *testing.T) { t.Fatal("Address with checksum is expected") } var dec Address - if err := json.Unmarshal(blob, &dec); err != nil { + if err := sonic.ConfigFastest.Unmarshal(blob, &dec); err != nil { t.Fatal("Failed to unmarshal AddressEIP55", err) } if addr != dec { diff --git a/go-ethereum/core/types/account.go b/go-ethereum/core/types/account.go index 283a0363..f5b19c29 100644 --- a/go-ethereum/core/types/account.go +++ b/go-ethereum/core/types/account.go @@ -19,13 +19,15 @@ package types import ( "bytes" "encoding/hex" - "encoding/json" "fmt" "math/big" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/common/math" + "github.com/bytedance/sonic" + + "github.com/0xsequence/ethkit/util" ) //go:generate go run github.com/fjl/gencodec -type Account -field-override accountMarshaling -out gen_account.go @@ -71,12 +73,17 @@ func (h storageJSON) MarshalText() ([]byte, error) { return hexutil.Bytes(h[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (h storageJSON) MarshalJSON() ([]byte, error) { + return util.QuoteString(h) +} + // GenesisAlloc specifies the initial state of a genesis block. type GenesisAlloc map[common.Address]Account func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { m := make(map[common.UnprefixedAddress]Account) - if err := json.Unmarshal(data, &m); err != nil { + if err := sonic.ConfigFastest.Unmarshal(data, &m); err != nil { return err } *ga = make(GenesisAlloc) diff --git a/go-ethereum/core/types/block.go b/go-ethereum/core/types/block.go index c0acc267..33d288c7 100644 --- a/go-ethereum/core/types/block.go +++ b/go-ethereum/core/types/block.go @@ -19,7 +19,6 @@ package types import ( "encoding/binary" - "encoding/json" "fmt" "io" "math/big" @@ -31,6 +30,9 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/rlp" + "github.com/bytedance/sonic" + + "github.com/0xsequence/ethkit/util" ) // A BlockNonce is a 64-bit hash which proves (combined with the @@ -55,6 +57,11 @@ func (n BlockNonce) MarshalText() ([]byte, error) { return hexutil.Bytes(n[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b BlockNonce) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalText implements encoding.TextUnmarshaler. func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) @@ -547,7 +554,7 @@ type blockHydrate struct { // NOTE: method added by ethkit func (b *Block) MarshalJSON() ([]byte, error) { - return json.Marshal(&blockHydrate{ + return sonic.ConfigFastest.Marshal(&blockHydrate{ Header: b.header, Uncles: b.uncles, Transactions: b.transactions, @@ -557,7 +564,7 @@ func (b *Block) MarshalJSON() ([]byte, error) { // NOTE: method added by ethkit func (b *Block) UnmarshalJSON(data []byte) error { var h *blockHydrate - err := json.Unmarshal(data, &h) + err := sonic.ConfigFastest.Unmarshal(data, &h) if err != nil { return err } diff --git a/go-ethereum/core/types/bloom9.go b/go-ethereum/core/types/bloom9.go index 87ba2e6b..0eb55b12 100644 --- a/go-ethereum/core/types/bloom9.go +++ b/go-ethereum/core/types/bloom9.go @@ -23,6 +23,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/crypto" + "github.com/0xsequence/ethkit/util" ) type bytesBacked interface { @@ -95,6 +96,11 @@ func (b Bloom) MarshalText() ([]byte, error) { return hexutil.Bytes(b[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b Bloom) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // UnmarshalText b as a hex string with 0x prefix. func (b *Bloom) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("Bloom", input, b[:]) @@ -116,7 +122,7 @@ func CreateBloom(receipts Receipts) Bloom { } // LogsBloom returns the bloom bytes for the given logs -func LogsBloom(logs []*Log) []byte { +func LogsBloom(logs []Log) []byte { buf := make([]byte, 6) var bin Bloom for _, log := range logs { diff --git a/go-ethereum/core/types/bloom9_test.go b/go-ethereum/core/types/bloom9_test.go index 26d21e0f..a599714f 100644 --- a/go-ethereum/core/types/bloom9_test.go +++ b/go-ethereum/core/types/bloom9_test.go @@ -100,7 +100,7 @@ func BenchmarkCreateBloom(b *testing.B) { &Receipt{ Status: ReceiptStatusFailed, CumulativeGasUsed: 1, - Logs: []*Log{ + Logs: []Log{ {Address: common.BytesToAddress([]byte{0x11})}, {Address: common.BytesToAddress([]byte{0x01, 0x11})}, }, @@ -111,7 +111,7 @@ func BenchmarkCreateBloom(b *testing.B) { &Receipt{ PostState: common.Hash{2}.Bytes(), CumulativeGasUsed: 3, - Logs: []*Log{ + Logs: []Log{ {Address: common.BytesToAddress([]byte{0x22})}, {Address: common.BytesToAddress([]byte{0x02, 0x22})}, }, diff --git a/go-ethereum/core/types/gen_access_tuple.go b/go-ethereum/core/types/gen_access_tuple.go index 46713dc7..40c199a5 100644 --- a/go-ethereum/core/types/gen_access_tuple.go +++ b/go-ethereum/core/types/gen_access_tuple.go @@ -3,10 +3,10 @@ package types import ( - "encoding/json" "errors" "github.com/0xsequence/ethkit/go-ethereum/common" + "github.com/bytedance/sonic" ) // MarshalJSON marshals as JSON. @@ -18,7 +18,7 @@ func (a AccessTuple) MarshalJSON() ([]byte, error) { var enc AccessTuple enc.Address = a.Address enc.StorageKeys = a.StorageKeys - return json.Marshal(&enc) + return sonic.ConfigFastest.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. @@ -28,7 +28,7 @@ func (a *AccessTuple) UnmarshalJSON(input []byte) error { StorageKeys []common.Hash `json:"storageKeys" gencodec:"required"` } var dec AccessTuple - if err := json.Unmarshal(input, &dec); err != nil { + if err := sonic.ConfigFastest.Unmarshal(input, &dec); err != nil { return err } if dec.Address == nil { diff --git a/go-ethereum/core/types/gen_header_json.go b/go-ethereum/core/types/gen_header_json.go index 6a476d47..e434775a 100644 --- a/go-ethereum/core/types/gen_header_json.go +++ b/go-ethereum/core/types/gen_header_json.go @@ -1,12 +1,12 @@ package types import ( - "encoding/json" "errors" "math/big" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) var _ = (*headerMarshaling)(nil) @@ -58,7 +58,7 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas) enc.ParentBeaconRoot = h.ParentBeaconRoot enc.BlockHash = h.BlockHash // added by ethkit - return json.Marshal(&enc) + return sonic.ConfigFastest.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. @@ -87,7 +87,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { BlockHash *common.Hash `json:"hash" gencodec:"required"` // added by ethkit } var dec Header - if err := json.Unmarshal(input, &dec); err != nil { + if err := sonic.ConfigFastest.Unmarshal(input, &dec); err != nil { return err } if dec.ParentHash == nil { diff --git a/go-ethereum/core/types/gen_log_json.go b/go-ethereum/core/types/gen_log_json.go index ad0c50b2..e3dccc2c 100644 --- a/go-ethereum/core/types/gen_log_json.go +++ b/go-ethereum/core/types/gen_log_json.go @@ -3,11 +3,11 @@ package types import ( - "encoding/json" "errors" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) var _ = (*logMarshaling)(nil) @@ -35,7 +35,7 @@ func (l Log) MarshalJSON() ([]byte, error) { enc.BlockHash = l.BlockHash enc.Index = hexutil.Uint(l.Index) enc.Removed = l.Removed - return json.Marshal(&enc) + return sonic.ConfigFastest.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. @@ -52,7 +52,7 @@ func (l *Log) UnmarshalJSON(input []byte) error { Removed *bool `json:"removed" rlp:"-"` } var dec Log - if err := json.Unmarshal(input, &dec); err != nil { + if err := sonic.ConfigFastest.Unmarshal(input, &dec); err != nil { return err } if dec.Address == nil { diff --git a/go-ethereum/core/types/gen_receipt_json.go b/go-ethereum/core/types/gen_receipt_json.go index 4d17b5e1..07a17e94 100644 --- a/go-ethereum/core/types/gen_receipt_json.go +++ b/go-ethereum/core/types/gen_receipt_json.go @@ -3,12 +3,12 @@ package types import ( - "encoding/json" "errors" "math/big" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) var _ = (*receiptMarshaling)(nil) @@ -21,7 +21,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { Status hexutil.Uint64 `json:"status"` CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + Logs []Log `json:"logs" gencodec:"required"` TxHash common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress common.Address `json:"contractAddress"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` @@ -48,7 +48,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { enc.BlockHash = r.BlockHash enc.BlockNumber = (*hexutil.Big)(r.BlockNumber) enc.TransactionIndex = hexutil.Uint(r.TransactionIndex) - return json.Marshal(&enc) + return sonic.ConfigFastest.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. @@ -59,7 +59,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { Status *hexutil.Uint64 `json:"status"` CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + Logs []Log `json:"logs" gencodec:"required"` TxHash *common.Hash `json:"transactionHash" gencodec:"required"` ContractAddress *common.Address `json:"contractAddress"` GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` @@ -71,7 +71,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { TransactionIndex *hexutil.Uint `json:"transactionIndex"` } var dec Receipt - if err := json.Unmarshal(input, &dec); err != nil { + if err := sonic.ConfigFastest.Unmarshal(input, &dec); err != nil { return err } if dec.Type != nil { diff --git a/go-ethereum/core/types/gen_withdrawal_json.go b/go-ethereum/core/types/gen_withdrawal_json.go index c5fd3119..dcedc7ec 100644 --- a/go-ethereum/core/types/gen_withdrawal_json.go +++ b/go-ethereum/core/types/gen_withdrawal_json.go @@ -3,10 +3,9 @@ package types import ( - "encoding/json" - "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" ) var _ = (*withdrawalMarshaling)(nil) @@ -24,7 +23,7 @@ func (w Withdrawal) MarshalJSON() ([]byte, error) { enc.Validator = hexutil.Uint64(w.Validator) enc.Address = w.Address enc.Amount = hexutil.Uint64(w.Amount) - return json.Marshal(&enc) + return sonic.ConfigFastest.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. @@ -36,7 +35,7 @@ func (w *Withdrawal) UnmarshalJSON(input []byte) error { Amount *hexutil.Uint64 `json:"amount"` } var dec Withdrawal - if err := json.Unmarshal(input, &dec); err != nil { + if err := sonic.ConfigFastest.Unmarshal(input, &dec); err != nil { return err } if dec.Index != nil { diff --git a/go-ethereum/core/types/log_test.go b/go-ethereum/core/types/log_test.go index 097eeec2..b3e03962 100644 --- a/go-ethereum/core/types/log_test.go +++ b/go-ethereum/core/types/log_test.go @@ -17,13 +17,14 @@ package types import ( - "encoding/json" "errors" "reflect" "testing" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" + "github.com/davecgh/go-spew/spew" ) @@ -105,7 +106,7 @@ func TestUnmarshalLog(t *testing.T) { dumper := spew.ConfigState{DisableMethods: true, Indent: " "} for name, test := range unmarshalLogTests { var log *Log - err := json.Unmarshal([]byte(test.input), &log) + err := sonic.ConfigFastest.Unmarshal([]byte(test.input), &log) checkError(t, name, err, test.wantError) if test.wantError == nil && err == nil { if !reflect.DeepEqual(log, test.want) { diff --git a/go-ethereum/core/types/receipt.go b/go-ethereum/core/types/receipt.go index b8fdde24..dabe226a 100644 --- a/go-ethereum/core/types/receipt.go +++ b/go-ethereum/core/types/receipt.go @@ -56,7 +56,7 @@ type Receipt struct { Status uint64 `json:"status"` CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + Logs []Log `json:"logs" gencodec:"required"` // Implementation fields: These fields are added by geth when processing a transaction. TxHash common.Hash `json:"transactionHash" gencodec:"required"` @@ -96,14 +96,14 @@ type receiptRLP struct { PostStateOrStatus []byte CumulativeGasUsed uint64 Bloom Bloom - Logs []*Log + Logs []Log } // storedReceiptRLP is the storage encoding of a receipt. type storedReceiptRLP struct { PostStateOrStatus []byte CumulativeGasUsed uint64 - Logs []*Log + Logs []Log } // NewReceipt creates a barebone transaction receipt, copying the init fields. diff --git a/go-ethereum/core/types/receipt_test.go b/go-ethereum/core/types/receipt_test.go index 90c458b8..36964b5b 100644 --- a/go-ethereum/core/types/receipt_test.go +++ b/go-ethereum/core/types/receipt_test.go @@ -18,7 +18,6 @@ package types import ( "bytes" - "encoding/json" "math" "math/big" "reflect" @@ -27,6 +26,8 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/params" "github.com/0xsequence/ethkit/go-ethereum/rlp" + "github.com/bytedance/sonic" + "github.com/holiman/uint256" "github.com/kylelemons/godebug/diff" ) @@ -35,7 +36,7 @@ var ( legacyReceipt = &Receipt{ Status: ReceiptStatusFailed, CumulativeGasUsed: 1, - Logs: []*Log{ + Logs: []Log{ { Address: common.BytesToAddress([]byte{0x11}), Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, @@ -51,7 +52,7 @@ var ( accessListReceipt = &Receipt{ Status: ReceiptStatusFailed, CumulativeGasUsed: 1, - Logs: []*Log{ + Logs: []Log{ { Address: common.BytesToAddress([]byte{0x11}), Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, @@ -68,7 +69,7 @@ var ( eip1559Receipt = &Receipt{ Status: ReceiptStatusFailed, CumulativeGasUsed: 1, - Logs: []*Log{ + Logs: []Log{ { Address: common.BytesToAddress([]byte{0x11}), Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, @@ -160,7 +161,7 @@ var ( &Receipt{ Status: ReceiptStatusFailed, CumulativeGasUsed: 1, - Logs: []*Log{ + Logs: []Log{ { Address: common.BytesToAddress([]byte{0x11}), Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, @@ -194,7 +195,7 @@ var ( &Receipt{ PostState: common.Hash{2}.Bytes(), CumulativeGasUsed: 3, - Logs: []*Log{ + Logs: []Log{ { Address: common.BytesToAddress([]byte{0x22}), Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, @@ -228,7 +229,7 @@ var ( Type: AccessListTxType, PostState: common.Hash{3}.Bytes(), CumulativeGasUsed: 6, - Logs: []*Log{}, + Logs: []Log{}, // derived fields: TxHash: txs[2].Hash(), GasUsed: 3, @@ -241,7 +242,7 @@ var ( Type: DynamicFeeTxType, PostState: common.Hash{4}.Bytes(), CumulativeGasUsed: 10, - Logs: []*Log{}, + Logs: []Log{}, // derived fields: TxHash: txs[3].Hash(), GasUsed: 4, @@ -254,7 +255,7 @@ var ( Type: DynamicFeeTxType, PostState: common.Hash{5}.Bytes(), CumulativeGasUsed: 15, - Logs: []*Log{}, + Logs: []Log{}, // derived fields: TxHash: txs[4].Hash(), GasUsed: 5, @@ -267,7 +268,7 @@ var ( Type: BlobTxType, PostState: common.Hash{6}.Bytes(), CumulativeGasUsed: 21, - Logs: []*Log{}, + Logs: []Log{}, // derived fields: TxHash: txs[5].Hash(), GasUsed: 6, @@ -282,7 +283,7 @@ var ( Type: BlobTxType, PostState: common.Hash{7}.Bytes(), CumulativeGasUsed: 28, - Logs: []*Log{}, + Logs: []Log{}, // derived fields: TxHash: txs[6].Hash(), GasUsed: 7, @@ -317,12 +318,12 @@ func TestDeriveFields(t *testing.T) { } // Check diff of receipts against derivedReceipts. - r1, err := json.MarshalIndent(receipts, "", " ") + r1, err := sonic.ConfigFastest.MarshalIndent(receipts, "", " ") if err != nil { t.Fatal("error marshaling input receipts:", err) } - r2, err := json.MarshalIndent(derivedReceipts, "", " ") + r2, err := sonic.ConfigFastest.MarshalIndent(derivedReceipts, "", " ") if err != nil { t.Fatal("error marshaling derived receipts:", err) } @@ -514,16 +515,16 @@ func clearComputedFieldsOnReceipt(receipt *Receipt) *Receipt { return &cpy } -func clearComputedFieldsOnLogs(logs []*Log) []*Log { - l := make([]*Log, len(logs)) +func clearComputedFieldsOnLogs(logs []Log) []Log { + l := make([]Log, len(logs)) for i, log := range logs { - cpy := *log + cpy := log cpy.BlockNumber = math.MaxUint32 cpy.BlockHash = common.Hash{} cpy.TxHash = common.Hash{} cpy.TxIndex = math.MaxUint32 cpy.Index = math.MaxUint32 - l[i] = &cpy + l[i] = cpy } return l } diff --git a/go-ethereum/core/types/transaction_marshalling.go b/go-ethereum/core/types/transaction_marshalling.go index ba1ca58d..8343daf6 100644 --- a/go-ethereum/core/types/transaction_marshalling.go +++ b/go-ethereum/core/types/transaction_marshalling.go @@ -17,13 +17,14 @@ package types import ( - "encoding/json" "errors" "math/big" "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/crypto/kzg4844" + "github.com/bytedance/sonic" + "github.com/holiman/uint256" ) @@ -154,13 +155,13 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { enc.Proofs = itx.Sidecar.Proofs } } - return json.Marshal(&enc) + return sonic.ConfigFastest.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (tx *Transaction) UnmarshalJSON(input []byte) error { var dec txJSON - err := json.Unmarshal(input, &dec) + err := sonic.ConfigFastest.Unmarshal(input, &dec) if err != nil { return err } diff --git a/go-ethereum/core/types/transaction_test.go b/go-ethereum/core/types/transaction_test.go index 1f903af5..88bc11c0 100644 --- a/go-ethereum/core/types/transaction_test.go +++ b/go-ethereum/core/types/transaction_test.go @@ -19,7 +19,6 @@ package types import ( "bytes" "crypto/ecdsa" - "encoding/json" "errors" "fmt" "maps" @@ -30,6 +29,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/crypto" "github.com/0xsequence/ethkit/go-ethereum/rlp" + "github.com/bytedance/sonic" ) // The values in those tests are from the Transaction Tests @@ -346,12 +346,12 @@ func TestTransactionCoding(t *testing.T) { } func encodeDecodeJSON(tx *Transaction) (*Transaction, error) { - data, err := json.Marshal(tx) + data, err := sonic.ConfigFastest.Marshal(tx) if err != nil { return nil, fmt.Errorf("json encoding failed: %v", err) } var parsedTx = &Transaction{} - if err := json.Unmarshal(data, &parsedTx); err != nil { + if err := sonic.ConfigFastest.Unmarshal(data, &parsedTx); err != nil { return nil, fmt.Errorf("json decoding failed: %v", err) } return parsedTx, nil @@ -528,7 +528,7 @@ func TestYParityJSONUnmarshalling(t *testing.T) { testJson["type"] = fmt.Sprintf("0x%x", txType) // Marshal the JSON - jsonBytes, err := json.Marshal(testJson) + jsonBytes, err := sonic.ConfigFastest.Marshal(testJson) if err != nil { t.Fatal(err) } diff --git a/go-ethereum/core/types/types_test.go b/go-ethereum/core/types/types_test.go index 13ce71d8..fb488f34 100644 --- a/go-ethereum/core/types/types_test.go +++ b/go-ethereum/core/types/types_test.go @@ -76,7 +76,7 @@ func benchRLP(b *testing.B, encode bool) { &ReceiptForStorage{ Status: ReceiptStatusSuccessful, CumulativeGasUsed: 0x888888888, - Logs: make([]*Log, 0), + Logs: make([]Log, 0), }, }, { @@ -84,7 +84,7 @@ func benchRLP(b *testing.B, encode bool) { &Receipt{ Status: ReceiptStatusSuccessful, CumulativeGasUsed: 0x888888888, - Logs: make([]*Log, 0), + Logs: make([]Log, 0), }, }, { diff --git a/go-ethereum/crypto/crypto.go b/go-ethereum/crypto/crypto.go index 3bfa1a56..0c4a68f5 100644 --- a/go-ethereum/crypto/crypto.go +++ b/go-ethereum/crypto/crypto.go @@ -257,8 +257,10 @@ func checkKeyFileEnd(r *bufio.Reader) error { // SaveECDSA saves a secp256k1 private key to the given file with // restrictive permissions. The key data is saved hex-encoded. func SaveECDSA(file string, key *ecdsa.PrivateKey) error { - k := hex.EncodeToString(FromECDSA(key)) - return os.WriteFile(file, []byte(k), 0600) + raw := FromECDSA(key) + k := make([]byte, hex.EncodedLen(len(raw))) + hex.Encode(k, raw) + return os.WriteFile(file, k, 0600) } // GenerateKey generates a new private key. diff --git a/go-ethereum/crypto/kzg4844/kzg4844.go b/go-ethereum/crypto/kzg4844/kzg4844.go index b5f26eb4..d10f10e2 100644 --- a/go-ethereum/crypto/kzg4844/kzg4844.go +++ b/go-ethereum/crypto/kzg4844/kzg4844.go @@ -25,6 +25,7 @@ import ( "sync/atomic" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/0xsequence/ethkit/util" ) //go:embed trusted_setup.json @@ -49,6 +50,11 @@ func (b Blob) MarshalText() ([]byte, error) { return hexutil.Bytes(b[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (b Blob) MarshalJSON() ([]byte, error) { + return util.QuoteString(b) +} + // Commitment is a serialized commitment to a polynomial. type Commitment [48]byte @@ -62,6 +68,11 @@ func (c Commitment) MarshalText() ([]byte, error) { return hexutil.Bytes(c[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (c Commitment) MarshalJSON() ([]byte, error) { + return util.QuoteString(c) +} + // Proof is a serialized commitment to the quotient polynomial. type Proof [48]byte @@ -75,6 +86,17 @@ func (p Proof) MarshalText() ([]byte, error) { return hexutil.Bytes(p[:]).MarshalText() } +// MarshalJSON implements json.Marshaler. +func (p Proof) MarshalJSON() ([]byte, error) { + raw, err := p.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil +} + // Point is a BLS field element. type Point [32]byte diff --git a/go-ethereum/crypto/kzg4844/kzg4844_ckzg_cgo.go b/go-ethereum/crypto/kzg4844/kzg4844_ckzg_cgo.go index 9b92af63..62bb4495 100644 --- a/go-ethereum/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/go-ethereum/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -19,11 +19,12 @@ package kzg4844 import ( - "encoding/json" "errors" "sync" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" + gokzg4844 "github.com/crate-crypto/go-kzg-4844" ckzg4844 "github.com/ethereum/c-kzg-4844/bindings/go" ) @@ -41,7 +42,7 @@ func ckzgInit() { panic(err) } params := new(gokzg4844.JSONTrustedSetup) - if err = json.Unmarshal(config, params); err != nil { + if err = sonic.ConfigFastest.Unmarshal(config, params); err != nil { panic(err) } if err = gokzg4844.CheckTrustedSetupIsWellFormed(params); err != nil { diff --git a/go-ethereum/crypto/kzg4844/kzg4844_gokzg.go b/go-ethereum/crypto/kzg4844/kzg4844_gokzg.go index b4af9b16..aa8b5239 100644 --- a/go-ethereum/crypto/kzg4844/kzg4844_gokzg.go +++ b/go-ethereum/crypto/kzg4844/kzg4844_gokzg.go @@ -17,9 +17,9 @@ package kzg4844 import ( - "encoding/json" "sync" + "github.com/bytedance/sonic" gokzg4844 "github.com/crate-crypto/go-kzg-4844" ) @@ -36,7 +36,7 @@ func gokzgInit() { panic(err) } params := new(gokzg4844.JSONTrustedSetup) - if err = json.Unmarshal(config, params); err != nil { + if err = sonic.ConfigFastest.Unmarshal(config, params); err != nil { panic(err) } context, err = gokzg4844.NewContext4096(params) diff --git a/go-ethereum/ethclient/ethclient.go b/go-ethereum/ethclient/ethclient.go index 806fe018..912e6eff 100644 --- a/go-ethereum/ethclient/ethclient.go +++ b/go-ethereum/ethclient/ethclient.go @@ -29,6 +29,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/core/types" "github.com/0xsequence/ethkit/go-ethereum/rpc" + "github.com/bytedance/sonic" ) // Client defines typed wrappers for the Ethereum RPC API. @@ -134,7 +135,7 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface // Decode header and transactions. var head *types.Header - if err := json.Unmarshal(raw, &head); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &head); err != nil { return nil, err } // When the block is not found, the API returns JSON null. @@ -143,7 +144,7 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface } var body rpcBlock - if err := json.Unmarshal(raw, &body); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &body); err != nil { return nil, err } // Quick-verify transaction and uncle lists. This mostly helps with debugging the server. @@ -232,10 +233,10 @@ type txExtraInfo struct { } func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error { - if err := json.Unmarshal(msg, &tx.tx); err != nil { + if err := sonic.ConfigFastest.Unmarshal(msg, &tx.tx); err != nil { return err } - return json.Unmarshal(msg, &tx.txExtraInfo) + return sonic.ConfigFastest.Unmarshal(msg, &tx.txExtraInfo) } // TransactionByHash returns the transaction with the given hash. @@ -327,11 +328,11 @@ func (ec *Client) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, err } // Handle the possible response types var syncing bool - if err := json.Unmarshal(raw, &syncing); err == nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &syncing); err == nil { return nil, nil // Not syncing (always false) } var p *rpcProgress - if err := json.Unmarshal(raw, &p); err != nil { + if err := sonic.ConfigFastest.Unmarshal(raw, &p); err != nil { return nil, err } return p.toSyncProgress(), nil diff --git a/go-ethereum/ethclient/gethclient/gethclient.go b/go-ethereum/ethclient/gethclient/gethclient.go index a547afa9..e62e2fd3 100644 --- a/go-ethereum/ethclient/gethclient/gethclient.go +++ b/go-ethereum/ethclient/gethclient/gethclient.go @@ -19,7 +19,6 @@ package gethclient import ( "context" - "encoding/json" "fmt" "math/big" "runtime" @@ -30,6 +29,7 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" "github.com/0xsequence/ethkit/go-ethereum/core/types" "github.com/0xsequence/ethkit/go-ethereum/rpc" + "github.com/bytedance/sonic" ) // Client is a wrapper around rpc.Client that implements geth-specific functionality. @@ -289,7 +289,7 @@ func (a OverrideAccount) MarshalJSON() ([]byte, error) { if a.State != nil { output.State = a.State } - return json.Marshal(output) + return sonic.ConfigFastest.Marshal(output) } // BlockOverrides specifies the set of header fields to override. @@ -338,5 +338,5 @@ func (o BlockOverrides) MarshalJSON() ([]byte, error) { if o.Random != (common.Hash{}) { output.Random = &o.Random } - return json.Marshal(output) + return sonic.ConfigFastest.Marshal(output) } diff --git a/go-ethereum/rpc/client.go b/go-ethereum/rpc/client.go index 9107ab4b..72473849 100644 --- a/go-ethereum/rpc/client.go +++ b/go-ethereum/rpc/client.go @@ -29,6 +29,7 @@ import ( "time" "github.com/0xsequence/ethkit/go-ethereum/log" + "github.com/bytedance/sonic" ) var ( @@ -371,7 +372,7 @@ func (c *Client) CallContext(ctx context.Context, result interface{}, method str if result == nil { return nil } - return json.Unmarshal(resp.Result, result) + return sonic.ConfigFastest.Unmarshal(resp.Result, result) } } @@ -453,7 +454,7 @@ func (c *Client) BatchCallContext(ctx context.Context, b []BatchElem) error { case resp.Result == nil: elem.Error = ErrNoResult default: - elem.Error = json.Unmarshal(resp.Result, elem.Result) + elem.Error = sonic.ConfigFastest.Unmarshal(resp.Result, elem.Result) } } @@ -549,7 +550,7 @@ func (c *Client) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMes msg := &jsonrpcMessage{Version: vsn, ID: c.nextID(), Method: method} if paramsIn != nil { // prevent sending "params":null var err error - if msg.Params, err = json.Marshal(paramsIn); err != nil { + if msg.Params, err = sonic.ConfigFastest.Marshal(paramsIn); err != nil { return nil, err } } diff --git a/go-ethereum/rpc/handler.go b/go-ethereum/rpc/handler.go index c5c62f0a..b9efc4fd 100644 --- a/go-ethereum/rpc/handler.go +++ b/go-ethereum/rpc/handler.go @@ -29,6 +29,7 @@ import ( "time" "github.com/0xsequence/ethkit/go-ethereum/log" + "github.com/bytedance/sonic" ) // handler handles JSON-RPC messages. There is one handler per connection. Note that @@ -410,7 +411,7 @@ func (h *handler) handleResponses(batch []*jsonrpcMessage, handleCall func(*json if msg.Error != nil { op.err = msg.Error } else { - op.err = json.Unmarshal(msg.Result, &op.sub.subid) + op.err = sonic.ConfigFastest.Unmarshal(msg.Result, &op.sub.subid) if op.err == nil { go op.sub.run() h.clientSubs[op.sub.subid] = op.sub @@ -451,7 +452,7 @@ func (h *handler) handleResponses(batch []*jsonrpcMessage, handleCall func(*json // handleSubscriptionResult processes subscription notifications. func (h *handler) handleSubscriptionResult(msg *jsonrpcMessage) { var result subscriptionResult - if err := json.Unmarshal(msg.Params, &result); err != nil { + if err := sonic.ConfigFastest.Unmarshal(msg.Params, &result); err != nil { h.log.Debug("Dropping invalid subscription message") return } diff --git a/go-ethereum/rpc/http.go b/go-ethereum/rpc/http.go index 768ac017..9f26cd2f 100644 --- a/go-ethereum/rpc/http.go +++ b/go-ethereum/rpc/http.go @@ -19,13 +19,14 @@ package rpc import ( "bytes" "context" - "encoding/json" "io" "math" "net/http" "net/url" "sync" "time" + + "github.com/bytedance/sonic" ) const ( @@ -174,7 +175,7 @@ func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) e var resp jsonrpcMessage batch := [1]*jsonrpcMessage{&resp} - if err := json.NewDecoder(respBody).Decode(&resp); err != nil { + if err := sonic.ConfigFastest.NewDecoder(respBody).Decode(&resp); err != nil { return err } op.resp <- batch[:] @@ -190,7 +191,7 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr defer respBody.Close() var respmsgs []*jsonrpcMessage - if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil { + if err := sonic.ConfigFastest.NewDecoder(respBody).Decode(&respmsgs); err != nil { return err } op.resp <- respmsgs @@ -204,7 +205,7 @@ type nopReadCloser struct { func (nopReadCloser) Close() error { return nil } func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadCloser, error) { - body, err := json.Marshal(msg) + body, err := sonic.ConfigFastest.Marshal(msg) if err != nil { return nil, err } diff --git a/go-ethereum/rpc/json.go b/go-ethereum/rpc/json.go index e932389d..5e5d866b 100644 --- a/go-ethereum/rpc/json.go +++ b/go-ethereum/rpc/json.go @@ -27,6 +27,8 @@ import ( "strings" "sync" "time" + + "github.com/bytedance/sonic" ) const ( @@ -102,7 +104,7 @@ func (msg *jsonrpcMessage) namespace() string { } func (msg *jsonrpcMessage) String() string { - b, _ := json.Marshal(msg) + b, _ := sonic.ConfigFastest.Marshal(msg) return string(b) } @@ -113,7 +115,7 @@ func (msg *jsonrpcMessage) errorResponse(err error) *jsonrpcMessage { } func (msg *jsonrpcMessage) response(result interface{}) *jsonrpcMessage { - enc, err := json.Marshal(result) + enc, err := sonic.ConfigFastest.Marshal(result) if err != nil { return msg.errorResponse(&internalServerError{errcodeMarshalError, err.Error()}) } @@ -211,7 +213,7 @@ func NewFuncCodec(conn deadlineCloser, encode encodeFunc, decode decodeFunc) Ser // messages will use it to include the remote address of the connection. func NewCodec(conn Conn) ServerCodec { enc := json.NewEncoder(conn) - dec := json.NewDecoder(conn) + dec := sonic.ConfigFastest.NewDecoder(conn) dec.UseNumber() encode := func(v interface{}, isErrorResponse bool) error { @@ -278,7 +280,7 @@ func (c *jsonCodec) closed() <-chan interface{} { func parseMessage(raw json.RawMessage) ([]*jsonrpcMessage, bool) { if !isBatch(raw) { msgs := []*jsonrpcMessage{{}} - json.Unmarshal(raw, &msgs[0]) + sonic.ConfigFastest.Unmarshal(raw, &msgs[0]) return msgs, false } dec := json.NewDecoder(bytes.NewReader(raw)) diff --git a/go-ethereum/rpc/subscription.go b/go-ethereum/rpc/subscription.go index d77c655b..4c44c51d 100644 --- a/go-ethereum/rpc/subscription.go +++ b/go-ethereum/rpc/subscription.go @@ -29,6 +29,8 @@ import ( "strings" "sync" "time" + + "github.com/bytedance/sonic" ) var ( @@ -197,7 +199,7 @@ func (s *Subscription) Err() <-chan error { // MarshalJSON marshals a subscription as its ID. func (s *Subscription) MarshalJSON() ([]byte, error) { - return json.Marshal(s.ID) + return sonic.ConfigFastest.Marshal(s.ID) } // ClientSubscription is a subscription established through the Client's Subscribe or @@ -365,7 +367,7 @@ func (sub *ClientSubscription) forward() (unsubscribeServer bool, err error) { func (sub *ClientSubscription) unmarshal(result json.RawMessage) (interface{}, error) { val := reflect.New(sub.etype) - err := json.Unmarshal(result, val.Interface()) + err := sonic.ConfigFastest.Unmarshal(result, val.Interface()) return val.Elem().Interface(), err } diff --git a/go-ethereum/rpc/types.go b/go-ethereum/rpc/types.go index de10a20a..740bc916 100644 --- a/go-ethereum/rpc/types.go +++ b/go-ethereum/rpc/types.go @@ -18,7 +18,6 @@ package rpc import ( "context" - "encoding/json" "errors" "fmt" "math" @@ -26,6 +25,9 @@ import ( "github.com/0xsequence/ethkit/go-ethereum/common" "github.com/0xsequence/ethkit/go-ethereum/common/hexutil" + "github.com/bytedance/sonic" + + "github.com/0xsequence/ethkit/util" ) // API describes the set of methods offered over the RPC interface @@ -123,6 +125,11 @@ func (bn BlockNumber) MarshalText() ([]byte, error) { return []byte(bn.String()), nil } +// MarshalJSON implements json.Marshaler. +func (bn BlockNumber) MarshalJSON() ([]byte, error) { + return util.QuoteString(bn) +} + func (bn BlockNumber) String() string { switch bn { case EarliestBlockNumber: @@ -152,7 +159,7 @@ type BlockNumberOrHash struct { func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { type erased BlockNumberOrHash e := erased{} - err := json.Unmarshal(data, &e) + err := sonic.ConfigFastest.Unmarshal(data, &e) if err == nil { if e.BlockNumber != nil && e.BlockHash != nil { return errors.New("cannot specify both BlockHash and BlockNumber, choose one or the other") @@ -163,7 +170,7 @@ func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { return nil } var input string - err = json.Unmarshal(data, &input) + err = sonic.ConfigFastest.Unmarshal(data, &input) if err != nil { return err } diff --git a/go.mod b/go.mod index d32c006a..e587ab25 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/btcsuite/btcd v0.24.2 github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/btcsuite/btcd/btcutil v1.1.6 + github.com/bytedance/sonic v1.13.2 github.com/cespare/cp v1.1.1 github.com/consensys/gnark-crypto v0.16.0 github.com/crate-crypto/go-kzg-4844 v1.1.0 @@ -39,6 +40,7 @@ require ( golang.org/x/net v0.39.0 golang.org/x/sync v0.13.0 golang.org/x/sys v0.32.0 + golang.org/x/term v0.31.0 golang.org/x/tools v0.31.0 ) @@ -51,7 +53,9 @@ require ( require ( github.com/bits-and-blooms/bitset v1.22.0 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/consensys/bavard v0.1.30 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -64,7 +68,8 @@ require ( github.com/redis/go-redis/v9 v9.7.3 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/supranational/blst v0.3.14 // indirect - golang.org/x/term v0.31.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index 011543cb..2c1d93a1 100644 --- a/go.sum +++ b/go.sum @@ -34,10 +34,18 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/consensys/bavard v0.1.30 h1:wwAj9lSnMLFXjEclKwyhf7Oslg8EoaFz9u1QGgt0bsk= github.com/consensys/bavard v0.1.30/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo= @@ -120,8 +128,10 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -168,12 +178,16 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -236,5 +250,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/util/quote.go b/util/quote.go new file mode 100644 index 00000000..432cf450 --- /dev/null +++ b/util/quote.go @@ -0,0 +1,14 @@ +package util + +import "encoding" + +// QuoteString adds quotes to the byte slice returned by the TextMarshaler. +func QuoteString(b encoding.TextMarshaler) ([]byte, error) { + raw, err := b.MarshalText() + if err != nil { + return nil, err + } + raw = append([]byte{'"'}, raw...) + raw = append(raw, '"') + return raw, nil +} diff --git a/util/testing.go b/util/testing.go index d45382d3..0cca2854 100644 --- a/util/testing.go +++ b/util/testing.go @@ -1,9 +1,10 @@ package util import ( - "encoding/json" "fmt" "os" + + "github.com/bytedance/sonic" ) func ReadTestConfig(testConfigFile string) (map[string]string, error) { @@ -19,7 +20,7 @@ func ReadTestConfig(testConfigFile string) (map[string]string, error) { return nil, fmt.Errorf("%s file could not be read", testConfigFile) } - err = json.Unmarshal(data, &config) + err = sonic.ConfigFastest.Unmarshal(data, &config) if err != nil { return nil, fmt.Errorf("%s file json parsing error", testConfigFile) }