Skip to content

Commit

Permalink
Generate own mnemonic for each Java test (#1428)
Browse files Browse the repository at this point in the history
* Generate own mnemonic for every test

* Format dependencies

* Update client/bindings/java/lib/src/main/java/org/iota/Client.java

Co-authored-by: Thoralf-M <[email protected]>

* Update client/bindings/java/lib/src/main/java/org/iota/Client.java

Co-authored-by: Thoralf-M <[email protected]>

* Remove unnecessary result

* Get bech32 from the client

* Avoid unnecessary allocations in utils.rs

* Update client/CHANGELOG.md

Co-authored-by: Thoralf-M <[email protected]>
  • Loading branch information
samuel-rufi and Thoralf-M authored Dec 1, 2022
1 parent 3715998 commit a1b279f
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 46 deletions.
4 changes: 4 additions & 0 deletions client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## 2.0.1-rc.5 - 20XX-XX-XX

### Added

- `alias_id_to_bech32()` to utils;

### Changed

- Abort the sync nodes task through its handle instead of a oneshot channel;
Expand Down
12 changes: 12 additions & 0 deletions client/bindings/java/lib/src/main/java/org/iota/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,18 @@ public String hexToBech32(String hex, String bech32) throws ClientException {
return utilsApi.hexToBech32(hex, bech32);
}

/**
* Converts an alias id to a bech32 address.
*
* @param aliasId The alias id to be converted.
* @param bech32Hrp The bech 32 human readable part to use.
* @return The bech32 address.
* @throws ClientException on error.
*/
public String aliasIdToBech32(AliasId aliasId, String bech32Hrp) throws ClientException {
return utilsApi.aliasIdToBech32(aliasId, bech32Hrp);
}

/**
* Converts a hex public key to a bech32 address
*
Expand Down
10 changes: 10 additions & 0 deletions client/bindings/java/lib/src/main/java/org/iota/apis/UtilsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ public String hexToBech32(String hex, String bech32) throws ClientException {
return responsePayload;
}

public String aliasIdToBech32(AliasId aliasId, String bech32) throws ClientException {
JsonObject o = new JsonObject();
o.addProperty("aliasId", aliasId.toString());
o.addProperty("bech32Hrp", bech32);

String responsePayload = nativeApi.sendCommand(new ClientCommand("aliasIdToBech32", o)).getAsString();

return responsePayload;
}

public String hexPublicKeyToBech32Address(String hex, String bech32) throws ClientException {
JsonObject o = new JsonObject();
o.addProperty("hex", hex);
Expand Down
7 changes: 2 additions & 5 deletions client/bindings/java/lib/src/test/java/org/iota/ApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
public abstract class ApiTest {

protected static final String DEFAULT_TESTNET_NODE_URL = "https://api.testnet.shimmer.network";
// Tests should use this mnemonic only in a read-only fashion. Tests that consume outputs must generate their own random mnemonic.
protected static final String DEFAULT_DEVELOPMENT_MNEMONIC = "hidden enroll proud copper decide negative orient asset speed work dolphin atom unhappy game cannon scheme glow kid ring core name still twist actor";

protected Client client;
protected ClientConfig config = new ClientConfig().withNodes(new String[] { DEFAULT_TESTNET_NODE_URL }).withIgnoreNodeHealth(false);

Expand All @@ -44,12 +41,12 @@ protected Block setUpTaggedDataBlock() throws ClientException {
}

protected TransactionId setUpTransactionId(String address) throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
OutputMetadata metadata = client.getOutputMetadata(setupOutputId(address));
OutputMetadata metadata = client.getOutputMetadata(setupBasicOutput(address));
TransactionId ret = new TransactionId(metadata.toJson().get("transactionId").getAsString());
return ret;
}

protected OutputId setupOutputId(String address) throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
protected OutputId setupBasicOutput(String address) throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
client.requestTestFundsFromFaucet(address);
return client.getBasicOutputIds(new NodeIndexerApi.QueryParams().withParam("address", address))[0];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ public class HighLevelApiTest extends ApiTest {

@Test
public void testGetOutputs() throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
OutputId[] outputs = new OutputId[] { setupOutputId(generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC)) };
OutputId[] outputs = new OutputId[] { setupBasicOutput(generateAddress(client.generateMnemonic())) };
for (Map.Entry e : client.getOutputs(outputs)) {
System.out.println(e.getKey());
}
}

@Test
public void testTryGetOutputs() throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
OutputId[] outputs = new OutputId[] { setupOutputId(generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC)) };
OutputId[] outputs = new OutputId[] { setupBasicOutput(generateAddress(client.generateMnemonic())) };
for (Map.Entry e : client.tryGetOutputs(outputs)) {
System.out.println(e.getKey());
}
Expand Down Expand Up @@ -78,8 +78,8 @@ public void testConsolidateFunds() throws ClientException, InitializeClientExcep
}

@Test
public void testFindInputs() throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
SecretManager secretManager = new MnemonicSecretManager(DEFAULT_DEVELOPMENT_MNEMONIC);
public void testFindInputs() throws ClientException, NoFundsReceivedFromFaucetException {
SecretManager secretManager = new MnemonicSecretManager(client.generateMnemonic());
String[] addresses = client.generateAddresses(secretManager, new GenerateAddressesOptions().withRange(new Range(0, 5)));
client.requestTestFundsFromFaucet(addresses[0]);
UtxoInput[] inputs = client.findInputs(addresses, 1000);
Expand All @@ -88,8 +88,8 @@ public void testFindInputs() throws ClientException, InitializeClientException,
}

@Test
public void testFindOutputs() throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
SecretManager secretManager = new MnemonicSecretManager(DEFAULT_DEVELOPMENT_MNEMONIC);
public void testFindOutputs() throws ClientException, NoFundsReceivedFromFaucetException {
SecretManager secretManager = new MnemonicSecretManager(client.generateMnemonic());
String[] addresses = client.generateAddresses(secretManager, new GenerateAddressesOptions().withRange(new Range(0, 5)));
client.requestTestFundsFromFaucet(addresses[0]);
for (Map.Entry e : client.findOutputs(new OutputId[]{}, addresses)) {
Expand Down
124 changes: 102 additions & 22 deletions client/bindings/java/lib/src/test/java/org/iota/IndexerApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,133 @@

package org.iota;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.iota.apis.NodeIndexerApi;
import org.iota.types.Output;
import org.iota.types.*;
import org.iota.types.expections.ClientException;
import org.iota.types.ids.AliasId;
import org.iota.types.ids.FoundryId;
import org.iota.types.ids.NftId;
import org.iota.types.ids.OutputId;
import org.iota.types.secret.BuildBlockOptions;
import org.iota.types.secret.MnemonicSecretManager;
import org.iota.types.expections.NoFundsReceivedFromFaucetException;
import org.iota.types.ids.*;
import org.iota.types.output_builder.AliasOutputBuilderParams;
import org.iota.types.output_builder.FoundryOutputBuilderParams;
import org.iota.types.output_builder.NftOutputBuilderParams;
import org.iota.types.secret.*;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class IndexerApiTest extends ApiTest {

@Test
public void testGetBasicOutputIds() throws ClientException {
for (OutputId outputId : client.getBasicOutputIds(new NodeIndexerApi.QueryParams().withParam("address", generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC))))
public void testGetBasicOutputIds() throws ClientException, NoFundsReceivedFromFaucetException {
String address = generateAddress(client.generateMnemonic());
client.requestTestFundsFromFaucet(address);
for (OutputId outputId : client.getBasicOutputIds(new NodeIndexerApi.QueryParams().withParam("address", address)))
System.out.println(outputId);
}

@Test
public void testGetAliasOutputIds() throws ClientException {
for (OutputId outputId : client.getAliasOutputIds(new NodeIndexerApi.QueryParams().withParam("issuer", generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC))))
public void testGetAliasOutputIds() throws ClientException, InterruptedException, NoFundsReceivedFromFaucetException {
SecretManager s = new MnemonicSecretManager(client.generateMnemonic());
String address = client.generateAddresses(s, new GenerateAddressesOptions().withRange(new Range(0, 1)))[0];
client.requestTestFundsFromFaucet(address);
String hexAddress = client.bech32ToHex(address);

AliasId aliasId = new AliasId("0x0000000000000000000000000000000000000000000000000000000000000000");
UnlockCondition[] unlockConditions = new UnlockCondition[]{
new UnlockCondition("{ type: 4, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }"),
new UnlockCondition("{ type: 5, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }")
};
AliasOutputBuilderParams params = new AliasOutputBuilderParams()
.withAliasId(aliasId)
.withUnlockConditions(unlockConditions);

Output aliasOutput = client.buildAliasOutput(params);

client.buildAndPostBlock(s, new BuildBlockOptions().withOutputs(new Output[] { aliasOutput }));
Thread.sleep(1000 * 25);

for (OutputId outputId : client.getAliasOutputIds(new NodeIndexerApi.QueryParams().withParam("governor", address)))
System.out.println(outputId);
}

@Test
public void testGetNftOutputIds() throws ClientException {
for (OutputId outputId : client.getNftOutputIds(new NodeIndexerApi.QueryParams().withParam("address", generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC))))
public void testGetNftOutputIds() throws ClientException, NoFundsReceivedFromFaucetException, InterruptedException {
SecretManager s = new MnemonicSecretManager(client.generateMnemonic());
String address = client.generateAddresses(s, new GenerateAddressesOptions().withRange(new Range(0, 1)))[0];
client.requestTestFundsFromFaucet(address);
String hexAddress = client.bech32ToHex(address);

NftId nftId = new NftId("0x0000000000000000000000000000000000000000000000000000000000000000");
UnlockCondition[] unlockConditions = new UnlockCondition[]{
new UnlockCondition("{ type: 0, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }"),
};
NftOutputBuilderParams params = new NftOutputBuilderParams()
.withNftId(nftId)
.withUnlockConditions(unlockConditions);

Output aliasOutput = client.buildNftOutput(params);

client.buildAndPostBlock(s, new BuildBlockOptions().withOutputs(new Output[] { aliasOutput }));
Thread.sleep(1000 * 25);

for (OutputId outputId : client.getNftOutputIds(new NodeIndexerApi.QueryParams().withParam("address", address)))
System.out.println(outputId);
}

@Test
public void testGetFoundryOutputIds() throws ClientException {
JsonObject json = new Gson().fromJson(
"{\"type\":4,\"amount\":\"1000000\",\"aliasId\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"stateIndex\":0,\"foundryCounter\":0,\"unlockConditions\":[{\"type\":4,\"address\":{\"type\":0,\"pubKeyHash\":\"0x4cfde0600797ae07d19d67d78910e70950bfdaf716f0035e9a30b97828aaf6a2\"}},{\"type\":5,\"address\":{\"type\":0,\"pubKeyHash\":\"0x4cfde0600797ae07d19d67d78910e70950bfdaf716f0035e9a30b97828aaf6a2\"}}],\"features\":[{\"type\":0,\"address\":{\"type\":0,\"pubKeyHash\":\"0x4cfde0600797ae07d19d67d78910e70950bfdaf716f0035e9a30b97828aaf6a2\"}},{\"type\":2,\"data\":\"0x010203\"}],\"immutableFeatures\":[{\"type\":1,\"address\":{\"type\":0,\"pubKeyHash\":\"0x4cfde0600797ae07d19d67d78910e70950bfdaf716f0035e9a30b97828aaf6a2\"}}]}",
JsonObject.class
public void testGetFoundryOutputIds() throws ClientException, NoFundsReceivedFromFaucetException, InterruptedException {
SecretManager s = new MnemonicSecretManager(client.generateMnemonic());
String address = client.generateAddresses(s, new GenerateAddressesOptions().withRange(new Range(0, 1)))[0];
client.requestTestFundsFromFaucet(address);
String hexAddress = client.bech32ToHex(address);

// Build an Alias Output
AliasOutputBuilderParams p = new AliasOutputBuilderParams()
.withAliasId(new AliasId("0x0000000000000000000000000000000000000000000000000000000000000000"))
.withUnlockConditions(new UnlockCondition[]{
new UnlockCondition("{ type: 4, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }"),
new UnlockCondition("{ type: 5, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }")
});

Map.Entry<BlockId, Block> response = client.buildAndPostBlock(s, new BuildBlockOptions().withOutputs(new Output[] { client.buildAliasOutput(p) }));
Thread.sleep(1000 * 25);
TransactionId transactionId = client.getTransactionId(new TransactionPayload(response.getValue().toJson().get("payload").getAsJsonObject()));

// Build the Foundry Output
client.requestTestFundsFromFaucet(address);
AliasId aliasId = client.computeAliasId(new OutputId(transactionId + "0000" ));
int serialNumber = 1;
TokenScheme tokenScheme = new TokenScheme("{ type: 0, meltedTokens: '0x0', mintedTokens: '0x32', maximumSupply: '0x64' }");
UnlockCondition[] unlockConditions = new UnlockCondition[]{new UnlockCondition("{ type: 6, address: { type: 8, aliasId: " + aliasId + " } }")};
FoundryOutputBuilderParams params = new FoundryOutputBuilderParams()
.withSerialNumber(serialNumber)
.withTokenScheme(tokenScheme)
.withUnlockConditions(unlockConditions);
Output foundryOutput = client.buildFoundryOutput(params);

// Build the new foundry output
Output newAliasOutput = client.buildAliasOutput(new AliasOutputBuilderParams()
.withAliasId(aliasId)
.withFoundryCounter(1)
.withStateIndex(1)
.withUnlockConditions(new UnlockCondition[]{
new UnlockCondition("{ type: 4, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }"),
new UnlockCondition("{ type: 5, address: { type: 0, pubKeyHash: \"" + hexAddress + "\" } }")
}));

// Create the transaction and use the outputs
client.buildAndPostBlock(s, new BuildBlockOptions()
.withOutputs(new Output[] {
foundryOutput,
newAliasOutput
})
);
Output o = new Output(json);

client.buildAndPostBlock(new MnemonicSecretManager(DEFAULT_DEVELOPMENT_MNEMONIC), new BuildBlockOptions().withOutputs(new Output[] { o }));
Thread.sleep(1000 * 25);

for (OutputId outputId : client.getFoundryOutputIds(new NodeIndexerApi.QueryParams().withParam("aliasAddress", "rms1pz022kd0zjmu4dms8whgnfus3ph347cmr8th3kk5g2qn7sl5xzfcj33gfu4")))
for (OutputId outputId : client.getFoundryOutputIds(new NodeIndexerApi.QueryParams().withParam("aliasAddress", client.aliasIdToBech32(aliasId, client.getBech32Hrp()))))
System.out.println(outputId);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ public void testGetBlockMetadata() throws ClientException {

@Test
public void testGetOutput() throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
Map.Entry<Output, OutputMetadata> r = client.getOutput(setupOutputId(generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC)));
Map.Entry<Output, OutputMetadata> r = client.getOutput(setupBasicOutput(generateAddress(client.generateMnemonic())));
System.out.println(r.getKey());
System.out.println(r.getValue());
}

@Test
public void testGetOutputMetadata() throws ClientException, InitializeClientException, NoFundsReceivedFromFaucetException {
OutputMetadata r = client.getOutputMetadata(setupOutputId(generateAddress(DEFAULT_DEVELOPMENT_MNEMONIC)));
OutputMetadata r = client.getOutputMetadata(setupBasicOutput(generateAddress(client.generateMnemonic())));
System.out.println(r);
}

Expand Down
9 changes: 9 additions & 0 deletions client/src/message_interface/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,15 @@ pub enum Message {
#[serde(rename = "bech32Hrp")]
bech32_hrp: Option<String>,
},
/// Transforms an alias id to a bech32 encoded address
AliasIdToBech32 {
/// Alias ID
#[serde(rename = "aliasId")]
alias_id: AliasId,
/// Human readable part
#[serde(rename = "bech32Hrp")]
bech32_hrp: Option<String>,
},
/// Transforms a hex encoded public key to a bech32 encoded address
HexPublicKeyToBech32Address {
/// Hex encoded public key
Expand Down
3 changes: 3 additions & 0 deletions client/src/message_interface/message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@ impl ClientMessageHandler {
Message::HexToBech32 { hex, bech32_hrp } => Ok(Response::HexToBech32(
self.client.hex_to_bech32(&hex, bech32_hrp.as_deref()).await?,
)),
Message::AliasIdToBech32 { alias_id, bech32_hrp } => Ok(Response::AliasIdToBech32(
self.client.alias_id_to_bech32(alias_id, bech32_hrp.as_deref()).await?,
)),
Message::HexPublicKeyToBech32Address { hex, bech32_hrp } => Ok(Response::HexToBech32(
self.client
.hex_public_key_to_bech32_address(&hex, bech32_hrp.as_deref())
Expand Down
3 changes: 3 additions & 0 deletions client/src/message_interface/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ pub enum Response {
/// - [`HexPublicKeyToBech32Address`](crate::message_interface::Message::HexPublicKeyToBech32Address)
HexToBech32(String),
/// Response for:
/// - [`AliasIdToBech32`](crate::message_interface::Message::AliasIdToBech32)
AliasIdToBech32(String),
/// Response for:
/// - [`ParseBech32Address`](crate::message_interface::Message::ParseBech32Address)
ParsedBech32Address(AddressDto),
/// Response for:
Expand Down
34 changes: 23 additions & 11 deletions client/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use crypto::{
utils,
};
use iota_types::block::{
address::{Address, Ed25519Address},
address::{Address, AliasAddress, Ed25519Address},
output::AliasId,
payload::TaggedDataPayload,
};
use zeroize::Zeroize;
Expand All @@ -36,6 +37,11 @@ pub fn hex_to_bech32(hex: &str, bech32_hrp: &str) -> Result<String> {
Ok(Address::Ed25519(address).to_bech32(bech32_hrp))
}

/// Transforms an alias id to a bech32 encoded address
pub fn alias_id_to_bech32(alias_id: AliasId, bech32_hrp: &str) -> String {
Address::Alias(AliasAddress::new(alias_id)).to_bech32(bech32_hrp)
}

/// Transforms a prefix hex encoded public key to a bech32 encoded address
pub fn hex_public_key_to_bech32_address(hex: &str, bech32_hrp: &str) -> Result<String> {
let public_key: [u8; Ed25519Address::LENGTH] = prefix_hex::decode(hex)?;
Expand Down Expand Up @@ -109,20 +115,26 @@ impl Client {

/// Transforms a hex encoded address to a bech32 encoded address
pub async fn hex_to_bech32(&self, hex: &str, bech32_hrp: Option<&str>) -> crate::Result<String> {
let bech32_hrp = match bech32_hrp {
Some(hrp) => hrp.into(),
None => self.get_bech32_hrp().await?,
};
hex_to_bech32(hex, &bech32_hrp)
match bech32_hrp {
Some(hrp) => Ok(hex_to_bech32(hex, hrp)?),
None => Ok(hex_to_bech32(hex, &self.get_bech32_hrp().await?)?),
}
}

/// Transforms an alias id to a bech32 encoded address
pub async fn alias_id_to_bech32(&self, alias_id: AliasId, bech32_hrp: Option<&str>) -> crate::Result<String> {
match bech32_hrp {
Some(hrp) => Ok(alias_id_to_bech32(alias_id, hrp)),
None => Ok(alias_id_to_bech32(alias_id, &self.get_bech32_hrp().await?)),
}
}

/// Transforms a hex encoded public key to a bech32 encoded address
pub async fn hex_public_key_to_bech32_address(&self, hex: &str, bech32_hrp: Option<&str>) -> crate::Result<String> {
let bech32_hrp = match bech32_hrp {
Some(hrp) => hrp.into(),
None => self.get_bech32_hrp().await?,
};
hex_public_key_to_bech32_address(hex, &bech32_hrp)
match bech32_hrp {
Some(hrp) => Ok(hex_public_key_to_bech32_address(hex, hrp)?),
None => Ok(hex_public_key_to_bech32_address(hex, &self.get_bech32_hrp().await?)?),
}
}

/// Returns a valid Address parsed from a String.
Expand Down

0 comments on commit a1b279f

Please sign in to comment.