Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update to latest TenureChange wire-format #16

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,18 @@ export interface TxPayloadVersionedSmartContract {

export interface TxPayloadTenureChange {
type_id: TxPayloadTypeID.TenureChange;
/** (Hex string) Stacks Block hash */
/** Consensus hash of this tenure. Corresponds to the sortition in which the miner of this
* block was chosen. It may be the case that this miner's tenure gets _extended_ across
* subsequent sortitions; if this happens, then this `consensus_hash` value _remains the same_
* as the sortition in which the winning block-commit was mined. */
tenure_consensus_hash: string;
/** Consensus hash of the previous tenure. Corresponds to the sortition of the previous winning block-commit. */
prev_tenure_consensus_hash: string;
/** Current consensus hash on the underlying burnchain. Corresponds to the last-seen sortition. */
burn_view_consensus_hash: string;
/** The StacksBlockId of the last block from the previous tenure */
previous_tenure_end: string;
/** The number of blocks produced in the previous tenure */
/** The number of blocks produced since the last sortition-linked tenure */
previous_tenure_blocks: number;
/** Cause of change in mining tenure. Depending on cause, tenure can be ended or extended. */
cause: TenureChangeCause;
Expand All @@ -233,10 +242,8 @@ export interface TxPayloadTenureChange {
export enum TenureChangeCause {
/** A valid winning block-commit */
BlockFound = 0,
/** No winning block-commits */
NoBlockFound = 1,
/** A "null miner" won the block-commit */
NullMiner = 2,
/** The next burnchain block is taking too long, so extend the runtime budget */
Extended = 1,
}

export enum TxPayloadTypeID {
Expand Down
39 changes: 26 additions & 13 deletions src/stacks_tx/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,15 @@ impl TransactionSmartContract {

impl TransactionTenureChange {
pub fn deserialize(fd: &mut Cursor<&[u8]>) -> Result<Self, DeserializeError> {
let mut tenure_consensus_hash = [0u8; 20];
fd.read_exact(&mut tenure_consensus_hash)?;

let mut prev_tenure_consensus_hash = [0u8; 20];
fd.read_exact(&mut prev_tenure_consensus_hash)?;

let mut burn_view_consensus_hash = [0u8; 20];
fd.read_exact(&mut burn_view_consensus_hash)?;

let mut previous_tenure_end = [0u8; 32];
fd.read_exact(&mut previous_tenure_end)?;

Expand All @@ -461,21 +470,24 @@ impl TransactionTenureChange {
let mut pubkey_hash = [0u8; 20];
fd.read_exact(&mut pubkey_hash)?;

let signers_len: u32 = fd.read_u32::<BigEndian>()?;
let mut signers: Vec<u8> = vec![0u8; signers_len as usize];
fd.read_exact(&mut signers)?;

// ThresholdSignature { R: [0u8; 33], z: [0u8; 32] }
let mut signature = [0u8; 65];
fd.read_exact(&mut signature)?;

let signers_len: u32 = fd.read_u32::<BigEndian>()?;
let mut signers: Vec<u8> = vec![0u8; signers_len as usize];
fd.read_exact(&mut signers)?;

Ok(TransactionTenureChange {
tenure_consensus_hash,
prev_tenure_consensus_hash,
burn_view_consensus_hash,
previous_tenure_end,
previous_tenure_blocks,
cause,
pubkey_hash,
signers,
signature,
signers,
})
}
}
Expand Down Expand Up @@ -710,30 +722,31 @@ pub struct CoinbasePayload(pub [u8; 32]);
pub struct VRFProof(pub Vec<u8>);

pub struct TransactionTenureChange {
pub tenure_consensus_hash: [u8; 20],
pub prev_tenure_consensus_hash: [u8; 20],
pub burn_view_consensus_hash: [u8; 20],
pub previous_tenure_end: [u8; 32],
pub previous_tenure_blocks: u32,
pub cause: TenureChangeCause,
pub pubkey_hash: [u8; 20],
pub signers: Vec<u8>,
pub signature: [u8; 65],
pub signers: Vec<u8>,
}

#[repr(u8)]
#[derive(PartialEq, Copy, Clone)]
pub enum TenureChangeCause {
/// A valid winning block-commit
BlockFound = 0,
NoBlockFound = 1,
NullMiner = 2,
/// The next burnchain block is taking too long, so extend the runtime budget
Extended = 1,
}

impl TenureChangeCause {
pub fn from_u8(n: u8) -> Option<TenureChangeCause> {
match n {
x if x == TenureChangeCause::BlockFound as u8 => Some(TenureChangeCause::BlockFound),
x if x == TenureChangeCause::NoBlockFound as u8 => {
Some(TenureChangeCause::NoBlockFound)
}
x if x == TenureChangeCause::NullMiner as u8 => Some(TenureChangeCause::NullMiner),
x if x == TenureChangeCause::Extended as u8 => Some(TenureChangeCause::Extended),
_ => None,
}
}
Expand Down Expand Up @@ -794,7 +807,7 @@ mod tests {
// tx prefix (before payload):
// let input = b"00000000010400982f3ec112a5f5928a5c96a914bd733793b896a5000000000000053000000000000002290000c85889dad0d5b08a997a93a28a7c93eb22c324e5f8992dc93e37865ef4f3e0d65383beefeffc4871a2facbc4b590ddf887c80de6638ed4e2ec0e633d1e130f23030100000000";

let input = b"80800000000400b40723ab4d7781cf1b45083aa043ce4563006c6100000000000000010000000000000000000158be820619a4838f74e63099bb113fcf7ee13ef3b2bb56728cd19470f9379f05288d4accc987d8dd85de5101776c2ad000784d118e35deb4f02852540bf6dd5f01020000000008010101010101010101010101010101010101010101010101010101010101010109119054d8cfba5f6aebaac75b0f6671a6917211729fa7bafa35ab0ad68fe243cf4169eb339d8a26ee8e036c8380e3afd63da8aca1f9673d19a59ef00bf13e1ba2e540257d0b471fc591a877a90e04e00b";
let input = b"808000000004001dc27eba0247f8cc9575e7d45e50a0bc7e72427d000000000000001d000000000000000000011dc72b6dfd9b36e414a2709e3b01eb5bbdd158f9bc77cd2ca6c3c8b0c803613e2189f6dacf709b34e8182e99d3a1af15812b75e59357d9c255c772695998665f010200000000076f2ff2c4517ab683bf2d588727f09603cc3e9328b9c500e21a939ead57c0560af8a3a132bd7d56566f2ff2c4517ab683bf2d588727f09603cc3e932828dcefb98f6b221eef731cabec7538314441c1e0ff06b44c22085d41aae447c1000000010014ff3cb19986645fd7e71282ad9fea07d540a60e0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798000000000000000000000000000000000000000000000000000000000000000000000000";

let bytes = decode_hex(input).unwrap();
let bytes_len = bytes.len();
Expand Down
9 changes: 9 additions & 0 deletions src/stacks_tx/neon_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,15 @@ impl NeonJsSerialize for TransactionTenureChange {
obj: &Handle<JsObject>,
_extra_ctx: &(),
) -> NeonResult<()> {
let tenure_consensus_hash = cx.string(encode_hex(&self.tenure_consensus_hash));
obj.set(cx, "tenure_consensus_hash", tenure_consensus_hash)?;

let prev_tenure_consensus_hash = cx.string(encode_hex(&self.prev_tenure_consensus_hash));
obj.set(cx, "prev_tenure_consensus_hash", prev_tenure_consensus_hash)?;

let burn_view_consensus_hash = cx.string(encode_hex(&self.burn_view_consensus_hash));
obj.set(cx, "burn_view_consensus_hash", burn_view_consensus_hash)?;

let previous_tenure_end = cx.string(encode_hex(&self.previous_tenure_end));
obj.set(cx, "previous_tenure_end", previous_tenure_end)?;

Expand Down
21 changes: 12 additions & 9 deletions tests/tx-decode-3.0.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {
} from '../index.js';

test('stacks3.0 - decode tx - tenure change', () => {
const tenureChangeTx = '808000000004000f873150e9790e305b701aa8c7b3bcff9e31a5f9000000000000000000000000000000000001d367da530b92f4984f537f0b903c330eb5158262afa08d67cbbdea6c8e2ecae06008248ac147fc34101d3cc207b1b3e386e0f53732b5548bd5abe1570c2271340302000000000755c9861be5cff984a20ce6d99d4aa65941412889bdc665094136429b84f8c2ee00000001000000000000000000000000000000000000000000000000000279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817980000000000000000000000000000000000000000000000000000000000000000';
const tenureChangeTx = '808000000004001dc27eba0247f8cc9575e7d45e50a0bc7e72427d000000000000001d000000000000000000011dc72b6dfd9b36e414a2709e3b01eb5bbdd158f9bc77cd2ca6c3c8b0c803613e2189f6dacf709b34e8182e99d3a1af15812b75e59357d9c255c772695998665f010200000000076f2ff2c4517ab683bf2d588727f09603cc3e9328b9c500e21a939ead57c0560af8a3a132bd7d56566f2ff2c4517ab683bf2d588727f09603cc3e932828dcefb98f6b221eef731cabec7538314441c1e0ff06b44c22085d41aae447c1000000010014ff3cb19986645fd7e71282ad9fea07d540a60e0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798000000000000000000000000000000000000000000000000000000000000000000000000';
const decoded = decodeTransaction(tenureChangeTx);
expect(decoded).toEqual({
"tx_id": "0xc00148be5e8edb457d1bd1ae7ae5fdc2b74b64455f714d512e717deddeedf069",
"tx_id": "0xc8d48b288a780bc98602c1ed137f80d8bf4a6c60fb50cc569bee33ee7563501b",
"version": TransactionVersion.Testnet,
"chain_id": 0x80000000,
"auth": {
Expand All @@ -24,25 +24,28 @@ test('stacks3.0 - decode tx - tenure change', () => {
"hash_mode": 0,
"signer": {
"address_version": 26,
"address_hash_bytes": "0x0f873150e9790e305b701aa8c7b3bcff9e31a5f9",
"address": "ST7RECAGX5WGWC2VE0DAHHXKQKZSWCD5Z4JRG6SR"
"address_hash_bytes": "0x1dc27eba0247f8cc9575e7d45e50a0bc7e72427d",
"address": "STEW4ZNT093ZHK4NEQKX8QJGM2Y7WWJ2FQQS5C19"
},
"nonce": "0",
"nonce": "29",
"tx_fee": "0",
"key_encoding": TxPublicKeyEncoding.Compressed,
"signature": "0x01d367da530b92f4984f537f0b903c330eb5158262afa08d67cbbdea6c8e2ecae06008248ac147fc34101d3cc207b1b3e386e0f53732b5548bd5abe1570c227134"
"signature": "0x011dc72b6dfd9b36e414a2709e3b01eb5bbdd158f9bc77cd2ca6c3c8b0c803613e2189f6dacf709b34e8182e99d3a1af15812b75e59357d9c255c772695998665f"
}
},
"anchor_mode": AnchorModeID.Any,
"anchor_mode": AnchorModeID.OnChainOnly,
"post_condition_mode": PostConditionModeID.Deny,
"post_conditions": [],
"post_conditions_buffer": "0x0200000000",
"payload": {
"type_id": TxPayloadTypeID.TenureChange,
"previous_tenure_end": "0x55c9861be5cff984a20ce6d99d4aa65941412889bdc665094136429b84f8c2ee",
"tenure_consensus_hash": "0x6f2ff2c4517ab683bf2d588727f09603cc3e9328",
"prev_tenure_consensus_hash": "0xb9c500e21a939ead57c0560af8a3a132bd7d5656",
"burn_view_consensus_hash": "0x6f2ff2c4517ab683bf2d588727f09603cc3e9328",
"previous_tenure_end": "0x28dcefb98f6b221eef731cabec7538314441c1e0ff06b44c22085d41aae447c1",
"previous_tenure_blocks": 1,
"cause": TenureChangeCause.BlockFound,
"pubkey_hash": "0x0000000000000000000000000000000000000000",
"pubkey_hash": "0x14ff3cb19986645fd7e71282ad9fea07d540a60e",
"signature": "0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817980000000000000000000000000000000000000000000000000000000000000000",
"signers": "0x"
}
Expand Down