Skip to content

Commit

Permalink
Merge pull request #232 from MinterTeam/dev
Browse files Browse the repository at this point in the history
v0.18.0
  • Loading branch information
danil-lashin authored Apr 9, 2019
2 parents ed3ed04 + f30bb51 commit 89c5f79
Show file tree
Hide file tree
Showing 23 changed files with 459 additions and 104 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 0.18.0

IMPROVEMENT

- [api] Add `/estimate_coin_sell_all` endpoint

BUG FIXES

- [p2p] Make new addressbook file for each testnet

## 0.17.1

BUG FIXES
Expand Down
1 change: 1 addition & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ var Routes = map[string]*rpcserver.RPCFunc{
"net_info": rpcserver.NewRPCFunc(NetInfo, ""),
"coin_info": rpcserver.NewRPCFunc(CoinInfo, "symbol,height"),
"estimate_coin_sell": rpcserver.NewRPCFunc(EstimateCoinSell, "coin_to_sell,coin_to_buy,value_to_sell,height"),
"estimate_coin_sell_all": rpcserver.NewRPCFunc(EstimateCoinSellAll, "coin_to_sell,coin_to_buy,value_to_sell,gas_price,height"),
"estimate_coin_buy": rpcserver.NewRPCFunc(EstimateCoinBuy, "coin_to_sell,coin_to_buy,value_to_buy,height"),
"estimate_tx_commission": rpcserver.NewRPCFunc(EstimateTxCommission, "tx,height"),
"unconfirmed_txs": rpcserver.NewRPCFunc(UnconfirmedTxs, "limit"),
Expand Down
83 changes: 83 additions & 0 deletions api/estimate_coin_sell_all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package api

import (
"github.com/MinterTeam/minter-go-node/core/commissions"
"github.com/MinterTeam/minter-go-node/core/transaction"
"github.com/MinterTeam/minter-go-node/core/types"
"github.com/MinterTeam/minter-go-node/formula"
"github.com/MinterTeam/minter-go-node/rpc/lib/types"
"math/big"
)

type EstimateCoinSellAllResponse struct {
WillGet *big.Int `json:"will_get"`
}

func EstimateCoinSellAll(
coinToSellString string, coinToBuyString string, valueToSell *big.Int, gasPrice uint64, height int) (*EstimateCoinSellAllResponse,
error) {
cState, err := GetStateForHeight(height)
if err != nil {
return nil, err
}

if gasPrice < 1 {
gasPrice = 1
}

coinToSell := types.StrToCoinSymbol(coinToSellString)
coinToBuy := types.StrToCoinSymbol(coinToBuyString)

var result *big.Int

if coinToSell == coinToBuy {
return nil, rpctypes.RPCError{Code: 400, Message: "\"From\" coin equals to \"to\" coin"}
}

if !cState.CoinExists(coinToSell) {
return nil, rpctypes.RPCError{Code: 404, Message: "Coin to sell not exists"}
}

if !cState.CoinExists(coinToBuy) {
return nil, rpctypes.RPCError{Code: 404, Message: "Coin to buy not exists"}
}

commissionInBaseCoin := big.NewInt(commissions.ConvertTx)
commissionInBaseCoin.Mul(commissionInBaseCoin, transaction.CommissionMultiplier)
commission := big.NewInt(0).Set(commissionInBaseCoin)

switch {
case coinToSell == types.GetBaseCoin():
coin := cState.GetStateCoin(coinToBuy).Data()

valueToSell.Sub(valueToSell, commission)
if valueToSell.Cmp(big.NewInt(0)) != 1 {
return nil, rpctypes.RPCError{Code: 400, Message: "Not enough coins to pay commission"}
}

result = formula.CalculatePurchaseReturn(coin.Volume, coin.ReserveBalance, coin.Crr, valueToSell)
case coinToBuy == types.GetBaseCoin():
coin := cState.GetStateCoin(coinToSell).Data()
result = formula.CalculateSaleReturn(coin.Volume, coin.ReserveBalance, coin.Crr, valueToSell)

result.Sub(result, commission)
if result.Cmp(big.NewInt(0)) != 1 {
return nil, rpctypes.RPCError{Code: 400, Message: "Not enough coins to pay commission"}
}
default:
coinFrom := cState.GetStateCoin(coinToSell).Data()
coinTo := cState.GetStateCoin(coinToBuy).Data()
basecoinValue := formula.CalculateSaleReturn(coinFrom.Volume, coinFrom.ReserveBalance, coinFrom.Crr, valueToSell)

basecoinValue.Sub(basecoinValue, commission)
if basecoinValue.Cmp(big.NewInt(0)) != 1 {
return nil, rpctypes.RPCError{Code: 400, Message: "Not enough coins to pay commission"}
}

result = formula.CalculatePurchaseReturn(coinTo.Volume, coinTo.ReserveBalance, coinTo.Crr, basecoinValue)
}

return &EstimateCoinSellAllResponse{
WillGet: result,
}, nil
}
14 changes: 7 additions & 7 deletions cmd/make_genesis/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ func main() {
}

balances := map[string]int64{
"Mxe6732a97c6445edb0becf685dd92655bb4a1b838": 17318590, // Minter One
"Mx89f5395a03847826d6b48bb02dbde64376945a20": 9833248, // MonsterNode
"Mx8da4f97b635cf751f2c0f0020f2e78ceb691d7d5": 3798414, // BTC.Secure
"Mxf5d006607e9420978b8f33a940a6fcbc67797db2": 2187460, // Minter Store
"Mx50003880d87db2fa48f6b824cdcfeeab1ac77733": 2038305, // DeCenter
"Mxe6732a97c6445edb0becf685dd92655bb4a1b838": 17351769, // Minter One
"Mx89f5395a03847826d6b48bb02dbde64376945a20": 9861716, // MonsterNode
"Mx8da4f97b635cf751f2c0f0020f2e78ceb691d7d5": 3809865, // BTC.Secure
"Mxf5d006607e9420978b8f33a940a6fcbc67797db2": 2190487, // Minter Store
"Mx50003880d87db2fa48f6b824cdcfeeab1ac77733": 2057729, // DeCenter
"Mx198208eb4d11d4b389ff262ac52494d920770879": 1063320, // MINTER CENTER
"Mx3bdee0d64fa9ac892720f48724ef6a4e2919a6ba": 803817, // Minternator
"Mx8bee92ba8999ab047cb5e2d98e190dada4d7a2b2": 803118, // StakeHolder
Expand All @@ -55,11 +55,11 @@ func main() {
}

appHash := [32]byte{}
networkId := "minter-test-network-36"
networkId := "minter-test-network-37"

// Compose Genesis
genesis := tmTypes.GenesisDoc{
GenesisTime: time.Date(2019, time.April, 5, 17, 0, 0, 0, time.UTC),
GenesisTime: time.Date(2019, time.April, 9, 17, 0, 0, 0, time.UTC),
ChainID: networkId,
ConsensusParams: &tmTypes.ConsensusParams{
Block: tmTypes.BlockParams{
Expand Down
2 changes: 1 addition & 1 deletion cmd/minter/a_main-packr.go

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions cmd/minter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@ func main() {

client := rpc.NewLocal(node)
status, _ := client.Status()
genesis, _ := client.Genesis()
if status.NodeInfo.Network != genesis.Genesis.ChainID {
log.Error("Different networks")
if status.NodeInfo.Network != config.NetworkId {
log.Error("Different networks", "expected", config.NetworkId, "got", status.NodeInfo.Network)
os.Exit(1)
}

Expand Down Expand Up @@ -156,7 +155,7 @@ func getGenesis() (doc *tmTypes.GenesisDoc, e error) {
genesisFile := utils.GetMinterHome() + "/config/genesis.json"

if !common.FileExists(genesisFile) {
box := packr.NewBox("../../testnet/minter-test-network-36")
box := packr.NewBox("../../testnet/" + config.NetworkId)

err := common.WriteFile(genesisFile, box.Bytes("genesis.json"), 0644)
if err != nil {
Expand Down
26 changes: 16 additions & 10 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import (
"time"
)

var (
const (
NetworkId = "minter-test-network-37"

// LogFormatPlain is a format for colored text
LogFormatPlain = "plain"
// LogFormatJSON is a format for json output
LogFormatJSON = "json"

defaultConfigDir = "config"
defaultDataDir = "data"

Expand All @@ -20,21 +27,16 @@ var (
defaultPrivValName = "priv_validator.json"
defaultPrivValStateName = "priv_validator_state.json"
defaultNodeKeyName = "node_key.json"
)

var (
defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
defaultPrivValKeyPath = filepath.Join(defaultConfigDir, defaultPrivValName)
defaultPrivValStatePath = filepath.Join(defaultConfigDir, defaultPrivValStateName)
defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName)
)

const (
// LogFormatPlain is a format for colored text
LogFormatPlain = "plain"
// LogFormatJSON is a format for json output
LogFormatJSON = "json"
)

func init() {
homeDir := utils.GetMinterHome()
viper.SetConfigName("config")
Expand All @@ -53,7 +55,10 @@ func init() {
func DefaultConfig() *Config {
cfg := defaultConfig()

cfg.P2P.Seeds = "647e32df3b9c54809b5aca2877d9ba60900bc2d9@minter-node-1.testnet.minter.network:26656,d20522aa7ba4af8139749c5e724063c4ba18c58b@minter-node-2.testnet.minter.network:26656,249c62818bf4601605a65b5adc35278236bd5312@minter-node-3.testnet.minter.network:26656,b698b07f13f2210dfc82967bfa2a127d1cdfdc54@minter-node-4.testnet.minter.network:26656"
cfg.P2P.Seeds = "647e32df3b9c54809b5aca2877d9ba60900bc2d9@minter-node-1.testnet.minter.network:26656," +
"d20522aa7ba4af8139749c5e724063c4ba18c58b@minter-node-2.testnet.minter.network:26656," +
"249c62818bf4601605a65b5adc35278236bd5312@minter-node-3.testnet.minter.network:26656," +
"b698b07f13f2210dfc82967bfa2a127d1cdfdc54@minter-node-4.testnet.minter.network:26656"

cfg.TxIndex = &tmConfig.TxIndexConfig{
Indexer: "kv",
Expand Down Expand Up @@ -83,7 +88,6 @@ func DefaultConfig() *Config {
cfg.PrivValidatorKey = "config/priv_validator.json"
cfg.PrivValidatorState = "config/priv_validator_state.json"
cfg.NodeKey = "config/node_key.json"
cfg.P2P.AddrBook = "config/addrbook.json"

return cfg
}
Expand All @@ -106,6 +110,8 @@ func GetConfig() *Config {

cfg.Mempool.Recheck = false

cfg.P2P.AddrBook = "config/addrbook-" + NetworkId + ".json"

cfg.SetRoot(utils.GetMinterHome())
EnsureRoot(utils.GetMinterHome())

Expand Down
3 changes: 0 additions & 3 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,6 @@ persistent_peers = "{{ .P2P.PersistentPeers }}"
# UPNP port forwarding
upnp = {{ .P2P.UPNP }}
# Path to address book
addr_book_file = "{{ js .P2P.AddrBook }}"
# Set true for strict address routability rules
addr_book_strict = {{ .P2P.AddrBookStrict }}
Expand Down
36 changes: 23 additions & 13 deletions core/minter/minter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import (
"github.com/MinterTeam/minter-go-node/core/types"
"github.com/MinterTeam/minter-go-node/core/validators"
"github.com/MinterTeam/minter-go-node/eventsdb"
"github.com/MinterTeam/minter-go-node/log"
"github.com/MinterTeam/minter-go-node/version"
"github.com/danil-lashin/tendermint/rpc/lib/types"
abciTypes "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/tendermint/tendermint/libs/db"
tmNode "github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/rpc/client"
types2 "github.com/tendermint/tendermint/types"
"math/big"
"sync"
Expand Down Expand Up @@ -243,22 +245,30 @@ func (app *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes.Respons
}

// accumulate rewards
reward := rewards.GetRewardForBlock(height)
reward.Add(reward, app.rewards)

// compute remainder to keep total emission consist
remainder := big.NewInt(0).Set(reward)

for i, val := range vals {
// skip if candidate is not present
if val.IsToDrop() || app.validatorsStatuses[val.GetAddress()] != ValidatorPresent {
continue
}

reward := rewards.GetRewardForBlock(height)

reward.Add(reward, app.rewards)

reward.Mul(reward, val.TotalBipStake)
reward.Div(reward, totalPower)
r := big.NewInt(0).Set(reward)
r.Mul(r, val.TotalBipStake)
r.Div(r, totalPower)

vals[i].AccumReward.Add(vals[i].AccumReward, reward)
remainder.Sub(remainder, r)
vals[i].AccumReward.Add(vals[i].AccumReward, r)
}

// add remainder to last validator
lastValidator := vals[len(vals)-1]
lastValidator.AccumReward.Add(lastValidator.AccumReward, remainder)

stateValidators.SetData(vals)
app.stateDeliver.SetStateValidators(stateValidators)

Expand Down Expand Up @@ -412,12 +422,12 @@ func (app *Blockchain) Commit() abciTypes.ResponseCommit {
app.currentMempool = sync.Map{}

// Check invariants
//if app.height%720 == 0 {
// genesis, _ := client.NewLocal(app.tmNode).Genesis()
// if err := state.NewForCheck(app.stateCheck).CheckForInvariants(genesis.Genesis); err != nil {
// log.With("module", "invariants").Error("Invariants error", "msg", err.Error())
// }
//}
if app.height%720 == 0 {
genesis, _ := client.NewLocal(app.tmNode).Genesis()
if err := state.NewForCheck(app.stateCheck).CheckForInvariants(genesis.Genesis); err != nil {
log.With("module", "invariants").Error("Invariants error", "msg", err.Error(), "height", app.height)
}
}

// Releasing wg
app.wg.Done()
Expand Down
14 changes: 9 additions & 5 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -933,14 +933,15 @@ func (s *StateDB) PayRewards() {
validator := vals.data[i]

if validator.AccumReward.Cmp(types.Big0) == 1 {

totalReward := big.NewInt(0).Set(validator.AccumReward)
remainder := big.NewInt(0).Set(validator.AccumReward)

// pay commission to DAO
DAOReward := big.NewInt(0).Set(totalReward)
DAOReward.Mul(DAOReward, big.NewInt(int64(dao.Commission)))
DAOReward.Div(DAOReward, big.NewInt(100))
s.AddBalance(dao.Address, types.GetBaseCoin(), DAOReward)
remainder.Sub(remainder, DAOReward)
edb.AddEvent(s.height, eventsdb.RewardEvent{
Role: eventsdb.RoleDAO,
Address: dao.Address,
Expand All @@ -953,6 +954,7 @@ func (s *StateDB) PayRewards() {
DevelopersReward.Mul(DevelopersReward, big.NewInt(int64(developers.Commission)))
DevelopersReward.Div(DevelopersReward, big.NewInt(100))
s.AddBalance(developers.Address, types.GetBaseCoin(), DevelopersReward)
remainder.Sub(remainder, DevelopersReward)
edb.AddEvent(s.height, eventsdb.RewardEvent{
Role: eventsdb.RoleDevelopers,
Address: developers.Address,
Expand All @@ -969,6 +971,7 @@ func (s *StateDB) PayRewards() {
validatorReward.Div(validatorReward, big.NewInt(100))
totalReward.Sub(totalReward, validatorReward)
s.AddBalance(validator.RewardAddress, types.GetBaseCoin(), validatorReward)
remainder.Sub(remainder, validatorReward)
edb.AddEvent(s.height, eventsdb.RewardEvent{
Role: eventsdb.RoleValidator,
Address: validator.RewardAddress,
Expand Down Expand Up @@ -996,6 +999,7 @@ func (s *StateDB) PayRewards() {
}

s.AddBalance(stake.Owner, types.GetBaseCoin(), reward)
remainder.Sub(remainder, reward)

edb.AddEvent(s.height, eventsdb.RewardEvent{
Role: eventsdb.RoleDelegator,
Expand All @@ -1005,7 +1009,7 @@ func (s *StateDB) PayRewards() {
})
}

validator.AccumReward.SetInt64(0)
validator.AccumReward.Set(remainder)
}
}

Expand Down Expand Up @@ -1900,7 +1904,7 @@ func (s *StateDB) Import(appState types.AppState) {
}

func (s *StateDB) CheckForInvariants(genesis *tmTypes.GenesisDoc) error {
height := s.height - 1
height := s.height

var genesisState types.AppState
_ = amino.UnmarshalJSON(genesis.AppState, &genesisState)
Expand Down Expand Up @@ -2020,8 +2024,8 @@ func (s *StateDB) CheckForInvariants(genesis *tmTypes.GenesisDoc) error {
predictedBasecoinVolume.Sub(predictedBasecoinVolume, s.GetTotalSlashed())
predictedBasecoinVolume.Add(predictedBasecoinVolume, GenesisAlloc)

delta := big.NewInt(0).Abs(big.NewInt(0).Sub(predictedBasecoinVolume, totalBasecoinVolume))
if delta.Cmp(big.NewInt(1000000000)) == 1 {
delta := big.NewInt(0).Sub(predictedBasecoinVolume, totalBasecoinVolume)
if delta.Cmp(big.NewInt(0)) != 0 {
return fmt.Errorf("smth wrong with total base coins in blockchain. Expected total supply to be %s, got %s",
predictedBasecoinVolume, totalBasecoinVolume)
}
Expand Down
6 changes: 0 additions & 6 deletions core/transaction/buy_coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,6 @@ func (data BuyCoinData) BasicCheck(tx *Transaction, context *state.StateDB) *Res
Log: fmt.Sprintf("\"From\" coin equals to \"to\" coin")}
}

if !context.CoinExists(tx.GasCoin) {
return &Response{
Code: code.CoinNotExists,
Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)}
}

if !context.CoinExists(data.CoinToSell) {
return &Response{
Code: code.CoinNotExists,
Expand Down
Loading

0 comments on commit 89c5f79

Please sign in to comment.