diff --git a/CHANGELOG.md b/CHANGELOG.md index 0510093c2..5e1266d4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/api/api.go b/api/api.go index 7032a6302..e57f60048 100644 --- a/api/api.go +++ b/api/api.go @@ -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"), diff --git a/api/estimate_coin_sell_all.go b/api/estimate_coin_sell_all.go new file mode 100644 index 000000000..a913c3337 --- /dev/null +++ b/api/estimate_coin_sell_all.go @@ -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 +} diff --git a/cmd/make_genesis/main.go b/cmd/make_genesis/main.go index 391a4cb91..b0a54ffb0 100644 --- a/cmd/make_genesis/main.go +++ b/cmd/make_genesis/main.go @@ -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 @@ -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{ diff --git a/cmd/minter/a_main-packr.go b/cmd/minter/a_main-packr.go index ad6f584d4..12b959909 100644 --- a/cmd/minter/a_main-packr.go +++ b/cmd/minter/a_main-packr.go @@ -7,5 +7,5 @@ import "github.com/gobuffalo/packr" // You can use the "packr clean" command to clean up this, // and any other packr generated files. func init() { - packr.PackJSONBytes("../../testnet/minter-test-network-36", "genesis.json", "\"ewogICJnZW5lc2lzX3RpbWUiOiAiMjAxOS0wNC0wNVQxNzowMDowMFoiLAogICJjaGFpbl9pZCI6ICJtaW50ZXItdGVzdC1uZXR3b3JrLTM2IiwKICAiY29uc2Vuc3VzX3BhcmFtcyI6IHsKICAgICJibG9jayI6IHsKICAgICAgIm1heF9ieXRlcyI6ICIxMDAwMDAwMCIsCiAgICAgICJtYXhfZ2FzIjogIjEwMDAwMCIsCiAgICAgICJ0aW1lX2lvdGFfbXMiOiAiMTAwMCIKICAgIH0sCiAgICAiZXZpZGVuY2UiOiB7CiAgICAgICJtYXhfYWdlIjogIjEwMDAiCiAgICB9LAogICAgInZhbGlkYXRvciI6IHsKICAgICAgInB1Yl9rZXlfdHlwZXMiOiBbCiAgICAgICAgImVkMjU1MTkiCiAgICAgIF0KICAgIH0KICB9LAogICJhcHBfaGFzaCI6ICIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwKICAiYXBwX3N0YXRlIjogewogICAgInN0YXJ0X2hlaWdodCI6ICIwIiwKICAgICJ2YWxpZGF0b3JzIjogWwogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgInRvdGFsX2JpcF9zdGFrZSI6ICIxIiwKICAgICAgICAicHViX2tleSI6ICJNcDRhZTFlZTczZTYxMzZjODViMGNhOTMzYTlhMTM0Nzc1OGEzMzQ4ODVmMTBiMzIzODM5OGE2N2FjMmViMTUzYjgiLAogICAgICAgICJjb21taXNzaW9uIjogIjEwMCIsCiAgICAgICAgImFjY3VtX3Jld2FyZCI6ICIwIiwKICAgICAgICAiYWJzZW50X3RpbWVzIjogIl9fX19fX19fX19fX19fX19fX19fX19fXyIKICAgICAgfSwKICAgICAgewogICAgICAgICJyZXdhcmRfYWRkcmVzcyI6ICJNeGVlODEzNDcyMTFjNzI1MjQzMzhmOTY4MDA3MmFmOTA3NDQzMzMxNDYiLAogICAgICAgICJ0b3RhbF9iaXBfc3Rha2UiOiAiMSIsCiAgICAgICAgInB1Yl9rZXkiOiAiTXA3MzhkYTQxYmE2YTdiN2Q2OWI3Mjk0YWZhMTU4Yjg5YzVhMWI0MTBjYmYwYzI0NDNjODVjNWZlMjRhZDFkZDFjIiwKICAgICAgICAiY29tbWlzc2lvbiI6ICIxMDAiLAogICAgICAgICJhY2N1bV9yZXdhcmQiOiAiMCIsCiAgICAgICAgImFic2VudF90aW1lcyI6ICJfX19fX19fX19fX19fX19fX19fX19fX18iCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAicmV3YXJkX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNmYxNmMxZmYyMWE2ZmI5NDZhYWVkMGY0YzFmY2NhMjcyYjcyZmQ5MDQ5ODhmOTFkMzg4MzI4MmI4YWUzMWJhMiIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAiYWNjdW1fcmV3YXJkIjogIjAiLAogICAgICAgICJhYnNlbnRfdGltZXMiOiAiX19fX19fX19fX19fX19fX19fX19fX19fIgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgInRvdGFsX2JpcF9zdGFrZSI6ICIxIiwKICAgICAgICAicHViX2tleSI6ICJNcDllMTNmMmY1NDY4ZGQ3ODJiMzE2NDQ0ZmJkNjY1OTVlMTNkYmE3ZDdiZDNlZmExYmVjZDUwYjQyMDQ1ZjU4YzYiLAogICAgICAgICJjb21taXNzaW9uIjogIjEwMCIsCiAgICAgICAgImFjY3VtX3Jld2FyZCI6ICIwIiwKICAgICAgICAiYWJzZW50X3RpbWVzIjogIl9fX19fX19fX19fX19fX19fX19fX19fXyIKICAgICAgfQogICAgXSwKICAgICJjYW5kaWRhdGVzIjogWwogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNGFlMWVlNzNlNjEzNmM4NWIwY2E5MzNhOWExMzQ3NzU4YTMzNDg4NWYxMGIzMjM4Mzk4YTY3YWMyZWIxNTNiOCIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNzM4ZGE0MWJhNmE3YjdkNjliNzI5NGFmYTE1OGI4OWM1YTFiNDEwY2JmMGMyNDQzYzg1YzVmZTI0YWQxZGQxYyIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNmYxNmMxZmYyMWE2ZmI5NDZhYWVkMGY0YzFmY2NhMjcyYjcyZmQ5MDQ5ODhmOTFkMzg4MzI4MmI4YWUzMWJhMiIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wOWUxM2YyZjU0NjhkZDc4MmIzMTY0NDRmYmQ2NjU5NWUxM2RiYTdkN2JkM2VmYTFiZWNkNTBiNDIwNDVmNThjNiIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9CiAgICBdLAogICAgImFjY291bnRzIjogWwogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXgzYmRlZTBkNjRmYTlhYzg5MjcyMGY0ODcyNGVmNmE0ZTI5MTlhNmJhIiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjgwMzgxNzAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjE2MTE0NTk4MTAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXhlNjczMmE5N2M2NDQ1ZWRiMGJlY2Y2ODVkZDkyNjU1YmI0YTFiODM4IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjE3MzE4NTkwMDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeDhiZWU5MmJhODk5OWFiMDQ3Y2I1ZTJkOThlMTkwZGFkYTRkN2EyYjIiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiODAzMTE4MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeDYwMTYwOWI4NWVlMjFiOTQ5M2RmZmJjYTEwNzljNzRkNDdiNzVmMmEiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiMTU4ODU3MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeDBhY2JkNWRmOWJjNGJkYzlmY2YyZjg3ZTgzOTM5MDc3Mzk0MDFhMjciLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiMzQ1MTIwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14ODlmNTM5NWEwMzg0NzgyNmQ2YjQ4YmIwMmRiZGU2NDM3Njk0NWEyMCIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICI5ODMzMjQ4MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeGY1ZDAwNjYwN2U5NDIwOTc4YjhmMzNhOTQwYTZmY2JjNjc3OTdkYjIiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiMjE4NzQ2MDAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXgxOTgyMDhlYjRkMTFkNGIzODlmZjI2MmFjNTI0OTRkOTIwNzcwODc5IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEwNjMzMjAwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14ZTFkYmRlNWMwMmE3MzBmNzQ3YTQ3ZDI0ZjBmOTkzYzI3ZGE5ZGZmMSIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICI2MzY4MzcwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14MzVjNDA1NjNlZTUxODE4OTlkMGQ2MDU4MzllZGI5ZTk0MGIwZDhlNSIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICIzMzg2OTAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXg4ZGE0Zjk3YjYzNWNmNzUxZjJjMGYwMDIwZjJlNzhjZWI2OTFkN2Q1IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjM3OTg0MTQwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14NTAwMDM4ODBkODdkYjJmYTQ4ZjZiODI0Y2RjZmVlYWIxYWM3NzczMyIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICIyMDM4MzA1MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeGRjZTE1NGI2ZTFkMDZiNDZlOTU4ODFiOTAwZWViMTY0ZTI0N2MxODAiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiNzU0MTQwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14ZGM3ZmNjNjM5MzBiZjgxZWJkY2UxMmIzYmNlZjU3YjkzZTk5YTE1NyIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICI2ODI1ODAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9CiAgICBdLAogICAgIm1heF9nYXMiOiAiMTAwMDAwIiwKICAgICJ0b3RhbF9zbGFzaGVkIjogIjAiCiAgfQp9\"") + packr.PackJSONBytes("../../testnet/minter-test-network-37", "genesis.json", "\"ewogICJnZW5lc2lzX3RpbWUiOiAiMjAxOS0wNC0wOVQxNzowMDowMFoiLAogICJjaGFpbl9pZCI6ICJtaW50ZXItdGVzdC1uZXR3b3JrLTM3IiwKICAiY29uc2Vuc3VzX3BhcmFtcyI6IHsKICAgICJibG9jayI6IHsKICAgICAgIm1heF9ieXRlcyI6ICIxMDAwMDAwMCIsCiAgICAgICJtYXhfZ2FzIjogIjEwMDAwMCIsCiAgICAgICJ0aW1lX2lvdGFfbXMiOiAiMTAwMCIKICAgIH0sCiAgICAiZXZpZGVuY2UiOiB7CiAgICAgICJtYXhfYWdlIjogIjEwMDAiCiAgICB9LAogICAgInZhbGlkYXRvciI6IHsKICAgICAgInB1Yl9rZXlfdHlwZXMiOiBbCiAgICAgICAgImVkMjU1MTkiCiAgICAgIF0KICAgIH0KICB9LAogICJhcHBfaGFzaCI6ICIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwKICAiYXBwX3N0YXRlIjogewogICAgInN0YXJ0X2hlaWdodCI6ICIwIiwKICAgICJ2YWxpZGF0b3JzIjogWwogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgInRvdGFsX2JpcF9zdGFrZSI6ICIxIiwKICAgICAgICAicHViX2tleSI6ICJNcDRhZTFlZTczZTYxMzZjODViMGNhOTMzYTlhMTM0Nzc1OGEzMzQ4ODVmMTBiMzIzODM5OGE2N2FjMmViMTUzYjgiLAogICAgICAgICJjb21taXNzaW9uIjogIjEwMCIsCiAgICAgICAgImFjY3VtX3Jld2FyZCI6ICIwIiwKICAgICAgICAiYWJzZW50X3RpbWVzIjogIl9fX19fX19fX19fX19fX19fX19fX19fXyIKICAgICAgfSwKICAgICAgewogICAgICAgICJyZXdhcmRfYWRkcmVzcyI6ICJNeGVlODEzNDcyMTFjNzI1MjQzMzhmOTY4MDA3MmFmOTA3NDQzMzMxNDYiLAogICAgICAgICJ0b3RhbF9iaXBfc3Rha2UiOiAiMSIsCiAgICAgICAgInB1Yl9rZXkiOiAiTXA3MzhkYTQxYmE2YTdiN2Q2OWI3Mjk0YWZhMTU4Yjg5YzVhMWI0MTBjYmYwYzI0NDNjODVjNWZlMjRhZDFkZDFjIiwKICAgICAgICAiY29tbWlzc2lvbiI6ICIxMDAiLAogICAgICAgICJhY2N1bV9yZXdhcmQiOiAiMCIsCiAgICAgICAgImFic2VudF90aW1lcyI6ICJfX19fX19fX19fX19fX19fX19fX19fX18iCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAicmV3YXJkX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNmYxNmMxZmYyMWE2ZmI5NDZhYWVkMGY0YzFmY2NhMjcyYjcyZmQ5MDQ5ODhmOTFkMzg4MzI4MmI4YWUzMWJhMiIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAiYWNjdW1fcmV3YXJkIjogIjAiLAogICAgICAgICJhYnNlbnRfdGltZXMiOiAiX19fX19fX19fX19fX19fX19fX19fX19fIgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgInRvdGFsX2JpcF9zdGFrZSI6ICIxIiwKICAgICAgICAicHViX2tleSI6ICJNcDllMTNmMmY1NDY4ZGQ3ODJiMzE2NDQ0ZmJkNjY1OTVlMTNkYmE3ZDdiZDNlZmExYmVjZDUwYjQyMDQ1ZjU4YzYiLAogICAgICAgICJjb21taXNzaW9uIjogIjEwMCIsCiAgICAgICAgImFjY3VtX3Jld2FyZCI6ICIwIiwKICAgICAgICAiYWJzZW50X3RpbWVzIjogIl9fX19fX19fX19fX19fX19fX19fX19fXyIKICAgICAgfQogICAgXSwKICAgICJjYW5kaWRhdGVzIjogWwogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNGFlMWVlNzNlNjEzNmM4NWIwY2E5MzNhOWExMzQ3NzU4YTMzNDg4NWYxMGIzMjM4Mzk4YTY3YWMyZWIxNTNiOCIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNzM4ZGE0MWJhNmE3YjdkNjliNzI5NGFmYTE1OGI4OWM1YTFiNDEwY2JmMGMyNDQzYzg1YzVmZTI0YWQxZGQxYyIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wNmYxNmMxZmYyMWE2ZmI5NDZhYWVkMGY0YzFmY2NhMjcyYjcyZmQ5MDQ5ODhmOTFkMzg4MzI4MmI4YWUzMWJhMiIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9LAogICAgICB7CiAgICAgICAgInJld2FyZF9hZGRyZXNzIjogIk14ZWU4MTM0NzIxMWM3MjUyNDMzOGY5NjgwMDcyYWY5MDc0NDMzMzE0NiIsCiAgICAgICAgIm93bmVyX2FkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAidG90YWxfYmlwX3N0YWtlIjogIjEiLAogICAgICAgICJwdWJfa2V5IjogIk1wOWUxM2YyZjU0NjhkZDc4MmIzMTY0NDRmYmQ2NjU5NWUxM2RiYTdkN2JkM2VmYTFiZWNkNTBiNDIwNDVmNThjNiIsCiAgICAgICAgImNvbW1pc3Npb24iOiAiMTAwIiwKICAgICAgICAic3Rha2VzIjogWwogICAgICAgICAgewogICAgICAgICAgICAib3duZXIiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEiLAogICAgICAgICAgICAiYmlwX3ZhbHVlIjogIjEiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiY3JlYXRlZF9hdF9ibG9jayI6ICIxIiwKICAgICAgICAic3RhdHVzIjogMgogICAgICB9CiAgICBdLAogICAgImFjY291bnRzIjogWwogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXgzYmRlZTBkNjRmYTlhYzg5MjcyMGY0ODcyNGVmNmE0ZTI5MTlhNmJhIiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjgwMzgxNzAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXhlZTgxMzQ3MjExYzcyNTI0MzM4Zjk2ODAwNzJhZjkwNzQ0MzMzMTQ2IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjE2MTE0NTk4MTAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXhlNjczMmE5N2M2NDQ1ZWRiMGJlY2Y2ODVkZDkyNjU1YmI0YTFiODM4IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjE3MzE4NTkwMDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeDhiZWU5MmJhODk5OWFiMDQ3Y2I1ZTJkOThlMTkwZGFkYTRkN2EyYjIiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiODAzMTE4MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeDYwMTYwOWI4NWVlMjFiOTQ5M2RmZmJjYTEwNzljNzRkNDdiNzVmMmEiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiMTU4ODU3MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeDBhY2JkNWRmOWJjNGJkYzlmY2YyZjg3ZTgzOTM5MDc3Mzk0MDFhMjciLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiMzQ1MTIwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14ODlmNTM5NWEwMzg0NzgyNmQ2YjQ4YmIwMmRiZGU2NDM3Njk0NWEyMCIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICI5ODMzMjQ4MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeGY1ZDAwNjYwN2U5NDIwOTc4YjhmMzNhOTQwYTZmY2JjNjc3OTdkYjIiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiMjE4NzQ2MDAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXgxOTgyMDhlYjRkMTFkNGIzODlmZjI2MmFjNTI0OTRkOTIwNzcwODc5IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjEwNjMzMjAwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14ZTFkYmRlNWMwMmE3MzBmNzQ3YTQ3ZDI0ZjBmOTkzYzI3ZGE5ZGZmMSIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICI2MzY4MzcwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14MzVjNDA1NjNlZTUxODE4OTlkMGQ2MDU4MzllZGI5ZTk0MGIwZDhlNSIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICIzMzg2OTAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9LAogICAgICB7CiAgICAgICAgImFkZHJlc3MiOiAiTXg4ZGE0Zjk3YjYzNWNmNzUxZjJjMGYwMDIwZjJlNzhjZWI2OTFkN2Q1IiwKICAgICAgICAiYmFsYW5jZSI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImNvaW4iOiAiTU5UIiwKICAgICAgICAgICAgInZhbHVlIjogIjM3OTg0MTQwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14NTAwMDM4ODBkODdkYjJmYTQ4ZjZiODI0Y2RjZmVlYWIxYWM3NzczMyIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICIyMDM4MzA1MDAwMDAwMDAwMDAwMDAwMDAwIgogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgIm5vbmNlIjogIjAiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiYWRkcmVzcyI6ICJNeGRjZTE1NGI2ZTFkMDZiNDZlOTU4ODFiOTAwZWViMTY0ZTI0N2MxODAiLAogICAgICAgICJiYWxhbmNlIjogWwogICAgICAgICAgewogICAgICAgICAgICAiY29pbiI6ICJNTlQiLAogICAgICAgICAgICAidmFsdWUiOiAiNzU0MTQwMDAwMDAwMDAwMDAwMDAwMDAiCiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAibm9uY2UiOiAiMCIKICAgICAgfSwKICAgICAgewogICAgICAgICJhZGRyZXNzIjogIk14ZGM3ZmNjNjM5MzBiZjgxZWJkY2UxMmIzYmNlZjU3YjkzZTk5YTE1NyIsCiAgICAgICAgImJhbGFuY2UiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb2luIjogIk1OVCIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICI2ODI1ODAwMDAwMDAwMDAwMDAwMDAwMCIKICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJub25jZSI6ICIwIgogICAgICB9CiAgICBdLAogICAgIm1heF9nYXMiOiAiMTAwMDAwIiwKICAgICJ0b3RhbF9zbGFzaGVkIjogIjAiCiAgfQp9\"") } diff --git a/cmd/minter/main.go b/cmd/minter/main.go index 0076dad53..5cf9e566d 100644 --- a/cmd/minter/main.go +++ b/cmd/minter/main.go @@ -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) } @@ -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 { diff --git a/config/config.go b/config/config.go index 3b878dfa8..d371cef41 100644 --- a/config/config.go +++ b/config/config.go @@ -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" @@ -20,7 +27,9 @@ 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) @@ -28,13 +37,6 @@ var ( 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") @@ -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", @@ -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 } @@ -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()) diff --git a/config/toml.go b/config/toml.go index 28d9710c5..7a4c94bf8 100644 --- a/config/toml.go +++ b/config/toml.go @@ -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 }} diff --git a/core/minter/minter.go b/core/minter/minter.go index f80bfe54e..6cf4cf7e0 100644 --- a/core/minter/minter.go +++ b/core/minter/minter.go @@ -12,6 +12,7 @@ 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" @@ -19,6 +20,7 @@ import ( "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" @@ -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) @@ -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() diff --git a/core/state/statedb.go b/core/state/statedb.go index 39011eeb9..59277573b 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -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, @@ -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, @@ -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, @@ -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, @@ -1005,7 +1009,7 @@ func (s *StateDB) PayRewards() { }) } - validator.AccumReward.SetInt64(0) + validator.AccumReward.Set(remainder) } } @@ -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) @@ -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) } diff --git a/core/transaction/buy_coin.go b/core/transaction/buy_coin.go index d131cf495..c94ed1751 100644 --- a/core/transaction/buy_coin.go +++ b/core/transaction/buy_coin.go @@ -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, diff --git a/core/transaction/create_coin.go b/core/transaction/create_coin.go index 62f4f5f42..4ea136f5c 100644 --- a/core/transaction/create_coin.go +++ b/core/transaction/create_coin.go @@ -41,12 +41,6 @@ func (data CreateCoinData) BasicCheck(tx *Transaction, context *state.StateDB) * Log: "Incorrect tx data"} } - if !context.CoinExists(tx.GasCoin) { - return &Response{ - Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} - } - if len(data.Name) > maxCoinNameBytes { return &Response{ Code: code.InvalidCoinName, diff --git a/core/transaction/create_multisig.go b/core/transaction/create_multisig.go index da792a473..1d665fca0 100644 --- a/core/transaction/create_multisig.go +++ b/core/transaction/create_multisig.go @@ -23,12 +23,6 @@ func (data CreateMultisigData) TotalSpend(tx *Transaction, context *state.StateD } func (data CreateMultisigData) BasicCheck(tx *Transaction, context *state.StateDB) *Response { - if !context.CoinExists(tx.GasCoin) { - return &Response{ - Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} - } - if len(data.Weights) > 32 { return &Response{ Code: code.TooLargeOwnersList, diff --git a/core/transaction/declare_candidacy.go b/core/transaction/declare_candidacy.go index 23ad99faf..25fd9bc9c 100644 --- a/core/transaction/declare_candidacy.go +++ b/core/transaction/declare_candidacy.go @@ -35,7 +35,7 @@ func (data DeclareCandidacyData) BasicCheck(tx *Transaction, context *state.Stat Log: "Incorrect tx data"} } - if context.Height() > 5000 && !context.CoinExists(data.Coin) { + if !context.CoinExists(data.Coin) { return &Response{ Code: code.CoinNotExists, Log: fmt.Sprintf("Coin %s not exists", data.Coin)} diff --git a/core/transaction/edit_candidate.go b/core/transaction/edit_candidate.go index a3e23b902..f75bb5b52 100644 --- a/core/transaction/edit_candidate.go +++ b/core/transaction/edit_candidate.go @@ -104,12 +104,6 @@ func checkCandidateOwnership(data CandidateTx, tx *Transaction, context *state.S Log: "Incorrect tx data"} } - if !context.CoinExists(tx.GasCoin) { - return &Response{ - Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} - } - if !context.CandidateExists(data.GetPubKey()) { return &Response{ Code: code.CandidateNotFound, diff --git a/core/transaction/executor.go b/core/transaction/executor.go index c1ff55813..242761bab 100644 --- a/core/transaction/executor.go +++ b/core/transaction/executor.go @@ -46,6 +46,12 @@ func RunTx(context *state.StateDB, isCheck bool, rawTx []byte, rewardPool *big.I Log: err.Error()} } + if !context.CoinExists(tx.GasCoin) { + return Response{ + Code: code.CoinNotExists, + Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} + } + if isCheck && tx.GasPrice.Cmp(minGasPrice) == -1 { return Response{ Code: code.TooLowGasPrice, diff --git a/core/transaction/multisend.go b/core/transaction/multisend.go index 6fd88fe7c..6a6afaec6 100644 --- a/core/transaction/multisend.go +++ b/core/transaction/multisend.go @@ -36,12 +36,6 @@ func (data MultisendData) BasicCheck(tx *Transaction, context *state.StateDB) *R Log: err.Error()} } - if !context.CoinExists(tx.GasCoin) { - return &Response{ - Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} - } - return nil } diff --git a/core/transaction/redeem_check.go b/core/transaction/redeem_check.go index 23671ec30..2fe3096d0 100644 --- a/core/transaction/redeem_check.go +++ b/core/transaction/redeem_check.go @@ -37,6 +37,19 @@ func (data RedeemCheckData) BasicCheck(tx *Transaction, context *state.StateDB) Log: "Incorrect tx data"} } + if tx.GasCoin != types.GetBaseCoin() { + return &Response{ + Code: code.WrongGasCoin, + Log: fmt.Sprintf("Gas coin for redeem check transaction can only be %s", types.GetBaseCoin())} + } + + // fixed potential problem with making too high commission for sender + if tx.GasPrice.Cmp(big.NewInt(1)) == 1 { + return &Response{ + Code: code.TooHighGasPrice, + Log: fmt.Sprintf("Gas price for check is limited to 1")} + } + return nil } @@ -78,12 +91,6 @@ func (data RedeemCheckData) Run(tx *Transaction, context *state.StateDB, isCheck Log: err.Error()} } - if tx.GasCoin != types.GetBaseCoin() { - return Response{ - Code: code.WrongGasCoin, - Log: fmt.Sprintf("Gas coin for redeem check transaction can only be %s", types.GetBaseCoin())} - } - if !context.CoinExists(decodedCheck.Coin) { return Response{ Code: code.CoinNotExists, @@ -102,13 +109,6 @@ func (data RedeemCheckData) Run(tx *Transaction, context *state.StateDB, isCheck Log: fmt.Sprintf("Check already redeemed")} } - // fixed potential problem with making too high commission for sender - if tx.GasPrice.Cmp(big.NewInt(1)) == 1 { - return Response{ - Code: code.TooHighGasPrice, - Log: fmt.Sprintf("Gas price for check is limited to 1")} - } - lockPublicKey, err := decodedCheck.LockPubKey() if err != nil { diff --git a/core/transaction/sell_coin.go b/core/transaction/sell_coin.go index 04b997b93..2850baf4c 100644 --- a/core/transaction/sell_coin.go +++ b/core/transaction/sell_coin.go @@ -255,12 +255,6 @@ func (data SellCoinData) BasicCheck(tx *Transaction, context *state.StateDB) *Re Log: fmt.Sprintf("Coin not exists")} } - if !context.CoinExists(tx.GasCoin) { - return &Response{ - Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} - } - return nil } diff --git a/core/transaction/send.go b/core/transaction/send.go index 35306eb18..9d1f54548 100644 --- a/core/transaction/send.go +++ b/core/transaction/send.go @@ -64,12 +64,6 @@ func (data SendData) BasicCheck(tx *Transaction, context *state.StateDB) *Respon Log: fmt.Sprintf("Coin %s not exists", data.Coin)} } - if !context.CoinExists(tx.GasCoin) { - return &Response{ - Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} - } - return nil } diff --git a/core/transaction/unbond.go b/core/transaction/unbond.go index c6af21065..c08814e90 100644 --- a/core/transaction/unbond.go +++ b/core/transaction/unbond.go @@ -32,10 +32,10 @@ func (data UnbondData) BasicCheck(tx *Transaction, context *state.StateDB) *Resp Log: "Incorrect tx data"} } - if !context.CoinExists(tx.GasCoin) { + if !context.CoinExists(data.Coin) { return &Response{ Code: code.CoinNotExists, - Log: fmt.Sprintf("Coin %s not exists", tx.GasCoin)} + Log: fmt.Sprintf("Coin %s not exists", data.Coin)} } if !context.CandidateExists(data.PubKey) { diff --git a/testnet/minter-test-network-37/genesis.json b/testnet/minter-test-network-37/genesis.json new file mode 100644 index 000000000..41dcbab2b --- /dev/null +++ b/testnet/minter-test-network-37/genesis.json @@ -0,0 +1,281 @@ +{ + "genesis_time": "2019-04-09T17:00:00Z", + "chain_id": "minter-test-network-37", + "consensus_params": { + "block": { + "max_bytes": "10000000", + "max_gas": "100000", + "time_iota_ms": "1000" + }, + "evidence": { + "max_age": "1000" + }, + "validator": { + "pub_key_types": [ + "ed25519" + ] + } + }, + "app_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "app_state": { + "start_height": "0", + "validators": [ + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp4ae1ee73e6136c85b0ca933a9a1347758a334885f10b3238398a67ac2eb153b8", + "commission": "100", + "accum_reward": "0", + "absent_times": "________________________" + }, + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp738da41ba6a7b7d69b7294afa158b89c5a1b410cbf0c2443c85c5fe24ad1dd1c", + "commission": "100", + "accum_reward": "0", + "absent_times": "________________________" + }, + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp6f16c1ff21a6fb946aaed0f4c1fcca272b72fd904988f91d3883282b8ae31ba2", + "commission": "100", + "accum_reward": "0", + "absent_times": "________________________" + }, + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp9e13f2f5468dd782b316444fbd66595e13dba7d7bd3efa1becd50b42045f58c6", + "commission": "100", + "accum_reward": "0", + "absent_times": "________________________" + } + ], + "candidates": [ + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "owner_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp4ae1ee73e6136c85b0ca933a9a1347758a334885f10b3238398a67ac2eb153b8", + "commission": "100", + "stakes": [ + { + "owner": "Mxee81347211c72524338f9680072af90744333146", + "coin": "MNT", + "value": "1", + "bip_value": "1" + } + ], + "created_at_block": "1", + "status": 2 + }, + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "owner_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp738da41ba6a7b7d69b7294afa158b89c5a1b410cbf0c2443c85c5fe24ad1dd1c", + "commission": "100", + "stakes": [ + { + "owner": "Mxee81347211c72524338f9680072af90744333146", + "coin": "MNT", + "value": "1", + "bip_value": "1" + } + ], + "created_at_block": "1", + "status": 2 + }, + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "owner_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp6f16c1ff21a6fb946aaed0f4c1fcca272b72fd904988f91d3883282b8ae31ba2", + "commission": "100", + "stakes": [ + { + "owner": "Mxee81347211c72524338f9680072af90744333146", + "coin": "MNT", + "value": "1", + "bip_value": "1" + } + ], + "created_at_block": "1", + "status": 2 + }, + { + "reward_address": "Mxee81347211c72524338f9680072af90744333146", + "owner_address": "Mxee81347211c72524338f9680072af90744333146", + "total_bip_stake": "1", + "pub_key": "Mp9e13f2f5468dd782b316444fbd66595e13dba7d7bd3efa1becd50b42045f58c6", + "commission": "100", + "stakes": [ + { + "owner": "Mxee81347211c72524338f9680072af90744333146", + "coin": "MNT", + "value": "1", + "bip_value": "1" + } + ], + "created_at_block": "1", + "status": 2 + } + ], + "accounts": [ + { + "address": "Mxe6732a97c6445edb0becf685dd92655bb4a1b838", + "balance": [ + { + "coin": "MNT", + "value": "17351769000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx89f5395a03847826d6b48bb02dbde64376945a20", + "balance": [ + { + "coin": "MNT", + "value": "9861716000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx3bdee0d64fa9ac892720f48724ef6a4e2919a6ba", + "balance": [ + { + "coin": "MNT", + "value": "803817000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx8bee92ba8999ab047cb5e2d98e190dada4d7a2b2", + "balance": [ + { + "coin": "MNT", + "value": "803118000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mxdce154b6e1d06b46e95881b900eeb164e247c180", + "balance": [ + { + "coin": "MNT", + "value": "75414000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mxdc7fcc63930bf81ebdce12b3bcef57b93e99a157", + "balance": [ + { + "coin": "MNT", + "value": "68258000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx198208eb4d11d4b389ff262ac52494d920770879", + "balance": [ + { + "coin": "MNT", + "value": "1063320000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx601609b85ee21b9493dffbca1079c74d47b75f2a", + "balance": [ + { + "coin": "MNT", + "value": "158857000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx0acbd5df9bc4bdc9fcf2f87e8393907739401a27", + "balance": [ + { + "coin": "MNT", + "value": "34512000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mxf5d006607e9420978b8f33a940a6fcbc67797db2", + "balance": [ + { + "coin": "MNT", + "value": "2190487000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx50003880d87db2fa48f6b824cdcfeeab1ac77733", + "balance": [ + { + "coin": "MNT", + "value": "2057729000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx35c40563ee5181899d0d605839edb9e940b0d8e5", + "balance": [ + { + "coin": "MNT", + "value": "33869000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mxee81347211c72524338f9680072af90744333146", + "balance": [ + { + "coin": "MNT", + "value": "161050432000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mx8da4f97b635cf751f2c0f0020f2e78ceb691d7d5", + "balance": [ + { + "coin": "MNT", + "value": "3809865000000000000000000" + } + ], + "nonce": "0" + }, + { + "address": "Mxe1dbde5c02a730f747a47d24f0f993c27da9dff1", + "balance": [ + { + "coin": "MNT", + "value": "636837000000000000000000" + } + ], + "nonce": "0" + } + ], + "max_gas": "100000", + "total_slashed": "0" + } +} \ No newline at end of file diff --git a/version/version.go b/version/version.go index 85ef7dc34..b2d4f1932 100755 --- a/version/version.go +++ b/version/version.go @@ -3,15 +3,15 @@ package version // Version components const ( Maj = "0" - Min = "17" - Fix = "1" + Min = "18" + Fix = "0" AppVer = 4 ) var ( // Must be a string because scripts like dist.sh read this file. - Version = "0.17.1" + Version = "0.18.0" // GitCommit is the current HEAD set using ldflags. GitCommit string