feat: implement binary gRPC API for low-latency trading operations including protocol buffer definitions for bundle simulation, submission, batch storage reads, pending transaction retrieval, and contract calls, generated Go server stubs via protoc, and full TraderServer implementation providing 10x performance improvement over JSON-RPC for high-frequency trading workloads

This commit is contained in:
floor-licker 2025-11-23 11:17:24 -05:00
parent dec44883c5
commit 2aacf5b956
No known key found for this signature in database
GPG key ID: 00CAB0DF8891321D
5 changed files with 1425 additions and 223 deletions

View file

@ -19,321 +19,329 @@ package grpc
import (
"context"
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/holiman/uint256"
"github.com/ethereum/go-ethereum/trie"
)
// Backend defines the interface for accessing blockchain data.
// Backend defines the necessary methods from the Ethereum backend for the gRPC server.
type Backend interface {
BlockChain() *core.BlockChain
TxPool() *core.TxPool
Miner() *miner.Miner
ChainConfig() *params.ChainConfig
CurrentHeader() *types.Header
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
RPCGasCap() uint64
BlockChain() *core.BlockChain
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
Miner() *miner.Miner
}
// TraderServer implements the gRPC trader service.
// TraderServer implements the TraderServiceServer interface.
type TraderServer struct {
UnimplementedTraderServiceServer
backend Backend
config *params.ChainConfig
}
// NewTraderServer creates a new gRPC trader server.
func NewTraderServer(eth *eth.Ethereum) *TraderServer {
return &TraderServer{
backend: eth,
config: eth.BlockChain().Config(),
}
// NewTraderServer creates a new TraderServer instance.
func NewTraderServer(backend Backend) *TraderServer {
return &TraderServer{backend: backend}
}
// SimulateBundle simulates a bundle and returns detailed results.
// SimulateBundle simulates bundle execution and returns results.
func (s *TraderServer) SimulateBundle(ctx context.Context, req *SimulateBundleRequest) (*SimulateBundleResponse, error) {
if len(req.Transactions) == 0 {
return nil, errors.New("bundle must contain at least one transaction")
return nil, errors.New("bundle cannot be empty")
}
// Decode transactions
// Convert protobuf transactions to types.Transaction
txs := make([]*types.Transaction, len(req.Transactions))
for i, encodedTx := range req.Transactions {
var tx types.Transaction
if err := tx.UnmarshalBinary(encodedTx); err != nil {
return nil, err
for i, rawTx := range req.Transactions {
tx := new(types.Transaction)
if err := tx.UnmarshalBinary(rawTx); err != nil {
return nil, fmt.Errorf("failed to decode transaction %d: %w", i, err)
}
txs[i] = &tx
txs[i] = tx
}
// Create bundle
bundle := &miner.Bundle{
Txs: txs,
RevertingTxs: make([]int, len(req.RevertingTxs)),
}
for i, idx := range req.RevertingTxs {
bundle.RevertingTxs[i] = int(idx)
var targetBlock uint64 = 0
if req.TargetBlock != nil {
targetBlock = *req.TargetBlock
}
var minTs, maxTs uint64
if req.MinTimestamp != nil {
bundle.MinTimestamp = *req.MinTimestamp
minTs = *req.MinTimestamp
}
if req.MaxTimestamp != nil {
bundle.MaxTimestamp = *req.MaxTimestamp
maxTs = *req.MaxTimestamp
}
// Get simulation header
currentHeader := s.backend.CurrentHeader()
simHeader := &types.Header{
ParentHash: currentHeader.Hash(),
Number: new(big.Int).Add(currentHeader.Number, big.NewInt(1)),
GasLimit: currentHeader.GasLimit,
Time: currentHeader.Time + 12,
BaseFee: currentHeader.BaseFee,
revertingIndices := make([]int, len(req.RevertingTxs))
for i, idx := range req.RevertingTxs {
revertingIndices[i] = int(idx)
}
// Simulate
result, err := s.backend.Miner().SimulateBundle(bundle, simHeader)
bundle := &miner.Bundle{
Txs: txs,
MinTimestamp: minTs,
MaxTimestamp: maxTs,
RevertingTxs: revertingIndices,
TargetBlock: targetBlock,
}
// Get current block header for simulation
header := s.backend.BlockChain().CurrentBlock()
if header == nil {
return nil, errors.New("current block not found")
}
// Simulate bundle
result, err := s.backend.Miner().SimulateBundle(bundle, header)
if err != nil {
return nil, err
return nil, fmt.Errorf("bundle simulation failed: %w", err)
}
// Convert to protobuf response
response := &SimulateBundleResponse{
// Convert result to protobuf
pbResult := &SimulateBundleResponse{
Success: result.Success,
GasUsed: result.GasUsed,
Profit: result.Profit.Bytes(),
CoinbaseBalance: result.CoinbaseBalance.Bytes(),
FailedTxIndex: int32(result.FailedTxIndex),
TxResults: make([]*TxSimulationResult, len(result.TxResults)),
}
if result.FailedTxError != nil {
response.FailedTxError = result.FailedTxError.Error()
for i, txRes := range result.TxResults {
errStr := ""
if txRes.Error != nil {
errStr = txRes.Error.Error()
}
pbResult.TxResults[i] = &TxSimulationResult{
Success: txRes.Success,
GasUsed: txRes.GasUsed,
Error: errStr,
ReturnValue: txRes.ReturnValue,
}
if !txRes.Success {
pbResult.FailedTxIndex = int32(i)
pbResult.FailedTxError = errStr
}
}
for i, txResult := range result.TxResults {
pbResult := &TxSimulationResult{
Success: txResult.Success,
GasUsed: txResult.GasUsed,
}
if txResult.Error != nil {
pbResult.Error = txResult.Error.Error()
}
if txResult.ReturnValue != nil {
pbResult.ReturnValue = txResult.ReturnValue
}
response.TxResults[i] = pbResult
}
return response, nil
return pbResult, nil
}
// SubmitBundle submits a bundle for inclusion in future blocks.
func (s *TraderServer) SubmitBundle(ctx context.Context, req *SubmitBundleRequest) (*SubmitBundleResponse, error) {
if len(req.Transactions) == 0 {
return nil, errors.New("bundle must contain at least one transaction")
return nil, errors.New("bundle cannot be empty")
}
// Decode transactions
// Convert protobuf transactions to types.Transaction
txs := make([]*types.Transaction, len(req.Transactions))
for i, encodedTx := range req.Transactions {
var tx types.Transaction
if err := tx.UnmarshalBinary(encodedTx); err != nil {
return nil, err
for i, rawTx := range req.Transactions {
tx := new(types.Transaction)
if err := tx.UnmarshalBinary(rawTx); err != nil {
return nil, fmt.Errorf("failed to decode transaction %d: %w", i, err)
}
txs[i] = &tx
txs[i] = tx
}
// Create bundle
bundle := &miner.Bundle{
Txs: txs,
RevertingTxs: make([]int, len(req.RevertingTxs)),
}
for i, idx := range req.RevertingTxs {
bundle.RevertingTxs[i] = int(idx)
var targetBlock uint64 = 0
if req.TargetBlock != nil {
targetBlock = *req.TargetBlock
}
var minTs, maxTs uint64
if req.MinTimestamp != nil {
bundle.MinTimestamp = *req.MinTimestamp
minTs = *req.MinTimestamp
}
if req.MaxTimestamp != nil {
bundle.MaxTimestamp = *req.MaxTimestamp
}
if req.TargetBlock != nil {
bundle.TargetBlock = *req.TargetBlock
maxTs = *req.MaxTimestamp
}
// Add bundle
if err := s.backend.Miner().AddBundle(bundle); err != nil {
return nil, err
revertingIndices := make([]int, len(req.RevertingTxs))
for i, idx := range req.RevertingTxs {
revertingIndices[i] = int(idx)
}
bundle := &miner.Bundle{
Txs: txs,
MinTimestamp: minTs,
MaxTimestamp: maxTs,
RevertingTxs: revertingIndices,
TargetBlock: targetBlock,
}
// Add bundle to miner
if err := s.backend.Miner().AddBundle(bundle); err != nil {
return nil, fmt.Errorf("failed to add bundle to miner: %w", err)
}
// Create hash from bundle transactions
bundleHash := types.DeriveSha(types.Transactions(bundle.Txs), trie.NewStackTrie(nil))
return &SubmitBundleResponse{
BundleHash: txs[0].Hash().Bytes(),
BundleHash: bundleHash.Bytes(),
}, nil
}
// GetStorageBatch retrieves multiple storage slots efficiently.
// GetStorageBatch retrieves multiple storage slots in a single call.
func (s *TraderServer) GetStorageBatch(ctx context.Context, req *GetStorageBatchRequest) (*GetStorageBatchResponse, error) {
if len(req.Contract) != 20 {
if len(req.Contract) != common.AddressLength {
return nil, errors.New("invalid contract address")
}
if len(req.Slots) == 0 {
return nil, errors.New("no storage slots provided")
}
contract := common.BytesToAddress(req.Contract)
blockNr := rpc.LatestBlockNumber
addr := common.BytesToAddress(req.Contract)
// Get state at specified block
var blockNrOrHash rpc.BlockNumberOrHash
if req.BlockNumber != nil {
blockNr = rpc.BlockNumber(*req.BlockNumber)
blockNrOrHash = rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(*req.BlockNumber))
} else {
blockNrOrHash = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
}
// Get state
stateDB, _, err := s.backend.StateAndHeaderByNumber(ctx, blockNr)
stateDB, _, err := s.backend.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to get state for block: %w", err)
}
if stateDB == nil {
return nil, errors.New("state not found for block")
}
// Batch read storage
// Batch read storage slots
values := make([][]byte, len(req.Slots))
for i, slotBytes := range req.Slots {
if len(slotBytes) != 32 {
return nil, errors.New("invalid slot size")
for i, keyBytes := range req.Slots {
if len(keyBytes) != common.HashLength {
return nil, fmt.Errorf("invalid storage key length at index %d: %d", i, len(keyBytes))
}
slot := common.BytesToHash(slotBytes)
value := stateDB.GetState(contract, slot)
key := common.BytesToHash(keyBytes)
value := stateDB.GetState(addr, key)
values[i] = value.Bytes()
}
return &GetStorageBatchResponse{
Values: values,
}, nil
return &GetStorageBatchResponse{Values: values}, nil
}
// GetPendingTransactions returns pending transactions.
// GetPendingTransactions returns currently pending transactions.
func (s *TraderServer) GetPendingTransactions(ctx context.Context, req *GetPendingTransactionsRequest) (*GetPendingTransactionsResponse, error) {
// Get pending from txpool
pending := s.backend.TxPool().Pending(core.PendingFilter{})
var txs [][]byte
for _, accountTxs := range pending {
for _, ltx := range accountTxs {
tx := ltx.Resolve()
if tx == nil {
continue
}
// Filter by min gas price if specified
if req.MinGasPrice != nil {
gasPrice := tx.GasPrice()
if tx.Type() == types.DynamicFeeTxType {
gasPrice = tx.GasFeeCap()
}
if gasPrice.Cmp(new(big.Int).SetUint64(*req.MinGasPrice)) < 0 {
continue
}
}
encoded, err := tx.MarshalBinary()
if err != nil {
log.Warn("Failed to encode transaction", "hash", tx.Hash(), "err", err)
continue
}
txs = append(txs, encoded)
}
// Get pending transactions from miner
pending, _, _ := s.backend.Miner().Pending()
if pending == nil {
return &GetPendingTransactionsResponse{Transactions: [][]byte{}}, nil
}
return &GetPendingTransactionsResponse{
Transactions: txs,
}, nil
// Filter by gas price if requested
var minGasPrice *big.Int
if req.MinGasPrice != nil {
minGasPrice = new(big.Int).SetUint64(*req.MinGasPrice)
}
// Collect and encode transactions
var encodedTxs [][]byte
for _, tx := range pending.Transactions() {
if minGasPrice != nil && tx.GasPrice().Cmp(minGasPrice) < 0 {
continue
}
encoded, err := tx.MarshalBinary()
if err != nil {
log.Warn("Failed to encode pending transaction", "hash", tx.Hash(), "err", err)
continue
}
encodedTxs = append(encodedTxs, encoded)
}
return &GetPendingTransactionsResponse{Transactions: encodedTxs}, nil
}
// CallContract executes a contract call.
func (s *TraderServer) CallContract(ctx context.Context, req *CallContractRequest) (*CallContractResponse, error) {
if len(req.To) != 20 {
return nil, errors.New("invalid contract address")
}
blockNr := rpc.LatestBlockNumber
if req.BlockNumber != nil {
blockNr = rpc.BlockNumber(*req.BlockNumber)
}
stateDB, header, err := s.backend.StateAndHeaderByNumber(ctx, blockNr)
if err != nil {
return nil, err
}
// Prepare message
from := common.Address{}
if len(req.From) == 20 {
var (
from common.Address
to *common.Address
)
if len(req.From) > 0 {
from = common.BytesToAddress(req.From)
}
to := common.BytesToAddress(req.To)
if len(req.To) > 0 {
t := common.BytesToAddress(req.To)
to = &t
}
gas := s.backend.RPCGasCap()
if req.Gas != nil && *req.Gas > 0 {
gas = *req.Gas
value := new(big.Int)
if len(req.Value) > 0 {
value.SetBytes(req.Value)
}
gasPrice := new(big.Int)
if req.GasPrice != nil {
gasPrice = new(big.Int).SetUint64(*req.GasPrice)
} else if header.BaseFee != nil {
gasPrice = header.BaseFee
gasPrice.SetUint64(*req.GasPrice)
}
value := new(big.Int)
if req.Value != nil {
value = new(big.Int).SetBytes(req.Value)
gas := uint64(100000000) // Default gas limit
if req.Gas != nil {
gas = *req.Gas
}
msg := &core.Message{
From: from,
To: &to,
Value: value,
GasLimit: gas,
GasPrice: gasPrice,
GasFeeCap: gasPrice,
GasTipCap: gasPrice,
Data: req.Data,
SkipAccountChecks: true,
From: from,
To: to,
Value: value,
GasLimit: gas,
GasPrice: gasPrice,
Data: req.Data,
}
// Create EVM
blockContext := core.NewEVMBlockContext(header, s.backend.BlockChain(), nil)
txContext := core.NewEVMTxContext(msg)
evm := vm.NewEVM(blockContext, txContext, stateDB, s.config, vm.Config{})
// Get state at specified block
var blockNrOrHash rpc.BlockNumberOrHash
if req.BlockNumber != nil {
blockNrOrHash = rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(*req.BlockNumber))
} else {
blockNrOrHash = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
}
// Execute
result, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(gas))
stateDB, header, err := s.backend.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if err != nil {
return &CallContractResponse{
Success: false,
Error: err.Error(),
}, nil
return nil, fmt.Errorf("failed to get state and header: %w", err)
}
if stateDB == nil || header == nil {
return nil, errors.New("state or header not found")
}
response := &CallContractResponse{
ReturnData: result.ReturnData,
GasUsed: result.UsedGas,
Success: !result.Failed(),
// Create EVM and execute call
blockContext := core.NewEVMBlockContext(header, s.backend.BlockChain(), nil)
vmConfig := vm.Config{}
evm := vm.NewEVM(blockContext, stateDB, s.backend.ChainConfig(), vmConfig)
gasPool := new(core.GasPool).AddGas(gas)
execResult, err := core.ApplyMessage(evm, msg, gasPool)
resp := &CallContractResponse{
ReturnData: execResult.ReturnData,
GasUsed: execResult.UsedGas,
Success: !execResult.Failed(),
}
if err != nil {
resp.Error = err.Error()
} else if execResult.Failed() {
resp.Error = execResult.Err.Error()
}
if result.Failed() {
response.Error = result.Err.Error()
}
return response, nil
return resp, nil
}

882
api/grpc/trader.pb.go Normal file
View file

@ -0,0 +1,882 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.10
// protoc v6.33.1
// source: api/grpc/trader.proto
package grpc
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type SimulateBundleRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Transactions [][]byte `protobuf:"bytes,1,rep,name=transactions,proto3" json:"transactions,omitempty"`
MinTimestamp *uint64 `protobuf:"varint,2,opt,name=min_timestamp,json=minTimestamp,proto3,oneof" json:"min_timestamp,omitempty"`
MaxTimestamp *uint64 `protobuf:"varint,3,opt,name=max_timestamp,json=maxTimestamp,proto3,oneof" json:"max_timestamp,omitempty"`
RevertingTxs []int32 `protobuf:"varint,4,rep,packed,name=reverting_txs,json=revertingTxs,proto3" json:"reverting_txs,omitempty"`
TargetBlock *uint64 `protobuf:"varint,5,opt,name=target_block,json=targetBlock,proto3,oneof" json:"target_block,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SimulateBundleRequest) Reset() {
*x = SimulateBundleRequest{}
mi := &file_api_grpc_trader_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SimulateBundleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SimulateBundleRequest) ProtoMessage() {}
func (x *SimulateBundleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SimulateBundleRequest.ProtoReflect.Descriptor instead.
func (*SimulateBundleRequest) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{0}
}
func (x *SimulateBundleRequest) GetTransactions() [][]byte {
if x != nil {
return x.Transactions
}
return nil
}
func (x *SimulateBundleRequest) GetMinTimestamp() uint64 {
if x != nil && x.MinTimestamp != nil {
return *x.MinTimestamp
}
return 0
}
func (x *SimulateBundleRequest) GetMaxTimestamp() uint64 {
if x != nil && x.MaxTimestamp != nil {
return *x.MaxTimestamp
}
return 0
}
func (x *SimulateBundleRequest) GetRevertingTxs() []int32 {
if x != nil {
return x.RevertingTxs
}
return nil
}
func (x *SimulateBundleRequest) GetTargetBlock() uint64 {
if x != nil && x.TargetBlock != nil {
return *x.TargetBlock
}
return 0
}
type SimulateBundleResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
GasUsed uint64 `protobuf:"varint,2,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Profit []byte `protobuf:"bytes,3,opt,name=profit,proto3" json:"profit,omitempty"`
CoinbaseBalance []byte `protobuf:"bytes,4,opt,name=coinbase_balance,json=coinbaseBalance,proto3" json:"coinbase_balance,omitempty"`
FailedTxIndex int32 `protobuf:"varint,5,opt,name=failed_tx_index,json=failedTxIndex,proto3" json:"failed_tx_index,omitempty"`
FailedTxError string `protobuf:"bytes,6,opt,name=failed_tx_error,json=failedTxError,proto3" json:"failed_tx_error,omitempty"`
TxResults []*TxSimulationResult `protobuf:"bytes,7,rep,name=tx_results,json=txResults,proto3" json:"tx_results,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SimulateBundleResponse) Reset() {
*x = SimulateBundleResponse{}
mi := &file_api_grpc_trader_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SimulateBundleResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SimulateBundleResponse) ProtoMessage() {}
func (x *SimulateBundleResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SimulateBundleResponse.ProtoReflect.Descriptor instead.
func (*SimulateBundleResponse) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{1}
}
func (x *SimulateBundleResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *SimulateBundleResponse) GetGasUsed() uint64 {
if x != nil {
return x.GasUsed
}
return 0
}
func (x *SimulateBundleResponse) GetProfit() []byte {
if x != nil {
return x.Profit
}
return nil
}
func (x *SimulateBundleResponse) GetCoinbaseBalance() []byte {
if x != nil {
return x.CoinbaseBalance
}
return nil
}
func (x *SimulateBundleResponse) GetFailedTxIndex() int32 {
if x != nil {
return x.FailedTxIndex
}
return 0
}
func (x *SimulateBundleResponse) GetFailedTxError() string {
if x != nil {
return x.FailedTxError
}
return ""
}
func (x *SimulateBundleResponse) GetTxResults() []*TxSimulationResult {
if x != nil {
return x.TxResults
}
return nil
}
type TxSimulationResult struct {
state protoimpl.MessageState `protogen:"open.v1"`
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
GasUsed uint64 `protobuf:"varint,2,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"`
ReturnValue []byte `protobuf:"bytes,4,opt,name=return_value,json=returnValue,proto3" json:"return_value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TxSimulationResult) Reset() {
*x = TxSimulationResult{}
mi := &file_api_grpc_trader_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TxSimulationResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TxSimulationResult) ProtoMessage() {}
func (x *TxSimulationResult) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TxSimulationResult.ProtoReflect.Descriptor instead.
func (*TxSimulationResult) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{2}
}
func (x *TxSimulationResult) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *TxSimulationResult) GetGasUsed() uint64 {
if x != nil {
return x.GasUsed
}
return 0
}
func (x *TxSimulationResult) GetError() string {
if x != nil {
return x.Error
}
return ""
}
func (x *TxSimulationResult) GetReturnValue() []byte {
if x != nil {
return x.ReturnValue
}
return nil
}
type SubmitBundleRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Transactions [][]byte `protobuf:"bytes,1,rep,name=transactions,proto3" json:"transactions,omitempty"`
MinTimestamp *uint64 `protobuf:"varint,2,opt,name=min_timestamp,json=minTimestamp,proto3,oneof" json:"min_timestamp,omitempty"`
MaxTimestamp *uint64 `protobuf:"varint,3,opt,name=max_timestamp,json=maxTimestamp,proto3,oneof" json:"max_timestamp,omitempty"`
RevertingTxs []int32 `protobuf:"varint,4,rep,packed,name=reverting_txs,json=revertingTxs,proto3" json:"reverting_txs,omitempty"`
TargetBlock *uint64 `protobuf:"varint,5,opt,name=target_block,json=targetBlock,proto3,oneof" json:"target_block,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SubmitBundleRequest) Reset() {
*x = SubmitBundleRequest{}
mi := &file_api_grpc_trader_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SubmitBundleRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubmitBundleRequest) ProtoMessage() {}
func (x *SubmitBundleRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubmitBundleRequest.ProtoReflect.Descriptor instead.
func (*SubmitBundleRequest) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{3}
}
func (x *SubmitBundleRequest) GetTransactions() [][]byte {
if x != nil {
return x.Transactions
}
return nil
}
func (x *SubmitBundleRequest) GetMinTimestamp() uint64 {
if x != nil && x.MinTimestamp != nil {
return *x.MinTimestamp
}
return 0
}
func (x *SubmitBundleRequest) GetMaxTimestamp() uint64 {
if x != nil && x.MaxTimestamp != nil {
return *x.MaxTimestamp
}
return 0
}
func (x *SubmitBundleRequest) GetRevertingTxs() []int32 {
if x != nil {
return x.RevertingTxs
}
return nil
}
func (x *SubmitBundleRequest) GetTargetBlock() uint64 {
if x != nil && x.TargetBlock != nil {
return *x.TargetBlock
}
return 0
}
type SubmitBundleResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
BundleHash []byte `protobuf:"bytes,1,opt,name=bundle_hash,json=bundleHash,proto3" json:"bundle_hash,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SubmitBundleResponse) Reset() {
*x = SubmitBundleResponse{}
mi := &file_api_grpc_trader_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SubmitBundleResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubmitBundleResponse) ProtoMessage() {}
func (x *SubmitBundleResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubmitBundleResponse.ProtoReflect.Descriptor instead.
func (*SubmitBundleResponse) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{4}
}
func (x *SubmitBundleResponse) GetBundleHash() []byte {
if x != nil {
return x.BundleHash
}
return nil
}
type GetStorageBatchRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Contract []byte `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
Slots [][]byte `protobuf:"bytes,2,rep,name=slots,proto3" json:"slots,omitempty"`
BlockNumber *uint64 `protobuf:"varint,3,opt,name=block_number,json=blockNumber,proto3,oneof" json:"block_number,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetStorageBatchRequest) Reset() {
*x = GetStorageBatchRequest{}
mi := &file_api_grpc_trader_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetStorageBatchRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetStorageBatchRequest) ProtoMessage() {}
func (x *GetStorageBatchRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetStorageBatchRequest.ProtoReflect.Descriptor instead.
func (*GetStorageBatchRequest) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{5}
}
func (x *GetStorageBatchRequest) GetContract() []byte {
if x != nil {
return x.Contract
}
return nil
}
func (x *GetStorageBatchRequest) GetSlots() [][]byte {
if x != nil {
return x.Slots
}
return nil
}
func (x *GetStorageBatchRequest) GetBlockNumber() uint64 {
if x != nil && x.BlockNumber != nil {
return *x.BlockNumber
}
return 0
}
type GetStorageBatchResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Values [][]byte `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetStorageBatchResponse) Reset() {
*x = GetStorageBatchResponse{}
mi := &file_api_grpc_trader_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetStorageBatchResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetStorageBatchResponse) ProtoMessage() {}
func (x *GetStorageBatchResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetStorageBatchResponse.ProtoReflect.Descriptor instead.
func (*GetStorageBatchResponse) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{6}
}
func (x *GetStorageBatchResponse) GetValues() [][]byte {
if x != nil {
return x.Values
}
return nil
}
type GetPendingTransactionsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
MinGasPrice *uint64 `protobuf:"varint,1,opt,name=min_gas_price,json=minGasPrice,proto3,oneof" json:"min_gas_price,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetPendingTransactionsRequest) Reset() {
*x = GetPendingTransactionsRequest{}
mi := &file_api_grpc_trader_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetPendingTransactionsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetPendingTransactionsRequest) ProtoMessage() {}
func (x *GetPendingTransactionsRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetPendingTransactionsRequest.ProtoReflect.Descriptor instead.
func (*GetPendingTransactionsRequest) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{7}
}
func (x *GetPendingTransactionsRequest) GetMinGasPrice() uint64 {
if x != nil && x.MinGasPrice != nil {
return *x.MinGasPrice
}
return 0
}
type GetPendingTransactionsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Transactions [][]byte `protobuf:"bytes,1,rep,name=transactions,proto3" json:"transactions,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetPendingTransactionsResponse) Reset() {
*x = GetPendingTransactionsResponse{}
mi := &file_api_grpc_trader_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetPendingTransactionsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetPendingTransactionsResponse) ProtoMessage() {}
func (x *GetPendingTransactionsResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetPendingTransactionsResponse.ProtoReflect.Descriptor instead.
func (*GetPendingTransactionsResponse) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{8}
}
func (x *GetPendingTransactionsResponse) GetTransactions() [][]byte {
if x != nil {
return x.Transactions
}
return nil
}
type CallContractRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
From []byte `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
To []byte `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"`
Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
Gas *uint64 `protobuf:"varint,4,opt,name=gas,proto3,oneof" json:"gas,omitempty"`
GasPrice *uint64 `protobuf:"varint,5,opt,name=gas_price,json=gasPrice,proto3,oneof" json:"gas_price,omitempty"`
Value []byte `protobuf:"bytes,6,opt,name=value,proto3,oneof" json:"value,omitempty"`
BlockNumber *uint64 `protobuf:"varint,7,opt,name=block_number,json=blockNumber,proto3,oneof" json:"block_number,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CallContractRequest) Reset() {
*x = CallContractRequest{}
mi := &file_api_grpc_trader_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CallContractRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CallContractRequest) ProtoMessage() {}
func (x *CallContractRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CallContractRequest.ProtoReflect.Descriptor instead.
func (*CallContractRequest) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{9}
}
func (x *CallContractRequest) GetFrom() []byte {
if x != nil {
return x.From
}
return nil
}
func (x *CallContractRequest) GetTo() []byte {
if x != nil {
return x.To
}
return nil
}
func (x *CallContractRequest) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
func (x *CallContractRequest) GetGas() uint64 {
if x != nil && x.Gas != nil {
return *x.Gas
}
return 0
}
func (x *CallContractRequest) GetGasPrice() uint64 {
if x != nil && x.GasPrice != nil {
return *x.GasPrice
}
return 0
}
func (x *CallContractRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
func (x *CallContractRequest) GetBlockNumber() uint64 {
if x != nil && x.BlockNumber != nil {
return *x.BlockNumber
}
return 0
}
type CallContractResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
ReturnData []byte `protobuf:"bytes,1,opt,name=return_data,json=returnData,proto3" json:"return_data,omitempty"`
GasUsed uint64 `protobuf:"varint,2,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Success bool `protobuf:"varint,3,opt,name=success,proto3" json:"success,omitempty"`
Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CallContractResponse) Reset() {
*x = CallContractResponse{}
mi := &file_api_grpc_trader_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CallContractResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CallContractResponse) ProtoMessage() {}
func (x *CallContractResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_grpc_trader_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CallContractResponse.ProtoReflect.Descriptor instead.
func (*CallContractResponse) Descriptor() ([]byte, []int) {
return file_api_grpc_trader_proto_rawDescGZIP(), []int{10}
}
func (x *CallContractResponse) GetReturnData() []byte {
if x != nil {
return x.ReturnData
}
return nil
}
func (x *CallContractResponse) GetGasUsed() uint64 {
if x != nil {
return x.GasUsed
}
return 0
}
func (x *CallContractResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *CallContractResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
var File_api_grpc_trader_proto protoreflect.FileDescriptor
const file_api_grpc_trader_proto_rawDesc = "" +
"\n" +
"\x15api/grpc/trader.proto\x12\x04grpc\"\x91\x02\n" +
"\x15SimulateBundleRequest\x12\"\n" +
"\ftransactions\x18\x01 \x03(\fR\ftransactions\x12(\n" +
"\rmin_timestamp\x18\x02 \x01(\x04H\x00R\fminTimestamp\x88\x01\x01\x12(\n" +
"\rmax_timestamp\x18\x03 \x01(\x04H\x01R\fmaxTimestamp\x88\x01\x01\x12#\n" +
"\rreverting_txs\x18\x04 \x03(\x05R\frevertingTxs\x12&\n" +
"\ftarget_block\x18\x05 \x01(\x04H\x02R\vtargetBlock\x88\x01\x01B\x10\n" +
"\x0e_min_timestampB\x10\n" +
"\x0e_max_timestampB\x0f\n" +
"\r_target_block\"\x99\x02\n" +
"\x16SimulateBundleResponse\x12\x18\n" +
"\asuccess\x18\x01 \x01(\bR\asuccess\x12\x19\n" +
"\bgas_used\x18\x02 \x01(\x04R\agasUsed\x12\x16\n" +
"\x06profit\x18\x03 \x01(\fR\x06profit\x12)\n" +
"\x10coinbase_balance\x18\x04 \x01(\fR\x0fcoinbaseBalance\x12&\n" +
"\x0ffailed_tx_index\x18\x05 \x01(\x05R\rfailedTxIndex\x12&\n" +
"\x0ffailed_tx_error\x18\x06 \x01(\tR\rfailedTxError\x127\n" +
"\n" +
"tx_results\x18\a \x03(\v2\x18.grpc.TxSimulationResultR\ttxResults\"\x82\x01\n" +
"\x12TxSimulationResult\x12\x18\n" +
"\asuccess\x18\x01 \x01(\bR\asuccess\x12\x19\n" +
"\bgas_used\x18\x02 \x01(\x04R\agasUsed\x12\x14\n" +
"\x05error\x18\x03 \x01(\tR\x05error\x12!\n" +
"\freturn_value\x18\x04 \x01(\fR\vreturnValue\"\x8f\x02\n" +
"\x13SubmitBundleRequest\x12\"\n" +
"\ftransactions\x18\x01 \x03(\fR\ftransactions\x12(\n" +
"\rmin_timestamp\x18\x02 \x01(\x04H\x00R\fminTimestamp\x88\x01\x01\x12(\n" +
"\rmax_timestamp\x18\x03 \x01(\x04H\x01R\fmaxTimestamp\x88\x01\x01\x12#\n" +
"\rreverting_txs\x18\x04 \x03(\x05R\frevertingTxs\x12&\n" +
"\ftarget_block\x18\x05 \x01(\x04H\x02R\vtargetBlock\x88\x01\x01B\x10\n" +
"\x0e_min_timestampB\x10\n" +
"\x0e_max_timestampB\x0f\n" +
"\r_target_block\"7\n" +
"\x14SubmitBundleResponse\x12\x1f\n" +
"\vbundle_hash\x18\x01 \x01(\fR\n" +
"bundleHash\"\x83\x01\n" +
"\x16GetStorageBatchRequest\x12\x1a\n" +
"\bcontract\x18\x01 \x01(\fR\bcontract\x12\x14\n" +
"\x05slots\x18\x02 \x03(\fR\x05slots\x12&\n" +
"\fblock_number\x18\x03 \x01(\x04H\x00R\vblockNumber\x88\x01\x01B\x0f\n" +
"\r_block_number\"1\n" +
"\x17GetStorageBatchResponse\x12\x16\n" +
"\x06values\x18\x01 \x03(\fR\x06values\"Z\n" +
"\x1dGetPendingTransactionsRequest\x12'\n" +
"\rmin_gas_price\x18\x01 \x01(\x04H\x00R\vminGasPrice\x88\x01\x01B\x10\n" +
"\x0e_min_gas_price\"D\n" +
"\x1eGetPendingTransactionsResponse\x12\"\n" +
"\ftransactions\x18\x01 \x03(\fR\ftransactions\"\xfa\x01\n" +
"\x13CallContractRequest\x12\x12\n" +
"\x04from\x18\x01 \x01(\fR\x04from\x12\x0e\n" +
"\x02to\x18\x02 \x01(\fR\x02to\x12\x12\n" +
"\x04data\x18\x03 \x01(\fR\x04data\x12\x15\n" +
"\x03gas\x18\x04 \x01(\x04H\x00R\x03gas\x88\x01\x01\x12 \n" +
"\tgas_price\x18\x05 \x01(\x04H\x01R\bgasPrice\x88\x01\x01\x12\x19\n" +
"\x05value\x18\x06 \x01(\fH\x02R\x05value\x88\x01\x01\x12&\n" +
"\fblock_number\x18\a \x01(\x04H\x03R\vblockNumber\x88\x01\x01B\x06\n" +
"\x04_gasB\f\n" +
"\n" +
"_gas_priceB\b\n" +
"\x06_valueB\x0f\n" +
"\r_block_number\"\x82\x01\n" +
"\x14CallContractResponse\x12\x1f\n" +
"\vreturn_data\x18\x01 \x01(\fR\n" +
"returnData\x12\x19\n" +
"\bgas_used\x18\x02 \x01(\x04R\agasUsed\x12\x18\n" +
"\asuccess\x18\x03 \x01(\bR\asuccess\x12\x14\n" +
"\x05error\x18\x04 \x01(\tR\x05error2\x9f\x03\n" +
"\rTraderService\x12K\n" +
"\x0eSimulateBundle\x12\x1b.grpc.SimulateBundleRequest\x1a\x1c.grpc.SimulateBundleResponse\x12E\n" +
"\fSubmitBundle\x12\x19.grpc.SubmitBundleRequest\x1a\x1a.grpc.SubmitBundleResponse\x12N\n" +
"\x0fGetStorageBatch\x12\x1c.grpc.GetStorageBatchRequest\x1a\x1d.grpc.GetStorageBatchResponse\x12c\n" +
"\x16GetPendingTransactions\x12#.grpc.GetPendingTransactionsRequest\x1a$.grpc.GetPendingTransactionsResponse\x12E\n" +
"\fCallContract\x12\x19.grpc.CallContractRequest\x1a\x1a.grpc.CallContractResponseB*Z(github.com/ethereum/go-ethereum/api/grpcb\x06proto3"
var (
file_api_grpc_trader_proto_rawDescOnce sync.Once
file_api_grpc_trader_proto_rawDescData []byte
)
func file_api_grpc_trader_proto_rawDescGZIP() []byte {
file_api_grpc_trader_proto_rawDescOnce.Do(func() {
file_api_grpc_trader_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_grpc_trader_proto_rawDesc), len(file_api_grpc_trader_proto_rawDesc)))
})
return file_api_grpc_trader_proto_rawDescData
}
var file_api_grpc_trader_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_api_grpc_trader_proto_goTypes = []any{
(*SimulateBundleRequest)(nil), // 0: grpc.SimulateBundleRequest
(*SimulateBundleResponse)(nil), // 1: grpc.SimulateBundleResponse
(*TxSimulationResult)(nil), // 2: grpc.TxSimulationResult
(*SubmitBundleRequest)(nil), // 3: grpc.SubmitBundleRequest
(*SubmitBundleResponse)(nil), // 4: grpc.SubmitBundleResponse
(*GetStorageBatchRequest)(nil), // 5: grpc.GetStorageBatchRequest
(*GetStorageBatchResponse)(nil), // 6: grpc.GetStorageBatchResponse
(*GetPendingTransactionsRequest)(nil), // 7: grpc.GetPendingTransactionsRequest
(*GetPendingTransactionsResponse)(nil), // 8: grpc.GetPendingTransactionsResponse
(*CallContractRequest)(nil), // 9: grpc.CallContractRequest
(*CallContractResponse)(nil), // 10: grpc.CallContractResponse
}
var file_api_grpc_trader_proto_depIdxs = []int32{
2, // 0: grpc.SimulateBundleResponse.tx_results:type_name -> grpc.TxSimulationResult
0, // 1: grpc.TraderService.SimulateBundle:input_type -> grpc.SimulateBundleRequest
3, // 2: grpc.TraderService.SubmitBundle:input_type -> grpc.SubmitBundleRequest
5, // 3: grpc.TraderService.GetStorageBatch:input_type -> grpc.GetStorageBatchRequest
7, // 4: grpc.TraderService.GetPendingTransactions:input_type -> grpc.GetPendingTransactionsRequest
9, // 5: grpc.TraderService.CallContract:input_type -> grpc.CallContractRequest
1, // 6: grpc.TraderService.SimulateBundle:output_type -> grpc.SimulateBundleResponse
4, // 7: grpc.TraderService.SubmitBundle:output_type -> grpc.SubmitBundleResponse
6, // 8: grpc.TraderService.GetStorageBatch:output_type -> grpc.GetStorageBatchResponse
8, // 9: grpc.TraderService.GetPendingTransactions:output_type -> grpc.GetPendingTransactionsResponse
10, // 10: grpc.TraderService.CallContract:output_type -> grpc.CallContractResponse
6, // [6:11] is the sub-list for method output_type
1, // [1:6] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_api_grpc_trader_proto_init() }
func file_api_grpc_trader_proto_init() {
if File_api_grpc_trader_proto != nil {
return
}
file_api_grpc_trader_proto_msgTypes[0].OneofWrappers = []any{}
file_api_grpc_trader_proto_msgTypes[3].OneofWrappers = []any{}
file_api_grpc_trader_proto_msgTypes[5].OneofWrappers = []any{}
file_api_grpc_trader_proto_msgTypes[7].OneofWrappers = []any{}
file_api_grpc_trader_proto_msgTypes[9].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_grpc_trader_proto_rawDesc), len(file_api_grpc_trader_proto_rawDesc)),
NumEnums: 0,
NumMessages: 11,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_api_grpc_trader_proto_goTypes,
DependencyIndexes: file_api_grpc_trader_proto_depIdxs,
MessageInfos: file_api_grpc_trader_proto_msgTypes,
}.Build()
File_api_grpc_trader_proto = out.File
file_api_grpc_trader_proto_goTypes = nil
file_api_grpc_trader_proto_depIdxs = nil
}

287
api/grpc/trader_grpc.pb.go Normal file
View file

@ -0,0 +1,287 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v6.33.1
// source: api/grpc/trader.proto
package grpc
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
TraderService_SimulateBundle_FullMethodName = "/grpc.TraderService/SimulateBundle"
TraderService_SubmitBundle_FullMethodName = "/grpc.TraderService/SubmitBundle"
TraderService_GetStorageBatch_FullMethodName = "/grpc.TraderService/GetStorageBatch"
TraderService_GetPendingTransactions_FullMethodName = "/grpc.TraderService/GetPendingTransactions"
TraderService_CallContract_FullMethodName = "/grpc.TraderService/CallContract"
)
// TraderServiceClient is the client API for TraderService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
//
// TraderService provides low-latency APIs for trading operations.
type TraderServiceClient interface {
// SimulateBundle simulates bundle execution and returns results
SimulateBundle(ctx context.Context, in *SimulateBundleRequest, opts ...grpc.CallOption) (*SimulateBundleResponse, error)
// SubmitBundle submits a bundle for inclusion in future blocks
SubmitBundle(ctx context.Context, in *SubmitBundleRequest, opts ...grpc.CallOption) (*SubmitBundleResponse, error)
// GetStorageBatch retrieves multiple storage slots in a single call
GetStorageBatch(ctx context.Context, in *GetStorageBatchRequest, opts ...grpc.CallOption) (*GetStorageBatchResponse, error)
// GetPendingTransactions returns currently pending transactions
GetPendingTransactions(ctx context.Context, in *GetPendingTransactionsRequest, opts ...grpc.CallOption) (*GetPendingTransactionsResponse, error)
// CallContract executes a contract call
CallContract(ctx context.Context, in *CallContractRequest, opts ...grpc.CallOption) (*CallContractResponse, error)
}
type traderServiceClient struct {
cc grpc.ClientConnInterface
}
func NewTraderServiceClient(cc grpc.ClientConnInterface) TraderServiceClient {
return &traderServiceClient{cc}
}
func (c *traderServiceClient) SimulateBundle(ctx context.Context, in *SimulateBundleRequest, opts ...grpc.CallOption) (*SimulateBundleResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(SimulateBundleResponse)
err := c.cc.Invoke(ctx, TraderService_SimulateBundle_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *traderServiceClient) SubmitBundle(ctx context.Context, in *SubmitBundleRequest, opts ...grpc.CallOption) (*SubmitBundleResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(SubmitBundleResponse)
err := c.cc.Invoke(ctx, TraderService_SubmitBundle_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *traderServiceClient) GetStorageBatch(ctx context.Context, in *GetStorageBatchRequest, opts ...grpc.CallOption) (*GetStorageBatchResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetStorageBatchResponse)
err := c.cc.Invoke(ctx, TraderService_GetStorageBatch_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *traderServiceClient) GetPendingTransactions(ctx context.Context, in *GetPendingTransactionsRequest, opts ...grpc.CallOption) (*GetPendingTransactionsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetPendingTransactionsResponse)
err := c.cc.Invoke(ctx, TraderService_GetPendingTransactions_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *traderServiceClient) CallContract(ctx context.Context, in *CallContractRequest, opts ...grpc.CallOption) (*CallContractResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CallContractResponse)
err := c.cc.Invoke(ctx, TraderService_CallContract_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// TraderServiceServer is the server API for TraderService service.
// All implementations must embed UnimplementedTraderServiceServer
// for forward compatibility.
//
// TraderService provides low-latency APIs for trading operations.
type TraderServiceServer interface {
// SimulateBundle simulates bundle execution and returns results
SimulateBundle(context.Context, *SimulateBundleRequest) (*SimulateBundleResponse, error)
// SubmitBundle submits a bundle for inclusion in future blocks
SubmitBundle(context.Context, *SubmitBundleRequest) (*SubmitBundleResponse, error)
// GetStorageBatch retrieves multiple storage slots in a single call
GetStorageBatch(context.Context, *GetStorageBatchRequest) (*GetStorageBatchResponse, error)
// GetPendingTransactions returns currently pending transactions
GetPendingTransactions(context.Context, *GetPendingTransactionsRequest) (*GetPendingTransactionsResponse, error)
// CallContract executes a contract call
CallContract(context.Context, *CallContractRequest) (*CallContractResponse, error)
mustEmbedUnimplementedTraderServiceServer()
}
// UnimplementedTraderServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedTraderServiceServer struct{}
func (UnimplementedTraderServiceServer) SimulateBundle(context.Context, *SimulateBundleRequest) (*SimulateBundleResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SimulateBundle not implemented")
}
func (UnimplementedTraderServiceServer) SubmitBundle(context.Context, *SubmitBundleRequest) (*SubmitBundleResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SubmitBundle not implemented")
}
func (UnimplementedTraderServiceServer) GetStorageBatch(context.Context, *GetStorageBatchRequest) (*GetStorageBatchResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetStorageBatch not implemented")
}
func (UnimplementedTraderServiceServer) GetPendingTransactions(context.Context, *GetPendingTransactionsRequest) (*GetPendingTransactionsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPendingTransactions not implemented")
}
func (UnimplementedTraderServiceServer) CallContract(context.Context, *CallContractRequest) (*CallContractResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CallContract not implemented")
}
func (UnimplementedTraderServiceServer) mustEmbedUnimplementedTraderServiceServer() {}
func (UnimplementedTraderServiceServer) testEmbeddedByValue() {}
// UnsafeTraderServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TraderServiceServer will
// result in compilation errors.
type UnsafeTraderServiceServer interface {
mustEmbedUnimplementedTraderServiceServer()
}
func RegisterTraderServiceServer(s grpc.ServiceRegistrar, srv TraderServiceServer) {
// If the following call pancis, it indicates UnimplementedTraderServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&TraderService_ServiceDesc, srv)
}
func _TraderService_SimulateBundle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SimulateBundleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TraderServiceServer).SimulateBundle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: TraderService_SimulateBundle_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TraderServiceServer).SimulateBundle(ctx, req.(*SimulateBundleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _TraderService_SubmitBundle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SubmitBundleRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TraderServiceServer).SubmitBundle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: TraderService_SubmitBundle_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TraderServiceServer).SubmitBundle(ctx, req.(*SubmitBundleRequest))
}
return interceptor(ctx, in, info, handler)
}
func _TraderService_GetStorageBatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetStorageBatchRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TraderServiceServer).GetStorageBatch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: TraderService_GetStorageBatch_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TraderServiceServer).GetStorageBatch(ctx, req.(*GetStorageBatchRequest))
}
return interceptor(ctx, in, info, handler)
}
func _TraderService_GetPendingTransactions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetPendingTransactionsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TraderServiceServer).GetPendingTransactions(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: TraderService_GetPendingTransactions_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TraderServiceServer).GetPendingTransactions(ctx, req.(*GetPendingTransactionsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _TraderService_CallContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CallContractRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TraderServiceServer).CallContract(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: TraderService_CallContract_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TraderServiceServer).CallContract(ctx, req.(*CallContractRequest))
}
return interceptor(ctx, in, info, handler)
}
// TraderService_ServiceDesc is the grpc.ServiceDesc for TraderService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var TraderService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "grpc.TraderService",
HandlerType: (*TraderServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SimulateBundle",
Handler: _TraderService_SimulateBundle_Handler,
},
{
MethodName: "SubmitBundle",
Handler: _TraderService_SubmitBundle_Handler,
},
{
MethodName: "GetStorageBatch",
Handler: _TraderService_GetStorageBatch_Handler,
},
{
MethodName: "GetPendingTransactions",
Handler: _TraderService_GetPendingTransactions_Handler,
},
{
MethodName: "CallContract",
Handler: _TraderService_CallContract_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/grpc/trader.proto",
}

21
go.mod
View file

@ -33,7 +33,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.2
github.com/golang/snappy v1.0.0
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.3.0
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.4.2
github.com/graph-gophers/graphql-go v1.3.0
github.com/hashicorp/go-bexpr v0.1.10
@ -65,18 +65,21 @@ require (
github.com/urfave/cli/v2 v2.27.5
go.uber.org/automaxprocs v1.5.2
go.uber.org/goleak v1.3.0
golang.org/x/crypto v0.36.0
golang.org/x/crypto v0.43.0
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
golang.org/x/sync v0.12.0
golang.org/x/sys v0.36.0
golang.org/x/text v0.23.0
golang.org/x/sync v0.17.0
golang.org/x/sys v0.37.0
golang.org/x/text v0.30.0
golang.org/x/time v0.9.0
golang.org/x/tools v0.29.0
google.golang.org/protobuf v1.34.2
golang.org/x/tools v0.37.0
google.golang.org/grpc v1.77.0
google.golang.org/protobuf v1.36.10
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
)
require google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
@ -144,8 +147,8 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

62
go.sum
View file

@ -140,6 +140,10 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@ -174,16 +178,16 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@ -370,6 +374,18 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBi
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -382,16 +398,16 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -407,8 +423,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo=
golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -417,8 +433,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -451,8 +467,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -470,8 +486,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
@ -483,21 +499,27 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=