示例#1
0
void token::issue( account_name to, asset quantity, string memo )
{
    auto sym = quantity.symbol;
    eosio_assert( sym.is_valid(), "invalid symbol name" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );

    auto sym_name = sym.name();
    stats statstable( _self, sym_name );
    auto existing = statstable.find( sym_name );
    eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
    const auto& st = *existing;

    require_auth( st.issuer );
    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must issue positive quantity" );

    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");

    statstable.modify( st, 0, [&]( auto& s ) {
       s.supply += quantity;
    });

    add_balance( st.issuer, quantity, st.issuer );

    if( to != st.issuer ) {
       SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} );
    }
}
    /// @brief
    /// Change knight battle stage
    /// @param from
    /// Player who requested change stage
    /// @param knt
    /// Knight type
    /// @param stage
    /// Stage code
    void setkntstage(name from, uint8_t stage) {
        require_auth(from);

        auto stagerule = stage_rule_controller.get_table().find(stage);
        assert_true(stagerule != stage_rule_controller.get_table().cend(), "no stage rule");

        int minlv = stagerule->lvfrom;
        bool pass = false;
        
        auto iter = knights.find(from);
        assert_true(iter != knights.cend(), "could not found knight");
        auto &rows = iter->rows;

        for (auto iter = rows.cbegin(); iter != rows.cend(); iter++) {
            auto &knight = *iter;
            if (knight.level >= minlv) {
                pass = true;
                break;
            }
        }

        assert_true(pass, "no one exceed stage minmium level");
        auto &players = player_controller.get_players();
        auto player = players.find(from);

        players.modify(player, self, [&](auto& target) {
            target.current_stage = stage;
        });
    }
    /// @brief
    /// Equip item
    /// @param to
    /// Knight who you want to equip the item
    /// @param id
    /// Target item id
    void equip(name from, uint8_t to, uint32_t id) {
        require_auth(from);
        assert_true(to > 0 && to < kt_count, "invalid knight type");

        auto item_iter = item_controller.find(from);
        auto &rows = item_controller.get_items(item_iter);
        auto &item = item_controller.get_item(rows, id);
        assert_true(item.saleid == 0, "item is on sale");

        auto &rule_table = item_controller.get_ritem_rule().get_table();
        auto rule = rule_table.find(item.code);
        assert_true(rule != rule_table.cend(), "could not find rule");
        assert_true(is_valid_for((knight_type)to, (item_sub_type)rule->sub_type), "it's invalid knight to attach");

        auto knt_iter = knights.find(from);
        assert_true(knt_iter != knights.cend(), "could not found knight");
        auto &knight = get_knight(knt_iter, to);
        assert_true(rule->min_level <= knight.level, "not enough knight level to equip item");

        for (int index = 0; index < rows.size(); index++) {
            if (rows[index].knight != to) {
                continue;
            }

            auto itr_rule = rule_table.find(rows[index].code);
            assert_true(itr_rule != rule_table.cend(), "could not find target item rule");
            if (itr_rule->type == rule->type) {
                item_controller.set_item_knight(item_iter, rows[index].id, 0);
                break;
            }
        }

        item_controller.set_item_knight(item_iter, id, to);
        refresh_stat(from, to);
    }
示例#4
0
文件: voting.cpp 项目: BestSilent/eos
   void system_contract::regproxy( const account_name proxy ) {
      require_auth( proxy );

      voters_table voters_tbl( _self, _self );
      auto proxy_it = voters_tbl.find( proxy );
      if ( proxy_it != voters_tbl.end() ) {
         eosio_assert( proxy_it->is_proxy == 0, "account is already a proxy" );
         eosio_assert( proxy_it->proxy == 0, "account that uses a proxy is not allowed to become a proxy" );
         voters_tbl.modify( proxy_it, 0, [&](voter_info& a) {
               a.is_proxy = 1;
               a.last_update = now();
               //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value
            });
         if ( 0 < proxy_it->proxied_votes ) {
            producers_table producers_tbl( _self, _self );
            for ( auto p : proxy_it->producers ) {
               auto prod = producers_tbl.find( p );
               eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption
               producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy_it->proxied_votes; });
            }
         }
      } else {
         voters_tbl.emplace( proxy, [&]( voter_info& a ) {
               a.owner = proxy;
               a.last_update = now();
               a.proxy = 0;
               a.is_proxy = 1;
               a.proxied_votes = 0;
               a.staked.amount = 0;
            });
      }
   }
示例#5
0
         static void on( const undelegatebw& del ) {
            eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" );
            eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" );

            auto total_stake = del.unstake_cpu_quantity + del.unstake_net_quantity;
            eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" );

            require_auth( del.from );

            del_bandwidth_index_type     del_index( SystemAccount, del.from );
            total_resources_index_type   total_index( SystemAccount, del.receiver );

            //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );

            const auto& dbw = del_index.get(del.receiver);
            eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" );
            eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" );

            del_index.update( dbw, del.from, [&]( auto& dbo ){
               dbo.net_weight -= del.unstake_net_quantity;
               dbo.cpu_weight -= del.unstake_cpu_quantity;

            });

            const auto& totals = total_index.get( del.receiver );
            total_index.update( totals, 0, [&]( auto& tot ) {
               tot.total_net_weight -= del.unstake_net_quantity;
               tot.total_cpu_weight -= del.unstake_cpu_quantity;
            });

            set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 );

            /// TODO: implement / enforce time delays on withdrawing
            currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" );
         } // undelegatebw
示例#6
0
文件: voting.cpp 项目: BestSilent/eos
   void system_contract::unregprod( const account_name producer ) {
      require_auth( producer );

      producers_table producers_tbl( _self, _self );
      auto prod = producers_tbl.find( producer );
      eosio_assert( prod != producers_tbl.end(), "producer not found" );

      producers_tbl.modify( prod, 0, [&]( producer_info& info ){
            info.packed_key.clear();
         });
   }
    /// @brief
    /// Detach item
    /// @param id
    /// Target item id
    void detach(name from, uint32_t id) {
        require_auth(from);

        auto iter = item_controller.find(from);
        auto &rows = item_controller.get_items(iter);
        auto &item = item_controller.get_item(rows, id);
        int8_t knight = item.knight;

        item_controller.set_item_knight(iter, id, 0);
        refresh_stat(from, knight);
    }
示例#8
0
         ACTION( SystemAccount, voteproducer ) {
            account_name                voter;
            account_name                proxy;
            std::vector<account_name>   producers;

            EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) )
         };

         /**
          *  @pre vp.producers must be sorted from lowest to highest
          *  @pre if proxy is set then no producers can be voted for
          *  @pre every listed producer or proxy must have been previously registered
          *  @pre vp.voter must authorize this action
          *  @pre voter must have previously staked some EOS for voting
          */
         static void on( const voteproducer& vp ) {
            eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" );
            eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" );
            if( vp.proxy != 0 ) eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" );

            require_auth( vp.voter );

            account_votes_index_type avotes( SystemAccount, SystemAccount );
            const auto& existing = avotes.get( vp.voter );

            std::map<account_name, pair<uint128_t, uint128_t> > producer_vote_changes;

            uint128_t old_weight = existing.staked.quantity; /// old time
            uint128_t new_weight = old_weight; /// TODO: update for current weight

            for( const auto& p : existing.producers )
               producer_vote_changes[p].first = old_weight;
            for( const auto& p : vp.producers ) 
               producer_vote_changes[p].second = new_weight;

            producer_votes_index_type votes( SystemAccount, SystemAccount );
            for( const auto& delta : producer_vote_changes ) {
               if( delta.second.first != delta.second.second ) {
                  const auto& provote = votes.get( delta.first );
                  votes.update( provote, 0, [&]( auto& pv ){
                     pv.total_votes -= delta.second.first;
                     pv.total_votes += delta.second.second;
                  });
               }
            }

            avotes.update( existing, 0, [&]( auto& av ) {
              av.proxy = vp.proxy;
              av.last_update = now();
              av.producers = vp.producers;
            });
         }
示例#9
0
文件: voting.cpp 项目: BestSilent/eos
   void system_contract::decrease_voting_power( account_name acnt, const eosio::asset& amount ) {
      require_auth( acnt );
      voters_table voters_tbl( _self, _self );
      auto voter = voters_tbl.find( acnt );
      eosio_assert( voter != voters_tbl.end(), "stake not found" );

      if ( 0 < amount.amount ) {
         eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" );
         voters_tbl.modify( voter, 0, [&](voter_info& a) {
               a.staked -= amount;
               a.last_update = now();
            });

         const std::vector<account_name>* producers = nullptr;
         if ( voter->proxy ) {
            auto proxy = voters_tbl.find( voter->proxy );
            voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= uint64_t(amount.amount); } );
            if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers
               producers = &proxy->producers;
            }
         } else {
            producers = &voter->producers;
         }

         if ( producers ) {
            producers_table producers_tbl( _self, _self );
            for( auto p : *producers ) {
               auto prod = producers_tbl.find( p );
               eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption
               producers_tbl.modify( prod, 0, [&]( auto& v ) {
                     v.total_votes -= uint64_t(amount.amount);
                  });
            }
         }
      } else {
         if (voter->deferred_trx_id) {
            //XXX cancel_deferred_transaction(voter->deferred_trx_id);
         }
         voters_tbl.modify( voter, 0, [&](voter_info& a) {
               a.staked += a.unstaking;
               a.unstaking.amount = 0;
               a.unstake_per_week.amount = 0;
               a.deferred_trx_id = 0;
               a.last_update = now();
            });
      }
   }
示例#10
0
         /**
          *  This method will create a producr_config and producer_votes object for 'producer' 
          *
          *  @pre producer is not already registered
          *  @pre producer to register is an account
          *  @pre authority of producer to register 
          *  
          */
         static void on( const regproducer& reg ) {
            auto producer = reg.producer;
            require_auth( producer );

            producer_votes_index_type votes( SystemAccount, SystemAccount );
            const auto* existing = votes.find( producer );
            eosio_assert( !existing, "producer already registered" );

            votes.emplace( producer, [&]( auto& pv ){
               pv.owner       = producer;
               pv.total_votes = 0;
            });

            producer_config_index_type proconfig( SystemAccount, SystemAccount );
            proconfig.emplace( producer, [&]( auto& pc ) {
               pc.owner      = producer;
               pc.packed_key = reg.producer_key;
            });
         }
示例#11
0
         ACTION( SystemAccount, stakevote ) {
            account_name      voter;
            system_token_type amount;

            EOSLIB_SERIALIZE( stakevote, (voter)(amount) )
         };

         static void on( const stakevote& sv ) {
            print( "on stake vote\n" );
            eosio_assert( sv.amount.quantity > 0, "must stake some tokens" );
            require_auth( sv.voter );

            account_votes_index_type avotes( SystemAccount, SystemAccount );

            const auto* acv = avotes.find( sv.voter );
            if( !acv ) {
               acv = &avotes.emplace( sv.voter, [&]( auto& av ) {
                 av.owner = sv.voter;
                 av.last_update = now();
                 av.proxy = 0;
               });
            }

            uint128_t old_weight = acv->staked.quantity;
            uint128_t new_weight = old_weight + sv.amount.quantity;

            producer_votes_index_type votes( SystemAccount, SystemAccount );

            for( auto p : acv->producers ) {
               votes.update( votes.get( p ), 0, [&]( auto& v ) {
                  v.total_votes -= old_weight;
                  v.total_votes += new_weight;
               });
            }

            avotes.update( *acv, 0, [&]( auto av ) {
               av.last_update = now();
               av.staked += sv.amount;
            });
            
            currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" );
         }
示例#12
0
void token::create( account_name issuer,
                    asset        maximum_supply )
{
    require_auth( _self );

    auto sym = maximum_supply.symbol;
    eosio_assert( sym.is_valid(), "invalid symbol name" );
    eosio_assert( maximum_supply.is_valid(), "invalid supply");
    eosio_assert( maximum_supply.amount > 0, "max-supply must be positive");

    stats statstable( _self, sym.name() );
    auto existing = statstable.find( sym.name() );
    eosio_assert( existing == statstable.end(), "token with symbol already exists" );

    statstable.emplace( _self, [&]( auto& s ) {
       s.supply.symbol = maximum_supply.symbol;
       s.max_supply    = maximum_supply;
       s.issuer        = issuer;
    });
}
    /// @brief
    /// level up knight. it will decrease powder.
    /// @param from
    /// Player who requested level up action
    /// @param type
    /// knight who you want to level up
    void lvupknight(name from, uint8_t type) {
        require_auth(from);
        assert_true(type > 0 && type < kt_count, "invalid knight type");

        auto iter = knights.find(from);
        assert_true(iter != knights.cend(), "could not found knight");
        auto &knight = get_knight(iter, type);

        auto player = player_controller.get_player(from);
        assert_true(player_controller.is_empty_player(player) == false, "could not find player");

        uint64_t level = knight.level + 1;
        assert_true(level <= kv_max_knight_level, "already max level");

        auto &rule_table = knight_level_rule_controller.get_table();
        auto rule = rule_table.find(level);
        assert_true(rule != rule_table.cend(), "there is no level rule");

        int powder = rule->powder;
        assert_true(knight.kill_count >= rule->exp, "Insufficient exp");
        assert_true(powder <= player->powder, "Insufficient powder");

        if (powder > 0) {
            player_controller.decrease_powder(player, powder);
        }

        knights.modify(iter, self, [&](auto& target) {
            for (int index = 0; index < target.rows.size(); index++) {
                if (target.rows[index].type == type) {
                    target.rows[index].level = level;
                    
                    auto stat = calculate_stat(from, knight);
                    target.rows[index].attack = stat.attack;
                    target.rows[index].defense = stat.defense;
                    target.rows[index].hp = stat.hp;
                    target.rows[index].luck = stat.luck;
                    break;
                }
            }
        });
    }
示例#14
0
文件: voting.cpp 项目: BestSilent/eos
   void system_contract::unregproxy( const account_name proxy ) {
      require_auth( proxy );

      voters_table voters_tbl( _self, _self );
      auto proxy_it = voters_tbl.find( proxy );
      eosio_assert( proxy_it != voters_tbl.end(), "proxy not found" );
      eosio_assert( proxy_it->is_proxy == 1, "account is not a proxy" );

      voters_tbl.modify( proxy_it, 0, [&](voter_info& a) {
            a.is_proxy = 0;
            a.last_update = now();
            //a.proxied_votes should be kept in order to be able to reenable this proxy in the future
         });

      if ( 0 < proxy_it->proxied_votes ) {
         producers_table producers_tbl( _self, _self );
         for ( auto p : proxy_it->producers ) {
            auto prod_it = producers_tbl.find( p );
            eosio_assert( prod_it != producers_tbl.end(), "never existed producer" ); //data corruption
            producers_tbl.modify( prod_it, 0, [&]( auto& pi ) { pi.total_votes -= proxy_it->proxied_votes; });
         }
      }
   }
示例#15
0
文件: dice.cpp 项目: dwj1979/eos
void apply_offer( const offer_bet& offer ) {
   eos_assert( offer.amount > 0, "insufficient bet" );
   eos_assert( !hasOffer( offer.commitment ), "offer with this commitment already exist" );
   require_auth( offer.player );

   auto acnt = get_account( offer.player );
   acnt.balance -= offer.amount;
   acnt.open_offers++;
   save( acnt );

   /**
    *  1. Lookup lowerbound on offer's by offer_primary_key
    *     if lowerbound.primary.bet == offer.bet
    *          global_dice.nextgameid++  (load and save to DB)
    *          create new game and set game.bet == offer.bet
    *          set player1 == lowerbound player
    *          set player2 == offer.player
    *          update lowerbound.primary.bet = 0 and lwoerbound.gameid = global_dice.nextgameid
    *          Create offer entry in offers table with bet = 0 and gameid == --^
    *     else      
    *          Create offer entry in offers table with bet = offer.bet and gameid = 0
    */
}
示例#16
0
void token::transfer( account_name from,
                      account_name to,
                      asset        quantity,
                      string       memo )
{
    eosio_assert( from != to, "cannot transfer to self" );
    require_auth( from );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );

    require_recipient( from );
    require_recipient( to );

    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );


    sub_balance( from, quantity );
    add_balance( to, quantity, from );
}
    /// @brief
    /// Rebirth all knights.
    /// @param from
    /// Player who requested rebirth
    void rebirth(name from) {
        require_auth(from);

        auto iter = knights.find(from);
        assert_true(iter != knights.cend(), "can not found knight");
        auto &rows = iter->rows;

        int old_total_kill;
        for (int index = 0; index < rows.size(); index++) {
            old_total_kill += rows[index].kill_count;
        }

        auto &players = player_controller.get_players();
        auto player = players.find(from);
        assert_true(players.cend() != player, "could not find player");

        int total_kill_count = 0;
        auto &mats = material_controller.get_materials(from);
        
        int exp_mat_count = mats.size() + rows.size();
        int max_mat_count = material_controller.get_max_inventory_size(*player);
        assert_true(exp_mat_count <= max_mat_count, "insufficient inventory");

        auto stagerule = stage_rule_controller.get_table().find(player->current_stage);
        assert_true(stagerule != stage_rule_controller.get_table().cend(), "no stage rule");

        time current = time_util::getnow();
        int elapsed_sec = (int)(current - player->last_rebirth);
        if (old_total_kill > 0) {
            assert_true(elapsed_sec >= kv_min_rebirth, "too short to get rebirth");
        }

        int kill_counts[kt_count] = {0, };
        int lucks[kt_count] = {0, };

        for (auto iter = rows.cbegin(); iter != rows.cend(); iter++) {
            auto &knight = *iter;
            int max_sec = calculate_max_alive_time(knight);
            int play_sec = elapsed_sec;
            if (play_sec > max_sec) {
                play_sec = max_sec;
            }

            int current_kill_count = knight.attack * play_sec / 60 / kv_enemy_hp;
            if (current_kill_count == 0) {
                current_kill_count = 1;
            }

            kill_counts[knight.type] = current_kill_count;
            lucks[knight.type] = knight.luck;
            total_kill_count += current_kill_count;
        }

        knights.modify(iter, self, [&](auto& target) {
            for (int index = 0; index < target.rows.size(); index++) {
                int type = target.rows[index].type;
                target.rows[index].kill_count += kill_counts[type];
            }
        });

        int powder = total_kill_count / kv_kill_powder_rate;
        if (powder <= 0) {
            powder = 1;
        }

        int floor = (total_kill_count / 10) + 1;
        for (int index = 1; index < kt_count; index++) {
            if (kill_counts[index] > 0) {
                int mat_code = get_botties(*player, floor, lucks[index], kill_counts[index], *stagerule);
                material_controller.add_material(from, mat_code);
            }
        }

        players.modify(player, self, [&](auto& target) {
            target.last_rebirth = current;
            target.powder += powder;
            if (target.maxfloor < floor) {
                target.maxfloor = floor;
            }
        });
    }
    // actions
    //-------------------------------------------------------------------------
    /// @brief
    /// hire new knight. player could pay the hire cost.
    /// @param from
    /// Player who requested hire action
    /// @param type
    /// knight who you want to hire
    void hireknight(name from, uint8_t type, const asset& quantity) {
        require_auth(from);
        assert_true(type > 0 && type < kt_count, "invalid knight type");

        auto rule = knight_rule_controller.get_table().find(type);
        assert_true(rule != knight_rule_controller.get_table().cend(), "no knight rule");

        knightrow knight;
        knight.type = type;
        knight.level = 1;
        knight.attack = rule->attack;
        knight.defense = rule->defense;
        knight.hp = rule->hp;
        knight.luck = rule->luck;

        int count = 1;
        auto iter = knights.find(from);
        if (iter == knights.cend()) {
            knights.emplace(self, [&](auto &target) {
                target.owner = from;
                target.rows.push_back(knight);
            });
        } else {
            bool found = false;
            knights.modify(iter, self, [&](auto &target) {
                for (int index = 0; index < target.rows.size(); index++) {
                    if (target.rows[index].type == type) {
                        found = true;
                        break;
                    }
                }
                
                target.rows.push_back(knight);
                count = target.rows.size();
            });

            assert_true(found == false, "you have already same knight");
        }

        auto price_itr = knight_price_rule_controller.get_table().find(count);
        assert_true(price_itr != knight_price_rule_controller.get_table().cend(), "could not find price rule");

        // pay the cost
        asset price = price_itr->price;
        assert_true(quantity.amount == price.amount, "knight price does not match");

        /*
        if (price.amount > 0) {
            player_controller.transfer(from, to_name(self), price);
        }
        */

        name seller;
        seller.value = self;

        buylog blog;
        blog.seller = seller;
        blog.dt = time_util::getnow();
        blog.type = ct_knight;
        blog.pid = 0;
        blog.code = type;
        blog.dna = 0;
        blog.level = 0;
        blog.exp = 0;
        blog.price = price;
        saleslog_controller.add_buylog(blog, from);

        auto &players = player_controller.get_players();
        auto player = players.find(from);
        assert_true(player != players.cend(), "could not find player");

        time current = time_util::getnow();
        players.modify(player, self, [&](auto& target) {
            target.last_rebirth = current;
        });
    }
示例#19
0
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) {
      if( code == N(eosio) && action == N(onerror) ) {
         auto error_dtrx = eosio::deferred_transaction::from_current_action();
         eosio::print("onerror called\n");
         auto error_action = error_dtrx.actions.at(0).name;

         // Error handlers for deferred transactions in these tests currently only support the first action

         WASM_TEST_ERROR_HANDLER("test_action", "assert_false", test_transaction, assert_false_error_handler );


         return;
      }

      if ( action == N(cf_action) ) {
         test_action::test_cf_action();
         return;
      }
      WASM_TEST_HANDLER(test_action, assert_true_cf);

      require_auth(code);

      //test_types
      WASM_TEST_HANDLER(test_types, types_size);
      WASM_TEST_HANDLER(test_types, char_to_symbol);
      WASM_TEST_HANDLER(test_types, string_to_name);
      WASM_TEST_HANDLER(test_types, name_class);

      //test_compiler_builtins
      WASM_TEST_HANDLER(test_compiler_builtins, test_multi3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_divti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_divti3_by_0);
      WASM_TEST_HANDLER(test_compiler_builtins, test_udivti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_udivti3_by_0);
      WASM_TEST_HANDLER(test_compiler_builtins, test_modti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_modti3_by_0);
      WASM_TEST_HANDLER(test_compiler_builtins, test_umodti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_umodti3_by_0);
      WASM_TEST_HANDLER(test_compiler_builtins, test_lshlti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_lshrti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_ashlti3);
      WASM_TEST_HANDLER(test_compiler_builtins, test_ashrti3);

      //test_action
      WASM_TEST_HANDLER(test_action, read_action_normal);
      WASM_TEST_HANDLER(test_action, read_action_to_0);
      WASM_TEST_HANDLER(test_action, read_action_to_64k);
      WASM_TEST_HANDLER_EX(test_action, require_notice);
      WASM_TEST_HANDLER(test_action, require_auth);
      WASM_TEST_HANDLER(test_action, assert_false);
      WASM_TEST_HANDLER(test_action, assert_true);
      WASM_TEST_HANDLER(test_action, now);
      WASM_TEST_HANDLER(test_action, test_abort);
      WASM_TEST_HANDLER_EX(test_action, test_current_receiver);
      WASM_TEST_HANDLER(test_action, test_current_sender);
      WASM_TEST_HANDLER(test_action, test_publication_time);

      // test named actions
      // We enforce action name matches action data type name, so name mangling will not work for these tests.
      if ( action == N(dummy_action) ) {
         test_action::test_dummy_action();
         return;
      }
      //test_print
      WASM_TEST_HANDLER(test_print, test_prints);
      WASM_TEST_HANDLER(test_print, test_prints_l);
      WASM_TEST_HANDLER(test_print, test_printi);
      WASM_TEST_HANDLER(test_print, test_printui);
      WASM_TEST_HANDLER(test_print, test_printi128);
      WASM_TEST_HANDLER(test_print, test_printui128);
      WASM_TEST_HANDLER(test_print, test_printn);
      WASM_TEST_HANDLER(test_print, test_printsf);
      WASM_TEST_HANDLER(test_print, test_printdf);
      WASM_TEST_HANDLER(test_print, test_printqf);

      //test_math
      WASM_TEST_HANDLER(test_math, test_multeq);
      WASM_TEST_HANDLER(test_math, test_diveq);
      WASM_TEST_HANDLER(test_math, test_i64_to_double);
      WASM_TEST_HANDLER(test_math, test_double_to_i64);
      WASM_TEST_HANDLER(test_math, test_diveq_by_0);
      WASM_TEST_HANDLER(test_math, test_double_api);
      WASM_TEST_HANDLER(test_math, test_double_api_div_0);

      //test crypto
      WASM_TEST_HANDLER(test_crypto, test_recover_key);
      WASM_TEST_HANDLER(test_crypto, test_recover_key_assert_true);
      WASM_TEST_HANDLER(test_crypto, test_recover_key_assert_false);
      WASM_TEST_HANDLER(test_crypto, test_sha1);
      WASM_TEST_HANDLER(test_crypto, test_sha256);
      WASM_TEST_HANDLER(test_crypto, test_sha512);
      WASM_TEST_HANDLER(test_crypto, test_ripemd160);
      WASM_TEST_HANDLER(test_crypto, sha1_no_data);
      WASM_TEST_HANDLER(test_crypto, sha256_no_data);
      WASM_TEST_HANDLER(test_crypto, sha512_no_data);
      WASM_TEST_HANDLER(test_crypto, ripemd160_no_data);
      WASM_TEST_HANDLER(test_crypto, sha256_null);
      WASM_TEST_HANDLER(test_crypto, assert_sha256_false);
      WASM_TEST_HANDLER(test_crypto, assert_sha256_true);
      WASM_TEST_HANDLER(test_crypto, assert_sha1_false);
      WASM_TEST_HANDLER(test_crypto, assert_sha1_true);
      WASM_TEST_HANDLER(test_crypto, assert_sha512_false);
      WASM_TEST_HANDLER(test_crypto, assert_sha512_true);
      WASM_TEST_HANDLER(test_crypto, assert_ripemd160_false);
      WASM_TEST_HANDLER(test_crypto, assert_ripemd160_true);

      //test transaction
      WASM_TEST_HANDLER(test_transaction, test_tapos_block_num);
      WASM_TEST_HANDLER(test_transaction, test_tapos_block_prefix);
      WASM_TEST_HANDLER(test_transaction, send_action);
      WASM_TEST_HANDLER(test_transaction, send_action_inline_fail);
      WASM_TEST_HANDLER(test_transaction, send_action_empty);
      WASM_TEST_HANDLER(test_transaction, send_action_large);
      WASM_TEST_HANDLER(test_transaction, send_action_recurse);
      WASM_TEST_HANDLER(test_transaction, test_read_transaction);
      WASM_TEST_HANDLER(test_transaction, test_transaction_size);
      WASM_TEST_HANDLER_EX(test_transaction, send_transaction);
      WASM_TEST_HANDLER_EX(test_transaction, send_transaction_empty);
      WASM_TEST_HANDLER_EX(test_transaction, send_transaction_trigger_error_handler);
      WASM_TEST_HANDLER_EX(test_transaction, send_transaction_large);
      WASM_TEST_HANDLER_EX(test_transaction, send_action_sender);
      WASM_TEST_HANDLER_EX(test_transaction, send_transaction_expiring_late);
      WASM_TEST_HANDLER(test_transaction, deferred_print);
      WASM_TEST_HANDLER_EX(test_transaction, send_deferred_transaction);
      WASM_TEST_HANDLER(test_transaction, cancel_deferred_transaction);
      WASM_TEST_HANDLER(test_transaction, send_cf_action);
      WASM_TEST_HANDLER(test_transaction, send_cf_action_fail);
      WASM_TEST_HANDLER(test_transaction, read_inline_action);
      WASM_TEST_HANDLER(test_transaction, read_inline_cf_action);

      //test chain
      WASM_TEST_HANDLER(test_chain, test_activeprods);

      // test fixed_point
      WASM_TEST_HANDLER(test_fixedpoint, create_instances);
      WASM_TEST_HANDLER(test_fixedpoint, test_addition);
      WASM_TEST_HANDLER(test_fixedpoint, test_subtraction);
      WASM_TEST_HANDLER(test_fixedpoint, test_multiplication);
      WASM_TEST_HANDLER(test_fixedpoint, test_division);
      WASM_TEST_HANDLER(test_fixedpoint, test_division_by_0);

      // test double
      WASM_TEST_HANDLER(test_real, create_instances);
      WASM_TEST_HANDLER(test_real, test_addition);
      WASM_TEST_HANDLER(test_real, test_multiplication);
      WASM_TEST_HANDLER(test_real, test_division);
      WASM_TEST_HANDLER(test_real, test_division_by_0);

      // test checktime
      WASM_TEST_HANDLER(test_checktime, checktime_pass);
      WASM_TEST_HANDLER(test_checktime, checktime_failure);

      // test datastream
      WASM_TEST_HANDLER(test_datastream, test_basic);

      // test permission
      WASM_TEST_HANDLER_EX(test_permission, check_authorization);

      //unhandled test call
      eosio_assert(false, "Unknown Test");

   }
示例#20
0
         static void on( const regproxy& reg ) {
            require_auth( reg.proxy_to_register );

         }
示例#21
0
文件: voting.cpp 项目: BestSilent/eos
   /**
    *  @pre producers must be sorted from lowest to highest
    *  @pre if proxy is set then no producers can be voted for
    *  @pre every listed producer or proxy must have been previously registered
    *  @pre voter must authorize this action
    *  @pre voter must have previously staked some EOS for voting
    */
   void system_contract::voteproducer( const account_name voter, const account_name proxy, const std::vector<account_name>& producers ) {
      require_auth( voter );

      //validate input
      if ( proxy ) {
         eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" );
         require_recipient( proxy );
      } else {
         eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" );
         for( size_t i = 1; i < producers.size(); ++i ) {
            eosio_assert( producers[i-1] < producers[i], "producer votes must be unique and sorted" );
         }
      }

      voters_table voters_tbl( _self, _self );
      auto voter_it = voters_tbl.find( voter );

      eosio_assert( 0 <= voter_it->staked.amount, "negative stake" );
      eosio_assert( voter_it != voters_tbl.end() && ( 0 < voter_it->staked.amount || ( voter_it->is_proxy && 0 < voter_it->proxied_votes ) ), "no stake to vote" );
      if ( voter_it->is_proxy ) {
         eosio_assert( proxy == 0 , "account registered as a proxy is not allowed to use a proxy" );
      }

      //find old producers, update old proxy if needed
      const std::vector<account_name>* old_producers = nullptr;
      if( voter_it->proxy ) {
         if ( voter_it->proxy == proxy ) {
            return; // nothing changed
         }
         auto old_proxy = voters_tbl.find( voter_it->proxy );
         eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption
         voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= uint64_t(voter_it->staked.amount); } );
         if ( old_proxy->is_proxy ) { //if proxy stopped being a proxy, the votes were already taken back from producers by on( const unregister_proxy& )
            old_producers = &old_proxy->producers;
         }
      } else {
         old_producers = &voter_it->producers;
      }

      //find new producers, update new proxy if needed
      const std::vector<account_name>* new_producers = nullptr;
      if ( proxy ) {
         auto new_proxy = voters_tbl.find( proxy );
         eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" );
         voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += uint64_t(voter_it->staked.amount); } );
         new_producers = &new_proxy->producers;
      } else {
         new_producers = &producers;
      }

      producers_table producers_tbl( _self, _self );
      uint128_t votes = uint64_t(voter_it->staked.amount);
      if ( voter_it->is_proxy ) {
         votes += voter_it->proxied_votes;
      }

      if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment
         //revoke votes only from no longer elected
         std::vector<account_name> revoked( old_producers->size() );
         auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() );
         for ( auto it = revoked.begin(); it != end_it; ++it ) {
            auto prod = producers_tbl.find( *it );
            eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption
            producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } );
         }
      }

      //update newly elected
      std::vector<account_name> elected( new_producers->size() );
      auto end_it = elected.begin();
      if( old_producers ) {
         end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() );
      } else {
         end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() );
      }
      for ( auto it = elected.begin(); it != end_it; ++it ) {
         auto prod = producers_tbl.find( *it );
         eosio_assert( prod != producers_tbl.end(), "producer is not registered" );
         if ( proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers
            eosio_assert( prod->active(), "producer is not currently registered" );
         }
         producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } );
      }

      // save new values to the account itself
      voters_tbl.modify( voter_it, 0, [&](voter_info& a) {
            a.proxy = proxy;
            a.last_update = now();
            a.producers = producers;
         });
   }
示例#22
0
         ACTION( SystemAccount, regproducer ) {
            account_name producer;
            bytes        producer_key;

            EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) )
         };

         ACTION( SystemAccount, regproxy ) {
            account_name proxy_to_register;

            EOSLIB_SERIALIZE( regproxy, (proxy_to_register) )
         };

         ACTION( SystemAccount, delegatebw ) {
            account_name                    from;
            account_name                    receiver;
            typename currency::token_type   stake_net_quantity;
            typename currency::token_type   stake_cpu_quantity;


            EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) )
         };

         ACTION( SystemAccount, undelegatebw ) {
            account_name                    from;
            account_name                    receiver;
            typename currency::token_type   unstake_net_quantity;
            typename currency::token_type   unstake_cpu_quantity;

            EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) )
         };

         ACTION( SystemAccount, nonce ) {
            eosio::string                   value;

            EOSLIB_SERIALIZE( nonce, (value) )
         };

         /// new id options:
         //  1. hash + collision 
         //  2. incrementing count  (key=> tablename 

         static void on( const delegatebw& del ) {
            eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" );
            eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" );

            auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity;
            eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" );


            require_auth( del.from );

            del_bandwidth_index_type     del_index( SystemAccount, del.from );
            total_resources_index_type   total_index( SystemAccount, del.receiver );

            //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );

            auto itr = del_index.find( del.receiver);
            if( itr != nullptr ) {
               del_index.emplace( del.from, [&]( auto& dbo ){
                  dbo.from       = del.from;      
                  dbo.to         = del.receiver;      
                  dbo.net_weight = del.stake_net_quantity;
                  dbo.cpu_weight = del.stake_cpu_quantity;
               });
            }
            else {
               del_index.update( *itr, del.from, [&]( auto& dbo ){
                  dbo.net_weight = del.stake_net_quantity;
                  dbo.cpu_weight = del.stake_cpu_quantity;
               });
            }

            auto tot_itr = total_index.find( del.receiver );
            if( tot_itr == nullptr ) {
               tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) {
                  tot.owner = del.receiver;
                  tot.total_net_weight += del.stake_net_quantity;
                  tot.total_cpu_weight += del.stake_cpu_quantity;
               });
            } else {
               total_index.update( *tot_itr, 0, [&]( auto& tot ) {
                  tot.total_net_weight += del.stake_net_quantity;
                  tot.total_cpu_weight += del.stake_cpu_quantity;
               });
            }

            set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 );

            currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" );
         } // delegatebw