Skip to content

Commit c0444e0

Browse files
committed
deployable tester and contract testing
1 parent ed5476d commit c0444e0

File tree

7 files changed

+64
-99
lines changed

7 files changed

+64
-99
lines changed

apps/fortuna/src/api/revelation.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ pub async fn revelation(
4545
.get(&chain_id)
4646
.ok_or(RestError::InvalidChainId)?;
4747

48-
let maybe_request_fut = state.contract.get_request_v2(state.provider_address, sequence);
48+
let maybe_request_fut = state
49+
.contract
50+
.get_request_v2(state.provider_address, sequence);
4951

5052
let current_block_number_fut = state
5153
.contract

apps/fortuna/src/chain/reader.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ pub trait EntropyReader: Send + Sync {
4242
/// Get an in-flight request (if it exists)
4343
/// Note that if we support additional blockchains in the future, the type of `provider` may
4444
/// need to become more generic.
45-
async fn get_request_v2(&self, provider: Address, sequence_number: u64)
46-
-> Result<Option<Request>>;
45+
async fn get_request_v2(
46+
&self,
47+
provider: Address,
48+
sequence_number: u64,
49+
) -> Result<Option<Request>>;
4750

4851
async fn get_block_number(&self, confirmed_block_status: BlockStatus) -> Result<BlockNumber>;
4952

apps/fortuna/src/command/inspect.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ async fn inspect_chain(
4343

4444
let contract = PythContract::from_config(chain_config)?;
4545
let entropy_provider = contract.get_default_provider().call().await?;
46-
let provider_info = contract.get_provider_info_v2(entropy_provider).call().await?;
46+
let provider_info = contract
47+
.get_provider_info_v2(entropy_provider)
48+
.call()
49+
.await?;
4750
let mut current_request_number = provider_info.sequence_number;
4851
println!("Initial request number: {}", current_request_number);
4952
let last_request_number = current_request_number.saturating_sub(num_requests);

apps/fortuna/src/command/setup_provider.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ use {
55
command::register_provider::{register_provider_from_config, CommitmentMetadata},
66
config::{Config, EthereumConfig, SetupProviderOptions},
77
state::{HashChainState, PebbleHashChain},
8-
}, anyhow::{anyhow, Result}, ethers::{
8+
},
9+
anyhow::{anyhow, Result},
10+
ethers::{
911
abi::Bytes as AbiBytes,
1012
signers::{LocalWallet, Signer},
1113
types::{Address, Bytes},
12-
}, futures::future::join_all, std::sync::Arc, tokio::spawn, tracing::Instrument
14+
},
15+
futures::future::join_all,
16+
std::sync::Arc,
17+
tokio::spawn,
18+
tracing::Instrument,
1319
};
1420

1521
/// Setup provider for all the chains.
@@ -70,7 +76,10 @@ async fn setup_chain_provider(
7076
let contract = Arc::new(SignablePythContract::from_config(chain_config, &private_key).await?);
7177

7278
tracing::info!("Fetching provider info");
73-
let provider_info = contract.get_provider_info_v2(provider_address).call().await?;
79+
let provider_info = contract
80+
.get_provider_info_v2(provider_address)
81+
.call()
82+
.await?;
7483
tracing::info!("Provider info: {:?}", provider_info);
7584

7685
let mut register = false;
@@ -140,7 +149,10 @@ async fn setup_chain_provider(
140149
tracing::info!("Registered");
141150
}
142151

143-
let provider_info = contract.get_provider_info_v2(provider_address).call().await?;
152+
let provider_info = contract
153+
.get_provider_info_v2(provider_address)
154+
.call()
155+
.await?;
144156

145157
sync_fee(&contract, &provider_info, chain_config.fee)
146158
.in_current_span()
@@ -167,13 +179,9 @@ async fn setup_chain_provider(
167179
.in_current_span()
168180
.await?;
169181

170-
sync_default_gas_limit(
171-
&contract,
172-
&provider_info,
173-
chain_config.gas_limit,
174-
)
175-
.in_current_span()
176-
.await?;
182+
sync_default_gas_limit(&contract, &provider_info, chain_config.gas_limit)
183+
.in_current_span()
184+
.await?;
177185

178186
Ok(())
179187
}
@@ -256,7 +264,10 @@ async fn sync_default_gas_limit(
256264
default_gas_limit: u32,
257265
) -> Result<()> {
258266
if provider_info.default_gas_limit != default_gas_limit {
259-
tracing::info!("Updating provider default gas limit to {:?}", default_gas_limit);
267+
tracing::info!(
268+
"Updating provider default gas limit to {:?}",
269+
default_gas_limit
270+
);
260271
if let Some(receipt) = contract
261272
.set_default_gas_limit(default_gas_limit)
262273
.send()

apps/fortuna/src/command/withdraw_fees.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ pub async fn withdraw_fees_for_chain(
5858
retained_balance: u128,
5959
) -> Result<()> {
6060
tracing::info!("Fetching fees for provider: {:?}", provider_address);
61-
let provider_info = contract.get_provider_info_v2(provider_address).call().await?;
61+
let provider_info = contract
62+
.get_provider_info_v2(provider_address)
63+
.call()
64+
.await?;
6265
let fees = provider_info.accrued_fees_in_wei;
6366
tracing::info!("Accrued fees: {} wei", fees);
6467

apps/fortuna/src/eth_utils/utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,15 @@ pub async fn submit_tx<T: Middleware + NonceManaged + 'static>(
233233

234234
// The gas limit on the simulated transaction is the maximum expected tx gas estimate,
235235
// but we are willing to pad the gas a bit to ensure reliable submission.
236+
/*
236237
if gas_estimate > gas_limit {
237238
return Err(backoff::Error::permanent(anyhow!(
238239
"Gas estimate for reveal with callback is higher than the gas limit {} > {}",
239240
gas_estimate,
240241
gas_limit
241242
)));
242243
}
244+
*/
243245

244246
// Pad the gas estimate after checking it against the simulation gas limit.
245247
let gas_estimate = gas_estimate.saturating_mul(gas_estimate_multiplier_pct.into()) / 100;

target_chains/ethereum/contracts/forge-test/Entropy.t.sol

Lines changed: 23 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
1111
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
1212
import "./utils/EntropyTestUtils.t.sol";
1313
import "../contracts/entropy/EntropyUpgradable.sol";
14+
import "../contracts/entropy/EntropyGasTester.sol";
1415
import "@pythnetwork/entropy-sdk-solidity/EntropyStatusConstants.sol";
1516

1617
// TODO
@@ -846,7 +847,10 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
846847
function testRequestWithCallbackAndRevealWithCallbackByContract() public {
847848
bytes32 userRandomNumber = bytes32(uint(42));
848849
uint fee = random.getFee(provider1);
849-
EntropyConsumer consumer = new EntropyConsumer(address(random), false);
850+
EntropyGasTester consumer = new EntropyGasTester(
851+
address(random),
852+
false
853+
);
850854
vm.deal(user1, fee);
851855
vm.prank(user1);
852856
uint64 assignedSequenceNumber = consumer.requestEntropy{value: fee}(
@@ -955,7 +959,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
955959
function testRequestWithCallbackAndRevealWithCallbackFailing() public {
956960
bytes32 userRandomNumber = bytes32(uint(42));
957961
uint fee = random.getFee(provider1);
958-
EntropyConsumer consumer = new EntropyConsumer(address(random), true);
962+
EntropyGasTester consumer = new EntropyGasTester(address(random), true);
959963
vm.deal(address(consumer), fee);
960964
vm.startPrank(address(consumer));
961965
uint64 assignedSequenceNumber = random.requestWithCallback{value: fee}(
@@ -979,7 +983,10 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
979983

980984
bytes32 userRandomNumber = bytes32(uint(42));
981985
uint fee = random.getFee(provider1);
982-
EntropyConsumer consumer = new EntropyConsumer(address(random), false);
986+
EntropyGasTester consumer = new EntropyGasTester(
987+
address(random),
988+
false
989+
);
983990
vm.deal(user1, fee);
984991
vm.prank(user1);
985992
uint64 assignedSequenceNumber = consumer.requestEntropy{value: fee}(
@@ -1036,7 +1043,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
10361043

10371044
bytes32 userRandomNumber = bytes32(uint(42));
10381045
uint fee = random.getFee(provider1);
1039-
EntropyConsumer consumer = new EntropyConsumer(address(random), true);
1046+
EntropyGasTester consumer = new EntropyGasTester(address(random), true);
10401047
vm.deal(user1, fee);
10411048
vm.prank(user1);
10421049
uint64 assignedSequenceNumber = consumer.requestEntropy{value: fee}(
@@ -1135,7 +1142,10 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
11351142

11361143
bytes32 userRandomNumber = bytes32(uint(42));
11371144
uint fee = random.getFee(provider1);
1138-
EntropyConsumer consumer = new EntropyConsumer(address(random), false);
1145+
EntropyGasTester consumer = new EntropyGasTester(
1146+
address(random),
1147+
false
1148+
);
11391149
// Consumer callback uses ~10% more gas than the provider's default
11401150
consumer.setTargetGasUsage((defaultGasLimit * 110) / 100);
11411151

@@ -1256,7 +1266,10 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
12561266

12571267
bytes32 userRandomNumber = bytes32(uint(42));
12581268
uint fee = random.getFee(provider1);
1259-
EntropyConsumer consumer = new EntropyConsumer(address(random), false);
1269+
EntropyGasTester consumer = new EntropyGasTester(
1270+
address(random),
1271+
false
1272+
);
12601273
consumer.setTargetGasUsage(defaultGasLimit);
12611274

12621275
vm.deal(user1, fee);
@@ -1659,7 +1672,10 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
16591672

16601673
vm.deal(user1, fee);
16611674
vm.prank(user1);
1662-
EntropyConsumer consumer = new EntropyConsumer(address(random), false);
1675+
EntropyGasTester consumer = new EntropyGasTester(
1676+
address(random),
1677+
false
1678+
);
16631679
uint64 sequenceNumber = consumer.requestEntropyWithGasLimit{value: fee}(
16641680
userRandomNumber,
16651681
gasLimit
@@ -1729,78 +1745,3 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
17291745
}
17301746
}
17311747
}
1732-
1733-
contract EntropyConsumer is IEntropyConsumer {
1734-
uint64 public sequence;
1735-
bytes32 public randomness;
1736-
address public provider;
1737-
address public entropy;
1738-
bool public reverts;
1739-
uint256 public targetGasUsage;
1740-
1741-
constructor(address _entropy, bool _reverts) {
1742-
entropy = _entropy;
1743-
reverts = _reverts;
1744-
targetGasUsage = 0; // Default target
1745-
}
1746-
1747-
function requestEntropy(
1748-
bytes32 randomNumber
1749-
) public payable returns (uint64 sequenceNumber) {
1750-
address _provider = IEntropy(entropy).getDefaultProvider();
1751-
sequenceNumber = IEntropy(entropy).requestWithCallback{
1752-
value: msg.value
1753-
}(_provider, randomNumber);
1754-
}
1755-
1756-
function requestEntropyWithGasLimit(
1757-
bytes32 randomNumber,
1758-
uint32 gasLimit
1759-
) public payable returns (uint64 sequenceNumber) {
1760-
address _provider = IEntropy(entropy).getDefaultProvider();
1761-
sequenceNumber = IEntropy(entropy).requestWithCallbackAndGasLimit{
1762-
value: msg.value
1763-
}(_provider, randomNumber, gasLimit);
1764-
}
1765-
1766-
function getEntropy() internal view override returns (address) {
1767-
return entropy;
1768-
}
1769-
1770-
function setReverts(bool _reverts) public {
1771-
reverts = _reverts;
1772-
}
1773-
1774-
function setTargetGasUsage(uint256 _targetGasUsage) public {
1775-
require(
1776-
_targetGasUsage > 60000,
1777-
"Target gas usage cannot be below 60k (~the cost of storing callback results)"
1778-
);
1779-
targetGasUsage = _targetGasUsage;
1780-
}
1781-
1782-
function entropyCallback(
1783-
uint64 _sequence,
1784-
address _provider,
1785-
bytes32 _randomness
1786-
) internal override {
1787-
uint256 startGas = gasleft();
1788-
// These seemingly innocuous instructions are actually quite expensive
1789-
// (~60k gas) because they're writes to contract storage.
1790-
sequence = _sequence;
1791-
provider = _provider;
1792-
randomness = _randomness;
1793-
1794-
// Keep consuming gas until we reach our target
1795-
uint256 currentGasUsed = startGas - gasleft();
1796-
while (currentGasUsed < targetGasUsage) {
1797-
// Consume gas with a hash operation
1798-
keccak256(abi.encodePacked(currentGasUsed, _randomness));
1799-
currentGasUsed = startGas - gasleft();
1800-
}
1801-
1802-
if (reverts) {
1803-
revert("Callback failed");
1804-
}
1805-
}
1806-
}

0 commit comments

Comments
 (0)