|  | 
|  | 1 | +package rpcv8 | 
|  | 2 | + | 
|  | 3 | +import ( | 
|  | 4 | +	"errors" | 
|  | 5 | + | 
|  | 6 | +	"github.com/NethermindEth/juno/core/felt" | 
|  | 7 | +	rpcv6 "github.com/NethermindEth/juno/rpc/v6" | 
|  | 8 | +	"github.com/NethermindEth/juno/starknet" | 
|  | 9 | +	"github.com/NethermindEth/juno/utils" | 
|  | 10 | +	"github.com/NethermindEth/juno/vm" | 
|  | 11 | +) | 
|  | 12 | + | 
|  | 13 | +/**************************************************** | 
|  | 14 | +		VM Adapters | 
|  | 15 | +*****************************************************/ | 
|  | 16 | + | 
|  | 17 | +func AdaptVMTransactionTrace(trace *vm.TransactionTrace) TransactionTrace { | 
|  | 18 | +	var validateInvocation *FunctionInvocation | 
|  | 19 | +	if trace.ValidateInvocation != nil && trace.Type != vm.TxnL1Handler { | 
|  | 20 | +		validateInvocation = utils.HeapPtr(adaptVMFunctionInvocation(trace.ValidateInvocation)) | 
|  | 21 | +	} | 
|  | 22 | + | 
|  | 23 | +	var feeTransferInvocation *FunctionInvocation | 
|  | 24 | +	if trace.FeeTransferInvocation != nil && trace.Type != vm.TxnL1Handler { | 
|  | 25 | +		feeTransferInvocation = utils.HeapPtr(adaptVMFunctionInvocation(trace.FeeTransferInvocation)) | 
|  | 26 | +	} | 
|  | 27 | + | 
|  | 28 | +	var constructorInvocation *FunctionInvocation | 
|  | 29 | +	var executeInvocation *ExecuteInvocation | 
|  | 30 | +	var functionInvocation *FunctionInvocation | 
|  | 31 | + | 
|  | 32 | +	switch trace.Type { | 
|  | 33 | +	case vm.TxnDeployAccount, vm.TxnDeploy: | 
|  | 34 | +		if trace.ConstructorInvocation != nil { | 
|  | 35 | +			constructorInvocation = utils.HeapPtr(adaptVMFunctionInvocation(trace.ConstructorInvocation)) | 
|  | 36 | +		} | 
|  | 37 | +	case vm.TxnInvoke: | 
|  | 38 | +		if trace.ExecuteInvocation != nil { | 
|  | 39 | +			executeInvocation = utils.HeapPtr(adaptVMExecuteInvocation(trace.ExecuteInvocation)) | 
|  | 40 | +		} | 
|  | 41 | +	case vm.TxnL1Handler: | 
|  | 42 | +		if trace.FunctionInvocation != nil { | 
|  | 43 | +			functionInvocation = utils.HeapPtr(adaptVMFunctionInvocation(trace.FunctionInvocation)) | 
|  | 44 | +		} | 
|  | 45 | +	} | 
|  | 46 | + | 
|  | 47 | +	var resources *ExecutionResources | 
|  | 48 | +	if trace.ExecutionResources != nil { | 
|  | 49 | +		resources = utils.HeapPtr(adaptVMExecutionResources(trace.ExecutionResources)) | 
|  | 50 | +	} | 
|  | 51 | + | 
|  | 52 | +	var stateDiff *rpcv6.StateDiff | 
|  | 53 | +	if trace.StateDiff != nil { | 
|  | 54 | +		stateDiff = utils.HeapPtr(rpcv6.AdaptVMStateDiff(trace.StateDiff)) | 
|  | 55 | +	} | 
|  | 56 | + | 
|  | 57 | +	return TransactionTrace{ | 
|  | 58 | +		Type:                  TransactionType(trace.Type), | 
|  | 59 | +		ValidateInvocation:    validateInvocation, | 
|  | 60 | +		ExecuteInvocation:     executeInvocation, | 
|  | 61 | +		FeeTransferInvocation: feeTransferInvocation, | 
|  | 62 | +		ConstructorInvocation: constructorInvocation, | 
|  | 63 | +		FunctionInvocation:    functionInvocation, | 
|  | 64 | +		StateDiff:             stateDiff, | 
|  | 65 | +		ExecutionResources:    resources, | 
|  | 66 | +	} | 
|  | 67 | +} | 
|  | 68 | + | 
|  | 69 | +func adaptVMExecuteInvocation(vmFnInvocation *vm.ExecuteInvocation) ExecuteInvocation { | 
|  | 70 | +	var functionInvocation *FunctionInvocation | 
|  | 71 | +	if vmFnInvocation.FunctionInvocation != nil { | 
|  | 72 | +		functionInvocation = utils.HeapPtr(adaptVMFunctionInvocation(vmFnInvocation.FunctionInvocation)) | 
|  | 73 | +	} | 
|  | 74 | + | 
|  | 75 | +	return ExecuteInvocation{ | 
|  | 76 | +		RevertReason:       vmFnInvocation.RevertReason, | 
|  | 77 | +		FunctionInvocation: functionInvocation, | 
|  | 78 | +	} | 
|  | 79 | +} | 
|  | 80 | + | 
|  | 81 | +func adaptVMFunctionInvocation(vmFnInvocation *vm.FunctionInvocation) FunctionInvocation { | 
|  | 82 | +	// Adapt inner calls | 
|  | 83 | +	adaptedCalls := make([]FunctionInvocation, len(vmFnInvocation.Calls)) | 
|  | 84 | +	for index := range vmFnInvocation.Calls { | 
|  | 85 | +		adaptedCalls[index] = adaptVMFunctionInvocation(&vmFnInvocation.Calls[index]) | 
|  | 86 | +	} | 
|  | 87 | + | 
|  | 88 | +	// Adapt events | 
|  | 89 | +	adaptedEvents := make([]rpcv6.OrderedEvent, len(vmFnInvocation.Events)) | 
|  | 90 | +	for index := range vmFnInvocation.Events { | 
|  | 91 | +		vmEvent := &vmFnInvocation.Events[index] | 
|  | 92 | + | 
|  | 93 | +		adaptedEvents[index] = rpcv6.OrderedEvent{ | 
|  | 94 | +			Order: vmEvent.Order, | 
|  | 95 | +			Keys:  vmEvent.Keys, | 
|  | 96 | +			Data:  vmEvent.Data, | 
|  | 97 | +		} | 
|  | 98 | +	} | 
|  | 99 | + | 
|  | 100 | +	// Adapt messages | 
|  | 101 | +	adaptedMessages := make([]rpcv6.OrderedL2toL1Message, len(vmFnInvocation.Messages)) | 
|  | 102 | +	for index := range vmFnInvocation.Messages { | 
|  | 103 | +		vmMessage := &vmFnInvocation.Messages[index] | 
|  | 104 | + | 
|  | 105 | +		toAddr, _ := new(felt.Felt).SetString(vmMessage.To) | 
|  | 106 | + | 
|  | 107 | +		adaptedMessages[index] = rpcv6.OrderedL2toL1Message{ | 
|  | 108 | +			Order:   vmMessage.Order, | 
|  | 109 | +			From:    vmMessage.From, | 
|  | 110 | +			To:      toAddr, | 
|  | 111 | +			Payload: vmMessage.Payload, | 
|  | 112 | +		} | 
|  | 113 | +	} | 
|  | 114 | + | 
|  | 115 | +	// Adapt execution resources | 
|  | 116 | +	var adaptedResources *InnerExecutionResources | 
|  | 117 | +	if r := vmFnInvocation.ExecutionResources; r != nil { | 
|  | 118 | +		adaptedResources = &InnerExecutionResources{ | 
|  | 119 | +			L1Gas: r.L1Gas, | 
|  | 120 | +			L2Gas: r.L2Gas, | 
|  | 121 | +		} | 
|  | 122 | +	} | 
|  | 123 | + | 
|  | 124 | +	return FunctionInvocation{ | 
|  | 125 | +		ContractAddress:    vmFnInvocation.ContractAddress, | 
|  | 126 | +		EntryPointSelector: vmFnInvocation.EntryPointSelector, | 
|  | 127 | +		Calldata:           vmFnInvocation.Calldata, | 
|  | 128 | +		CallerAddress:      vmFnInvocation.CallerAddress, | 
|  | 129 | +		ClassHash:          vmFnInvocation.ClassHash, | 
|  | 130 | +		EntryPointType:     vmFnInvocation.EntryPointType, | 
|  | 131 | +		CallType:           vmFnInvocation.CallType, | 
|  | 132 | +		Result:             vmFnInvocation.Result, | 
|  | 133 | +		Calls:              adaptedCalls, | 
|  | 134 | +		Events:             adaptedEvents, | 
|  | 135 | +		Messages:           adaptedMessages, | 
|  | 136 | +		ExecutionResources: adaptedResources, | 
|  | 137 | +		IsReverted:         vmFnInvocation.IsReverted, | 
|  | 138 | +	} | 
|  | 139 | +} | 
|  | 140 | + | 
|  | 141 | +func adaptVMExecutionResources(r *vm.ExecutionResources) ExecutionResources { | 
|  | 142 | +	return ExecutionResources{ | 
|  | 143 | +		InnerExecutionResources: InnerExecutionResources{ | 
|  | 144 | +			L1Gas: r.L1Gas, | 
|  | 145 | +			L2Gas: r.L2Gas, | 
|  | 146 | +		}, | 
|  | 147 | +		L1DataGas: r.L1DataGas, | 
|  | 148 | +	} | 
|  | 149 | +} | 
|  | 150 | + | 
|  | 151 | +/**************************************************** | 
|  | 152 | +		Feeder Adapters | 
|  | 153 | +*****************************************************/ | 
|  | 154 | + | 
|  | 155 | +func AdaptFeederBlockTrace(block *BlockWithTxs, blockTrace *starknet.BlockTrace) ([]TracedBlockTransaction, error) { | 
|  | 156 | +	if blockTrace == nil { | 
|  | 157 | +		return nil, nil | 
|  | 158 | +	} | 
|  | 159 | + | 
|  | 160 | +	if len(block.Transactions) != len(blockTrace.Traces) { | 
|  | 161 | +		return nil, errors.New("mismatched number of txs and traces") | 
|  | 162 | +	} | 
|  | 163 | + | 
|  | 164 | +	// Adapt every feeder block trace to rpc v8 trace | 
|  | 165 | +	adaptedTraces := make([]TracedBlockTransaction, len(blockTrace.Traces)) | 
|  | 166 | +	for index := range blockTrace.Traces { | 
|  | 167 | +		feederTrace := &blockTrace.Traces[index] | 
|  | 168 | + | 
|  | 169 | +		trace := TransactionTrace{ | 
|  | 170 | +			Type: block.Transactions[index].Type, | 
|  | 171 | +		} | 
|  | 172 | + | 
|  | 173 | +		if feederTrace.FeeTransferInvocation != nil && trace.Type != TxnL1Handler { | 
|  | 174 | +			trace.FeeTransferInvocation = utils.HeapPtr(adaptFeederFunctionInvocation(feederTrace.FeeTransferInvocation)) | 
|  | 175 | +		} | 
|  | 176 | + | 
|  | 177 | +		if feederTrace.ValidateInvocation != nil && trace.Type != TxnL1Handler { | 
|  | 178 | +			trace.ValidateInvocation = utils.HeapPtr(adaptFeederFunctionInvocation(feederTrace.ValidateInvocation)) | 
|  | 179 | +		} | 
|  | 180 | + | 
|  | 181 | +		var fnInvocation *FunctionInvocation | 
|  | 182 | +		if fct := feederTrace.FunctionInvocation; fct != nil { | 
|  | 183 | +			fnInvocation = utils.HeapPtr(adaptFeederFunctionInvocation(fct)) | 
|  | 184 | +		} | 
|  | 185 | + | 
|  | 186 | +		switch trace.Type { | 
|  | 187 | +		case TxnDeploy, TxnDeployAccount: | 
|  | 188 | +			trace.ConstructorInvocation = fnInvocation | 
|  | 189 | +		case TxnInvoke: | 
|  | 190 | +			trace.ExecuteInvocation = new(ExecuteInvocation) | 
|  | 191 | +			if feederTrace.RevertError != "" { | 
|  | 192 | +				trace.ExecuteInvocation.RevertReason = feederTrace.RevertError | 
|  | 193 | +			} else { | 
|  | 194 | +				trace.ExecuteInvocation.FunctionInvocation = fnInvocation | 
|  | 195 | +			} | 
|  | 196 | +		case TxnL1Handler: | 
|  | 197 | +			trace.FunctionInvocation = fnInvocation | 
|  | 198 | +		} | 
|  | 199 | + | 
|  | 200 | +		adaptedTraces[index] = TracedBlockTransaction{ | 
|  | 201 | +			TransactionHash: &feederTrace.TransactionHash, | 
|  | 202 | +			TraceRoot:       &trace, | 
|  | 203 | +		} | 
|  | 204 | +	} | 
|  | 205 | + | 
|  | 206 | +	return adaptedTraces, nil | 
|  | 207 | +} | 
|  | 208 | + | 
|  | 209 | +func adaptFeederFunctionInvocation(snFnInvocation *starknet.FunctionInvocation) FunctionInvocation { | 
|  | 210 | +	// Adapt inner calls | 
|  | 211 | +	adaptedCalls := make([]FunctionInvocation, len(snFnInvocation.InternalCalls)) | 
|  | 212 | +	for index := range snFnInvocation.InternalCalls { | 
|  | 213 | +		adaptedCalls[index] = adaptFeederFunctionInvocation(&snFnInvocation.InternalCalls[index]) | 
|  | 214 | +	} | 
|  | 215 | + | 
|  | 216 | +	// Adapt events | 
|  | 217 | +	adaptedEvents := make([]rpcv6.OrderedEvent, len(snFnInvocation.Events)) | 
|  | 218 | +	for index := range snFnInvocation.Events { | 
|  | 219 | +		snEvent := &snFnInvocation.Events[index] | 
|  | 220 | + | 
|  | 221 | +		adaptedEvents[index] = rpcv6.OrderedEvent{ | 
|  | 222 | +			Order: snEvent.Order, | 
|  | 223 | +			Keys:  utils.Map(snEvent.Keys, utils.HeapPtr[felt.Felt]), | 
|  | 224 | +			Data:  utils.Map(snEvent.Data, utils.HeapPtr[felt.Felt]), | 
|  | 225 | +		} | 
|  | 226 | +	} | 
|  | 227 | + | 
|  | 228 | +	// Adapt messages | 
|  | 229 | +	adaptedMessages := make([]rpcv6.OrderedL2toL1Message, len(snFnInvocation.Messages)) | 
|  | 230 | +	for index := range snFnInvocation.Messages { | 
|  | 231 | +		snMessage := &snFnInvocation.Messages[index] | 
|  | 232 | + | 
|  | 233 | +		toAddr, _ := new(felt.Felt).SetString(snMessage.ToAddr) | 
|  | 234 | + | 
|  | 235 | +		adaptedMessages[index] = rpcv6.OrderedL2toL1Message{ | 
|  | 236 | +			Order:   snMessage.Order, | 
|  | 237 | +			From:    &snFnInvocation.ContractAddress, | 
|  | 238 | +			To:      toAddr, | 
|  | 239 | +			Payload: utils.Map(snMessage.Payload, utils.HeapPtr[felt.Felt]), | 
|  | 240 | +		} | 
|  | 241 | +	} | 
|  | 242 | + | 
|  | 243 | +	return FunctionInvocation{ | 
|  | 244 | +		ContractAddress:    snFnInvocation.ContractAddress, | 
|  | 245 | +		EntryPointSelector: snFnInvocation.Selector, | 
|  | 246 | +		Calldata:           snFnInvocation.Calldata, | 
|  | 247 | +		CallerAddress:      snFnInvocation.CallerAddress, | 
|  | 248 | +		ClassHash:          snFnInvocation.ClassHash, | 
|  | 249 | +		EntryPointType:     snFnInvocation.EntryPointType, | 
|  | 250 | +		CallType:           snFnInvocation.CallType, | 
|  | 251 | +		Result:             snFnInvocation.Result, | 
|  | 252 | +		Calls:              adaptedCalls, | 
|  | 253 | +		Events:             adaptedEvents, | 
|  | 254 | +		Messages:           adaptedMessages, | 
|  | 255 | +		ExecutionResources: utils.HeapPtr(adaptFeederExecutionResources(&snFnInvocation.ExecutionResources)), | 
|  | 256 | +		IsReverted:         snFnInvocation.Failed, | 
|  | 257 | +	} | 
|  | 258 | +} | 
|  | 259 | + | 
|  | 260 | +func adaptFeederExecutionResources(resources *starknet.ExecutionResources) InnerExecutionResources { | 
|  | 261 | +	var l1Gas, l2Gas uint64 | 
|  | 262 | +	if tgs := resources.TotalGasConsumed; tgs != nil { | 
|  | 263 | +		l1Gas = tgs.L1Gas | 
|  | 264 | +		l2Gas = tgs.L2Gas | 
|  | 265 | +	} | 
|  | 266 | + | 
|  | 267 | +	return InnerExecutionResources{ | 
|  | 268 | +		L1Gas: l1Gas, | 
|  | 269 | +		L2Gas: l2Gas, | 
|  | 270 | +	} | 
|  | 271 | +} | 
0 commit comments