Skip to content

Commit

Permalink
Merge pull request #197 from multiversx/fix_lowest_tx_id
Browse files Browse the repository at this point in the history
fix lowest_tx_id logic
  • Loading branch information
dragos-rebegea authored Aug 28, 2024
2 parents 6def514 + dd7ce3e commit e9265c8
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 10 deletions.
21 changes: 13 additions & 8 deletions bridge-proxy/src/bridge-proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,8 @@ pub trait BridgeProxyContract:
if result.is_err() {
self.refund_transaction(tx_id);
}
let lowest_tx_id = self.lowest_tx_id().get();
if tx_id < lowest_tx_id {
self.lowest_tx_id().set(tx_id + 1);
}
self.pending_transactions().clear_entry_unchecked(tx_id);
self.update_lowest_tx_id();
}

fn refund_transaction(&self, tx_id: usize) {
Expand All @@ -120,11 +117,19 @@ pub trait BridgeProxyContract:

fn finish_execute_gracefully(&self, tx_id: usize) {
self.refund_transaction(tx_id);
let lowest_tx_id = self.lowest_tx_id().get();
if tx_id < lowest_tx_id {
self.lowest_tx_id().set(tx_id + 1);
}
self.pending_transactions().clear_entry_unchecked(tx_id);
self.update_lowest_tx_id();
}

fn update_lowest_tx_id(&self) {
let mut new_lowest = self.lowest_tx_id().get();
let len = self.pending_transactions().len();

while new_lowest < len && self.pending_transactions().item_is_empty(new_lowest) {
new_lowest += 1;
}

self.lowest_tx_id().set(new_lowest);
}

#[view(getPendingTransactionById)]
Expand Down
9 changes: 9 additions & 0 deletions bridge-proxy/src/bridge_proxy_contract_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ where
.original_result()
}

pub fn lowest_tx_id(
self,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
self.wrapped_tx
.payment(NotPayable)
.raw_call("lowestTxId")
.original_result()
}

pub fn pause_endpoint(
self,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
Expand Down
1 change: 1 addition & 0 deletions bridge-proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub trait ConfigModule {
#[storage_mapper("payments")]
fn payments(&self, tx_id: usize) -> SingleValueMapper<EsdtTokenPayment<Self::Api>>;

#[view(lowestTxId)]
#[storage_mapper("lowest_tx_id")]
fn lowest_tx_id(&self) -> SingleValueMapper<usize>;
}
101 changes: 101 additions & 0 deletions bridge-proxy/tests/bridge_proxy_blackbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,104 @@ fn multiple_deposit_test() {
.returns(ExpectValue(1_000u64))
.run();
}

#[test]
fn test_lowest_tx_id() {
let mut test = BridgeProxyTestState::new();

test.bridge_proxy_deploy();
test.deploy_crowdfunding();
test.config_bridge();

let mut args = ManagedVec::new();

let call_data: CallData<StaticApi> = CallData {
endpoint: ManagedBuffer::from(b"fund"),
gas_limit: GAS_LIMIT,
args: ManagedOption::some(args),
};
let call_data = ManagedSerializer::new().top_encode_to_managed_buffer(&call_data);

// Generate 100 transactions
let mut transactions = Vec::new();
for i in 1..=100 {
let eth_tx = EthTransaction {
from: EthAddress {
raw_addr: ManagedByteArray::new_from_bytes(b"01020304050607080910"),
},
to: ManagedAddress::from(CROWDFUNDING_ADDRESS.eval_to_array()),
token_id: BRIDGE_TOKEN_ID.into(),
amount: BigUint::from(5u64),
tx_nonce: i as u64,
call_data: ManagedOption::some(call_data.clone()),
};
transactions.push(eth_tx);
}

// Deposit all transactions
for tx in &transactions {
test.world
.tx()
.from(MULTI_TRANSFER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.deposit(tx)
.single_esdt(
&TokenIdentifier::from(BRIDGE_TOKEN_ID),
0u64,
&BigUint::from(5u64),
)
.run();
}

// Check the lowest_tx_id
test.world
.query()
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.lowest_tx_id()
.returns(ExpectValue(1usize))
.run();

// Execute the first 50 transactions
for i in 1..=50usize {
test.world
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(i)
.run();
}

// Check the lowest_tx_id again
test.world
.query()
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.lowest_tx_id()
.returns(ExpectValue(51usize))
.run();

// Execute transactions 75 to 100
for i in 75..=100usize {
test.world
.tx()
.from(OWNER_ADDRESS)
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.execute(i)
.run();
}

// Check the lowest_tx_id one last time
test.world
.query()
.to(BRIDGE_PROXY_ADDRESS)
.typed(bridge_proxy_contract_proxy::BridgeProxyContractProxy)
.lowest_tx_id()
.returns(ExpectValue(51usize))
.run();
}


5 changes: 3 additions & 2 deletions bridge-proxy/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

// Init: 1
// Upgrade: 1
// Endpoints: 11
// Endpoints: 12
// Async Callback (empty): 1
// Promise callbacks: 1
// Total number of exported functions: 15
// Total number of exported functions: 16

#![no_std]

Expand All @@ -29,6 +29,7 @@ multiversx_sc_wasm_adapter::endpoints! {
setBridgedTokensWrapper => set_bridged_tokens_wrapper
getMultiTransferAddress => multi_transfer_address
getBridgedTokensWrapperAddress => bridged_tokens_wrapper_address
lowestTxId => lowest_tx_id
pause => pause_endpoint
unpause => unpause_endpoint
isPaused => paused_status
Expand Down
9 changes: 9 additions & 0 deletions multi-transfer-esdt/src/bridge_proxy_contract_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ where
.original_result()
}

pub fn lowest_tx_id(
self,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, usize> {
self.wrapped_tx
.payment(NotPayable)
.raw_call("lowestTxId")
.original_result()
}

pub fn pause_endpoint(
self,
) -> TxTypedCall<Env, From, To, NotPayable, Gas, ()> {
Expand Down

0 comments on commit e9265c8

Please sign in to comment.