Skip to content

Commit

Permalink
Refactor: Reuse v6 starknet_add...Transaction handler for v7
Browse files Browse the repository at this point in the history
  • Loading branch information
hudem1 committed Feb 21, 2025
1 parent 1709a05 commit 1a7ac25
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 439 deletions.
6 changes: 3 additions & 3 deletions rpc/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,17 +362,17 @@ func (h *Handler) MethodsV0_7() ([]jsonrpc.Method, string) { //nolint: funlen
{
Name: "starknet_addInvokeTransaction",
Params: []jsonrpc.Parameter{{Name: "invoke_transaction"}},
Handler: h.rpcv7Handler.AddTransaction,
Handler: h.rpcv6Handler.AddTransaction,
},
{
Name: "starknet_addDeployAccountTransaction",
Params: []jsonrpc.Parameter{{Name: "deploy_account_transaction"}},
Handler: h.rpcv7Handler.AddTransaction,
Handler: h.rpcv6Handler.AddTransaction,
},
{
Name: "starknet_addDeclareTransaction",
Params: []jsonrpc.Parameter{{Name: "declare_transaction"}},
Handler: h.rpcv7Handler.AddTransaction,
Handler: h.rpcv6Handler.AddTransaction,
},
{
Name: "starknet_getEvents",
Expand Down
2 changes: 1 addition & 1 deletion rpc/v6/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ type Transaction struct {
ContractAddressSalt *felt.Felt `json:"contract_address_salt,omitempty" validate:"required_if=Type DEPLOY,required_if=Type DEPLOY_ACCOUNT"`
ClassHash *felt.Felt `json:"class_hash,omitempty" validate:"required_if=Type DEPLOY,required_if=Type DEPLOY_ACCOUNT"`
ConstructorCallData *[]*felt.Felt `json:"constructor_calldata,omitempty" validate:"required_if=Type DEPLOY,required_if=Type DEPLOY_ACCOUNT"`
SenderAddress *felt.Felt `json:"sender_address,omitempty" validate:"required_if=Type DECLARE,required_if=Type INVOKE Version 0x1"`
SenderAddress *felt.Felt `json:"sender_address,omitempty" validate:"required_if=Type DECLARE,required_if=Type INVOKE Version 0x1,required_if=Type INVOKE Version 0x3"`
Signature *[]*felt.Felt `json:"signature,omitempty" validate:"required"`
CallData *[]*felt.Felt `json:"calldata,omitempty" validate:"required_if=Type INVOKE"`
EntryPointSelector *felt.Felt `json:"entry_point_selector,omitempty" validate:"required_if=Type INVOKE Version 0x0"`
Expand Down
151 changes: 0 additions & 151 deletions rpc/v7/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"fmt"

"github.com/NethermindEth/juno/adapters/sn2core"
"github.com/NethermindEth/juno/clients/gateway"
"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/db"
Expand Down Expand Up @@ -372,52 +371,6 @@ func adaptResourceBounds(rb map[core.Resource]core.ResourceBounds) map[Resource]
return rpcResourceBounds
}

func adaptToFeederResourceBounds(rb *map[Resource]ResourceBounds) *map[starknet.Resource]starknet.ResourceBounds { //nolint:gocritic
if rb == nil {
return nil
}
feederResourceBounds := make(map[starknet.Resource]starknet.ResourceBounds)
for resource, bounds := range *rb {
feederResourceBounds[starknet.Resource(resource)] = starknet.ResourceBounds{
MaxAmount: bounds.MaxAmount,
MaxPricePerUnit: bounds.MaxPricePerUnit,
}
}
return &feederResourceBounds
}

func adaptToFeederDAMode(mode *DataAvailabilityMode) *starknet.DataAvailabilityMode {
if mode == nil {
return nil
}
return utils.Ptr(starknet.DataAvailabilityMode(*mode))
}

func adaptRPCTxToFeederTx(rpcTx *Transaction) *starknet.Transaction {
return &starknet.Transaction{
Hash: rpcTx.Hash,
Version: rpcTx.Version,
ContractAddress: rpcTx.ContractAddress,
ContractAddressSalt: rpcTx.ContractAddressSalt,
ClassHash: rpcTx.ClassHash,
ConstructorCallData: rpcTx.ConstructorCallData,
Type: starknet.TransactionType(rpcTx.Type),
SenderAddress: rpcTx.SenderAddress,
MaxFee: rpcTx.MaxFee,
Signature: rpcTx.Signature,
CallData: rpcTx.CallData,
EntryPointSelector: rpcTx.EntryPointSelector,
Nonce: rpcTx.Nonce,
CompiledClassHash: rpcTx.CompiledClassHash,
ResourceBounds: adaptToFeederResourceBounds(rpcTx.ResourceBounds),
Tip: rpcTx.Tip,
NonceDAMode: adaptToFeederDAMode(rpcTx.NonceDAMode),
FeeDAMode: adaptToFeederDAMode(rpcTx.FeeDAMode),
AccountDeploymentData: rpcTx.AccountDeploymentData,
PaymasterData: rpcTx.PaymasterData,
}
}

/****************************************************
Transaction Handlers
*****************************************************/
Expand Down Expand Up @@ -553,72 +506,6 @@ func (h *Handler) TransactionReceiptByHash(hash felt.Felt) (*TransactionReceipt,
return AdaptReceipt(receipt, txn, status, blockHash, blockNumber), nil
}

// AddTransaction relays a transaction to the gateway.
func (h *Handler) AddTransaction(ctx context.Context, tx BroadcastedTransaction) (*AddTxResponse, *jsonrpc.Error) { //nolint:gocritic
if tx.Type == TxnDeclare && tx.Version.Cmp(new(felt.Felt).SetUint64(2)) != -1 {
contractClass := make(map[string]any)
if err := json.Unmarshal(tx.ContractClass, &contractClass); err != nil {
return nil, rpccore.ErrInternal.CloneWithData(fmt.Sprintf("unmarshal contract class: %v", err))
}
sierraProg, ok := contractClass["sierra_program"]
if !ok {
return nil, jsonrpc.Err(jsonrpc.InvalidParams, "{'sierra_program': ['Missing data for required field.']}")
}

sierraProgBytes, errIn := json.Marshal(sierraProg)
if errIn != nil {
return nil, jsonrpc.Err(jsonrpc.InternalError, errIn.Error())
}

gwSierraProg, errIn := utils.Gzip64Encode(sierraProgBytes)
if errIn != nil {
return nil, jsonrpc.Err(jsonrpc.InternalError, errIn.Error())
}

contractClass["sierra_program"] = gwSierraProg
newContractClass, err := json.Marshal(contractClass)
if err != nil {
return nil, rpccore.ErrInternal.CloneWithData(fmt.Sprintf("marshal revised contract class: %v", err))
}
tx.ContractClass = newContractClass
}

txJSON, err := json.Marshal(&struct {
*starknet.Transaction
ContractClass json.RawMessage `json:"contract_class,omitempty"`
}{
Transaction: adaptRPCTxToFeederTx(&tx.Transaction),
ContractClass: tx.ContractClass,
})
if err != nil {
return nil, rpccore.ErrInternal.CloneWithData(fmt.Sprintf("marshal transaction: %v", err))
}

if h.gatewayClient == nil {
return nil, rpccore.ErrInternal.CloneWithData("no gateway client configured")
}

respJSON, err := h.gatewayClient.AddTransaction(ctx, txJSON)
if err != nil {
return nil, makeJSONErrorFromGatewayError(err)
}

var gatewayResponse struct {
TransactionHash *felt.Felt `json:"transaction_hash"`
ContractAddress *felt.Felt `json:"address"`
ClassHash *felt.Felt `json:"class_hash"`
}
if err = json.Unmarshal(respJSON, &gatewayResponse); err != nil {
return nil, jsonrpc.Err(jsonrpc.InternalError, fmt.Sprintf("unmarshal gateway response: %v", err))
}

return &AddTxResponse{
TransactionHash: gatewayResponse.TransactionHash,
ContractAddress: gatewayResponse.ContractAddress,
ClassHash: gatewayResponse.ClassHash,
}, nil
}

var errTransactionNotFound = errors.New("transaction not found")

func (h *Handler) TransactionStatus(ctx context.Context, hash felt.Felt) (*TransactionStatus, *jsonrpc.Error) {
Expand Down Expand Up @@ -670,44 +557,6 @@ func (h *Handler) TransactionStatusV0_7(ctx context.Context, hash felt.Felt) (*T
}, nil
}

func makeJSONErrorFromGatewayError(err error) *jsonrpc.Error {
gatewayErr, ok := err.(*gateway.Error)
if !ok {
return jsonrpc.Err(jsonrpc.InternalError, err.Error())
}

switch gatewayErr.Code {
case gateway.InvalidContractClass:
return rpccore.ErrInvalidContractClass
case gateway.UndeclaredClass:
return rpccore.ErrClassHashNotFound
case gateway.ClassAlreadyDeclared:
return rpccore.ErrClassAlreadyDeclared
case gateway.InsufficientMaxFee:
return rpccore.ErrInsufficientMaxFee
case gateway.InsufficientAccountBalance:
return rpccore.ErrInsufficientAccountBalance
case gateway.ValidateFailure:
return rpccore.ErrValidationFailure.CloneWithData(gatewayErr.Message)
case gateway.ContractBytecodeSizeTooLarge, gateway.ContractClassObjectSizeTooLarge:
return rpccore.ErrContractClassSizeTooLarge
case gateway.DuplicatedTransaction:
return rpccore.ErrDuplicateTx
case gateway.InvalidTransactionNonce:
return rpccore.ErrInvalidTransactionNonce
case gateway.CompilationFailed:
return rpccore.ErrCompilationFailed
case gateway.InvalidCompiledClassHash:
return rpccore.ErrCompiledClassHashMismatch
case gateway.InvalidTransactionVersion:
return rpccore.ErrUnsupportedTxVersion
case gateway.InvalidContractClassVersion:
return rpccore.ErrUnsupportedContractClassVersion
default:
return rpccore.ErrUnexpectedError.CloneWithData(gatewayErr.Message)
}
}

func AdaptTransaction(t core.Transaction) *Transaction {
var txn *Transaction
switch v := t.(type) {
Expand Down
Loading

0 comments on commit 1a7ac25

Please sign in to comment.