Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - JianJolly

Pages: [1]
1
General Discussion / Re: Jolly Scripts
« on: May 01, 2017, 12:07:11 am »
I added a simple market making script.

This one fetches price data from an outer source (this source is Bitstamp below) and gives market making orders in the DEX. Bitstamp's "last price" in the BTC/USD market is converted to TRY via python-forex, and this data is checked once a minute. The script gives bid orders at the prices which are 1%, 1.5% and 2% lower than the "last price", and records the price as Bot.ref_price, i.e., the reference price. Three corresponding ask orders are also given at the prices which are 1%, 1.5% and 2% above the reference price. If the price source changes more than 0.5% according to the reference price, the orders are canceled and a new set of bids and asks are given, changing the reference price.

2
General Discussion / Re: Jolly Scripts
« on: April 05, 2017, 02:01:32 pm »
Try this:

Code: [Select]
[code block omitted from the quote for a clearer view]

Remark: The "difficult" looking stuff in the return of index() is only to "stringify" each of the keys in the market ticker dictionary.
This makes the output look 'nice'. If you where to return 'ticker' directly with  "return jsonify(ticker)" .. you would get a whole lot more information that is unfortunately, way less useful for most people :D

Thanks for the insight! Yes, I tried json.dumps(market.ticker()) and it gave a lot more information. In my example, I manually do all the work which is done by the two Flask modules in your version. There is one question, though. When we construct the webpage with Flask's route, does the script send a request to the API node each time someone browses the page? If so, I'd go with the more primitive file writing-reading version.

Best,

Jian

3
General Discussion / Jolly Scripts
« on: April 04, 2017, 08:16:24 pm »
Hi Everyone,

Here I will put some of the things I am playing with, and hope that it will go in a meaningful direction as I have more goodies to put together.

* ticker *

The first one is a ticker for the markets in the BTS DEX. It depends on pybitshares, and is meant to run as a daemon which has the permission to write to a file on a web server. It chekcs the ticker and waits for 60 seconds, and repeats this forever. The web server will be public for everyone to request ticker instead of requesting it from the API directly, thereby reducing the load.

A concern that may come out of this would be about security. Let's say a bot uses this ticker to yield trading signals. Thus, one of the things on which the reliability of the bot depends is the quality of the ticker. Concerning that, what preventive measures could the server running the script take in order to minimize the relevant risks? That is the question I am now working on.


Code: [Select]
#!/usr/bin/env python3


from time import sleep
from json import dumps
from math import floor

from bitshares import BitShares
from bitshares.instance import set_shared_bitshares_instance
from bitshares.market import Market
from bitshares.blockchain import Blockchain


def value(string, decimals):
    num_string = str.split(str(string))[0]
    no_comma = ""
    for char in num_string:
      if (char != ','):
        no_comma += char
    return round_down(float(no_comma), decimals)

def round_down(number, decimals):
    return floor(number * pow(10, decimals)) / pow(10, decimals)

def ticker(market_string, decimals=[8,8]):
    """ e.g. market_string = "OPEN.BTC:KAPITAL"
        e.g. decimals = [8, 5] """
    try:

        (quote, base) = market_string.split(":")
        if (base == "KAPITAL"):
            decimals[1] = 5
        bitshares = BitShares("wss://eu.openledger.info/ws")
        # alternative: wss://secure.freedomledger.com/ws
        # wss://eu.openledger.info/ws
        set_shared_bitshares_instance(bitshares)
        chain = Blockchain()
        block_num = chain.get_current_block_num()
        market = Market(market_string)
        ticker = market.ticker()
        last = value(ticker["latest"], decimals[1])
        try:
            avg = round_down(value(ticker["baseVolume"], decimals[1]) / \
            value(ticker["quoteVolume"], decimals[0]), decimals[1])
        except:
            avg = last
        change = format(ticker["percentChange"] / 100, '.5f')
        # e.g. for 1.2% change, change = 1.2

        response = {
            "status": "success",
            "data": {
                "market": market_string,
                # max and min values are to be added
                # "max": max_value,
                # "min": min_value,
                "avg": avg,
                "vol": value(ticker["quoteVolume"], decimals[0]),
                "bid": value(ticker["highestBid"], decimals[1]),
                "ask": value(ticker["lowestAsk"], decimals[1]),
                "last": last,
                "change": change
            },
            "message": "Block: " + str(block_num)
        }
        return response
    except Exception as e:
        return {"status": "error", "data": {}, "message": e}


if __name__ == "__main__":
    while True:
        market_dict = {"btc": "OPEN.BTC:KAPITAL", "eth": "OPEN.ETH:KAPITAL",
                       "bts": "BTS:KAPITAL", "dash": "OPEN.DASH:KAPITAL",
                       "usd": "OPEN.USDT:KAPITAL", "doge": "OPEN.DOGE:KAPITAL",
                       "maid": "OPEN.MAID:KAPITAL", "ltc": "OPEN.LTC:KAPITAL" }
        for k in market_dict:
            response = ticker(market_dict[k])
            print(response)
            if (response["status"] == "success"):
                # with open("/var/www/html/ticker/" + k + ".json", "w") as f:
                # with open(k + ".json", "w") as f:
                with open(k + ".json", "w") as f:
                    response_text = dumps(response,
                                          indent=4,
                                          separators=(',', ': '))
                    f.write(response_text)
            else:
                print(response["message"])
            sleep(6)

The outputs may be seen here: https://bitkapital.com/ticker/


* market-maker *

This one fetches price data from an outer source (this source is Bitstamp below) and gives market making orders in the DEX. Bitstamp's "last price" in the BTC/USD market is converted to TRY via python-forex, and this data is checked once a minute. The script gives bid orders at the prices which are 1%, 1.5% and 2% lower than the "last price", and records the price as Bot.ref_price, i.e., the reference price. Three corresponding ask orders are also given at the prices which are 1%, 1.5% and 2% above the reference price. If the price source changes more than 0.5% according to the reference price, the orders are canceled and a new set of bids and asks are given, changing the reference price.


Code: [Select]
#!/usr/bin/env python3


import json
from math import floor
from time import sleep
from datetime import datetime
from datetime import timedelta

# from the package forex-python
from forex_python.converter import CurrencyRates

import bitfinex
from poloniex.poloniex import Poloniex
from bitstamp import bitstamp

from bitshares.bitshares.bitshares import BitShares
from bitshares.bitshares.instance import set_shared_bitshares_instance
from bitshares.bitshares.market import Market
from bitshares.bitshares.account import Account


TIME_ZONE = 3
LOG_PATH = "/var/www/html/"
LOG_FILENAME = "index.html"


def round_down(number, decimals):
    return floor(number * pow(10, decimals)) / pow(10, decimals)

def append_log(msg, path=LOG_PATH, filename=LOG_FILENAME, timestamp=True):
    try:
        with open(path + filename, "r") as f:
            contents = f.read()
    except:
        contents = ""

    with open(path + filename, "w") as f:
        if timestamp:
            today = datetime.utcnow() + timedelta(hours=TIME_ZONE)
            if today.month is 1:
                month = "Ocak"
            elif today.month is 2:
                month = "Subat"
            elif today.month is 3:
                month = "Mart"
            elif today.month is 4:
                month = "Nisan"
            elif today.month is 5:
                month = "Mayis"
            elif today.month is 6:
                month = "Haziran"
            elif today.month is 7:
                month = "Temmuz"
            elif today.month is 8:
                month = "Agustos"
            elif today.month is 9:
                month = "Eylul"
            elif today.month is 10:
                month = "Ekim"
            elif today.month is 11:
                month = "Kasim"
            elif today.month is 12:
                month = "Aralik"
            if today.hour < 10:
                hour = "0" + str(today.hour)
            else:
                hour = str(today.hour)
            if today.minute < 10:
                minute = "0" + str(today.minute)
            else:
                minute = str(today.minute)

            contents = str(today.day) + ' ' + month + ' ' + str(today.year) + \
                " " + hour + ":" + minute + " ||| " + msg + "<br/>\n" + contents
        else:
            contents = msg + "<br/>\n" + contents

        f.write(contents)

class Price(object):
    def __init__(self, ref_price):
        self.forex_USDTRY = CurrencyRates().get_rates("USD")["TRY"]

        self.polo_ticker = Poloniex("", "").returnTicker()["USDT_BTC"]
        self.polo_BTCTRY = round(float(self.polo_ticker["last"]) * \
                                 self.forex_USDTRY, 5)

        self.finex_ticker = bitfinex.publicAPI.Ticker("BTCUSD").response
        self.finex_BTCTRY = round(float(json.loads(self.finex_ticker)
                                  ["last_price"]) * self.forex_USDTRY, 5)

        self.stamp_ticker = bitstamp.client.Public().ticker()
        self.stamp_BTCTRY = round(float(self.stamp_ticker["last"]) * \
                                  self.forex_USDTRY, 5)

        if ref_price is "":
            self.ref_price = {"source": ref_price, "value": -1}
        elif ref_price is "polo_BTCTRY":
            self.ref_price = {"source": ref_price, "value": self.polo_BTCTRY}
        elif ref_price is "finex_BTCTRY":
            self.ref_price = {"source": ref_price, "value": self.finex_BTCTRY}
        elif ref_price is "stamp_BTCTRY":
            self.ref_price = {"source": ref_price, "value": self.stamp_BTCTRY}

    def update(self):
        self.__init__(self.ref_price["source"])
        return self

class Bot(object):
    def __init__(self, wss, WIF, price_source):
        # initialize bitshares instance, account, market, and reference price
        self.bitshares = BitShares(wss, keys=[WIF], expiration=6000)
        set_shared_bitshares_instance(self.bitshares)
        self.account = Account("market-buster", full=True)
        self.market = Market("OPEN.BTC:KAPITAL")
        self.price_obj = Price(price_source)

        # strategy params
        # minimum change in the price source to trigger trade
        self.trigger_threshold = 0.005
        # waiting period between each market check in minutes
        self.waiting_period = 1
        # profit margins for the order grid
        self.profit_margins_normal = [0.01, 0.015, 0.02]
        self.profit_margins_tight = [0.004, 0.005, 0.006]

    def open_orders(self):
        return Account("market-buster", full=True).openorders

    def cancel_all(self):
        open_orders = [order["id"] for order in self.open_orders()]
        if len(open_orders)> 0:
            self.market.cancel(open_orders, account="market-buster")
            append_log("Tum emirler iptal edildi.")

    def balances(self, log=False):
        """
        make sure self.ref_price is up-to-date
        when calling this method with log=True
        """
        try: KAPITAL = self.account.balance("KAPITAL").amount
        except: KAPITAL = 0
        try: BTC = self.account.balance("OPEN.BTC").amount
        except: BTC = 0

        if log:
            append_log("Bakiye: " + str(KAPITAL) + " KAPITAL, " + str(BTC) + \
                       " OPEN.BTC. Guncel hesap degeri: " + \
                       str(round_down(KAPITAL + BTC * self.ref_price, 2)) + \
                       " TL")

        return {"KAPITAL": KAPITAL, "BTC": BTC}

    def run(self):
        self.ref_price = self.price_obj.update().ref_price["value"]
        append_log("Referans fiyat: " + str(self.ref_price))
        while True:
            self.cancel_all()
            self.balance = self.balances(log=True)

            # strategy rule 1: profit margins
            KAPITAL_ratio = self.balance["KAPITAL"] / (self.balance["KAPITAL"] \
                            + self.balance["BTC"] * self.ref_price)
            if (KAPITAL_ratio < 0.125):
                profit_margins_bid = self.profit_margins_normal
                profit_margins_ask = self.profit_margins_tight
                append_log("Dusuk KAPITAL bakiyesi. Satis marji dusuruldu.")
            if (KAPITAL_ratio > 0.875):
                profit_margins_bid = self.profit_margins_tight
                profit_margins_ask = self.profit_margins_normal
                append_log("Dusuk BTC bakiyesi. Alis marji dusuruldu.")
            # end strategy

            # strategy rule 2: bid
            balance_per_bid = round_down(self.balance["KAPITAL"] / \
                len(profit_margins_bid), 5)
            for i, profit_margin in enumerate(profit_margins_bid):
                price = round_down(self.ref_price * (1 - profit_margin), 5)
                amount = round_down(balance_per_bid / price, 8)
                if amount > 0:
                    self.market.buy(price, amount, account="market-buster")
                    append_log("BID @ " + str(price))
                elif i is 0:
                    append_log("YETERSIZ BAKIYE! KAPITAL yukleyin.")
            # end strategy

            # strategy rule 3: ask
            balance_per_ask = round_down(self.balance["BTC"] / \
                len(profit_margins_ask), 8)
            for i, profit_margin in enumerate(profit_margins_ask):
                price = round_down(self.ref_price * (1 + profit_margin), 5)
                amount = balance_per_ask
                if amount > 0:
                    self.market.sell(price, amount, account="market-buster")
                    append_log("ASK @ " + str(price))
                elif i is 0:
                    append_log("YETERSİZ BAKİYE! BTC yükleyin.")
            # end strategy

            sleep(self.waiting_period * 60)

            while True:
                # strategy rule 4: price update
                new_price = self.price_obj.update().ref_price["value"]
                upper_threshold = self.ref_price * (1 + self.trigger_threshold)
                lower_threshold = self.ref_price * (1 - self.trigger_threshold)

                if new_price >= upper_threshold or new_price <= lower_threshold:
                    append_log("Referans fiyat: " + str(self.ref_price) + \
                               " --> " + str(new_price))
                    self.ref_price = new_price
                    break
                # end strategy

                # strategy rule 5: filled orders
                no_bid = True
                no_ask = True
                orders = self.open_orders()
                for order in orders:
                    if order["base"]["asset"]["symbol"] == "KAPITAL" and \
                       order["quote"]["asset"]["symbol"] == "OPEN.BTC":
                        no_bid = False
                    if order["base"]["asset"]["symbol"] == "OPEN.BTC" and \
                       order["quote"]["asset"]["symbol"] == "KAPITAL":
                        no_ask = False

                should_break = False
                self.balance = self.balances()
                if no_bid:
                    if round_down(round_down(self.balance["KAPITAL"] / \
                       len(self.profit_margins), 5) / new_price, 8) > 0:
                        self.ref_price = new_price
                        should_break = True
                if no_ask:
                    if round_down(self.balance["BTC"] / \
                       len(self.profit_margins), 5) > 0:
                        self.ref_price = new_price
                        should_break = True
                if should_break:
                    break
                # end strategy

                sleep(self.waiting_period * 60)


if __name__ == "__main__":
    wss = "wss://eu.openledger.info/ws"
    WIF = "<WIF>"
    price_source = "stamp_BTCTRY"
    bot = Bot(wss, WIF, price_source)
    bot.run()

You may just disregard the append_log function, which has some Turkish in it for logging purposes.

4
General Discussion / Re: Semi-centralized smart contracts on Bitshares
« on: March 30, 2017, 02:17:26 am »
There we go with some prototyping ideas: https://bitcointalk.org/index.php?topic=1847669.msg18385614

5
General Discussion / Re: Transaction Throughput Testing
« on: March 19, 2017, 08:59:06 pm »
Is there any plan to stress the mainnet as well?
Makes no sense .. it's expensive and uses the same software .. so why would we?

Hence I added this to the OP: "Conducting the stress test on the mainnet is canceled because of the conclusiveness of the test on the testnet."

6
General Discussion / Re: Transaction Throughput Testing
« on: March 19, 2017, 12:38:16 pm »
Thank you everyone for participating in the stress test.

Is there any plan to stress the mainnet as well?

7
General Discussion / Re: bitshares asset KAPITAL can't sell???
« on: March 14, 2017, 11:03:51 am »
There was a short period of time where we accidentally turned off the whitelist/blacklist feature. It was basically because we wanted to update something with the asset, and did it through the light client. The light client doesn't have the feature of defining whitelist authorities added, and whenever you update an asset detail through the light client, it automatically empties the asset's whitelist authority list. Luckily we realized the situation shortly, and updated the whitelist authority list once more to fix it. Apparently, you acquired the assets during that short interval.

8
General Discussion / Re: Semi-centralized smart contracts on Bitshares
« on: March 12, 2017, 07:52:41 pm »
Why promote a centralized scheme? What value is provided through it that can't be provided in a decentralized way?

The scheme is not centralized, though it makes the involvement of centralized components possible. That being said, what those centralized components would bring are speed and low weight of execution, and convenience in production.

9
General Discussion / Semi-centralized smart contracts on Bitshares
« on: March 10, 2017, 10:27:34 am »
I am copying the following text in order not to lose the concise definition of what I have had in mind for some time. It is originally from Bitshares Telegram channel, and written in a rather less elaborate way in a chatting manner.

-

I can summarize it as follows. There is an asset, whose issuer is a multisig account. Each of the keys controlling the account is held by a node running in a separate server. The asset's transfer-restricted flag is on, meaning that each and every transaction involving the asset will have to be approved by the issuer account, which means that each of those separate servers will have to approve the transaction independently.

Now, the model I propose assumes a central server where everyone can propose tx. So, let's say Alice wants to send 10 tokens to Bob. She cannot do it by herself, because the transaction has to be approved by the issuer. How it works is that she proposes the tx in order for the issuer to approve. So, she pushes a proposed tx to the centralized server. That server is just a place to host an unsigned proposed tx list and nothing else. The issuer then comes and sees that there is a proposed tx, by which Alice wants to send 10 tokens to Bob.

When the "issuer nodes" (i.e., the nodes which hold the keys that constitute the multisig issuer account) see the proposed transaction, there are two options. Tx will be approved or not. Now, the issuer nodes can do ANYTHING to decide whether or not to allow the transaction - hence semi-centralized smart contracts.

For instance, let's say that token can only be sent to the VIP members of the service that the issuer provides (one is free to be as imaginative as possible in this phase, since anything is possible, but let me stick with this simplest exampe). So, let's say Alice is a VIP member and Bob isn't - in that case the tx won't be approved. The decision for or against this transaction is done by the nodes. The nodes can use whatever database they wish, and execute the process which checks whether Bob is a VIP member in any programming language that they like.

This I believe is superior to decentralized smart contracts, in that, this one necessitates that the contracts are executed by a number of nodes and not by the entire blockchain participants. Hence, less likelihood of bloating, and super fast execution possibilities. Also, auditability, transparency and immutability stay with us.

10
General Discussion / Re: User Stats Poll
« on: March 08, 2017, 01:38:34 pm »
Thanks for participating. Seems like our traders have wide portfolios.

11
General Discussion / User Stats Poll
« on: March 07, 2017, 04:08:02 pm »
The poll's aim is to evaluate the user needs in order to guide the UX development.

12
General Discussion / Re: Pegged Cryptocurrencies for Remittances
« on: January 30, 2017, 08:34:42 am »
Even if OpenLedger were to disappear, what stops another gateway from stepping up and accepting Open assets in exchange for their asset?   Trades on Open assets generate a fee given to the issuer, another gateway could simply swap these out.  open.steem vs BitUSD would become blocktrades.steem vs BitUSD for example.

The issuer holds the reserve backing the asset. If the issuer disappears, it also means that the reserve disappears. Without the reserve, another exchange cannot offer the service you mention.


and without liquidity its even riskier since you may not be able to close your positions.
i would like to clarify this by saying that position can always be settled 1:1 for the underlying collateral; this is not a market sell operation but a smart contract that will destroy the smartcoin being settled and release the collateral to the settler at the price feed.

I think the hypothetical situation he refers involves the inability to get back the bitassets after creating and spending them. So, the question is: What if I buy all those $100k-worth bitUSD, and refuse to give them back? Creators of the bitassets would be willing to give more than 1 USD per 1 bitUSD, because according to their contract, they may get $2-worth of BTS per bitUSD. So this is a lose-lose situtation.

13
General Discussion / Re: Pegged Cryptocurrencies for Remittances
« on: January 29, 2017, 08:59:41 pm »
Hi George,

First of all, welcome! I hope you will get some clues from this community for the benefit of your venture. I read your CoinDesk article, and will try to continue your line of thought. To restate it, the issue is enabling cross-border micropayments. In that regard, cryptocurrencies have proven to bring forth one big advantage and an equally important drawback. The advantage is obviously that the transfer of value-bearing assets is made easy. The drawback is that one is limited to a specific asset group in such operations (i.e., cryptocurrencies), which obligates the existence of local cashflow nodes (i.e., fiat-to-crypto exchanges).

Let us restrict ourselves with US dollar remittances, since even that remains unsolved. If Alice, who is in the US, wants to send $200 to Bob, who is in EU, she would exchange her dollars for, say, bitcoins, and send the bitcoins to Bob, who will then exchange the bitcoins for dollars. In this case, the imbalance between US-to-EU transfers and EU-to-US transfers (cf. "P2P netting of payments" in your CoinDesk article) is resolved by way of arbitragers.

As for fiat-pegged crypto-assets, they seem to be an abstraction layer on top of the abovementioned dollar->bitcoin->dollar method. As such, they bring a new set of solutions and problems. The solution is, again, obvious; easy transfer of dollars. However, if Alice is to send a fiat-pegged crypto-asset to Bob, she will still need to convert her dollars to crypto-dollars to begin with. In this case, again, centralized local institutions may help. But this time those institutions need to agree on an interoperability framework which must provide not only the reliable transfer capabilities but also a crypto-dollar the validity of whose pegging is beyond local circumstances. This requirement holds regardless of how the pegging is undertaken.

Now, fundamentals: There is no taking without giving. In order to get a fiat-pegged asset, one needs to put some value somewhere. Let's say Alice buys 200 crypto-USD from the local vendor by depositing $200. As Bob gets the pegged assets, he will need to cash them out for dollars. But the $200 is still in Alice's jurisdiction. Thus, there needs to be a backend where the local vendor converts Alice's deposited money into the underlying cryptocurrency and sends it to Bob's jurisdiction at the same moment when Alice transfers the $200-worth crypto-assets. Not only this, but also the local vendor in Bob's jurisdiction should convert the underlying cryptocurrency into dollars in order to transfer them to Bob's bank account.

This model calls for the entire set of problems associated with liquidity and credit risk management. One might ask at this point why Alice buys the crypto-dollars by depositing dollars. She may as well use a cryptocurrency such as bitcoin to acquire the said asset. However, as has been said, the fiat-pegged cypto-asset already serves as an abstraction layer to this process. So it would be in this case meaningless to send the fiat-pegged crypto-assets instead of the underlying cryptocurrency. To approach the problem from another perspective, Alice needs to deposit dollars at some point in order to get the cryptocurrency in anyways. Hence, if Alice directly uses dollars to buy crypto-dollars, it means this: Alice asks her local vendor to make the conversion on behalf of herself. Well, it sounds like this is a service. As a service, it should cost something. So the question is whether or not it would cost more than SWIFT.

To restate a cardinal point, those considerations do not depend on how the pegging is undertaken. The vendor may faciliate Nubits or Bitshares, and bitcoins or other cryptocurrencies may be utilized as collateral. It does not matter. In the end, Alice will need to get that pegged asset. As far as my research goes, there is no fulfilling solution to this problem which is publicly discussed. Notwithstanding, I believe I have found a solution which does not at all depend on the idea of pegging, but rather on playing with the fundamental logic of "no taking without giving." If somehow Alice could deposit dollars without actually depositing cash, and if this process would yield a kind of blockchain entity, then there might be a novel path upon us. But I will not go into the details of that.

Returning to an earlier issue, if there are local exchanges enabling dollar-to-cryptodollar conversion back and forth, then different exchanges located in different parts of the world should work with one and the same crypto-dollar asset whose value they all agree is pegged to dollar. Begging help from central banks won't work, since using blockchain cannot magically help them solve the issues which prevent them to facilitate real-time cross-border settlements. Utilizing a centrally issued crypto-asset (such as TetherUSD) won't work either, since it involves a considerable default risk. One may think that a licensed multinational money transfer agent (such as PayPal) could issue the needed crypto-asset. However, again, utilizing blockchain could hardly solve the problems that prevent PayPal to allow seamless and cost-efficient cross-border operations.

As for bitUSD or Nubits, as far as the issue of cross-border settlement is considered, they serve as nothing but an abstraction layer on top of sending the underlying cryptocurrency, leaving all the liquidity management problems unsolved. Therefore, a shift of focus is needed. We need to understand that the problem is not in designing a fiat-pegged crypto-asset, but in managing liquidity and other risks. Take BitPay as an example. They do not have a fiat-pegged crypto-asset. They take 1% fee, and they make it possible to pay in fiat with bitcoins. We thus need a similar complementary structure with which one may pay in fiat with fiat - but with the intermediation of a reserve cryptocurrency.

That is all I have to say for now. There are much to discuss about how to structure a solution for the last point I made, but I feel that I have already written too much.

Best,

Jian

14
General Discussion / Transaction Throughput Testing
« on: December 27, 2016, 02:25:47 pm »
Motivation

Scalability of consensus protocol implementations is a well known and much debated issue, in which the capacity of a blockchain to handle a large number of transactions per second plays a central role. In this regard, to test the performance of the Graphene technology, on which Bitshares is built, a group of people from the community have expressed their willingness to conduct a collaborative performance test on Bitshares. The aim of the test is to get a measure of the platform's transaction throughput by trying to execute a heavy load of transactions on the blockchain.


Design

A script will be run by multiple participants to broadcast transactions. The participants will agree on a time to run the script, and flood the network at that time for a predetermined timespan. There is no upper limit to the load of transactions, which means that more participants and better testing environment will result in a higher load.

There will be multiple phases of the test, described as follows:

Phase I: The participants will broadcast transactions at the same time with the same delay between each transaction for 1 minute.
Phase II: The participants will broadcast transactions at random times with a random delay between transactions for 1 minute.
Phase III: The participants will broadcast as many transactions as possible for 10 minutes.


Implementation

The testing will first be performed on the testnet, for which the conditions will be emulated to the mainnet environment. To this end, a total of 30 witness nodes will be installed and the necessary configurations will be made for them to get an active witness status on the testnet. Afterwards, the testing script will be written and tested by individual participants. The participants will then agree on a time to start the testing on the testnet.

As many statistically significant details as possible about the test results will be collected, compiled, visualized, interpreted, and published. A member or a group of members from the community will be chosen to execute the post-testing work.

The details of the mainnet testing will be determined later.


Roadmap

- Installation & configuration of the necessary number of testnet witness nodes.
- Writing the testing script & individual sanity checks.
- Agreeing on a time & agreeing on the details of the post-testing work.
- Performing the test on the testnet.
- Collection, refinement, and presentation of the test results.
- Deciding for the details of the mainnet testing.


Call for Participants

Please write under this thread to participate in the test for the swift communication and easy resource handling.


Relevant Links

Bitshares Telegram group: https://telegram.me/BitSharesDEX
Graphene testnet repo: https://github.com/BitSharesEurope/graphene-testnet
Documentation for producing witness nodes: http://docs.bitshares.org/bitshares/tutorials/witness-howto.html


Result

The test conducted on the testnet has successfully shown that the Bitshares network could process 3300 transactions per second. For more details, see the following post:

1h30 min BitShares Stress Test of the 15 March 2017 - 3300TXs 14000OPs

Conducting the stress test on the mainnet is canceled because of the conclusiveness of the test on the testnet.

Pages: [1]