Skip to content

Commit

Permalink
feat: update to latest TenureChange wire-format (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
zone117x authored Dec 13, 2023
1 parent ee78a5d commit 8e44b2d
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 28 deletions.
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

0 comments on commit 8e44b2d

Please sign in to comment.