KomodoPlatform / komodo-defi-framework

This is the official Komodo DeFi Framework repository
https://komodoplatform.com/en/docs/komodo-defi-framework/
102 stars 94 forks source link

Simple Payment Verification #1612

Open shamardy opened 1 year ago

shamardy commented 1 year ago

This checklist is for what still needs to be implemented to complete SPV implementation

borngraced commented 1 year ago

LITECOIN DIFFCULTY CHECK

Both Litecoin and Bitcoin retarget their mining difficulty every 2016 blocks. However, due to the 4x faster block speed for Litecoin, mining difficulty retargets occur approximately every 3.5 days. This compares to approximately every 14 days for Bitcoin. — https://en.wikipedia.org/wiki/Litecoin#Differences_from_Bitcoin

hence, here are the required configs needed for LTC

/// LTC_TARGET_TIMESPAN_SECONDS is 1/5 of BTC_TARGET_TIMESPAN_SECONDS, so
const LTC_TARGET_TIMESPAN_SECONDS: u32 = 3.5 * 24 * 60 * 60;
const LTC_MIN_TIMESPAN: u32 = LTC_TARGET_TIMESPAN_SECONDS / RETARGETING_FACTOR;
const LTC_MAX_TIMESPAN: u32 = LTC_TARGET_TIMESPAN_SECONDS* RETARGETING_FACTOR;

will keep updating for rest PoW chains cc. @shamardy

shamardy commented 1 year ago

@borngraced did you try a full chain headers sync for LTC with this config? Did it work fine, no problems with headers deserializations, etc...?

borngraced commented 1 year ago

@borngraced did you try a full chain headers sync for LTC with this config? Did it work fine, no problems with headers deserializations, etc...?

yes!, all positive :}

borngraced commented 1 year ago

SPV lib refactoring idea https://github.com/KomodoPlatform/atomicDEX-API/tree/dev/mm2src/mm2_bitcoin/spv_validation.

This will def get complicated as more chains are added to SPV so I have some ideas for refactoring this lib for flexibility.

sample demonstration code


#[async_trait]
pub trait DifficultyCheckOps {
    async fn calculate_next_block_bits(
        coin: &str,
        last_block_header: SPVBlockHeader,
        storage: &dyn BlockHeaderStorageOps,
    ) -> Result<BlockHeaderBits, NextBlockBitsError>;

    async fn retarget_bits(
        coin: &str,
        current_block_timestamp: u32,
        last_block_header: SPVBlockHeader,
        storage: &dyn BlockHeaderStorageOps,
        algorithm: &DifficultyAlgorithm,
    ) -> Result<BlockHeaderBits, NextBlockBitsError>;
}

pub mod chains {
    pub mod litecoin {
        use crate::helpers_validation::DifficultyCheckOps;
        use crate::work::{DifficultyAlgorithm, NextBlockBitsError};
        use chain::BlockHeaderBits;

        pub struct LitecoinDifficulty;

        impl LitecoinDifficulty {
            pub fn new() -> Self { Self }
        }

        impl DifficultyCheckOps for LitecoinDifficulty {
            async fn calculate_next_block_bits(
                algorithm: &DifficultyAlgorithm,
                coin: &str,
                last_block_header: SPVBlockHeader,
                storage: &dyn BlockHeaderStorageOps,
            ) -> Result<BlockHeaderBits, NextBlockBitsError> {
                match algorithm {
                    DifficultyAlgorithm::LitecoinDifficulty => {
                        todo!()
                    },
                    DifficultyAlgorithm::LitecoinTestnet => {
                        todo!()
                    },
                    _ => {},
                }
            }

            async fn retarget_bits(
                coin: &str,
                current_block_timestamp: u32,
                last_block_header: SPVBlockHeader,
                storage: &dyn BlockHeaderStorageOps,
                algorithm: &DifficultyAlgorithm,
            ) -> Result<BlockHeaderBits, NextBlockBitsError> {
                match algorithm {
                    DifficultyAlgorithm::LitecoinDifficulty => {
                        todo!()
                    },
                    DifficultyAlgorithm::LitecoinTestnet => {
                        todo!()
                    },
                    _ => {},
                }
            }
        }
    }

    pub mod btc {}
    pub mod zcash {}
}

pub async fn _next_block_bits(
    coin: &str,
    current_block_timestamp: u32,
    last_block_header: SPVBlockHeader,
    storage: &dyn BlockHeaderStorageOps,
    algorithm: &DifficultyAlgorithm,
) -> Result<BlockHeaderBits, NextBlockBitsError> {
    match algorithm {
        DifficultyAlgorithm::BitcoinMainnet => BitcoinDifficulty::calculate_next_block_bits(
            algorithm,
            coin,
            current_block_timestamp,
            last_block_header,
            storage,
        ),
        DifficultyAlgorithm::BitcoinTestnet => {
            BitcoinDifficulty::calculate_next_block_bits(
                algorithm,
                coin,
                current_block_timestamp,
                last_block_header,
                storage,
            )
            .await
        },
        DifficultyAlgorithm::LitecoinDifficulty => {
            LitecoinDifficulty::calculate_next_block_bits(
                algorithm,
                coin,
                current_block_timestamp,
                last_block_header,
                storage,
            )
            .await
        },
        DifficultyAlgorithm::LitecoinTestnet => {
            LitecoinDifficulty::calculate_next_block_bits(
                algorithm,
                coin,
                current_block_timestamp,
                last_block_header,
                storage,
            )
            .await
        },
    }
}

cc. @shamardy

borngraced commented 1 year ago

SPV is now working in WASM again and can be re-enabled for BTC cc. @tonymorony @ca33 @shamardy

shamardy commented 1 year ago

remove and move https://github.com/KomodoPlatform/atomicDEX-API/tree/dev/mm2src/mm2_bitcoin/spv_validation lib from mm2-bitcoin to mm2src.

not all spv_validation lib will need to be moved since there are parts that are utxo specific, I get the confusion that this crate is called mm2-bitcoin, it should be renamed mm2_utxo since it includes some common implementations for all utxo coins. Only the block headers storage part will need to be moved if it will be used for other non-utxo coins too but I don't think we will start spv implementation for non-utxos now.

In general, I think this refactor needs to be done gradually (with every new added difficulty algorithm), in the example you provided you assumed the LitecoinDifficulty is different from btc but they use the same calculations so adding LTC as a next step shouldn't need a lot of refactoring as discussed in DM before.

SPV is now working in WASM again and can be re-enabled for BTC

@smk762 @cipig @ca333 since this is a long feature implementation I think we shouldn't enable spv for BTC yet (WASM or otherwise), although it's working. The reason behind this is the coin config can change again since we want a generic spv config for all coins and it changes with each new coin addition, so this might require coin config changes with each new PR. We can re-enable spv once the implementation has settled on a unified spv coin config.

cipig commented 1 year ago

@smk762 @cipig @ca333 since this is a long feature implementation I think we shouldn't enable spv for BTC yet (WASM or otherwise), although it's working. The reason behind this is the coin config can change again since we want a generic spv config for all coins and it changes with each new coin addition, so this might require coin config changes with each new PR. We can re-enable spv once the implementation has settled on a unified spv coin config.

BTC has "enable_spv_proof": true in coins file atm: https://github.com/KomodoPlatform/coins/blob/master/coins#L1819 should i do a PR and set it to false?

shamardy commented 1 year ago

should i do a PR and set it to false?

Just remove the field entirely

shamardy commented 1 year ago

For more details @cipig, I tried a complete BTC headers sync in WASM after this PR was merged and it took a very long time, that's why we will use a recent header (maybe a month old or something) in the config in the future to sync the headers faster, this is how the spv config looks currently https://github.com/KomodoPlatform/atomicDEX-API/issues/1483#issuecomment-1425642620.