mirror of
https://github.com/alexgo-io/stacks-subnets.git
synced 2026-01-12 16:53:24 +08:00
Merge pull request #257 from hirosystems/fix/versioned-contract
fix: support versioned contract transactions
This commit is contained in:
@@ -618,6 +618,8 @@ pub enum TransactionPayloadID {
|
||||
ContractCall = 2,
|
||||
PoisonMicroblock = 3,
|
||||
Coinbase = 4,
|
||||
CoinbaseToAltRecipient = 5,
|
||||
VersionedSmartContract = 6,
|
||||
}
|
||||
|
||||
/// Encoding of an asset type identifier
|
||||
|
||||
@@ -113,6 +113,30 @@ impl StacksMessageCodec for TransactionSmartContract {
|
||||
}
|
||||
}
|
||||
|
||||
fn ClarityVersion_consensus_serialize<W: Write>(
|
||||
version: &ClarityVersion,
|
||||
fd: &mut W,
|
||||
) -> Result<(), codec_error> {
|
||||
match version {
|
||||
ClarityVersion::Clarity1 => write_next(fd, &1u8),
|
||||
ClarityVersion::Clarity2 => write_next(fd, &2u8),
|
||||
}
|
||||
}
|
||||
|
||||
fn ClarityVersion_consensus_deserialize<R: Read>(
|
||||
fd: &mut R,
|
||||
) -> Result<ClarityVersion, codec_error> {
|
||||
let version_byte: u8 = read_next(fd)?;
|
||||
match version_byte {
|
||||
1u8 => Ok(ClarityVersion::Clarity1),
|
||||
2u8 => Ok(ClarityVersion::Clarity2),
|
||||
_ => Err(codec_error::DeserializeError(format!(
|
||||
"Unrecognized ClarityVersion byte {}",
|
||||
&version_byte
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
impl StacksMessageCodec for TransactionPayload {
|
||||
fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
|
||||
match *self {
|
||||
@@ -126,9 +150,17 @@ impl StacksMessageCodec for TransactionPayload {
|
||||
write_next(fd, &(TransactionPayloadID::ContractCall as u8))?;
|
||||
cc.consensus_serialize(fd)?;
|
||||
}
|
||||
TransactionPayload::SmartContract(ref sc, _) => {
|
||||
write_next(fd, &(TransactionPayloadID::SmartContract as u8))?;
|
||||
sc.consensus_serialize(fd)?;
|
||||
TransactionPayload::SmartContract(ref sc, ref version_opt) => {
|
||||
if let Some(version) = version_opt {
|
||||
// caller requests a specific Clarity version
|
||||
write_next(fd, &(TransactionPayloadID::VersionedSmartContract as u8))?;
|
||||
ClarityVersion_consensus_serialize(&version, fd)?;
|
||||
sc.consensus_serialize(fd)?;
|
||||
} else {
|
||||
// caller requests to use whatever the current clarity version is
|
||||
write_next(fd, &(TransactionPayloadID::SmartContract as u8))?;
|
||||
sc.consensus_serialize(fd)?;
|
||||
}
|
||||
}
|
||||
TransactionPayload::PoisonMicroblock(ref h1, ref h2) => {
|
||||
write_next(fd, &(TransactionPayloadID::PoisonMicroblock as u8))?;
|
||||
@@ -160,6 +192,11 @@ impl StacksMessageCodec for TransactionPayload {
|
||||
let payload: TransactionSmartContract = read_next(fd)?;
|
||||
TransactionPayload::SmartContract(payload, None)
|
||||
}
|
||||
x if x == TransactionPayloadID::VersionedSmartContract as u8 => {
|
||||
let version = ClarityVersion_consensus_deserialize(fd)?;
|
||||
let payload: TransactionSmartContract = read_next(fd)?;
|
||||
TransactionPayload::SmartContract(payload, Some(version))
|
||||
}
|
||||
x if x == TransactionPayloadID::PoisonMicroblock as u8 => {
|
||||
let h1: StacksMicroblockHeader = read_next(fd)?;
|
||||
let h2: StacksMicroblockHeader = read_next(fd)?;
|
||||
@@ -1592,7 +1629,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tx_stacks_transacton_payload_contracts() {
|
||||
fn tx_stacks_transaction_payload_contracts() {
|
||||
let hello_contract_call = "hello-contract-call";
|
||||
let hello_contract_name = "hello-contract-name";
|
||||
let hello_function_name = "hello-function-name";
|
||||
@@ -1641,12 +1678,48 @@ mod test {
|
||||
.consensus_serialize(&mut smart_contract_bytes)
|
||||
.unwrap();
|
||||
|
||||
let mut version_1_smart_contract_bytes = vec![];
|
||||
ClarityVersion_consensus_serialize(
|
||||
&ClarityVersion::Clarity1,
|
||||
&mut version_1_smart_contract_bytes,
|
||||
)
|
||||
.unwrap();
|
||||
smart_contract
|
||||
.name
|
||||
.consensus_serialize(&mut version_1_smart_contract_bytes)
|
||||
.unwrap();
|
||||
smart_contract
|
||||
.code_body
|
||||
.consensus_serialize(&mut version_1_smart_contract_bytes)
|
||||
.unwrap();
|
||||
|
||||
let mut version_2_smart_contract_bytes = vec![];
|
||||
ClarityVersion_consensus_serialize(
|
||||
&ClarityVersion::Clarity2,
|
||||
&mut version_2_smart_contract_bytes,
|
||||
)
|
||||
.unwrap();
|
||||
smart_contract
|
||||
.name
|
||||
.consensus_serialize(&mut version_2_smart_contract_bytes)
|
||||
.unwrap();
|
||||
smart_contract
|
||||
.code_body
|
||||
.consensus_serialize(&mut version_2_smart_contract_bytes)
|
||||
.unwrap();
|
||||
|
||||
let mut transaction_contract_call = vec![TransactionPayloadID::ContractCall as u8];
|
||||
transaction_contract_call.append(&mut contract_call_bytes.clone());
|
||||
|
||||
let mut transaction_smart_contract = vec![TransactionPayloadID::SmartContract as u8];
|
||||
transaction_smart_contract.append(&mut smart_contract_bytes.clone());
|
||||
|
||||
let mut v1_smart_contract = vec![TransactionPayloadID::VersionedSmartContract as u8];
|
||||
v1_smart_contract.append(&mut version_1_smart_contract_bytes.clone());
|
||||
|
||||
let mut v2_smart_contract = vec![TransactionPayloadID::VersionedSmartContract as u8];
|
||||
v2_smart_contract.append(&mut version_2_smart_contract_bytes.clone());
|
||||
|
||||
check_codec_and_corruption::<TransactionContractCall>(&contract_call, &contract_call_bytes);
|
||||
check_codec_and_corruption::<TransactionSmartContract>(
|
||||
&smart_contract,
|
||||
@@ -1660,6 +1733,20 @@ mod test {
|
||||
&TransactionPayload::SmartContract(smart_contract.clone(), None),
|
||||
&transaction_smart_contract,
|
||||
);
|
||||
check_codec_and_corruption::<TransactionPayload>(
|
||||
&TransactionPayload::SmartContract(
|
||||
smart_contract.clone(),
|
||||
Some(ClarityVersion::Clarity1),
|
||||
),
|
||||
&v1_smart_contract,
|
||||
);
|
||||
check_codec_and_corruption::<TransactionPayload>(
|
||||
&TransactionPayload::SmartContract(
|
||||
smart_contract.clone(),
|
||||
Some(ClarityVersion::Clarity2),
|
||||
),
|
||||
&v2_smart_contract,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user