bool zerotime_lock::decode(data_buffer & buffer)
{
    /**
     * Decode the version.
     */
    m_version = buffer.read_uint32();

    assert(m_version == current_version);

    /**
     * Decode the transaction.
     */
    m_transaction.decode(buffer);

    /**
     * Decode the transaction hash.
     */
    buffer.read_bytes(
        reinterpret_cast<char *> (m_hash_tx.digest()), sha256::digest_length
    );

    assert(m_transaction.get_hash() == m_hash_tx);

    /**
     * Decode the expiration.
     */
    m_expiration = buffer.read_uint64();

    /**
     * Enforce the expiration.
     */
    if (
        m_expiration < time::instance().get_adjusted() + interval_min_expire ||
        m_expiration > time::instance().get_adjusted() + interval_max_expire
    )
    {
        m_expiration = time::instance().get_adjusted() + interval_min_expire;
    }

    /**
     * No signature is required because:
     * 1. The receiver may want to lock a non-zerotime transaction.
     * 2. It causes no harm to let other's lock the transaction.
     * 3. It conserves bandwidth and processing power.
     */

    return m_transaction.get_hash() == m_hash_tx;
}
Beispiel #2
0
bool db_wallet::read_key_value(
    wallet & w, data_buffer & buffer_key,
    data_buffer & buffer_value, std::int32_t & file_version,
    std::vector<sha256> & wallet_upgrade, bool & is_encrypted,
    bool & any_unordered, std::string & type, std::string & err
    )
 {
    type.clear();
    type.resize(buffer_key.read_var_int());
    
    buffer_key.read_bytes(
        const_cast<char *> (type.data()), type.size()
    );

    if (type == "name")
    {
        std::string addr;
        
        auto len = buffer_key.read_var_int();
        
        if (len > 0)
        {
            addr.resize(len);
            
            buffer_key.read_bytes(
                const_cast<char *> (addr.data()), addr.size()
            );
        }
        
        std::string value;
        
        len = buffer_value.read_var_int();
        
        if (len > 0)
        {
            value.resize(len);
            
            buffer_value.read_bytes(
                const_cast<char *> (value.data()), value.size()
            );
        }
        
        w.address_book()[address(addr).get()] = value;
    }
    else if (type == "tx")
    {
        sha256 hash = buffer_key.read_sha256();

        auto & wtx = w.transactions()[hash];
        
        wtx.decode(buffer_value);

        if (wtx.get_hash() == hash)
        {
            wtx.bind_wallet(w);
        }
        else
        {
            w.transactions().erase(hash);
            
            return false;
        }

        /**
         * Undo serialize changes in 31600.
         */
        if (
            31404 <= wtx.time_received_is_tx_time() &&
            wtx.time_received_is_tx_time() <= 31703
            )
        {
            if (buffer_value.remaining() > 0)
            {
                char tmp;
                char unused;
                
                buffer_value.read_bytes(&tmp, sizeof(tmp));
                buffer_value.read_bytes(&unused, sizeof(unused));
                
                wtx.from_account().clear();
                wtx.from_account().resize(buffer_value.read_var_int());
                
                buffer_value.read_bytes(
                    const_cast<char *> (wtx.from_account().data()),
                    wtx.from_account().size()
                );
                
                wtx.set_time_received_is_tx_time(tmp);
            }
            else
            {
                wtx.set_time_received_is_tx_time(0);
            }
            
            wallet_upgrade.push_back(hash);
        }

        if (wtx.order_position() == -1)
        {
            any_unordered = true;
        }
    }
    else if (type == "acentry")
    {
        std::string acct;
        
        auto len = buffer_key.read_var_int();
        
        if (len > 0)
        {
            acct.resize(len);
            
            buffer_key.read_bytes(
                const_cast<char *> (acct.data()), acct.size()
            );
        }
        
        std::uint64_t entry_number = buffer_key.read_uint64();
        
        if (entry_number > g_accounting_entry_number)
        {
            g_accounting_entry_number = entry_number;
        }
        
        if (any_unordered == false)
        {
            accounting_entry entry;
            
            entry.decode(buffer_value);
            
            if (entry.order_position() == -1)
            {
                any_unordered = true;
            }
        }
    }
    else if (type == "key" || type == "wkey")
    {
        std::vector<std::uint8_t> pub_key;
        
        auto len_public_key = buffer_key.read_var_int();
        
        if (len_public_key > 0)
        {
            pub_key.resize(len_public_key);
            
            buffer_key.read_bytes(
                reinterpret_cast<char *>(&pub_key[0]), pub_key.size()
            );
        }
        
        key k;
        
        if (type == "key")
        {
            key::private_t pkey;
            
            auto len_private_key = buffer_value.read_var_int();
            
            if (len_private_key > 0)
            {
                pkey.resize(len_private_key);
                
                buffer_value.read_bytes(
                    reinterpret_cast<char *>(&pkey[0]), pkey.size()
                );
            }
            
            k.set_public_key(pub_key);
            
            if (k.set_private_key(pkey) == false)
            {
                err = "private key is corrupt";
                
                return false;
            }
            if (k.get_public_key() != pub_key)
            {
                err = "public key inconsistency";
                
                return false;
            }
            if (k.is_valid() == false)
            {
                err = "invalid private key";
                
                return false;
            }
        }
        else
        {
            key_wallet wkey;
            
            wkey.decode(buffer_value);
            
            k.set_public_key(pub_key);
            
            if (k.set_private_key(wkey.key_private()) == false)
            {
                err = "private key is corrupt";
                
                return false;
            }
            
            if (k.get_public_key() != pub_key)
            {
                err = "public key inconsistency";
                
                return false;
            }
            
            if (k.is_valid() == false)
            {
                err = "invalid wallet key";
                
                return false;
            }
        }
        
        if (w.load_key(k) == false)
        {
            err = "load key failed";
            
            return false;
        }
    }
    else if (type == "mkey")
    {
        auto id = buffer_key.read_uint32();
        
        key_wallet_master master_key;
        
        master_key.decode(buffer_value);
        
        if (w.master_keys().count(id) != 0)
        {
            err = "duplicate master key id " + std::to_string(id);
            
            return false;
        }
        
        w.master_keys()[id] = master_key;
        
        if (w.master_key_max_id() < id)
        {
            w.set_master_key_max_id(id);
        }
    }
    else if (type == "ckey")
    {
        std::vector<std::uint8_t> pub_key;
        
        auto len = buffer_key.read_var_int();
        
        if (len > 0)
        {
            pub_key.resize(len);
            buffer_key.read_bytes(
                reinterpret_cast<char *> (&pub_key[0]), pub_key.size()
            );
        }
        
        std::vector<std::uint8_t> pri_key;
        
        len = buffer_value.read_var_int();
        
        if (len > 0)
        {
            pri_key.resize(len);
            buffer_value.read_bytes(
                reinterpret_cast<char *> (&pri_key[0]), pri_key.size()
            );
        }
        
        if (w.load_crypted_key(pub_key, pri_key) == false)
        {
            err = "load crypted key failed";
            
            return false;
        }
        
        is_encrypted = true;
    }
    else if (type == "defaultkey")
    {
        /**
         * Allocate the default public key.
         */
        key_public key_public_default;

        /**
         * Decode the default public key.
         */
        if (key_public_default.decode(buffer_value))
        {
            /**
             * Set the default public key.
             */
            w.set_key_public_default(key_public_default);
        }
    }
    else if (type == "pool")
    {
        auto index = buffer_key.read_int64();
        
        w.get_key_pool().insert(index);
    }
    else if (type == "version")
    {
        file_version = buffer_value.read_uint32();
        
        if (file_version == 10300)
        {
            file_version = 300;
        }
    }
    else if (type == "cscript")
    {
        auto digest = buffer_key.read_bytes(ripemd160::digest_length);
    
        auto len = buffer_value.read_var_int();
        
        if (len > 0)
        {
            script s(len);
            
            buffer_value.read_bytes(reinterpret_cast<char *> (&s[0]), s.size());

            if (w.load_c_script(s) == false)
            {
                err = "load c script failed";
                
                return false;
            }
        }
    }
    else if (type == "orderposnext")
    {
        std::int64_t order_position_next = buffer_value.read_int64();
        
        w.set_order_position_next(order_position_next);
    }

    return true;
}
bool incentive_collaterals::decode(data_buffer & buffer)
{
    /**
     * Decode the version.
     */
    m_version = buffer.read_uint32();
    
    assert(m_version == current_version);
    
    /**
     * Read the number of collateral entries.
     */
    auto count = buffer.read_var_int();
    
    /**
     * Read each collateral entry.
     */
    for (auto i = 0; i < count; i++)
    {
        address_manager::recent_endpoint_t collateral;
        
        /**
         * Read the address.
         */
        collateral.addr = buffer.read_network_address(false, true);
        
        auto len = buffer.read_var_int();
        
        collateral.wallet_address.resize(len);
        
        /**
         * Read the wallet address.
         */
        buffer.read_bytes(
            const_cast<char *> (collateral.wallet_address.data()),
            collateral.wallet_address.size()
        );
        
        /**
         * Read the public key.
         */
        collateral.public_key.decode(buffer);
        
        /**
         * Read the transaction_in.
         */
        collateral.tx_in.decode(buffer);
        
        /**
         * Read the time.
         */
        collateral.time = buffer.read_uint64();
        
        /**
         * Read the protocol version.
         */
        collateral.protocol_version = buffer.read_uint32();
        
        /**
         * Read the protocol version user agent length.
         */
        len = buffer.read_var_int();
        
        collateral.protocol_version_user_agent.resize(len);
        
        /**
         * Read the protocol version user agent.
         */
        buffer.read_bytes(
            const_cast<char *> (collateral.protocol_version_user_agent.data()),
            collateral.protocol_version_user_agent.size()
        );
        
        /**
         * Read the protocol version services.
         */
        collateral.protocol_version_services = buffer.read_uint64();
        
        /**
         * Read the protocol version start height.
         */
        collateral.protocol_version_start_height = buffer.read_int32();
        
        m_collaterals.insert(collateral);
    }
    
    return true;
}