Skip to content

Commit a0ea97c

Browse files
refactor(rpcv10): empty proof facts (#3477)
* refactor: when proof_facts are requested but unavailable, return empty slice * chore: fix linter issues * chore: PR comments
1 parent d7dd135 commit a0ea97c

4 files changed

Lines changed: 154 additions & 37 deletions

File tree

rpc/v10/block_test.go

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -992,19 +992,23 @@ func TestBlockWithTxsWithResponseFlags(t *testing.T) {
992992
var invokeV3Count int
993993
for _, tx := range block.Transactions {
994994
if invokeTx, ok := tx.(*core.InvokeTransaction); ok {
995-
if invokeTx.Version != nil && invokeTx.Version.Is(3) {
996-
invokeV3Count++
997-
if invokeTx.ProofFacts != nil {
998-
invokeV3WithProofFactsCount++
999-
}
995+
invokeV3Count++
996+
if invokeTx.ProofFacts != nil {
997+
invokeV3WithProofFactsCount++
1000998
}
1001999
}
10021000
}
10031001
require.Greater(
10041002
t,
1005-
invokeV3WithProofFactsCount,
1003+
invokeV3Count,
10061004
0,
1007-
"Block should contain at least one invoke v3 transaction with proof_facts",
1005+
"Block should contain at least one invoke v3 transaction",
1006+
)
1007+
require.Equal(
1008+
t,
1009+
invokeV3Count,
1010+
invokeV3WithProofFactsCount,
1011+
"All invoke v3 transactions should have proof_facts set when flag is included",
10081012
)
10091013

10101014
mockReader := mocks.NewMockReader(mockCtrl)
@@ -1050,9 +1054,9 @@ func TestBlockWithTxsWithResponseFlags(t *testing.T) {
10501054
// Verify number of transactions with proof_facts matches expected
10511055
require.Equal(
10521056
t,
1053-
invokeV3WithProofFactsCount,
1057+
invokeV3Count,
10541058
txsWithProofFactsCount,
1055-
"Number of transactions with proof_facts should match",
1059+
"All invoke v3 transactions should have proof_facts set when flag is included",
10561060
)
10571061
})
10581062

@@ -1090,20 +1094,18 @@ func TestBlockWithReceiptsWithResponseFlags(t *testing.T) {
10901094
"Block should have receipts for all transactions",
10911095
)
10921096

1093-
// Count invoke v3 transactions with proof_facts
1094-
var invokeV3WithProofFactsCount int
1097+
// Count invoke v3 transactions
1098+
var invokeV3Count int
10951099
for _, tx := range block.Transactions {
1096-
if invokeTx, ok := tx.(*core.InvokeTransaction); ok {
1097-
if invokeTx.Version != nil && invokeTx.Version.Is(3) && invokeTx.ProofFacts != nil {
1098-
invokeV3WithProofFactsCount++
1099-
}
1100+
if _, ok := tx.(*core.InvokeTransaction); ok {
1101+
invokeV3Count++
11001102
}
11011103
}
11021104
require.Greater(
11031105
t,
1104-
invokeV3WithProofFactsCount, 0,
1105-
"Block should contain at least one invoke v3 transaction with proof_facts",
1106-
)
1106+
invokeV3Count,
1107+
0,
1108+
"Block should contain at least one invoke v3 transaction")
11071109

11081110
// Count all transactions
11091111
totalTxCount := len(block.Transactions)
@@ -1148,9 +1150,9 @@ func TestBlockWithReceiptsWithResponseFlags(t *testing.T) {
11481150
// Verify number of transactions with proof_facts matches expected
11491151
require.Equal(
11501152
t,
1151-
invokeV3WithProofFactsCount,
1153+
invokeV3Count,
11521154
txsWithProofFactsCount,
1153-
"Number of transactions with proof_facts should match",
1155+
"All invoke v3 transactions should have proof_facts set when flag is included",
11541156
)
11551157
})
11561158

rpc/v10/subscriptions_test.go

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,9 +2116,10 @@ func TestSubscribeNewTransactions(t *testing.T) {
21162116
},
21172117
}
21182118

2119-
// Create a block with Invoke V3 transaction with proof facts for testing
2119+
// Create a block with two Invoke V3 transactions (one with proof facts, one without),
2120+
// for proof facts testing.
21202121
invokeV3WithProofFacts := &core.InvokeTransaction{
2121-
TransactionHash: felt.NewFromUint64[felt.Felt](123),
2122+
TransactionHash: felt.NewFromUint64[felt.Felt](124),
21222123
Version: new(core.TransactionVersion).SetUint64(3),
21232124
SenderAddress: felt.NewFromUint64[felt.Felt](456),
21242125
Nonce: felt.NewFromUint64[felt.Felt](1),
@@ -2132,17 +2133,34 @@ func TestSubscribeNewTransactions(t *testing.T) {
21322133
MaxPricePerUnit: felt.NewFromUint64[felt.Felt](10),
21332134
},
21342135
},
2135-
ProofFacts: []felt.Felt{
2136-
felt.FromUint64[felt.Felt](999),
2136+
ProofFacts: []felt.Felt{felt.FromUint64[felt.Felt](999)},
2137+
}
2138+
2139+
invokeV3WithoutProofFacts := &core.InvokeTransaction{
2140+
TransactionHash: felt.NewFromUint64[felt.Felt](123),
2141+
Version: new(core.TransactionVersion).SetUint64(3),
2142+
SenderAddress: felt.NewFromUint64[felt.Felt](456),
2143+
Nonce: felt.NewFromUint64[felt.Felt](1),
2144+
ResourceBounds: map[core.Resource]core.ResourceBounds{
2145+
core.ResourceL1Gas: {
2146+
MaxAmount: 1,
2147+
MaxPricePerUnit: felt.NewFromUint64[felt.Felt](10),
2148+
},
2149+
core.ResourceL2Gas: {
2150+
MaxAmount: 1,
2151+
MaxPricePerUnit: felt.NewFromUint64[felt.Felt](10),
2152+
},
21372153
},
2154+
// ProofFacts intentionally absent
21382155
}
2156+
21392157
proofFactsBlock := &core.Block{
21402158
Header: &core.Header{
21412159
Hash: felt.NewFromUint64[felt.Felt](99999),
21422160
ParentHash: newHead2.ParentHash,
21432161
Number: newHead2.Number + 1,
21442162
SequencerAddress: newHead2.SequencerAddress,
2145-
TransactionCount: 1,
2163+
TransactionCount: 2,
21462164
Timestamp: newHead2.Timestamp + 1,
21472165
ProtocolVersion: newHead2.ProtocolVersion,
21482166
L1GasPriceETH: newHead2.L1GasPriceETH,
@@ -2151,12 +2169,16 @@ func TestSubscribeNewTransactions(t *testing.T) {
21512169
L1DataGasPrice: newHead2.L1DataGasPrice,
21522170
L1DAMode: newHead2.L1DAMode,
21532171
},
2154-
Transactions: []core.Transaction{invokeV3WithProofFacts},
2172+
Transactions: []core.Transaction{invokeV3WithProofFacts, invokeV3WithoutProofFacts},
21552173
Receipts: []*core.TransactionReceipt{
21562174
{
21572175
TransactionHash: invokeV3WithProofFacts.TransactionHash,
21582176
Events: []*core.Event{},
21592177
},
2178+
{
2179+
TransactionHash: invokeV3WithoutProofFacts.TransactionHash,
2180+
Events: []*core.Event{},
2181+
},
21602182
},
21612183
}
21622184
proofFactsBlock.EventsBloom = core.EventsBloom(proofFactsBlock.Receipts)
@@ -2205,6 +2227,28 @@ func TestSubscribeNewTransactions(t *testing.T) {
22052227
},
22062228
}
22072229

2230+
noProofFactsWithTag := testCase{
2231+
description: "Empty slice for INVOKE v3 with no proof_facts when INCLUDE_PROOF_FACTS is set",
2232+
statuses: nil,
2233+
senderAddress: nil,
2234+
tags: SubscriptionTags{IncludeProofFacts: true},
2235+
steps: []stepInfo{
2236+
{
2237+
description: "on new head with invoke v3 transaction without proof facts",
2238+
notify: func() {
2239+
syncer.newHeads.Send(proofFactsBlock)
2240+
},
2241+
expect: [][]*SubscriptionNewTransaction{
2242+
toTransactionsWithFinalityStatus(
2243+
proofFactsBlock.Transactions,
2244+
TxnStatusWithoutL1(TxnStatusAcceptedOnL2),
2245+
true,
2246+
),
2247+
},
2248+
},
2249+
},
2250+
}
2251+
22082252
testCases := []testCase{
22092253
defaultFinality, // onlyAcceptedOnL2
22102254
onlyPreConfirmed,
@@ -2216,6 +2260,7 @@ func TestSubscribeNewTransactions(t *testing.T) {
22162260
reorgEvent,
22172261
proofFactsWithTag,
22182262
proofFactsWithoutTag,
2263+
noProofFactsWithTag,
22192264
}
22202265
for _, tc := range testCases {
22212266
t.Run(tc.description, func(t *testing.T) {

rpc/v10/transaction.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@ import (
2626
func AdaptTransaction(coreTx core.Transaction, includeProofFacts bool) Transaction {
2727
tx := *AdaptCoreTransaction(coreTx)
2828

29-
if !includeProofFacts {
30-
if invokeTx, ok := coreTx.(*core.InvokeTransaction); ok {
31-
if invokeTx.Version.Is(3) {
32-
tx.ProofFacts = nil
33-
}
29+
if _, ok := coreTx.(*core.InvokeTransaction); ok {
30+
if !includeProofFacts {
31+
tx.ProofFacts = nil
32+
} else if tx.ProofFacts == nil {
33+
// When proof facts are requested for INVOKE V3 transactions,
34+
// but they are not available, return an empty array
35+
emptyProofFacts := []felt.Felt{}
36+
tx.ProofFacts = &emptyProofFacts
3437
}
3538
}
3639

rpc/v10/transaction_test.go

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,11 @@ func TestTransactionByHashNotFoundInPreConfirmedBlock(t *testing.T) {
9595

9696
func TestTransactionByHash(t *testing.T) {
9797
tests := map[string]struct {
98-
hash string
99-
network *utils.Network
100-
expected string
101-
responseFlags rpcv10.ResponseFlags
98+
hash string
99+
network *utils.Network
100+
expected string
101+
responseFlags rpcv10.ResponseFlags
102+
withProofFacts bool
102103
}{
103104
"DECLARE v1": {
104105
hash: "0x1b4d9f09276629d496af1af8ff00173c11ff146affacb1b5c858d7aa89001ae",
@@ -437,6 +438,57 @@ func TestTransactionByHash(t *testing.T) {
437438
}`,
438439
},
439440
"INVOKE v3 with response flags": {
441+
hash: "0x49728601e0bb2f48ce506b0cbd9c0e2a9e50d95858aa41463f46386dca489fd",
442+
network: &utils.Integration,
443+
withProofFacts: true,
444+
expected: `{
445+
"type": "INVOKE",
446+
"transaction_hash": "0x49728601e0bb2f48ce506b0cbd9c0e2a9e50d95858aa41463f46386dca489fd",
447+
"version": "0x3",
448+
"signature": [
449+
"0x71a9b2cd8a8a6a4ca284dcddcdefc6c4fd20b92c1b201bd9836e4ce376fad16",
450+
"0x6bef4745194c9447fdc8dd3aec4fc738ab0a560b0d2c7bf62fbf58aef3abfc5"
451+
],
452+
"nonce": "0xe97",
453+
"resource_bounds": {
454+
"l1_gas": {
455+
"max_amount": "0x186a0",
456+
"max_price_per_unit": "0x5af3107a4000"
457+
},
458+
"l1_data_gas": {
459+
"max_amount": "0x186a0",
460+
"max_price_per_unit": "0x5af3107a4000"
461+
},
462+
"l2_gas": { "max_amount": "0x0", "max_price_per_unit": "0x0" }
463+
},
464+
"tip": "0x0",
465+
"paymaster_data": [],
466+
"sender_address": "0x3f6f3bc663aedc5285d6013cc3ffcbc4341d86ab488b8b68d297f8258793c41",
467+
"calldata": [
468+
"0x2",
469+
"0x450703c32370cf7ffff540b9352e7ee4ad583af143a361155f2b485c0c39684",
470+
"0x27c3334165536f239cfd400ed956eabff55fc60de4fb56728b6a4f6b87db01c",
471+
"0x0",
472+
"0x4",
473+
"0x4c312760dfd17a954cdd09e76aa9f149f806d88ec3e402ffaf5c4926f568a42",
474+
"0x5df99ae77df976b4f0e5cf28c7dcfe09bd6e81aab787b19ac0c08e03d928cf",
475+
"0x4",
476+
"0x1",
477+
"0x5",
478+
"0x450703c32370cf7ffff540b9352e7ee4ad583af143a361155f2b485c0c39684",
479+
"0x5df99ae77df976b4f0e5cf28c7dcfe09bd6e81aab787b19ac0c08e03d928cf",
480+
"0x1",
481+
"0x7fe4fd616c7fece1244b3616bb516562e230be8c9f29668b46ce0369d5ca829",
482+
"0x287acddb27a2f9ba7f2612d72788dc96a5b30e401fc1e8072250940e024a587"
483+
],
484+
"account_deployment_data": [],
485+
"nonce_data_availability_mode": "L1",
486+
"fee_data_availability_mode": "L1",
487+
"proof_facts": ["0x64", "0xc8"]
488+
}`,
489+
responseFlags: rpcv10.ResponseFlags{IncludeProofFacts: true},
490+
},
491+
"INVOKE v3 with response flags and no proof facts": {
440492
hash: "0x49728601e0bb2f48ce506b0cbd9c0e2a9e50d95858aa41463f46386dca489fd",
441493
network: &utils.Integration,
442494
expected: `{
@@ -482,7 +534,7 @@ func TestTransactionByHash(t *testing.T) {
482534
"account_deployment_data": [],
483535
"nonce_data_availability_mode": "L1",
484536
"fee_data_availability_mode": "L1",
485-
"proof_facts": ["0x64", "0xc8"]
537+
"proof_facts": []
486538
}`,
487539
responseFlags: rpcv10.ResponseFlags{IncludeProofFacts: true},
488540
},
@@ -503,7 +555,7 @@ func TestTransactionByHash(t *testing.T) {
503555
}
504556
// Mock the gateway to include proof_facts for "INVOKE v3 with response flags" test
505557
invokeTx, ok := tx.(*core.InvokeTransaction)
506-
if ok && invokeTx.Version.Is(3) && test.responseFlags.IncludeProofFacts {
558+
if ok && test.withProofFacts {
507559
invokeTx.ProofFacts = []felt.Felt{
508560
felt.FromUint64[felt.Felt](100),
509561
felt.FromUint64[felt.Felt](200),
@@ -797,6 +849,21 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
797849
require.NotNil(t, tx)
798850
require.Nil(t, tx.ProofFacts)
799851
})
852+
853+
blockID2 := rpcv10.BlockIDFromNumber(2)
854+
mockReader.EXPECT().TransactionByBlockNumberAndIndex(uint64(2), uint64(0)).
855+
Return(invokeTxCore, nil)
856+
t.Run("WithResponseFlag and empty proof facts", func(t *testing.T) {
857+
tx, rpcErr := h.TransactionByBlockIDAndIndex(
858+
&blockID2,
859+
0,
860+
rpcv10.ResponseFlags{IncludeProofFacts: true},
861+
)
862+
require.Nil(t, rpcErr)
863+
require.NotNil(t, tx)
864+
require.NotNil(t, tx.ProofFacts)
865+
require.Empty(t, *tx.ProofFacts)
866+
})
800867
})
801868
}
802869

0 commit comments

Comments
 (0)