Skip to content

Commit

Permalink
rpc: preflight: include system events in fee calculation (#986)
Browse files Browse the repository at this point in the history
* rpc: preflight: include system events in fee calculation

* Address review feedback

* add unit test

* update test constants.

---------

Co-authored-by: Tsachi Herman <[email protected]>
  • Loading branch information
2opremio and tsachiherman authored Sep 26, 2023
1 parent 365b184 commit aaff333
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![no_std]
use soroban_sdk::{
contract, contractimpl, log, symbol_short, vec, Address, Env, String, Symbol, Vec,
contract, contractimpl, log, symbol_short, vec, Address, BytesN, Env, String, Symbol, Vec,
};

const COUNTER: Symbol = symbol_short!("COUNTER");
Expand Down Expand Up @@ -46,6 +46,10 @@ impl Contract {
env.prng().u64_in_range(low..=high)
}

pub fn upgrade_contract(env: Env, hash: BytesN<32>) {
env.deployer().update_current_contract_wasm(hash);
}

#[allow(unused_variables)]
pub fn multi_word_cmd(env: Env, contract_owner: String) {}
/// Logs a string with `hello ` in front.
Expand Down
119 changes: 117 additions & 2 deletions cmd/soroban-rpc/internal/test/simulate_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ func TestSimulateTransactionSucceeds(t *testing.T) {
},
},
},
Instructions: 5733936,
Instructions: 6070660,
ReadBytes: 48,
WriteBytes: 6576,
WriteBytes: 7060,
},
RefundableFee: 20056,
}
Expand Down Expand Up @@ -1015,3 +1015,118 @@ func TestSimulateInvokePrng_u64_in_range(t *testing.T) {
require.LessOrEqual(t, uint64(*obtainedResult.U64), uint64(high))
require.GreaterOrEqual(t, uint64(*obtainedResult.U64), uint64(low))
}

func TestSimulateSystemEvent(t *testing.T) {
test := NewTest(t)

ch := jhttp.NewChannel(test.sorobanRPCURL(), nil)
client := jrpc2.NewClient(ch, nil)

sourceAccount := keypair.Root(StandaloneNetworkPassphrase)
address := sourceAccount.Address()
account := txnbuild.NewSimpleAccount(address, 0)

helloWorldContract := getHelloWorldContract(t)

params := preflightTransactionParams(t, client, txnbuild.TransactionParams{
SourceAccount: &account,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
createInstallContractCodeOperation(account.AccountID, helloWorldContract),
},
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(),
},
})

tx, err := txnbuild.NewTransaction(params)
require.NoError(t, err)
sendSuccessfulTransaction(t, client, sourceAccount, tx)

params = preflightTransactionParams(t, client, txnbuild.TransactionParams{
SourceAccount: &account,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
createCreateContractOperation(address, helloWorldContract),
},
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(),
},
})

tx, err = txnbuild.NewTransaction(params)
require.NoError(t, err)
sendSuccessfulTransaction(t, client, sourceAccount, tx)

contractID := getContractID(t, address, testSalt, StandaloneNetworkPassphrase)
authAddrArg := "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H"
tx, err = txnbuild.NewTransaction(txnbuild.TransactionParams{
SourceAccount: &account,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
&txnbuild.CreateAccount{
Destination: authAddrArg,
Amount: "100000",
SourceAccount: address,
},
},
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(),
},
})
require.NoError(t, err)
sendSuccessfulTransaction(t, client, sourceAccount, tx)

contractHash := sha256.Sum256(helloWorldContract)
byteSlice := xdr.ScBytes(contractHash[:])

params = txnbuild.TransactionParams{
SourceAccount: &account,
IncrementSequenceNum: false,
Operations: []txnbuild.Operation{
createInvokeHostOperation(
address,
contractID,
"upgrade_contract",
xdr.ScVal{
Type: xdr.ScValTypeScvBytes,
Bytes: &byteSlice,
},
),
},
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(),
},
}
tx, err = txnbuild.NewTransaction(params)

require.NoError(t, err)

txB64, err := tx.Base64()
require.NoError(t, err)

request := methods.SimulateTransactionRequest{Transaction: txB64}
var response methods.SimulateTransactionResponse
err = client.CallResult(context.Background(), "simulateTransaction", request, &response)
require.NoError(t, err)
require.Empty(t, response.Error)

// check the result
require.Len(t, response.Results, 1)
var obtainedResult xdr.ScVal
err = xdr.SafeUnmarshalBase64(response.Results[0].XDR, &obtainedResult)
require.NoError(t, err)

var transactionData xdr.SorobanTransactionData
err = xdr.SafeUnmarshalBase64(response.TransactionData, &transactionData)
require.NoError(t, err)

assert.Equal(t, xdr.Int64(45), transactionData.RefundableFee)
assert.Equal(t, xdr.Uint32(7260), transactionData.Resources.ReadBytes)
assert.Equal(t, xdr.Uint32(104), transactionData.Resources.WriteBytes)
require.GreaterOrEqual(t, len(response.Events), 3)
}
4 changes: 3 additions & 1 deletion cmd/soroban-rpc/lib/preflight/src/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ fn calculate_unmodified_ledger_entry_bytes(
fn calculate_contract_events_size_bytes(events: &Vec<DiagnosticEvent>) -> Result<u32> {
let mut res: u32 = 0;
for e in events {
if e.event.type_ != ContractEventType::Contract {
if e.event.type_ != ContractEventType::Contract
&& e.event.type_ != ContractEventType::System
{
continue;
}
let event_xdr = e
Expand Down

0 comments on commit aaff333

Please sign in to comment.