ido: migrate to bitcoincash 0.32 script API; fix mempool diff
Update ido/mod.rs for the bitcoincash 0.32 API: Script -> ScriptBuf, push_slice via &PushBytes (new pb() helper), as_byte_array/as_bytes. Fix update_mempool to diff against cauldron_txs instead of defi_txs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
edf7955a23
commit
a410aee95f
2 changed files with 96 additions and 88 deletions
|
|
@ -3,7 +3,7 @@ use anyhow::Result;
|
|||
use log::{info,warn,debug};
|
||||
use num_bigint::{BigInt, Sign};
|
||||
use num_traits::{Zero, ToPrimitive};
|
||||
use bitcoincash::blockdata::script::{Builder, Script, Instruction};
|
||||
use bitcoincash::blockdata::script::{Builder, Script, ScriptBuf, Instruction, PushBytes};
|
||||
use bitcoincash::blockdata::opcodes;
|
||||
use bitcoin_hashes::sha256d;
|
||||
use bitcoin_hashes::Hash;
|
||||
|
|
@ -322,40 +322,46 @@ pub enum IdoState {
|
|||
Distributed(IdoDistributedState),
|
||||
}
|
||||
|
||||
fn build_p2nfth_script(nfthash: &[u8]) -> Script {
|
||||
/// Convert a byte slice into a `&PushBytes` for use with `Builder::push_slice`.
|
||||
/// bitcoincash 0.32 requires `AsRef<PushBytes>` rather than a raw `&[u8]`.
|
||||
fn pb(data: &[u8]) -> &PushBytes {
|
||||
data.try_into().expect("push slice exceeds maximum length")
|
||||
}
|
||||
|
||||
fn build_p2nfth_script(nfthash: &[u8]) -> ScriptBuf {
|
||||
let mut bytes = Builder::new()
|
||||
.push_slice(nfthash)
|
||||
.push_slice(pb(nfthash))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
bytes.extend_from_slice(&P2NFTH_CONTRACT);
|
||||
Script::from(bytes)
|
||||
ScriptBuf::from(bytes)
|
||||
}
|
||||
|
||||
fn build_storage_script(governingOutpointIndex: u32) -> Script {
|
||||
fn build_storage_script(governingOutpointIndex: u32) -> ScriptBuf {
|
||||
let mut bytes = Builder::new()
|
||||
.push_slice(&encode_padded_vm_number(&BigInt::from(governingOutpointIndex), 2).unwrap())
|
||||
.push_slice(pb(&encode_padded_vm_number(&BigInt::from(governingOutpointIndex), 2).unwrap()))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
bytes.extend_from_slice(&STORAGE_CONTRACT);
|
||||
Script::from(bytes)
|
||||
ScriptBuf::from(bytes)
|
||||
}
|
||||
|
||||
fn build_storage_script_with_data_and_size(governingOutpointIndex: u32, data: &[u8]) -> Script {
|
||||
fn build_storage_script_with_data_and_size(governingOutpointIndex: u32, data: &[u8]) -> ScriptBuf {
|
||||
let mut data_and_size = Vec::new();
|
||||
data_and_size.extend_from_slice(data);
|
||||
data_and_size.extend_from_slice(&encode_padded_vm_number(&BigInt::from(data.len()), 2).unwrap());
|
||||
let mut bytes = Builder::new()
|
||||
.push_slice(&encode_padded_vm_number(&BigInt::from(governingOutpointIndex), 2).unwrap())
|
||||
.push_slice(pb(&encode_padded_vm_number(&BigInt::from(governingOutpointIndex), 2).unwrap()))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
bytes.extend_from_slice(&STORAGE_CONTRACT);
|
||||
let suffix = Builder::new()
|
||||
.push_slice(&data_and_size)
|
||||
.push_slice(pb(&data_and_size))
|
||||
.push_opcode(opcodes::all::OP_DROP)
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
bytes.extend_from_slice(&suffix);
|
||||
Script::from(bytes)
|
||||
ScriptBuf::from(bytes)
|
||||
}
|
||||
|
||||
fn extract_data_from_storage_script_with_data_and_size(script: &Script) -> Result<Vec<u8>> {
|
||||
|
|
@ -365,7 +371,7 @@ fn extract_data_from_storage_script_with_data_and_size(script: &Script) -> Resul
|
|||
return Err(anyhow::anyhow!("storage with data should have at least two instructions"));
|
||||
}
|
||||
match &inst_list[n - 2] {
|
||||
Ok(Instruction::PushBytes(data)) => Ok(data[0..data.len()-2].to_vec()),
|
||||
Ok(Instruction::PushBytes(data)) => { let data = data.as_bytes(); Ok(data[0..data.len()-2].to_vec()) },
|
||||
_ => Err(anyhow::anyhow!("storage with data should have a push opcode at instructions[count - 2]")),
|
||||
}
|
||||
}
|
||||
|
|
@ -377,7 +383,7 @@ fn extract_data_from_unlocking_bytecode_of_storage_with_data_and_size(unlocking_
|
|||
}
|
||||
match &instructions[1] {
|
||||
Ok(Instruction::PushBytes(redeem_bytecode)) => {
|
||||
extract_data_from_storage_script_with_data_and_size(&Script::from(redeem_bytecode.to_vec()))
|
||||
extract_data_from_storage_script_with_data_and_size(Script::from_bytes(redeem_bytecode.as_bytes()))
|
||||
},
|
||||
_ => Err(anyhow::anyhow!("invalid unlocking bytecode, p2sh redeem script push opcode is expected")),
|
||||
}
|
||||
|
|
@ -387,6 +393,7 @@ fn has_script_ido_signature(unlocking_bytecode: &Script) -> bool {
|
|||
let instructions: Vec<_> = unlocking_bytecode.instructions().collect();
|
||||
match instructions.last() {
|
||||
Some(Ok(Instruction::PushBytes(redeem_bytecode))) => {
|
||||
let redeem_bytecode = redeem_bytecode.as_bytes();
|
||||
redeem_bytecode.len() >= IDO_SIGNATURE.len() &&
|
||||
&redeem_bytecode[0..IDO_SIGNATURE.len()] == IDO_SIGNATURE
|
||||
},
|
||||
|
|
@ -396,8 +403,8 @@ fn has_script_ido_signature(unlocking_bytecode: &Script) -> bool {
|
|||
|
||||
fn build_offering_bytecode(maxDiscountRate: &BigInt, discountAnnualRate: &BigInt, price: &BigInt, minOffer: &BigInt, xTokenCategory: &[u8]) -> Vec<u8> {
|
||||
let mut input_bytecode = Builder::new()
|
||||
.push_slice(&STORAGE_CONTRACT)
|
||||
.push_slice(&OFFERING_ENTRY_CONTRACT)
|
||||
.push_slice(pb(&STORAGE_CONTRACT))
|
||||
.push_slice(pb(&OFFERING_ENTRY_CONTRACT))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
input_bytecode.extend_from_slice(&bigint_to_push_opcode(maxDiscountRate));
|
||||
|
|
@ -405,7 +412,7 @@ fn build_offering_bytecode(maxDiscountRate: &BigInt, discountAnnualRate: &BigInt
|
|||
input_bytecode.extend_from_slice(&bigint_to_push_opcode(price));
|
||||
input_bytecode.extend_from_slice(&bigint_to_push_opcode(minOffer));
|
||||
input_bytecode.extend_from_slice(&Builder::new()
|
||||
.push_slice(xTokenCategory)
|
||||
.push_slice(pb(xTokenCategory))
|
||||
.into_script()
|
||||
.to_bytes()
|
||||
);
|
||||
|
|
@ -418,14 +425,14 @@ fn build_offering_bytecode(maxDiscountRate: &BigInt, discountAnnualRate: &BigInt
|
|||
fn build_launcher_bytecode(collectorNFTH: &[u8], platformFeeNFTH: &[u8], platformFee: &BigInt, delphiCategory: &[u8], expiresAt: &BigInt, deployThreshold: &BigInt, immediateDeployThreshold: &BigInt) -> Vec<u8> {
|
||||
let rev_delphi_cat: Vec<u8> = delphiCategory.iter().copied().rev().collect();
|
||||
let mut input_bytecode = Builder::new()
|
||||
.push_slice(collectorNFTH)
|
||||
.push_slice(platformFeeNFTH)
|
||||
.push_slice(&encode_padded_vm_number(&platformFee, 4).unwrap())
|
||||
.push_slice(&EXECUTION_FEE_PAYOUT_CONTRACT)
|
||||
.push_slice(&STORAGE_CONTRACT)
|
||||
.push_slice(&OFFERING_INTEGRATED_TIMELOCKED_P2NFTH_CONTRACT)
|
||||
.push_slice(&P2NFTH_CONTRACT)
|
||||
.push_slice(&rev_delphi_cat)
|
||||
.push_slice(pb(collectorNFTH))
|
||||
.push_slice(pb(platformFeeNFTH))
|
||||
.push_slice(pb(&encode_padded_vm_number(&platformFee, 4).unwrap()))
|
||||
.push_slice(pb(&EXECUTION_FEE_PAYOUT_CONTRACT))
|
||||
.push_slice(pb(&STORAGE_CONTRACT))
|
||||
.push_slice(pb(&OFFERING_INTEGRATED_TIMELOCKED_P2NFTH_CONTRACT))
|
||||
.push_slice(pb(&P2NFTH_CONTRACT))
|
||||
.push_slice(pb(&rev_delphi_cat))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
input_bytecode.extend_from_slice(&bigint_to_push_opcode(expiresAt));
|
||||
|
|
@ -439,7 +446,7 @@ fn build_launcher_bytecode(collectorNFTH: &[u8], platformFeeNFTH: &[u8], platfor
|
|||
|
||||
fn build_partial_offering_initiator_bytecode(extensionOutpointIndex: &BigInt, tokenStorageOutpointIndex: &BigInt, offeringBcmrStorageOutpointIndex: &BigInt, distRefundOutpointIndex: &BigInt, distDeployOutpointIndex: &BigInt, launcherBytecodeOutpointIndex: &BigInt, offeringBytecodeOutpointIndex: &BigInt, executionFee: &BigInt) -> Vec<u8> {
|
||||
let mut bytecode = Builder::new()
|
||||
.push_slice(&STORAGE_CONTRACT)
|
||||
.push_slice(pb(&STORAGE_CONTRACT))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
bytecode.extend_from_slice(&bigint_to_push_opcode(extensionOutpointIndex));
|
||||
|
|
@ -465,9 +472,9 @@ fn build_partial_postlaunch_bytecode(permanentLiquidityShare: &BigInt, price: &B
|
|||
|
||||
fn build_partial_ido_initiator_bytecode(postLaunchPartialBytecode: &[u8], permanentPoolOTokenReserveOutpointIndex: &BigInt, offeringInitiatorOutpointIndex: &BigInt) -> Vec<u8> {
|
||||
let mut bytecode = Builder::new()
|
||||
.push_slice(postLaunchPartialBytecode)
|
||||
.push_slice(&STORAGE_CONTRACT)
|
||||
.push_slice(&P2NFTH_CONTRACT)
|
||||
.push_slice(pb(postLaunchPartialBytecode))
|
||||
.push_slice(pb(&STORAGE_CONTRACT))
|
||||
.push_slice(pb(&P2NFTH_CONTRACT))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
bytecode.extend_from_slice(&bigint_to_push_opcode(permanentPoolOTokenReserveOutpointIndex));
|
||||
|
|
@ -481,17 +488,17 @@ fn create_rebuild_ipfs_placeholder_bcmr_partial_inputs(data: &IpfsBcmrWithPlaceh
|
|||
bcmrUrisWithReplaceCalls.extend_from_slice(&data.metadata.bcmrUrisReplaceCalls);
|
||||
bcmrUrisWithReplaceCalls.extend_from_slice(
|
||||
&Builder::new()
|
||||
.push_slice(&data.urisBytecode)
|
||||
.push_slice(pb(&data.urisBytecode))
|
||||
.into_script()
|
||||
.to_bytes()
|
||||
);
|
||||
Builder::new()
|
||||
.push_slice(&data.contentHash)
|
||||
.push_slice(&data.metadata.registryReplaceCalls)
|
||||
.push_slice(pb(&data.contentHash))
|
||||
.push_slice(pb(&data.metadata.registryReplaceCalls))
|
||||
.push_int(1i64)
|
||||
// OP_DEFINE
|
||||
.push_opcode(bitcoincash::blockdata::opcodes::All::from(0x89u8))
|
||||
.push_slice(&bcmrUrisWithReplaceCalls)
|
||||
.push_slice(pb(&bcmrUrisWithReplaceCalls))
|
||||
.push_int(2i64)
|
||||
// OP_DEFINE
|
||||
.push_opcode(bitcoincash::blockdata::opcodes::All::from(0x89u8))
|
||||
|
|
@ -512,14 +519,14 @@ fn build_preinit_bytecode(parameters: &IdoPreInitLockParameters, state: &IdoPreI
|
|||
};
|
||||
|
||||
let middle = Builder::new()
|
||||
.push_slice(&rev_ido)
|
||||
.push_slice(&rev_authguard)
|
||||
.push_slice(¶meters.authguardLockingBytecode)
|
||||
.push_slice(&offering_bcmr_partial_inputs)
|
||||
.push_slice(&oToken_bcmr_partial_inputs)
|
||||
.push_slice(&REBUILD_IPFS_PLACEHOLDER_BCMR_FOR_GENESIS_WITH_AUTHGUARD_CONTRACT)
|
||||
.push_slice(&CASHTOKENS_STUDIO_PAY2CATEGORY_CONTRACT)
|
||||
.push_slice(&STORAGE_CONTRACT)
|
||||
.push_slice(pb(&rev_ido))
|
||||
.push_slice(pb(&rev_authguard))
|
||||
.push_slice(pb(¶meters.authguardLockingBytecode))
|
||||
.push_slice(pb(&offering_bcmr_partial_inputs))
|
||||
.push_slice(pb(&oToken_bcmr_partial_inputs))
|
||||
.push_slice(pb(&REBUILD_IPFS_PLACEHOLDER_BCMR_FOR_GENESIS_WITH_AUTHGUARD_CONTRACT))
|
||||
.push_slice(pb(&CASHTOKENS_STUDIO_PAY2CATEGORY_CONTRACT))
|
||||
.push_slice(pb(&STORAGE_CONTRACT))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
let mut bytecode = IDO_SIGNATURE.to_vec();
|
||||
|
|
@ -533,10 +540,10 @@ fn build_preinit_bytecode(parameters: &IdoPreInitLockParameters, state: &IdoPreI
|
|||
bytecode
|
||||
}
|
||||
|
||||
fn build_p2sh32_script(bytecode: &[u8]) -> Script {
|
||||
fn build_p2sh32_script(bytecode: &[u8]) -> ScriptBuf {
|
||||
Builder::new()
|
||||
.push_opcode(opcodes::all::OP_HASH256)
|
||||
.push_slice(sha256d::Hash::hash(bytecode).as_inner())
|
||||
.push_slice(pb(sha256d::Hash::hash(bytecode).as_byte_array()))
|
||||
.push_opcode(opcodes::all::OP_EQUAL)
|
||||
.into_script()
|
||||
}
|
||||
|
|
@ -545,7 +552,7 @@ fn build_p2sh32_script(bytecode: &[u8]) -> Script {
|
|||
fn build_p2sh20_script(bytecode: &[u8]) -> Script {
|
||||
Builder::new()
|
||||
.push_opcode(opcodes::all::OP_HASH160)
|
||||
.push_slice(hash160::Hash::hash(bytecode).as_inner())
|
||||
.push_slice(pb(hash160::Hash::hash(bytecode).as_byte_array()))
|
||||
.push_opcode(opcodes::all::OP_EQUAL)
|
||||
.into_script()
|
||||
}
|
||||
|
|
@ -957,19 +964,19 @@ fn deserialize_ipfs_bcmr_with_placeholder(
|
|||
return Err(anyhow::anyhow!("bcmr needs metadata!"));
|
||||
}
|
||||
let metadata_size = bcmr_data[0].to_usize().unwrap();
|
||||
let metadata_script = Script::from(bcmr_data[1..(metadata_size+1)].to_vec());
|
||||
let metadata_script = ScriptBuf::from(bcmr_data[1..(metadata_size+1)].to_vec());
|
||||
let metadata_inst_list: Vec<_> = metadata_script.instructions().collect();
|
||||
if metadata_inst_list.len() != 2 {
|
||||
return Err(anyhow::anyhow!("bcmr metadata should have two push opcodes!"));
|
||||
}
|
||||
let registryReplaceCalls = match &metadata_inst_list[0] {
|
||||
Ok(Instruction::PushBytes(data)) => data.to_vec(),
|
||||
Ok(Instruction::PushBytes(data)) => data.as_bytes().to_vec(),
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!("oToken bcmr metadata opcode#0 is not a push opcode"));
|
||||
}
|
||||
};
|
||||
let bcmrUrisReplaceCalls = match &metadata_inst_list[1] {
|
||||
Ok(Instruction::PushBytes(data)) => data.to_vec(),
|
||||
Ok(Instruction::PushBytes(data)) => data.as_bytes().to_vec(),
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!("oToken bcmr metadata opcode#0 is not a push opcode"));
|
||||
}
|
||||
|
|
@ -995,8 +1002,8 @@ fn serialize_ipfs_bcmr_with_placeholder(
|
|||
match input {
|
||||
Some(value) => {
|
||||
let metadata_bytecode = Builder::new()
|
||||
.push_slice(&value.metadata.registryReplaceCalls)
|
||||
.push_slice(&value.metadata.bcmrUrisReplaceCalls)
|
||||
.push_slice(pb(&value.metadata.registryReplaceCalls))
|
||||
.push_slice(pb(&value.metadata.bcmrUrisReplaceCalls))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
let mut bcmr_bytecode = Vec::new();
|
||||
|
|
@ -1004,7 +1011,7 @@ fn serialize_ipfs_bcmr_with_placeholder(
|
|||
bcmr_bytecode.extend_from_slice(&value.contentHash);
|
||||
bcmr_bytecode.extend_from_slice(&value.urisBytecode);
|
||||
let metadata_push = Builder::new()
|
||||
.push_slice(&metadata_bytecode)
|
||||
.push_slice(pb(&metadata_bytecode))
|
||||
.into_script()
|
||||
.to_bytes();
|
||||
let mut bytes = Vec::new();
|
||||
|
|
@ -1056,7 +1063,7 @@ fn parse_ido_preinit_tx_params(tx: &Transaction, delphi_token_id: &[u8], platfor
|
|||
let authguardLockingBytecode;
|
||||
match &instructions[2] {
|
||||
Ok(Instruction::PushBytes(data)) => {
|
||||
authguardLockingBytecode = data.to_vec();
|
||||
authguardLockingBytecode = data.as_bytes().to_vec();
|
||||
}
|
||||
_ => {
|
||||
errors.push(anyhow::anyhow!("invalid announcement (3)"));
|
||||
|
|
@ -1066,6 +1073,7 @@ fn parse_ido_preinit_tx_params(tx: &Transaction, delphi_token_id: &[u8], platfor
|
|||
// params main
|
||||
match &instructions[1] {
|
||||
Ok(Instruction::PushBytes(data)) => {
|
||||
let data = data.as_bytes();
|
||||
if data.len() < 187 {
|
||||
errors.push(anyhow::anyhow!("Incorrect announcement.mainData size"));
|
||||
return None;
|
||||
|
|
@ -1505,7 +1513,7 @@ fn parse_ido_preinit_tx(network: Option<Network>, tx: &Transaction, errors: &mut
|
|||
if build_p2sh32_script(
|
||||
&build_p2nfth_script(&platform_fee_nfth).to_bytes()
|
||||
) == output.script_pubkey {
|
||||
preinit_paid_fee += output.value;
|
||||
preinit_paid_fee += output.value.to_sat();
|
||||
}
|
||||
}
|
||||
if BigInt::from(preinit_paid_fee) < *IDO_CREATE_EXECUTION_FEE {
|
||||
|
|
@ -1538,7 +1546,7 @@ fn create_ido_context_from_preinit(network: Option<Network>, tx: &Transaction, e
|
|||
let params = result.parameters.expect("parameters should be defined!");
|
||||
let state = result.state.expect("state should be defined!");
|
||||
Ok(IdoContext {
|
||||
preinit_txid: tx.txid().to_blob(),
|
||||
preinit_txid: tx.compute_txid().to_blob(),
|
||||
init_txid: None,
|
||||
launch_txid: None,
|
||||
otoken_genesis_txid: None,
|
||||
|
|
@ -1549,7 +1557,7 @@ fn create_ido_context_from_preinit(network: Option<Network>, tx: &Transaction, e
|
|||
offered_token_id: result.offered_token_id,
|
||||
offering_token_id: None,
|
||||
is_token_created_at_preinit: !result.offered_token_is_in_supply,
|
||||
head_txid: tx.txid().to_blob(),
|
||||
head_txid: tx.compute_txid().to_blob(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1560,18 +1568,18 @@ async fn on_create_ido(
|
|||
tx: &Transaction,
|
||||
block_height: i64,
|
||||
) -> Result<()> {
|
||||
debug!("IDO on_create_ido: {}", blob_to_display_hex::<Txid>(&tx.txid())?);
|
||||
debug!("IDO on_create_ido: {}", blob_to_display_hex::<Txid>(&tx.compute_txid().to_blob())?);
|
||||
let mut errors: Vec<Error> = Vec::new();
|
||||
let mut invalid_ido_reasons: Vec<Error> = Vec::new();
|
||||
let result = create_ido_context_from_preinit(network, tx, &mut errors, &mut invalid_ido_reasons);
|
||||
if errors.len() > 0 {
|
||||
info!("Parse ido preinit failed, txid: {}\nError(s):", hex::encode(tx.txid().to_blob()));
|
||||
info!("Parse ido preinit failed, txid: {}\nError(s):", hex::encode(tx.compute_txid().to_blob()));
|
||||
for error in errors {
|
||||
info!(" - {}", error);
|
||||
}
|
||||
}
|
||||
if invalid_ido_reasons.len() > 0 {
|
||||
info!("Invalid ido found, preinit_txid: {}\nReason(s):", hex::encode(tx.txid().to_blob()));
|
||||
info!("Invalid ido found, preinit_txid: {}\nReason(s):", hex::encode(tx.compute_txid().to_blob()));
|
||||
for reason in invalid_ido_reasons {
|
||||
info!(" - {}", reason);
|
||||
}
|
||||
|
|
@ -1725,12 +1733,12 @@ fn ido_add_tx(
|
|||
if preinit_state.initiatorCreated {
|
||||
// init outputs created & init tx
|
||||
updates.push(IdoUpdate::Status("ACTIVE".to_string()));
|
||||
updates.push(IdoUpdate::InitTxId(tx.txid().to_blob()));
|
||||
updates.push(IdoUpdate::InitTxId(tx.compute_txid().to_blob()));
|
||||
let launcherBytecodeIn = tx.input.get(2)
|
||||
.ok_or_else(|| anyhow::anyhow!("launcher bytecode storage does not exist!"))?;
|
||||
let launcher_data = extract_data_from_unlocking_bytecode_of_storage_with_data_and_size(&launcherBytecodeIn.script_sig)
|
||||
.map_err(|e| anyhow::anyhow!("failed to extract launcher bytecode: {e}"))?;
|
||||
let launcher_script = Script::from(launcher_data);
|
||||
let launcher_script = ScriptBuf::from(launcher_data);
|
||||
let launcher_inst_list: Vec<_> = launcher_script.instructions().collect();
|
||||
let collectorNFTH: Vec<u8>;
|
||||
if launcher_inst_list.len() == 0 {
|
||||
|
|
@ -1738,7 +1746,7 @@ fn ido_add_tx(
|
|||
}
|
||||
match &launcher_inst_list[2] {
|
||||
Ok(Instruction::PushBytes(data)) => {
|
||||
collectorNFTH = data.to_vec();
|
||||
collectorNFTH = data.as_bytes().to_vec();
|
||||
}
|
||||
_ => return Err(anyhow::anyhow!("expecting push opcode for collectorNFTH")),
|
||||
}
|
||||
|
|
@ -1786,7 +1794,7 @@ fn ido_add_tx(
|
|||
next_state.authguardCategory = context.head_txid.iter().copied().rev().collect();
|
||||
} else if preinit_state.oTokenGenerated == BigInt::from(0) {
|
||||
next_state.oTokenGenerated = BigInt::from(1);
|
||||
updates.push(IdoUpdate::OTokenGenesisTxId(tx.txid().to_blob()));
|
||||
updates.push(IdoUpdate::OTokenGenesisTxId(tx.compute_txid().to_blob()));
|
||||
} else if !preinit_state.idoCategory.iter().any(|&b| b != 0) {
|
||||
next_state.idoCategory = context.head_txid.iter().copied().rev().collect();
|
||||
}
|
||||
|
|
@ -1841,7 +1849,7 @@ fn ido_add_tx(
|
|||
}
|
||||
match &instructions[0] {
|
||||
Ok(Instruction::PushBytes(data)) => {
|
||||
owner_nfthash = data.to_vec();
|
||||
owner_nfthash = data.as_bytes().to_vec();
|
||||
},
|
||||
_ => return Err(anyhow::anyhow!("OP_PUSH expected in the unlocking bytecode of the offering utxo!")),
|
||||
}
|
||||
|
|
@ -1852,9 +1860,9 @@ fn ido_add_tx(
|
|||
return Err(anyhow::anyhow!("Incorrect commitment size at output#1"));
|
||||
}
|
||||
updates.push(IdoUpdate::Entry(IdoUpdateEntry {
|
||||
txid: tx.txid().to_blob(),
|
||||
txid: tx.compute_txid().to_blob(),
|
||||
owner_nfthash: owner_nfthash,
|
||||
supply_amount: second_output.value,
|
||||
supply_amount: second_output.value.to_sat(),
|
||||
demand_amount: second_output.token.as_ref().unwrap().amount as u64,
|
||||
lockup_timeval: decode_padded_vm_number(&second_output.token.as_ref().unwrap().commitment[1..7]).to_u64().unwrap_or(0),
|
||||
discount: decode_padded_vm_number(&second_output.token.as_ref().unwrap().commitment[7..15]).to_u64().unwrap_or(0),
|
||||
|
|
@ -1874,7 +1882,7 @@ fn ido_add_tx(
|
|||
return Err(anyhow::anyhow!("Incorrect commitment size at output#0"));
|
||||
}
|
||||
updates.push(IdoUpdate::Status("DISTRIBUTING".to_string()));
|
||||
updates.push(IdoUpdate::LaunchTxId(tx.txid().to_blob()));
|
||||
updates.push(IdoUpdate::LaunchTxId(tx.compute_txid().to_blob()));
|
||||
updates.push(IdoUpdate::State(
|
||||
IdoState::Distributing(IdoDistributingState {
|
||||
authguardCategory: active_state.authguardCategory.clone(),
|
||||
|
|
@ -1896,7 +1904,7 @@ fn ido_add_tx(
|
|||
return Err(anyhow::anyhow!("Incorrect commitment size at output#0"));
|
||||
}
|
||||
updates.push(IdoUpdate::Status("POSTLAUNCH".to_string()));
|
||||
updates.push(IdoUpdate::LaunchTxId(tx.txid().to_blob()));
|
||||
updates.push(IdoUpdate::LaunchTxId(tx.compute_txid().to_blob()));
|
||||
updates.push(IdoUpdate::State(
|
||||
IdoState::PostLaunch(IdoPostLaunchState {
|
||||
authguardCategory: active_state.authguardCategory.clone(),
|
||||
|
|
@ -1965,7 +1973,7 @@ fn ido_add_tx(
|
|||
earnedAmount: decode_padded_vm_number(&dist_commitment[11..19]),
|
||||
refundAmount: decode_padded_vm_number(&dist_commitment[19..27]),
|
||||
discountAmount: decode_padded_vm_number(&dist_commitment[27..35]),
|
||||
platformEarnedAmount: &prev_state.platformEarnedAmount + BigInt::from(platform_fee_output.value),
|
||||
platformEarnedAmount: &prev_state.platformEarnedAmount + BigInt::from(platform_fee_output.value.to_sat()),
|
||||
})
|
||||
));
|
||||
} else if (first_output.token.as_ref().unwrap().commitment[0] & ITEM_TYPE_BITS) == ITEM_TYPE_CONFIRMATION_NFT {
|
||||
|
|
@ -1984,7 +1992,7 @@ fn ido_add_tx(
|
|||
earnedAmount: decode_padded_vm_number(&conf_commitment[7..15]),
|
||||
refundAmount: decode_padded_vm_number(&conf_commitment[15..23]),
|
||||
discountAmount: decode_padded_vm_number(&conf_commitment[23..31]),
|
||||
platformEarnedAmount: &prev_state.platformEarnedAmount + BigInt::from(platform_fee_output.value),
|
||||
platformEarnedAmount: &prev_state.platformEarnedAmount + BigInt::from(platform_fee_output.value.to_sat()),
|
||||
})
|
||||
));
|
||||
} else {
|
||||
|
|
@ -2015,18 +2023,18 @@ fn ido_add_tx(
|
|||
tokenAmount: BigInt::from(pp_output.token.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("pp should have tokens"))?
|
||||
.amount),
|
||||
satoshiAmount: BigInt::from(pp_output.value),
|
||||
satoshiAmount: BigInt::from(pp_output.value.to_sat()),
|
||||
}) },
|
||||
refundAmount: BigInt::from(collector_p2nfth.token.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("collector_p2nfth should have tokens"))?
|
||||
.amount),
|
||||
discountAmount: prev_state.discountAmount.clone(),
|
||||
collectorEarnedAmount: BigInt::from(collector_p2nfth.value),
|
||||
collectorEarnedAmount: BigInt::from(collector_p2nfth.value.to_sat()),
|
||||
platformEarnedAmount: prev_state.platformEarnedAmount.clone(),
|
||||
})
|
||||
));
|
||||
updates.push(IdoUpdate::EntryDistributed {
|
||||
txid: tx.txid().to_blob(),
|
||||
txid: tx.compute_txid().to_blob(),
|
||||
});
|
||||
print_updates(&updates);
|
||||
return Ok(IdoAddResult {
|
||||
|
|
@ -2170,7 +2178,7 @@ async fn upsert_ido_txchain(
|
|||
)
|
||||
.bind(prev_txchain_id)
|
||||
.bind(internal_id)
|
||||
.bind(tx.txid().to_blob())
|
||||
.bind(tx.compute_txid().to_blob())
|
||||
.bind(serialized_tx)
|
||||
.execute(&mut **dbtx)
|
||||
.await?;
|
||||
|
|
@ -2180,7 +2188,7 @@ async fn upsert_ido_txchain(
|
|||
"REPLACE INTO ido_txchain_tracker_map (txid, next_output_index, height, txchain_id) VALUES
|
||||
(?, ?, ?, ?)"
|
||||
)
|
||||
.bind(tx.txid().to_blob())
|
||||
.bind(tx.compute_txid().to_blob())
|
||||
.bind(next_output_index)
|
||||
.bind(block_height)
|
||||
.bind(txchain_item_id)
|
||||
|
|
@ -2200,7 +2208,7 @@ async fn update_ido_txchain_tracker_block_height(
|
|||
"UPDATE ido_txchain_tracker_map SET height = ? WHERE txid = ?"
|
||||
)
|
||||
.bind(block_height)
|
||||
.bind(tx.txid().to_blob())
|
||||
.bind(tx.compute_txid().to_blob())
|
||||
.execute(&mut **dbtx)
|
||||
.await?;
|
||||
Ok(())
|
||||
|
|
@ -2214,16 +2222,16 @@ async fn on_add_ido_tx(
|
|||
tx: &Transaction,
|
||||
block_height: i64,
|
||||
) -> Result<()> {
|
||||
debug!("IDO on_add_ido_tx: {}", blob_to_display_hex::<Txid>(&tx.txid())?);
|
||||
debug!("IDO on_add_ido_tx: {}", blob_to_display_hex::<Txid>(&tx.compute_txid().to_blob())?);
|
||||
let mut dbtx = pool.begin().await?;
|
||||
let current_item = get_txchain_item_by_txid(pool, &tx.txid())
|
||||
let current_item = get_txchain_item_by_txid(pool, &tx.compute_txid())
|
||||
.await?;
|
||||
if current_item.is_some() && Some(current_item.unwrap().id) == ido.txchain_head {
|
||||
// already added, only update block height
|
||||
update_ido_txchain_tracker_block_height(&mut dbtx, tx, block_height)
|
||||
.await?;
|
||||
} else if prev_txchain_item.id != ido.txchain_head.unwrap_or(0) {
|
||||
debug!("IDO rebuild: {}, prev: {}", blob_to_display_hex::<Txid>(&tx.txid())?, blob_to_display_hex::<Txid>(&prev_txchain_item.txid)?);
|
||||
debug!("IDO rebuild: {}, prev: {}", blob_to_display_hex::<Txid>(&tx.compute_txid().to_blob())?, blob_to_display_hex::<Txid>(&prev_txchain_item.txid)?);
|
||||
// rebuild the state, txchain is broken, recreate the chain
|
||||
let items = get_ido_txchain_list(pool, ido.internal_id)
|
||||
.await?;
|
||||
|
|
@ -2256,13 +2264,13 @@ async fn on_add_ido_tx(
|
|||
let item_tx = items_tx_map.get(&item.txid).ok_or_else(|| anyhow::anyhow!("txchain tx not found in map"))?;
|
||||
// add tx
|
||||
let result = ido_add_tx(&context, item_tx)?;
|
||||
context.head_txid = item_tx.txid().to_blob();
|
||||
context.head_txid = item_tx.compute_txid().to_blob();
|
||||
apply_updates_to_context(&mut context, &result.updates);
|
||||
updates.extend_from_slice(&result.updates);
|
||||
}
|
||||
// add the tx to the chain
|
||||
let result = ido_add_tx(&context, tx)?;
|
||||
context.head_txid = tx.txid().to_blob();
|
||||
context.head_txid = tx.compute_txid().to_blob();
|
||||
apply_updates_to_context(&mut context, &result.updates);
|
||||
updates.extend_from_slice(&result.updates);
|
||||
let txchain_item_id = upsert_ido_txchain(&mut dbtx, tx, ido.internal_id, Some(prev_txchain_item.id), block_height, result.next_output_index)
|
||||
|
|
@ -2301,7 +2309,7 @@ async fn on_add_ido_tx(
|
|||
};
|
||||
// add to the chain
|
||||
let result = ido_add_tx(&context, tx)?;
|
||||
context.head_txid = tx.txid().to_blob();
|
||||
context.head_txid = tx.compute_txid().to_blob();
|
||||
apply_updates_to_context(&mut context, &result.updates);
|
||||
let txchain_item_id = upsert_ido_txchain(&mut dbtx, tx, ido.internal_id, Some(prev_txchain_item.id), block_height, result.next_output_index)
|
||||
.await?;
|
||||
|
|
@ -2335,8 +2343,8 @@ async fn index_txs(
|
|||
for tx in sorted_txs {
|
||||
// detect a new ido
|
||||
if is_preinit_broadcast(tx) {
|
||||
debug!("IDO index preinit: {}", blob_to_display_hex::<Txid>(&tx.txid())?);
|
||||
if lookup_internal_id_by_preinit_txid(pool, &tx.txid().to_blob()).await?.is_some() {
|
||||
debug!("IDO index preinit: {}", blob_to_display_hex::<Txid>(&tx.compute_txid().to_blob())?);
|
||||
if lookup_internal_id_by_preinit_txid(pool, &tx.compute_txid().to_blob()).await?.is_some() {
|
||||
// already created (eg. indexed from the mempool), only update block height
|
||||
let mut dbtx = pool.begin().await?;
|
||||
update_ido_txchain_tracker_block_height(&mut dbtx, tx, block_height)
|
||||
|
|
@ -2346,11 +2354,11 @@ async fn index_txs(
|
|||
}
|
||||
match on_create_ido(network, pool, tx, block_height)
|
||||
.await {
|
||||
Err(err) => info!("failed to detect an ido, or an invalid ido detected, txid: {}, {}", hex::encode(tx.txid().to_blob()), err),
|
||||
Err(err) => info!("failed to detect an ido, or an invalid ido detected, txid: {}, {}", hex::encode(tx.compute_txid().to_blob()), err),
|
||||
_ => (),
|
||||
}
|
||||
} else if is_ido_sig_in_tx_inputs(tx) {
|
||||
debug!("IDO tx to index: {}", blob_to_display_hex::<Txid>(&tx.txid())?);
|
||||
debug!("IDO tx to index: {}", blob_to_display_hex::<Txid>(&tx.compute_txid().to_blob())?);
|
||||
// has ido sig
|
||||
for input_index in [ 0, 1, 3 ] {
|
||||
let input = tx.input.get(input_index);
|
||||
|
|
@ -2368,7 +2376,7 @@ async fn index_txs(
|
|||
Ok(Some(ido)) => {
|
||||
match on_add_ido_tx(network, pool, &ido, &txchain_item, tx, block_height)
|
||||
.await {
|
||||
Err(err) => info!("add tx to an ido failed, txid: {}, {}", hex::encode(tx.txid().to_blob()), err),
|
||||
Err(err) => info!("add tx to an ido failed, txid: {}, {}", hex::encode(tx.compute_txid().to_blob()), err),
|
||||
_ => (),
|
||||
}
|
||||
},
|
||||
|
|
@ -2521,13 +2529,13 @@ mod tests {
|
|||
let network = Some(Network::Chipnet);
|
||||
let result = parse_ido_preinit_tx(network, &tx, &mut errors, &mut invalid_ido_reasons);
|
||||
if errors.len() > 0 {
|
||||
debug!("Parse ido preinit failed, txid: {}\nError(s):", hex::encode(tx.txid().to_blob()));
|
||||
debug!("Parse ido preinit failed, txid: {}\nError(s):", hex::encode(tx.compute_txid().to_blob()));
|
||||
for error in &errors {
|
||||
debug!(" - {}", error);
|
||||
}
|
||||
}
|
||||
if invalid_ido_reasons.len() > 0 {
|
||||
debug!("Invalid ido found, preinit_txid: {}\nReason(s):", hex::encode(tx.txid().to_blob()));
|
||||
debug!("Invalid ido found, preinit_txid: {}\nReason(s):", hex::encode(tx.compute_txid().to_blob()));
|
||||
for reason in &invalid_ido_reasons {
|
||||
debug!(" - {}", reason);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ pub async fn update_mempool(
|
|||
})
|
||||
.await??;
|
||||
|
||||
let txs_to_delete: Vec<Txid> = our_mempool_txs.difference(&defi_txs).cloned().collect();
|
||||
let txs_to_add: Vec<&Txid> = defi_txs.difference(&our_mempool_txs).collect();
|
||||
let txs_to_delete: Vec<Txid> = our_mempool_txs.difference(&cauldron_txs).cloned().collect();
|
||||
let txs_to_add: Vec<&Txid> = cauldron_txs.difference(&our_mempool_txs).collect();
|
||||
|
||||
let electrum_for_fetch = electrum.clone();
|
||||
let txids_to_fetch: Vec<Txid> = txs_to_add.iter().map(|t| **t).collect();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue