use of com.hedera.services.bdd.spec.HapiSpecOperation in project hedera-services by hashgraph.
the class AdHocTokenTransfers method tokenTransfersFactory.
private Function<HapiApiSpec, OpProvider> tokenTransfersFactory() {
var firstDir = new AtomicBoolean(Boolean.TRUE);
var balanceInit = new AtomicLong();
var tokensPerTxn = new AtomicInteger();
var sendingAccountsPerToken = new AtomicInteger();
var receivingAccountsPerToken = new AtomicInteger();
List<String> treasuries = new ArrayList<>();
Map<String, List<String>> senders = new HashMap<>();
Map<String, List<String>> receivers = new HashMap<>();
String targetAccount = targetNodeAccount();
return spec -> new OpProvider() {
@Override
public List<HapiSpecOperation> suggestedInitializers() {
var ciProps = spec.setup().ciPropertiesMap();
balanceInit.set(ciProps.getLong("balanceInit"));
tokensPerTxn.set(ciProps.getInteger("tokensPerTxn"));
sendingAccountsPerToken.set(ciProps.getInteger("sendingAccountsPerToken"));
receivingAccountsPerToken.set(ciProps.getInteger("receivingAccountsPerToken"));
var initialSupply = (sendingAccountsPerToken.get() + receivingAccountsPerToken.get()) * balanceInit.get();
List<HapiSpecOperation> initializers = new ArrayList<>();
for (int i = 0; i < tokensPerTxn.get(); i++) {
var token = "token" + i;
var treasury = "treasury" + i;
initializers.add(cryptoCreate(treasury));
initializers.add(tokenCreate(token).treasury(treasury).initialSupply(initialSupply));
treasuries.add(treasury);
for (int j = 0; j < sendingAccountsPerToken.get(); j++) {
var sender = token + "sender" + j;
senders.computeIfAbsent(token, ignore -> new ArrayList<>()).add(sender);
initializers.add(cryptoCreate(sender).balance(5_000_000_000_000L).withRecharging().rechargeWindow(3));
initializers.add(tokenAssociate(sender, token));
initializers.add(cryptoTransfer(moving(balanceInit.get(), token).between(treasury, sender)));
}
for (int j = 0; j < receivingAccountsPerToken.get(); j++) {
var receiver = token + "receiver" + j;
receivers.computeIfAbsent(token, ignore -> new ArrayList<>()).add(receiver);
initializers.add(cryptoCreate(receiver).balance(5_000_000_000_000L).withRecharging().rechargeWindow(3));
initializers.add(tokenAssociate(receiver, token));
initializers.add(cryptoTransfer(moving(balanceInit.get(), token).between(treasury, receiver)));
}
}
for (HapiSpecOperation op : initializers) {
((HapiTxnOp) op).hasRetryPrecheckFrom(NOISY_RETRY_PRECHECKS).setNode(targetAccount);
}
return initializers;
}
@Override
public Optional<HapiSpecOperation> get() {
HapiSpecOperation op;
var numTokens = tokensPerTxn.get();
var numSenders = sendingAccountsPerToken.get();
var numReceivers = receivingAccountsPerToken.get();
String effPayer = null;
var now = "" + Instant.now();
if (firstDir.get()) {
var xfers = new TokenMovement[numTokens * numSenders];
for (int i = 0; i < numTokens; i++) {
var token = "token" + i;
for (int j = 0; j < numSenders; j++) {
var receivers = new String[numReceivers];
for (int k = 0; k < numReceivers; k++) {
receivers[k] = token + "receiver" + k;
}
var source = token + "sender" + j;
if (effPayer == null) {
effPayer = source;
}
xfers[i * numSenders + j] = moving(numReceivers, token).distributing(source, receivers);
}
}
op = cryptoTransfer(xfers).hasKnownStatusFrom(NOISY_ALLOWED_STATUSES).hasRetryPrecheckFrom(NOISY_RETRY_PRECHECKS).memo(now).payingWith(effPayer).setNode(targetAccount).noLogging().deferStatusResolution();
firstDir.set(Boolean.FALSE);
} else {
var xfers = new TokenMovement[numTokens * numReceivers];
for (int i = 0; i < numTokens; i++) {
var token = "token" + i;
for (int j = 0; j < numReceivers; j++) {
var senders = new String[numSenders];
for (int k = 0; k < numSenders; k++) {
senders[k] = token + "sender" + k;
}
var source = token + "receiver" + j;
if (effPayer == null) {
effPayer = source;
}
xfers[i * numReceivers + j] = moving(numSenders, token).distributing(source, senders);
}
}
op = cryptoTransfer(xfers).hasKnownStatusFrom(NOISY_ALLOWED_STATUSES).hasRetryPrecheckFrom(NOISY_RETRY_PRECHECKS).memo(now).payingWith(effPayer).setNode(targetAccount).noLogging().deferStatusResolution();
firstDir.set(Boolean.TRUE);
}
return Optional.of(op);
}
};
}
use of com.hedera.services.bdd.spec.HapiSpecOperation in project hedera-services by hashgraph.
the class TokenTransferBasicLoadTest method runTokenTransferBasicLoadTest.
private HapiApiSpec runTokenTransferBasicLoadTest() {
PerfTestLoadSettings settings = new PerfTestLoadSettings();
Supplier<HapiSpecOperation[]> tokenTransferBurst = () -> new HapiSpecOperation[] { opSupplier(settings).get() };
return defaultHapiSpec("TokenTransferBasicLoadTest").given(withOpContext((spec, ignore) -> settings.setFrom(spec.setup().ciPropertiesMap()))).when(sourcing(() -> runWithProvider(tokenCreatesFactory(settings)).lasting(// 10s as buffering time
() -> settings.getTotalTokens() / ESTIMATED_TOKEN_CREATION_RATE + 10, () -> TimeUnit.SECONDS).totalOpsToSumbit(() -> (int) Math.ceil((double) (settings.getTotalTokens()) / settings.getTotalClients())).maxOpsPerSec(() -> (EXPECTED_MAX_OPS_PER_SEC / settings.getTotalClients())).maxPendingOps(() -> MAX_PENDING_OPS_FOR_SETUP)), sourcing(() -> runWithProvider(activeTokenAssociatesFactory(settings)).lasting(() -> (settings.getTotalTokens() * settings.getTotalTestTokenAccounts() / EXPECTED_MAX_OPS_PER_SEC) + // 30s as buffering time
30, () -> TimeUnit.SECONDS).totalOpsToSumbit(() -> (int) Math.ceil((double) (settings.getTotalTokens()) / settings.getTotalClients()) * settings.getTotalTestTokenAccounts()).maxOpsPerSec(() -> (EXPECTED_MAX_OPS_PER_SEC / settings.getTotalClients())).maxPendingOps(() -> MAX_PENDING_OPS_FOR_SETUP)), sleepFor(2000)).then(defaultLoadTest(tokenTransferBurst, settings));
}
use of com.hedera.services.bdd.spec.HapiSpecOperation in project hedera-services by hashgraph.
the class TokenTransferBasicLoadTest method activeTokenAssociatesFactory.
private Function<HapiApiSpec, OpProvider> activeTokenAssociatesFactory(PerfTestLoadSettings settings) {
int numTotalTokens = settings.getTotalTokens();
int numActiveTokenAccounts = settings.getTotalTestTokenAccounts();
int totalClients = settings.getTotalClients();
int numActiveTokens = (totalClients >= 1) ? numTotalTokens / totalClients : numTotalTokens;
AtomicLong remainingAssociations = new AtomicLong(numActiveTokens * numActiveTokenAccounts - 1);
if (log.isDebugEnabled()) {
log.debug("Total active token accounts {}, total test tokens {}, my portion of tokens {}", numActiveTokenAccounts, numTotalTokens, numActiveTokens);
}
long startAccountId = settings.getTestTreasureStartAccount();
return spec -> new OpProvider() {
@Override
public List<HapiSpecOperation> suggestedInitializers() {
return Collections.emptyList();
}
@Override
public Optional<HapiSpecOperation> get() {
long nextAssocId;
if ((nextAssocId = remainingAssociations.getAndDecrement()) < 0) {
return Optional.empty();
}
int curToken = (int) nextAssocId / numActiveTokenAccounts;
long curAccount = nextAssocId % numActiveTokenAccounts;
var accountId = "0.0." + (startAccountId + curAccount);
var op = tokenAssociate(accountId, tokenRegistryName(curToken)).payingWith(DEFAULT_PAYER).signedBy(DEFAULT_PAYER).hasRetryPrecheckFrom(BUSY, PLATFORM_TRANSACTION_NOT_CREATED, DUPLICATE_TRANSACTION, INSUFFICIENT_PAYER_BALANCE).hasPrecheckFrom(DUPLICATE_TRANSACTION, OK).hasKnownStatusFrom(SUCCESS, TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT, INVALID_TOKEN_ID, TRANSACTION_EXPIRED, TOKENS_PER_ACCOUNT_LIMIT_EXCEEDED, FAIL_INVALID, OK).fee(ONE_HUNDRED_HBARS).noLogging().suppressStats(true).deferStatusResolution();
return Optional.of(op);
}
};
}
use of com.hedera.services.bdd.spec.HapiSpecOperation in project hedera-services by hashgraph.
the class MixedTransferAndSubmitLoadTest method runMixedTransferAndSubmits.
private HapiApiSpec runMixedTransferAndSubmits() {
PerfTestLoadSettings settings = new PerfTestLoadSettings();
final AtomicInteger submittedSoFar = new AtomicInteger(0);
Supplier<HapiSpecOperation[]> transferBurst = () -> new HapiSpecOperation[] { inParallel(flattened(IntStream.range(0, settings.getBurstSize() / 2).mapToObj(ignore -> cryptoTransfer(tinyBarsFromTo("sender", "receiver", 1L)).noLogging().hasPrecheckFrom(OK, BUSY, DUPLICATE_TRANSACTION, PLATFORM_TRANSACTION_NOT_CREATED).deferStatusResolution()).toArray(n -> new HapiSpecOperation[n]), IntStream.range(0, settings.getBurstSize() / 2).mapToObj(ignore -> submitMessageTo("topic").message("A fascinating item of general interest!").noLogging().hasPrecheckFrom(OK, BUSY, DUPLICATE_TRANSACTION, PLATFORM_TRANSACTION_NOT_CREATED).deferStatusResolution()).toArray(n -> new HapiSpecOperation[n]))), logIt(ignore -> String.format("Now a 50/50 mix of %d transfers and messages submitted in total.", submittedSoFar.addAndGet(settings.getBurstSize()))) };
return defaultHapiSpec("RunMixedTransferAndSubmits").given(withOpContext((spec, ignore) -> settings.setFrom(spec.setup().ciPropertiesMap())), logIt(ignore -> settings.toString())).when(createTopic("topic"), cryptoCreate("sender").balance(ignore -> settings.getInitialBalance()), cryptoCreate("receiver")).then(runLoadTest(transferBurst).tps(settings::getTps).tolerance(settings::getTolerancePercentage).allowedSecsBelow(settings::getAllowedSecsBelow).lasting(settings::getMins, () -> MINUTES));
}
use of com.hedera.services.bdd.spec.HapiSpecOperation in project hedera-services by hashgraph.
the class PerpetualTransfers method transfersFactory.
private Function<HapiApiSpec, OpProvider> transfersFactory() {
AtomicBoolean fromAtoB = new AtomicBoolean(true);
return spec -> new OpProvider() {
@Override
public List<HapiSpecOperation> suggestedInitializers() {
return List.of(cryptoCreate("A"), cryptoCreate("B"));
}
@Override
public Optional<HapiSpecOperation> get() {
var from = fromAtoB.get() ? "A" : "B";
var to = fromAtoB.get() ? "B" : "A";
fromAtoB.set(!fromAtoB.get());
var op = cryptoTransfer(tinyBarsFromTo(from, to, 1)).noLogging().deferStatusResolution();
return Optional.of(op);
}
};
}
Aggregations