pub fn try_update_offset<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    _env: Env,
    headers: Vec<String>,
) -> StdResult<HandleResponse> {
    config(&mut deps.storage).update(|mut state| {
        // Check that the number of block header hashes passed in is large enough.
        let num_headers = u32::try_from(headers.len()).unwrap();
        if state.min_update_length > num_headers {
            return Err(StdError::GenericErr {
                msg: format!(
                    "Number of blocks provided ({}) is less than minimum required ({})",
                    num_headers, state.min_update_length
                ),
                backtrace: Option::Some(Backtrace::generate()),
            });
        }

        // The first header must reference the current hash stored by the contract.
        let mut prev_hash = state.curr_hash;

        // Verify every header.
        for header in headers.iter() {
            // Check the header length.
            if header.len() != BLOCK_HEADER_LEN {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Encoded block header length is {}, must be {}",
                        header.len(),
                        BLOCK_HEADER_LEN
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }

            // Check the difficulty bits in the header against the
            // difficulty threshold stored by the contract.
            let difficulty_bits = &header[144..144 + 8];
            let parsed_res = parse_bits(difficulty_bits);
            let parsed = match parsed_res {
                Ok(res) => res,
                Err(err) => {
                    return Err(StdError::GenericErr {
                        msg: format!(
                            "Could not parse difficulty bits \"{}\" into u32: {}",
                            difficulty_bits, err
                        ),
                        backtrace: Option::Some(Backtrace::generate()),
                    });
                }
            };
            let block_diff = bits_to_difficulty(parsed.swap_bytes());
            let thresh_diff_res = U256::from_str_radix(&state.threshold_difficulty, 16);
            let thresh_diff = match thresh_diff_res {
                Ok(res) => res,
                Err(err) => {
                    return Err(StdError::GenericErr {
                        msg: format!("Could not convert difficulty bits into U256: {}", err),
                        backtrace: Option::Some(Backtrace::generate()),
                    });
                }
            };
            if block_diff > thresh_diff {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Block difficulty {} cannot be greater than threshold {}",
                        format!("{:x}", block_diff),
                        format!("{:x}", thresh_diff)
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }

            // Check that the header references the correct previous header hash.
            let prev_block = &header[8..8 + 64];
            if prev_block != prev_hash {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Previous block header hash {} is not equal to value in header {}",
                        prev_hash, prev_block
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }

            // Compute the target hash and update the prev_hash with it.
            prev_hash = double_hash_hex(&header);

            // Check the difficulty of the target hash against the block difficulty.
            let flipped = flip_bytes_in_str(&prev_hash);
            let target_res = U256::from_str_radix(&flipped, 16);
            let target = match target_res {
                Ok(res) => res,
                Err(err) => {
                    return Err(StdError::GenericErr {
                        msg: format!(
                            "Could not convert target hash \"{}\" into U256: {}",
                            flipped, err
                        ),
                        backtrace: Option::Some(Backtrace::generate()),
                    });
                }
            };
            if target > block_diff {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Block header hash {} must be less than block difficulty {}",
                        format!("{:x}", target),
                        format!("{:x}", block_diff)
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }
        }

        state.curr_hash = prev_hash;
        state.curr_offset += num_headers;
        Ok(state)
    })?;

    // TODO: what is this for?
    Ok(HandleResponse::default())
}
// Verifies header values. If successful, updates the offset
// and the current block header hash.
Verifies header values. If successful, updates the offset
and the current block header hash.
Verifies header values . If successful updates the offset and the current block header hash .
pub fn try_update_offset<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    _env: Env,
    headers: Vec<String>,
) -> StdResult<HandleResponse> {
    config(&mut deps.storage).update(|mut state| {
        // Check that the number of block header hashes passed in is large enough.
        let num_headers = u32::try_from(headers.len()).unwrap();
        if state.min_update_length > num_headers {
            return Err(StdError::GenericErr {
                msg: format!(
                    "Number of blocks provided ({}) is less than minimum required ({})",
                    num_headers, state.min_update_length
                ),
                backtrace: Option::Some(Backtrace::generate()),
            });
        }
        // The first header must reference the current hash stored by the contract.
        let mut prev_hash = state.curr_hash;
        // Verify every header.
        for header in headers.iter() {
            // Check the header length.
            if header.len() != BLOCK_HEADER_LEN {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Encoded block header length is {}, must be {}",
                        header.len(),
                        BLOCK_HEADER_LEN
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }
            // Check the difficulty bits in the header against the
            // difficulty threshold stored by the contract.
            let difficulty_bits = &header[144..144 + 8];
            let parsed_res = parse_bits(difficulty_bits);
            let parsed = match parsed_res {
                Ok(res) => res,
                Err(err) => {
                    return Err(StdError::GenericErr {
                        msg: format!(
                            "Could not parse difficulty bits \"{}\" into u32: {}",
                            difficulty_bits, err
                        ),
                        backtrace: Option::Some(Backtrace::generate()),
                    });
                }
            };
            let block_diff = bits_to_difficulty(parsed.swap_bytes());
            let thresh_diff_res = U256::from_str_radix(&state.threshold_difficulty, 16);
            let thresh_diff = match thresh_diff_res {
                Ok(res) => res,
                Err(err) => {
                    return Err(StdError::GenericErr {
                        msg: format!("Could not convert difficulty bits into U256: {}", err),
                        backtrace: Option::Some(Backtrace::generate()),
                    });
                }
            };
            if block_diff > thresh_diff {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Block difficulty {} cannot be greater than threshold {}",
                        format!("{:x}", block_diff),
                        format!("{:x}", thresh_diff)
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }
            // Check that the header references the correct previous header hash.
            let prev_block = &header[8..8 + 64];
            if prev_block != prev_hash {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Previous block header hash {} is not equal to value in header {}",
                        prev_hash, prev_block
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }
            // Compute the target hash and update the prev_hash with it.
            prev_hash = double_hash_hex(&header);
            // Check the difficulty of the target hash against the block difficulty.
            let flipped = flip_bytes_in_str(&prev_hash);
            let target_res = U256::from_str_radix(&flipped, 16);
            let target = match target_res {
                Ok(res) => res,
                Err(err) => {
                    return Err(StdError::GenericErr {
                        msg: format!(
                            "Could not convert target hash \"{}\" into U256: {}",
                            flipped, err
                        ),
                        backtrace: Option::Some(Backtrace::generate()),
                    });
                }
            };
            if target > block_diff {
                return Err(StdError::GenericErr {
                    msg: format!(
                        "Block header hash {} must be less than block difficulty {}",
                        format!("{:x}", target),
                        format!("{:x}", block_diff)
                    ),
                    backtrace: Option::Some(Backtrace::generate()),
                });
            }
        }
        state.curr_hash = prev_hash;
        state.curr_offset += num_headers;
        Ok(state)
    })?;
    // TODO: what is this for?
    Ok(HandleResponse::default())
}
pub fn try_update_offset < S : Storage , A : Api , Q : Querier > ( deps : & mut Extern < S , A , Q > , _env : Env , headers : Vec < String > , ) -> StdResult < HandleResponse > { config ( & mut deps . storage ) . update ( | mut state | { // Check that the number of block header hashes passed in is large enough. let num_headers = u32 :: try_from ( headers . len ( ) ) . unwrap ( ) ; if state . min_update_length > num_headers { return Err ( StdError :: GenericErr { msg : format ! ( " " num_headers state min_update_length ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } // The first header must reference the current hash stored by the contract. let mut prev_hash = state . curr_hash ; // Verify every header. for header in headers . iter ( ) { // Check the header length. if header . len ( ) != BLOCK_HEADER_LEN { return Err ( StdError :: GenericErr { msg : format ! ( " " header len ( ) BLOCK_HEADER_LEN ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } // Check the difficulty bits in the header against the // difficulty threshold stored by the contract. let difficulty_bits = & header [ 144 .. 144 + 8 ] ; let parsed_res = parse_bits ( difficulty_bits ) ; let parsed = match parsed_res { Ok ( res ) => res , Err ( err ) => { return Err ( StdError :: GenericErr { msg : format ! ( " \" \" " difficulty_bits err ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } } ; let block_diff = bits_to_difficulty ( parsed . swap_bytes ( ) ) ; let thresh_diff_res = U256 :: from_str_radix ( & state . threshold_difficulty , 16 ) ; let thresh_diff = match thresh_diff_res { Ok ( res ) => res , Err ( err ) => { return Err ( StdError :: GenericErr { msg : format ! ( " " err ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } } ; if block_diff > thresh_diff { return Err ( StdError :: GenericErr { msg : format ! ( " " format ( " " block_diff ) format ( " " thresh_diff ) ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } // Check that the header references the correct previous header hash. let prev_block = & header [ 8 .. 8 + 64 ] ; if prev_block != prev_hash { return Err ( StdError :: GenericErr { msg : format ! ( " " prev_hash prev_block ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } // Compute the target hash and update the prev_hash with it. prev_hash = double_hash_hex ( & header ) ; // Check the difficulty of the target hash against the block difficulty. let flipped = flip_bytes_in_str ( & prev_hash ) ; let target_res = U256 :: from_str_radix ( & flipped , 16 ) ; let target = match target_res { Ok ( res ) => res , Err ( err ) => { return Err ( StdError :: GenericErr { msg : format ! ( " \" \" " flipped err ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } } ; if target > block_diff { return Err ( StdError :: GenericErr { msg : format ! ( " " format ( " " target ) format ( " " block_diff ) ) , backtrace : Option :: Some ( Backtrace :: generate ( ) ) , } ) ; } } state . curr_hash = prev_hash ; state . curr_offset += num_headers ; Ok ( state ) } ) ? ; // TODO: what is this for? Ok ( HandleResponse :: default ( ) ) }
Verifies header values.
Verifies header values .
deps
&mut Extern<S, A, Q>
_env
Env
headers
Vec<String>
deps
&mut Extern<S, A, Q>
_env
Env
headers
Vec<String>