Skip to content

Commit

Permalink
use broadcasted transaction data for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f committed Nov 1, 2024
1 parent 7e7e8bc commit ef91a53
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 321 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,125 @@ class TestPactusSigner {
}

@Test
fun testPactusTransactionSigning() {
fun testPactusTransferSigning() {
// Successfully broadcasted transaction:
// https://pacviewer.com/transaction/1b6b7226f7935a15f05371d1a1fefead585a89704ce464b7cc1d453d299d235f
//
val signingInput = Pactus.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6".toHexByteArray()).data())
privateKey = ByteString.copyFrom(
PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6"
.toHexByteArray()).data()
)
transaction = Pactus.TransactionMessage.newBuilder().apply {
lockTime = 0x00030201
fee = 1000
memo = "test"
lockTime = 2335524
fee = 10000000
memo = "wallet-core"
transfer = Pactus.TransferPayload.newBuilder().apply {
sender = "pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr"
receiver = "pc1r0g22ufzn8qtw0742dmfglnw73e260hep0k3yra"
amount = 20000
amount = 200000000
}.build()
}.build()
}

val output = AnySigner.sign(signingInput.build(), PACTUS, SigningOutput.parser())

assertEquals(
"0x34cd4656a98f7eb996e83efdc384cefbe3a9c52dca79a99245b4eacc0b0b4311",
"0x1b6b7226f7935a15f05371d1a1fefead585a89704ce464b7cc1d453d299d235f",
Numeric.toHexString(output.transactionId.toByteArray())
)

assertEquals(
"0x50ac25c7125271489b0cd230549257c93fb8c6265f2914a988ba7b81c1bc47fff027412dd59447867911035ff69742d171060a1f132ac38b95acc6e39ec0bd09",
"0x8dea6d79ee7ec60f66433f189ed9b3c50b2ad6fa004e26790ee736693eda850695794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
Numeric.toHexString(output.signature.toByteArray())
)

assertEquals(
"0x000101020300e807047465737401037098338e0b6808119dfd4457ab806b9c2059b89b037a14ae24533816e7faaa6ed28fcdde8e55a7df21a09c0150ac25c7125271489b0cd230549257c93fb8c6265f2914a988ba7b81c1bc47fff027412dd59447867911035ff69742d171060a1f132ac38b95acc6e39ec0bd0995794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
"0x000124a3230080ade2040b77616c6c65742d636f726501037098338e0b6808119dfd4457ab806b9c2059b89b037a14ae24533816e7faaa6ed28fcdde8e55a7df218084af5f4ed8fee3d8992e82660dd05bbe8608fc56ceabffdeeee61e3213b9b49d33a0fc8dea6d79ee7ec60f66433f189ed9b3c50b2ad6fa004e26790ee736693eda850695794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
Numeric.toHexString(output.signedTransactionData.toByteArray())
)
}

@Test
fun testPactusBondWithPublicKeySigning() {
// Successfully broadcasted transaction:
// https://pacviewer.com/transaction/d194b445642a04ec78ced4448696e50b733f2f0b517a23871882c0eefaf1c28f
//
val signingInput = Pactus.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(
PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6"
.toHexByteArray()).data()
)
transaction = Pactus.TransactionMessage.newBuilder().apply {
lockTime = 2339009
fee = 10000000
memo = "wallet-core"
bond = Pactus.BondPayload.newBuilder().apply {
sender = "pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr"
receiver = "pc1p9y5gmu9l002tt60wak9extgvwm69rq3a9ackrl"
stake = 1000000000
publicKey = "public1pnz75msstqdrq5eguvcwanug0zauhqjw2cc4flmez3qethnp68y64ehc4k69amapj7x4na2uda0snqz4yxujgx3jsse4f64fgy7jkh0xauvhrc5ts09vfk48g85t0js66hvajm6xruemsvlxqv3xvkyur8v9v0mtn"
}.build()
}.build()
}

val output = AnySigner.sign(signingInput.build(), PACTUS, SigningOutput.parser())

assertEquals(
"0xd194b445642a04ec78ced4448696e50b733f2f0b517a23871882c0eefaf1c28f",
Numeric.toHexString(output.transactionId.toByteArray())
)

assertEquals(
"0x0d7bc6d94927534b89e2f53bcfc9fc849e0e2982438955eda55b4338328adac79d4ee3216d143f0e1629764ab650734f8ba188e716d71f9eff65e39ce7006300",
Numeric.toHexString(output.signature.toByteArray())
)

assertEquals(
"0x0001c1b0230080ade2040b77616c6c65742d636f726502037098338e0b6808119dfd4457ab806b9c2059b89b0129288df0bf7bd4b5e9eeed8b932d0c76f451823d6098bd4dc20b03460a651c661dd9f10f17797049cac62a9fef228832bbcc3a39355cdf15b68bddf432f1ab3eab8debe1300aa43724834650866a9d552827a56bbcdde32e3c517079589b54e83d16f9435abb3b2de8c3e677067cc0644ccb13833b8094ebdc030d7bc6d94927534b89e2f53bcfc9fc849e0e2982438955eda55b4338328adac79d4ee3216d143f0e1629764ab650734f8ba188e716d71f9eff65e39ce700630095794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
Numeric.toHexString(output.signedTransactionData.toByteArray())
)
}

@Test
fun testPactusBondWithoutPublicKeySigning() {
// Successfully broadcasted transaction:
// https://pacviewer.com/transaction/f83f583a5c40adf93a90ea536a7e4b467d30ca4f308d5da52624d80c42adec80
//
val signingInput = Pactus.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(
PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6"
.toHexByteArray()).data()
)
transaction = Pactus.TransactionMessage.newBuilder().apply {
lockTime = 2335580
fee = 10000000
memo = "wallet-core"
bond = Pactus.BondPayload.newBuilder().apply {
sender = "pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr"
receiver = "pc1p6taz5l2kq5ppnxv4agnqj48svnvsy797xpe6wd"
stake = 1000000000
}.build()
}.build()
}

val output = AnySigner.sign(signingInput.build(), PACTUS, SigningOutput.parser())

assertEquals(
"0xf83f583a5c40adf93a90ea536a7e4b467d30ca4f308d5da52624d80c42adec80",
Numeric.toHexString(output.transactionId.toByteArray())
)

assertEquals(
"0x9e6279fb64067c7d7316ac74630bbb8589df268aa4548f1c7d85c087a8748ff0715b9149afbd94c5d8ee6b37c787ec63e963cbb38be513ebc436aa58f9a8f00d",
Numeric.toHexString(output.signature.toByteArray())
)

assertEquals(
"0x01015ca3230080ade2040b77616c6c65742d636f726502037098338e0b6808119dfd4457ab806b9c2059b89b01d2fa2a7d560502199995ea260954f064d90278be008094ebdc039e6279fb64067c7d7316ac74630bbb8589df268aa4548f1c7d85c087a8748ff0715b9149afbd94c5d8ee6b37c787ec63e963cbb38be513ebc436aa58f9a8f00d",
Numeric.toHexString(output.signedTransactionData.toByteArray())
)
}
Expand Down
174 changes: 56 additions & 118 deletions rust/tw_tests/tests/chains/pactus/pactus_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Copyright © 2017 Trust Wallet.

use crate::chains::pactus::test_cases::PRIVATE_KEY;
use crate::chains::pactus::test_cases::{bond_test_case, transfer_test_case};
use crate::chains::pactus::test_cases::TEST_CASES;
use tw_any_coin::ffi::tw_transaction_compiler::{
tw_transaction_compiler_compile, tw_transaction_compiler_pre_image_hashes,
};
Expand All @@ -20,121 +20,59 @@ use tw_proto::TxCompiler::Proto as CompilerProto;
use tw_proto::{deserialize, serialize};

#[test]
fn test_pactus_transfer_compile() {
// Step 1: Create signing input.
let input = transfer_test_case::sign_input();

// Step 2: Obtain preimage hash
let input_data = TWDataHelper::create(serialize(&input).unwrap());
let preimage_data = TWDataHelper::wrap(unsafe {
tw_transaction_compiler_pre_image_hashes(CoinType::Pactus as u32, input_data.ptr())
})
.to_vec()
.expect("!tw_transaction_compiler_pre_image_hashes returned nullptr");

let preimage: CompilerProto::PreSigningOutput =
deserialize(&preimage_data).expect("Coin entry returned an invalid output");

assert_eq!(preimage.error, SigningErrorType::OK);
assert!(preimage.error_message.is_empty());
assert_eq!(preimage.data.to_hex(), transfer_test_case::SIGN_BYTES);

// Step 3: Sign the data "externally"
let private_key = ed25519::sha512::KeyPair::try_from(PRIVATE_KEY).unwrap();
let public_key = private_key.public().to_vec();

let signature = private_key
.sign(preimage.data.to_vec())
.expect("Error signing data")
.to_vec();
assert_eq!(signature.to_hex(), transfer_test_case::SIGNATURE);

// Step 4: Compile transaction info

let signatures = TWDataVectorHelper::create([signature]);
let public_keys = TWDataVectorHelper::create([public_key]);

let input_data = TWDataHelper::create(serialize(&input).unwrap());
let output_data = TWDataHelper::wrap(unsafe {
tw_transaction_compiler_compile(
CoinType::Pactus as u32,
input_data.ptr(),
signatures.ptr(),
public_keys.ptr(),
)
})
.to_vec()
.expect("!tw_transaction_compiler_compile returned nullptr");

let output: Proto::SigningOutput =
deserialize(&output_data).expect("Coin entry returned an invalid output");

assert_eq!(output.error, SigningErrorType::OK);
assert!(output.error_message.is_empty());
assert_eq!(output.transaction_id.to_hex(), transfer_test_case::TX_ID);
assert_eq!(output.signature.to_hex(), transfer_test_case::SIGNATURE);
assert_eq!(
output.signed_transaction_data.to_hex(),
transfer_test_case::SIGNED_DATA
);
}

#[test]
fn test_pactus_bond_compile() {
// Step 1: Create signing input.
let input = bond_test_case::sign_input();

// Step 2: Obtain preimage hash
let input_data = TWDataHelper::create(serialize(&input).unwrap());
let preimage_data = TWDataHelper::wrap(unsafe {
tw_transaction_compiler_pre_image_hashes(CoinType::Pactus as u32, input_data.ptr())
})
.to_vec()
.expect("!tw_transaction_compiler_pre_image_hashes returned nullptr");

let preimage: CompilerProto::PreSigningOutput =
deserialize(&preimage_data).expect("Coin entry returned an invalid output");

assert_eq!(preimage.error, SigningErrorType::OK);
assert!(preimage.error_message.is_empty());
assert_eq!(preimage.data.to_hex(), bond_test_case::SIGN_BYTES);

// Step 3: Sign the data "externally"
let private_key = ed25519::sha512::KeyPair::try_from(PRIVATE_KEY).unwrap();
let public_key = private_key.public().to_vec();

let signature = private_key
.sign(preimage.data.to_vec())
.expect("Error signing data")
.to_vec();
assert_eq!(signature.to_hex(), bond_test_case::SIGNATURE);

// Step 4: Compile transaction info

let signatures = TWDataVectorHelper::create([signature]);
let public_keys = TWDataVectorHelper::create([public_key]);

let input_data = TWDataHelper::create(serialize(&input).unwrap());
let output_data = TWDataHelper::wrap(unsafe {
tw_transaction_compiler_compile(
CoinType::Pactus as u32,
input_data.ptr(),
signatures.ptr(),
public_keys.ptr(),
)
})
.to_vec()
.expect("!tw_transaction_compiler_compile returned nullptr");

let output: Proto::SigningOutput =
deserialize(&output_data).expect("Coin entry returned an invalid output");

assert_eq!(output.error, SigningErrorType::OK);
assert!(output.error_message.is_empty());
assert_eq!(output.transaction_id.to_hex(), bond_test_case::TX_ID);
assert_eq!(output.signature.to_hex(), bond_test_case::SIGNATURE);
assert_eq!(
output.signed_transaction_data.to_hex(),
bond_test_case::SIGNED_DATA
);
fn test_pactus_transaction_compile() {
for case in TEST_CASES.iter() {
// Step 1: Create signing input.
let input = (case.sign_input_fn)();

// Step 2: Obtain preimage hash
let input_data = TWDataHelper::create(serialize(&input).unwrap());
let preimage_data = TWDataHelper::wrap(unsafe {
tw_transaction_compiler_pre_image_hashes(CoinType::Pactus as u32, input_data.ptr())
})
.to_vec()
.expect("!tw_transaction_compiler_pre_image_hashes returned nullptr");

let preimage: CompilerProto::PreSigningOutput =
deserialize(&preimage_data).expect("Coin entry returned an invalid output");

assert_eq!(preimage.error, SigningErrorType::OK);
assert!(preimage.error_message.is_empty());
assert_eq!(preimage.data.to_hex(), case.data_to_sign);

// Step 3: Sign the data "externally"
let private_key = ed25519::sha512::KeyPair::try_from(PRIVATE_KEY).unwrap();
let public_key = private_key.public().to_vec();

let signature = private_key
.sign(preimage.data.to_vec())
.expect("Error signing data")
.to_vec();
assert_eq!(signature.to_hex(), case.signature);

// Step 4: Compile transaction info
let signatures = TWDataVectorHelper::create([signature]);
let public_keys = TWDataVectorHelper::create([public_key]);

let input_data = TWDataHelper::create(serialize(&input).unwrap());
let output_data = TWDataHelper::wrap(unsafe {
tw_transaction_compiler_compile(
CoinType::Pactus as u32,
input_data.ptr(),
signatures.ptr(),
public_keys.ptr(),
)
})
.to_vec()
.expect("!tw_transaction_compiler_compile returned nullptr");

let output: Proto::SigningOutput =
deserialize(&output_data).expect("Coin entry returned an invalid output");

assert_eq!(output.error, SigningErrorType::OK);
assert!(output.error_message.is_empty());
assert_eq!(output.transaction_id.to_hex(), case.transaction_id);
assert_eq!(output.signature.to_hex(), case.signature);
assert_eq!(output.signed_transaction_data.to_hex(), case.signed_data);
}
}
Loading

0 comments on commit ef91a53

Please sign in to comment.