Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions vms/saevm/sae/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,12 @@ func (b *backend) server(filter *filters.FilterAPI) (*rpc.Server, error) {
// - debug_dbAncient
// - debug_dbAncients
// - debug_dbGet
// - debug_getRawTransaction
// - debug_printBlock
// - debug_setHead (no-op, logs info)
//
// TODO: implement once BlockByNumberOrHash and GetReceipts exist:
// - debug_getRawBlock
// - debug_getRawHeader
// - debug_getRawReceipts
// - debug_getRawTransaction
// - debug_printBlock
// - debug_setHead (no-op, logs info)
"debug", ethapi.NewDebugAPI(b),
})
}
Expand Down
205 changes: 156 additions & 49 deletions vms/saevm/sae/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"github.com/ava-labs/libevm/libevm/hookstest"
"github.com/ava-labs/libevm/libevm/options"
"github.com/ava-labs/libevm/params"
"github.com/ava-labs/libevm/rlp"
"github.com/ava-labs/libevm/rpc"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
Expand Down Expand Up @@ -533,7 +534,7 @@
timeOpt, vmTime := withVMTime(t, time.Unix(saeparams.TauSeconds, 0))
blockingPrecompile := common.Address{'b', 'l', 'o', 'c', 'k'}
precompileOpt, unblock := withBlockingPrecompile(blockingPrecompile)
ctx, sut := newSUT(t, 1, timeOpt, precompileOpt)
ctx, sut := newSUT(t, 1, timeOpt, precompileOpt, withDebugAPI())
t.Cleanup(unblock)

t.Run("unknown_hashes", func(t *testing.T) {
Expand Down Expand Up @@ -608,6 +609,39 @@
})
}

func TestMempoolTxGetters(t *testing.T) {
ctx, sut := newSUT(t, 1, withDebugAPI())

mempoolTx := sut.wallet.SetNonceAndSign(t, 0, &types.DynamicFeeTx{
To: &zeroAddr,
Gas: params.TxGas,
GasFeeCap: big.NewInt(1),
})
sut.mustSendTx(t, mempoolTx)
sut.syncMempool(t)

Check failure on line 621 in vms/saevm/sae/rpc_test.go

View workflow job for this annotation

GitHub Actions / Unit (custom-arm64-jammy)

sut.syncMempool undefined (type *SUT has no field or method syncMempool)

Check failure on line 621 in vms/saevm/sae/rpc_test.go

View workflow job for this annotation

GitHub Actions / Unit (custom-arm64-noble)

sut.syncMempool undefined (type *SUT has no field or method syncMempool)
Comment thread
JonathanOppenheimer marked this conversation as resolved.
Outdated

marshaled, err := mempoolTx.MarshalBinary()
require.NoErrorf(t, err, "%T.MarshalBinary()", mempoolTx)

sut.testRPC(ctx, t, []rpcTest{
{
method: "eth_getTransactionByHash",
args: []any{mempoolTx.Hash()},
want: mempoolTx,
},
{
method: "eth_getRawTransactionByHash",
args: []any{mempoolTx.Hash()},
want: hexutil.Bytes(marshaled),
},
{
method: "debug_getRawTransaction",
args: []any{mempoolTx.Hash()},
want: hexutil.Bytes(marshaled),
},
}...)
}

func TestGetLogs(t *testing.T) {
// We shorten section size to reduce number of required blocks in the test.
const bloomSectionSize = 8
Expand Down Expand Up @@ -789,7 +823,7 @@

timeOpt, vmTime := withVMTime(t, time.Unix(saeparams.TauSeconds, 0))
precompileOpt, unblock := withBlockingPrecompile(blockingPrecompile)
ctx, sut := newSUT(t, 1, timeOpt, precompileOpt)
ctx, sut := newSUT(t, 1, timeOpt, precompileOpt, withDebugAPI())
t.Cleanup(unblock)

var (
Expand Down Expand Up @@ -842,6 +876,16 @@
GasPrice: big.NewInt(1),
}))

marshalReceipts := func(rs []*types.Receipt) []hexutil.Bytes {
raw := make([]hexutil.Bytes, len(rs))
for i, r := range rs {
buf, err := r.MarshalBinary()
require.NoErrorf(t, err, "receipts[%d].MarshalBinary()", i)
raw[i] = buf
}
return raw
}

var tests []rpcTest
for _, tc := range []struct {
id rpc.BlockNumberOrHash
Expand All @@ -859,15 +903,39 @@
id: rpc.BlockNumberOrHashWithHash(unsettled.Hash(), true),
want: wantUnsettled,
},
{
id: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(onDisk.Height())), //nolint:gosec // Test block heights won't overflow
want: wantOnDisk,
},
{
id: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(settled.Height())), //nolint:gosec // Test block heights won't overflow
want: wantSettled,
},
{
id: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(unsettled.Height())), //nolint:gosec // Test block heights won't overflow
want: wantUnsettled,
},
{
id: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber),
want: wantUnsettled,
},
{
id: rpc.BlockNumberOrHashWithNumber(rpc.SafeBlockNumber),
want: wantSettled,
},
{
id: rpc.BlockNumberOrHashWithNumber(rpc.FinalizedBlockNumber),
want: wantSettled,
},
} {
tests = append(tests, rpcTest{
method: "eth_getBlockReceipts",
args: []any{tc.id.String()},
want: tc.want,
}, rpcTest{
method: "debug_getRawReceipts",
args: []any{tc.id.String()},
want: marshalReceipts(tc.want),
})
Comment thread
JonathanOppenheimer marked this conversation as resolved.
Outdated
}
Comment thread
JonathanOppenheimer marked this conversation as resolved.

Expand All @@ -893,21 +961,41 @@
args: []any{common.Hash{}},
want: ([]*types.Receipt)(nil),
},
{
method: "debug_getRawReceipts",
args: []any{common.Hash{}},
want: []hexutil.Bytes{},
},
{
method: "eth_getBlockReceipts",
args: []any{genesis.Hash()},
want: []*types.Receipt{},
},
{
method: "debug_getRawReceipts",
args: []any{genesis.Hash()},
want: []hexutil.Bytes{},
},
{
method: "eth_getBlockReceipts",
args: []any{pending.Hash()},
want: ([]*types.Receipt)(nil),
},
{
method: "debug_getRawReceipts",
args: []any{pending.Hash()},
want: []hexutil.Bytes{},
},
{
method: "eth_getBlockReceipts",
args: []any{hexutil.Uint64(pending.Height())},
want: ([]*types.Receipt)(nil),
},
{
method: "debug_getRawReceipts",
args: []any{hexutil.Uint64(pending.Height())},
want: []hexutil.Bytes{},
},
}...)

sut.testRPC(ctx, t, tests...)
Expand Down Expand Up @@ -1157,6 +1245,11 @@
method: "debug_dbAncients",
wantErr: testerr.Contains("not supported"),
},
{
method: "debug_printBlock",
args: []any{uint64(1)}, // SUT only has genesis, so block 1 doesn't exist.
wantErr: testerr.Contains("not found"),
},
}...)

// The profiling debug namespace is handled entirely by upstream code
Expand Down Expand Up @@ -1187,57 +1280,16 @@
})
}

func TestDebugGetRawTransaction(t *testing.T) {
ctx, sut := newSUT(t, 1, withDebugAPI())

tx := sut.wallet.SetNonceAndSign(t, 0, &types.DynamicFeeTx{
To: &common.Address{},
Gas: params.TxGas,
GasFeeCap: big.NewInt(1),
})
b := sut.runConsensusLoop(t, tx)
require.NoErrorf(t, b.WaitUntilExecuted(ctx), "%T.WaitUntilExecuted()", b)

marshaled, err := tx.MarshalBinary()
require.NoErrorf(t, err, "%T.MarshalBinary()", tx)

// Mempool tx: send without building a block, then query.
mempoolTx := sut.wallet.SetNonceAndSign(t, 0, &types.DynamicFeeTx{
To: &common.Address{},
Gas: params.TxGas,
GasFeeCap: big.NewInt(1),
})
sut.sendTxsAndWaitUntilPending(t, mempoolTx)

mempoolMarshaled, err := mempoolTx.MarshalBinary()
require.NoErrorf(t, err, "%T.MarshalBinary()", mempoolTx)

t.Logf("Tx in block: %#x", tx.Hash())
t.Logf("Tx in mempool: %#x", mempoolTx.Hash())

sut.testRPC(ctx, t, []rpcTest{
{
method: "debug_getRawTransaction",
args: []any{tx.Hash()},
want: hexutil.Bytes(marshaled),
},
{
method: "debug_getRawTransaction",
args: []any{common.Hash{}},
want: hexutil.Bytes(nil),
},
{
method: "debug_getRawTransaction",
args: []any{mempoolTx.Hash()},
want: hexutil.Bytes(mempoolMarshaled),
},
}...)
}

func (s *SUT) testGetByHash(ctx context.Context, t *testing.T, want *types.Block) {
t.Helper()

testRPCGetter(ctx, t, "eth_getBlockByHash", s.BlockByHash, want.Hash(), want)

wantBlockRLP, err := rlp.EncodeToBytes(want)
require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", want)
wantHeaderRLP, err := rlp.EncodeToBytes(want.Header())
require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", want.Header())

s.testRPC(ctx, t, []rpcTest{
{
method: "eth_getBlockByHash",
Expand All @@ -1259,6 +1311,16 @@
args: []any{want.Hash()},
want: hexutil.Uint(0), // SAE never has uncles (no reorgs)
},
{
method: "debug_getRawBlock",
args: []any{want.Hash()},
want: hexutil.Bytes(wantBlockRLP),
},
{
method: "debug_getRawHeader",
args: []any{want.Hash()},
want: hexutil.Bytes(wantHeaderRLP),
},
}...)

for i, wantTx := range want.Transactions() {
Expand Down Expand Up @@ -1287,6 +1349,11 @@
args: []any{wantTx.Hash()},
want: hexutil.Bytes(marshaled),
},
{
method: "debug_getRawTransaction",
args: []any{wantTx.Hash()},
want: hexutil.Bytes(marshaled),
},
}...)
}

Expand Down Expand Up @@ -1344,6 +1411,21 @@
args: []any{common.Hash{}},
want: hexutil.Bytes(nil),
},
{
method: "debug_getRawTransaction",
args: []any{common.Hash{}},
want: hexutil.Bytes(nil),
},
{
method: "debug_getRawBlock",
args: []any{common.Hash{}},
wantErr: testerr.Contains("not found"),
},
{
method: "debug_getRawHeader",
args: []any{common.Hash{}},
wantErr: testerr.Contains("not found"),
},
}...)
}

Expand All @@ -1354,6 +1436,11 @@
t.Helper()
testRPCGetter(ctx, t, "eth_getBlockByNumber", s.BlockByNumber, big.NewInt(n.Int64()), want)

wantBlockRLP, err := rlp.EncodeToBytes(want)
require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", want)
wantHeaderRLP, err := rlp.EncodeToBytes(want.Header())
require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", want.Header())

s.testRPC(ctx, t, []rpcTest{
{
method: "eth_getBlockByNumber",
Expand All @@ -1375,6 +1462,16 @@
args: []any{n},
want: hexutil.Uint(0), // SAE never has uncles (no reorgs)
},
{
method: "debug_getRawBlock",
args: []any{n},
want: hexutil.Bytes(wantBlockRLP),
},
{
method: "debug_getRawHeader",
args: []any{n},
want: hexutil.Bytes(wantHeaderRLP),
},
}...)

for i, wantTx := range want.Transactions() {
Expand Down Expand Up @@ -1441,6 +1538,16 @@
args: []any{n, hexutil.Uint(0)},
want: hexutil.Bytes(nil),
},
{
method: "debug_getRawBlock",
args: []any{n},
want: hexutil.Bytes(nil),
},
{
method: "debug_getRawHeader",
args: []any{n},
want: hexutil.Bytes(nil),
},
}...)
}

Expand Down
Loading