GithubHelp home page GithubHelp logo

federatedsidechains's People

Contributors

arcsin2000x avatar bokobza avatar carlton355 avatar codingupastorm avatar dangershony avatar ferdeen avatar imclint21 avatar justintopham avatar mithrilman avatar monsieurleberre avatar noescape00 avatar quantumagi avatar rowandh avatar stratisiain avatar tkaic666 avatar zeptin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

federatedsidechains's Issues

Define key functionalities for the federation dashboard

We need to come up with a bunch of functionalities that a sidechain dashboard needs to offer, and if it is in scope for this first prod release...

Each member/node could offer a few API endpoints to report

  • Status of other members/nodes (maybe push warnings on members unavailability)
  • Query status of transfers by source or target address, by block number, for each transfer
    • transfer details
    • session leader table
    • amounts and target address
    • current transaction template state (pending maturity, initiated, signed by 1,2,3 members, in mempool, on chain, on chain and matured, rejected)
  • Query tranfers by status for date range
  • Current (and future for the next 5-10 blocks) transfer session leaders (for both chains)
  • Current (and future for the next 5-10 blocks) block producer (for POA)
  • Multisig addresses and balance (confirmed, pending)
  • Trigger node resync (resync chains)
  • Trigger session reset (resync cross chain transfers since block X), this is needed for recovery after an offline period anyway

Rework the way transfer session

In the current implementation, sessions for transfering coins from chainA to chainB work this way:

For the block at height H on chainA

  • Read all deposits made to the multisig on chainA + corresponding OP_RETURNS
  • If any, then derive from H a table ordering preferred leader for the given block
  • If leader 1 is online, leader 1 generates a session containing all transaction deposit transaction number on block H + corresponding OP_RETURNS, then shares it with other federated node to warn them they should expect to sign a few transactions soon
  • leader 1 creates a chain B transaction template for all transactions found on chain A's block H, propagates it to other fed members
  • chainB members sign transaction template and return it until quorum
  • leader 1 sends the signed transaction

Problems are
1 - sessions are not persisted so failure of leader node mid transfer is likely to result in an inconsistent state #76
2 - picking up a sessions started by another node which went down is not tested well enough
3 - better naming in the code would improve readability

Solution

  • use a database or a message queue to react to and persist session states
  • monitor the target chain and match transaction to close the sessions
  • sessions that are not closed can be monitored and picked up from the store / message queue

BlockObverver.OnNextCore must not try to extract deposits from the latest block

In this code:

        protected override void OnNextCore(ChainedHeaderBlock chainedHeaderBlock)
        {
            this.walletSyncManager.ProcessBlock(chainedHeaderBlock.Block);

            this.blockTipSender.SendBlockTipAsync(
                new BlockTipModel(
                    chainedHeaderBlock.ChainedHeader.HashBlock,
                    chainedHeaderBlock.ChainedHeader.Height,
                    (int)this.depositExtractor.MinimumDepositConfirmations));

            var withdrawals = this.withdrawalExtractor.ExtractWithdrawalsFromBlock(
                chainedHeaderBlock.Block,
                chainedHeaderBlock.ChainedHeader.Height);

            this.withdrawalReceiver.ReceiveWithdrawals(withdrawals);

            IMaturedBlockDeposits maturedBlockDeposits =
                this.depositExtractor.ExtractMaturedBlockDeposits(chainedHeaderBlock.ChainedHeader);

            if (maturedBlockDeposits == null) return;

            this.maturedBlockSender.SendMaturedBlockDepositsAsync(maturedBlockDeposits).ConfigureAwait(false);
        }
    }

The method call ExtractMaturedBlockDeposits should subtract the deposit confirmations from the block height being parsed for mature block deposits.

Deterministic creation of target transactions

With the new design to handle cross chain transfers, we are going to need to create transactions that take funds out of the multisig and into targeted chain addresses in a deterministic way.
This will allow all federation members to come up with the exact same transaction without communication, and we are hoping that this will result in a more fault tolerant federation.

An basic idea for the design is explained here
https://github.com/stratisproject/FederatedSidechains/blob/master/Requirements/cross-chain-transfer.md#3-building-the-chain-b-transaction-deterministically

Please feel free to ask if any detail is missing there!

Change federation wallet to native multisig

This may be required if the smart contracts functionality disallows P2SH on the sidechain network.

Alternatively, maybe the rule can be relaxed to allow P2SH for federation members only?

Design contents of TemplateTransaction class

Needs at least the following, probably more:

  1. Key value for database storage (e.g. hash of transaction without any signatures, so all members work from the same identifier)
  2. Actual transaction that needs to be signed
    ...

Block matured message structure

In order to agree on the content of block relevant to cross chain deposits
As a federated member
I want have a data structure to describe these contents

NOTE:
- message sending is defined in #129
- message receiving is defined in issue XX

Acceptance Criteria

  • block height, absence of deposit transactions, or in case some deposit transaction are observed, transaction ids, transaction target addresses on chain B, and transaction values, can be retrieved easily from that structure.

Trigger cross chain status change on reorgs

In order to make sure transfers previously on chain get to the end destination even after a reorg of the target chain
As a federated member's B-node
I want to trigger a re-validation of the transactions matching the cross chains transfers that were affected by the reorg.

NOTE:
- these transfers can already have been persisted on the new branch onto which the node reorged

Acceptance Criteria

  • When a reorg is observed on chain B, the node needs to resync fully, then go through the same resync process as the one that happens upon getting back online (issue XXX)

Resync transfers store upon coming back online

In order to ensure that the cross chain transfer store is up to date after disconnecting / reconnecting
As a federated member's B-node
I want to trigger a re-validation of the transactions matching the cross chains transfers that were found on the chain A blocks that were created while I was offline

NOTE:
- this resync process will also be used on reorg cf issue #135
- a federation member cannot act as a leader or create template transactions until it has finished syncing and has a correct view of the UTXO available to release funds out of the multisig

Acceptance Criteria

  • As the node B re-syncs its chain, it saves informations about the multisig transactions that it notices on the B chain blocks
  • Once the sync is finished, node B needs to ask node A for all the blocks past its last known block and recreate entries in its cross chain transfer store.
  • It needs to then match the transactions in the mempool and on chain against these entries, and update their statuses. If a template / transaction is not found in either chain or mempool it needs to broadcast it with its own signature (or collect signatures if it is the leader).

Network generation

This is a high-level issue describing what the Network Generation process entails.

Motivation

Offer an easy-to-use tool for customers wishing to create their own custom sidechain.

Interfaces

Simple page web app that will gather the data defining the network the user wants to create, and produce a bunch of usable files in return, as described below.

User flow

  1. User downloads and runs an executable.

  2. User opens a web page to start the data gathering process.

  3. User fills the required fields to match their requirements. Some fields have default values and are therefore optional, some others are required (according to the Required fields table).

  4. On submission, the tool will validate the inputs and any error is communicated to the user.

  5. If the inputs are valid, the app will mine genesis blocks, compile multisig addresses, create networks files and produce the following:

    • a project similar to Stratis.Sidechains.Networks + the compiled dll
    • a project similar to Stratis.FederationGatewayD + the compiled dll + the 2 necessary config files (mainchain.config and sidechain.config)
    • a script that can be used by members to start their nodes
    • the corresponding documentation

    The above produced items will be delivered as a folder that the sidechain creator can distribute to the federation members.

Required fields table

Name Description Example Notes
Name The name for the chain “Apex” for the Apex network By default, the network names will be the chain name with “Main”, “Test”, “Regtest” appended to it.
Coinbase text Text that will be inserted in the input coinbase transaction script The Times 03/Jan/2009 Chancellor on brink of second bailout for banks for Bitcoin Use a news headline or any other appropriate string.
http://www.theonion.com/article/olympics-head-priestess-slits-throat-official-rio--53466 for Stratis
Type The type of the network “pow” for bitcoin The type will help validating the values passed in the json file.
“pos” for Stratis
“poa” for Apex
Magic Number A number used to uniquely identify the network 0xD9B4BEF9 (Bitcoin Main)
0x5223570 (Stratis Main)
PubKey address prefix Prefix for a generated address on the network ‘S’ (63) for Stratis Main https://en.bitcoin.it/wiki/List_of_address_prefixes
‘T’ (65) for Stratis Test
Script address prefix Prefix for a generated P2SH address on the network ‘s’ for Stratis Main https://en.bitcoin.it/wiki/List_of_address_prefixes
‘3’ for Bitcoin Main
CoinTicker An indicative coin ticker for use with external applications. “BTC” for Bitcoin Main
“TSTRAT” for Stratis Testnet
CoinType BIP44 coin type for this network 105 for Stratis Ideally find a number that is not in this list: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
Premine Reward Amount of coins mined when a new network is bootstrapped 98000000 for Stratis Set to 0 when there is no premine.
0 for Bitcoin
PoW Reward The reward that goes to the miner when a block is mined using proof-of-work. 50 for Bitcoin
4 for Stratis
0 for Apex
PoS Reward The reward that goes to the miner when a block is mined using proof-of-stake. 0 for Bitcoin
1 for Stratis
0 for Apex
Federation members public keys The list of a federation members public keys
Federation M number The minimum number of signatures required to sign a multisig transactions “2” for a 2-of-3 multisig address.
Federation members IPs The list of a federation members IP addresses

Reprocessing needs for each transfer status

In order to allow a new leader to pick up and continue processing a transaction that was already started
As a federated member's B node
I want to be able to decide on what operations I need to perform to ensure the new leader has a chance to pick up that transfer

NOTE:
- operations have to be performed on each transaction chronologically based (cf. issue #103)

Acceptance Criteria

  • When a partially signed transaction is received from another B node, but doesn't tie to the information received my own A node, it needs to be rejected.
  • When a partially signed transaction is received from another B node, but I don't have the information to validate / sign it, I need to request my A node for that information (resync from at least the corresponding block on chain A)
  • When a transaction is known but has not made it to the mempool, all nodes should rebroadcast the corresponding template with their signatures (cf. issue #103)
  • When a transaction has been found on chain B, nothing needs to be done
  • When a transaction was found on chain B, but then got involved in a reorg, the node B needs to resync, then the corresponding template transaction needs to be rebuilt using up to date UTXOs, and look on chain and in the mempool for its status
  • When a transaction has matured on chain B, nothing needs to be done

Block matured message exchange sender

In order to pass deposit (or absence of deposit) information from A-node to B-node
As a federated member chain A node
I want to react to block maturing events, by composing and sending a message to my B-node.

NOTE: message structure is defined in issue #130

Acceptance Criteria

  • when a blocks matured event is observed, the content of the block relevant to cross chain deposits is extracted and put into a message.

Rework how the leader selects current/previous tx

This task is about how the leader processes its own transactions (in the current block that made it the leader) and before that any previous transactions that have not been processed.
cf. #75

In order to ensure that cross chain transfers are dealt with in their order of appearance on chain A
As a federated member's B-node
I want to validate the status of all previous transactions and process the ones that need to chronologically

NOTE:
- processing things in chronological order is key to building transactions deterministically, since all members need to agree on which UTXOs are going to be picked up
- the kind of processing required by different transactions is explained in issue #134

Acceptance Criteria

  • When a new leader is elected as a result of chain A progressing, every node from chain B needs to search its database for all transactions that are not yet in chain B's mempool, then process them.
  • When a new message appears for block i+1, all nodes need to check that they received all information for blocks up to i, if it is not the case, they need to ask their node A for all missing information, and process them chronologically before

[LE] Create template database

The class that will push tx templates to disk, should use the debreeze db.

Probably does not need to habdle deletetions are reorg should never happen.

Testing

This is a high-level issue containing all the work that needs to be done for testing the sidechain solution.

Testing will be made up of

  • unit tests
  • integration tests
  • manual tests

Dependencies: a comprehensive list of scenarios to test needs to be produced. #88

Create the Network Generation tool interface

Create an executable that a user can run and be presented with a web page to populate with a bunch of fields.
This task is done when

  • a web page is fully designed and contains fields to fill + a "generate" button
  • it is packaged, distributable and runnable.

Corresponds to 1 and 2 of the User Flow in #79.

Raise events on withdrawals status changes

This is going to be needed by the dashboard. When a given transfer changes status, a message with enough information to unambiguously identify the transfer and report its new status should be broadcast. The dashboard can then use this event source to provide the users with up to date transaction informations

In order to inform other services of the statuses of cross chain transfers
As a federated member
I want to broadcast messages to remote processes when a transfer changes status in my database

the broadcast could be done using WebSockets, unless someone disagrees

Acceptance Criteria

  • Whenever a new cross chain transaction appears, gets removed, or has its status updated in the target node database, a message containing enough info to update the status is broadcast, remote processes should have a way to subscribe and listen to these messages.

Need for an admin dashboard

Currently there is no way to monitor sessions that handle transfers between two chains, there is a need for a tool able to report on each chain :

  • current mutlisig balance (confirmed, pending)

  • current session transfer details

  1. session leader (if any)
  2. amounts and target address
  3. current transaction template state (created, signed by 1,2,3 members, etc)
  4. ?? orphaned transfer (hopefully never) ??
  • maybe ability to validate that the transactions in a block have resulted in matching transfers, and if not, quick the transfer process again

  • which federation nodes are online in each chain

Integration Sidechain-SC

We need to put aside some time to integrate sidechains and smart contract as well as test the integration.

Chain never synch

I was following all steps to setup sidechain wallet but when starting stratis.SidechainD (on testnet) the chain is never synchronized, all headers remain zero always:

info: Stratis.Bitcoin.FullNode[0]
======Node stats====== 08/21/2018 22:33:58 agent StratisBitcoin:1.1.13
Headers.Height: 0 Headers.Hash: 0000e451752bac9f67cb5d63fd32442ba42d42b1b2ea28131d91e1e3f29f523b
BlockStore.Height: 0 BlockStore.Hash: 0000e451752bac9f67cb5d63fd32442ba42d42b1b2ea28131d91e1e3f29f523b
Consensus.Height: 0 Consensus.Hash: 0000e451752bac9f67cb5d63fd32442ba42d42b1b2ea28131d91e1e3f29f523b
Wallet.Height: 0 Wallet.Hash: 0000e451752bac9f67cb5d63fd32442ba42d42b1b2ea28131d91e1e3f29f523b

  ======Mempool======
  MempoolSize: 0    DynamicSize: 0 kb   OrphanSize: 0

All TSTRAT sent to sidechain address are confirmed in mainchain side but never received in sidechain.

please advice, thanks

Proof of authority

Implement a consensus protocol where only a known set of miners can mine blocks, and are randomly selected to do so
Failure to find a member would result in the next one mining the block

Here are some of Ivan's ideas about this:

Federations consists of N people (N is not divisible by 2: 3/5/7/9 members and so on)
Each of them has a private key. Their public keys are predefined and known to everyone. 

Order in which they can mine a block is defined on the sidechain setup.

Federation members mine the blocks in the defined order and sign those blocks with their keys. They include only those transactions that they think are valid.
If one of the federation members don't mine a block when it's his turn member after him will wait 64 seconds and will mine the block. 

Here is an example: 
We have 3 federation members: A,B,C
`-` equals to 64 seconds passed:

Normal scenario is: 
A-B-C-A-B-C-A-B...

In case B is offline: 
A--C-A--C-A--C...


There is a single rule for miner: you can produce a block only in your slot (in case there are 3 members it will be once in 3*64 seconds. 7 members- once in 64*7 seconds).
Miners don't sign any transactions, only the blocks. 

In case federation members have a disagreement and some of them include txes that other think are invalid we will have a chain split. Let's say A at some point decided that he wants to mine a fake TX:

A-B-C--B-C--B-C--B-C
      -A---A---A---A

A's chain will always be shorter in terms of chainwork so all the nodes will go with the best chain. 

Security model of this sidechain design relies on 51% of miners being honest. As long as it's true fake chain will always have less chainwork.


So in terms of the implementation we just need to add a validation rule that will check block's signature against predefined list of signatures and a rule that checks that the order is in place. (and also disable some of the PoS rules)

That's pretty much it.

Also here we have a guarantee that every fork will be resolved in 1 round (round length = number of members * 64)

And in case something goes wrong and we will see a scenario when the keys are stolen or some fed members went rogue they will have plenty of time to create a hardfork which will remove/replace such members. 
Ofc since members went rogue till the hardfork we will have missing slots and overall throughput of the chain will be smaller by `(number of rogue members / total members) * 100`% but we don't really care because this is very unlikely to happen and because we won't have full blocks on the sidechains (edited)
Btw it's not entirely my design, some of that was taken from cardano's PoS (that's how they solve nothing at stake vulnerability without a max reorg protection)

Create Network Generation final package

This corresponds to item 5 in User Flow in #79.

Dependencies: #80, #81, #83.

At the end of the Network Generation process, we should have:

  • projects created for Networks and the FederationGatewayD
  • compiled dlls of the above projects
  • config files for FederationGatewayD
  • a script to start the 2 nodes each member needs to run
  • some extra documentation (how to).

Add suspended status to store.

In order to make sure transfers that had insufficient funds for creating the partial transaction get retried.

As a federated member's B-node
I want to trigger a re-validation of the transfers that had insufficient funds for creating the partial transactions in the store.

Acceptance Criteria

  • Transfers with insufficient UTXO's and subsequent transfers are set to Suspended in the store.
  • The chain A tip is NOT advanced if there are any suspended transfers for that block height.
  • The next time RecordLatestMatureDepositsAsync is called for the same block height we will again attempt to create partial transactions for Suspended transfers.

Coin locking for Federation members

Find a way to lock coins of federated members and create an incentive for them to behave well.

an idea:

Our federation will have a min size of 3 and a max size of 15 (cf. multisig limitations), and the size will be an odd number 

Keeping that in mind, I think it is possible, for a federation of size N to generate 
Combination(N, N-2) = 1/2 N * (N-1) multisig escrows

If less than N/2 members try to cheat, we can punish them (by taking the money on the multisigs on which they are not a majority) more than they can steal (by taking the money on the escrows on which they have a majority).

This could be a good punishment if we make sure that they can't get a majority on the cross chain multisigs.

We can maybe calculate the optimal number/size of escrow multisigs to generate depending on the sizes of the cross chain multisigs.

thinking about it, although it means setting up more escrows, it is probably more fault tolerant to use only Combination(N, 3) 2 of 3 multisigs, but in both cases, you can ensure that the rogue part of the federation will be penalised.

Handling communication between Mainchain Node and Sidechain Node in Federation Deamon

There are different possibilities:

  1. We rework the deamon so that it can run 2 nodes, one on each network, in the same process

  2. We use a mechanism to share information between the 2 nodes (a database, a messaging) and keep each node in its own process

  3. We use a distributed sharing mechanism (at the level of the federation) so that every node is able to share information and none of them needs to be a leader, rather they all try to modify that db and all get a copy of it. This is independent of block production otherwise we'll have many many issues !

This ties to #75 and #76 obviously.

Gather data and generate networks for Network generation

From the Network Generation tool created here, the data needs to be validated and if validation is successful, the tool will mine genesis blocks, compile multisig addresses, and create projects using the project templates done here.

This task corresponds to item 4 and the beginning of item 5 in #79.

Dependencies:
#80 and #81

Leader ordering and change

Order fed members alphabetically by public key, and use that order + the block heights to select preferred leaders in a round robin fashion, when a new message arrives (triggered by new blocks tip height).

In order to agree on who is the leader for the deposit of a given block
As a federated member
I want to agree with my other federation fellows on who is the leader for every block that may appear in the future

this might be as simple as a "modulo" operation

Acceptance Criteria

  • Leader is selected deterministically based on the public keys of the multisig, and the height of a given block
  • Upon receiving a new message (Block Tip HashHieght Pair) from the block signaler, the new leader is selected automatically
  • All federation members get the same number of opportunities to be leaders

Resync matured block deposits when a federated member's B-node comes back online

In order to ensure federated member's node-B matured block deposits (MBDs) are up to date after disconnecting / reconnecting.
As a federated member's B-node.
I want to trigger a re-sync of MBDs that were found on node-A that were created while I was offline.

Note : node-A lives on chain A, and node-B lives on chain B.
Diagram

Acceptance Criteria

  • When a node B re-sync is invoked, node A will start to create the missing MBDs.
  • Once the MBDs are created, node A will send the blocks back to node B.

Example

node-A MBDs 1 - 2 - 3 - 4 - 5 - 6
node-B MBDs 1 - 2 - 3 [offline]
node-B [comes online : resyncs]
node-A [sends Node-B] - 4 - 5 - 6

Question: Why Does Proof-of-Work Double-Validate State?

I'm having a ball of a time meeting everyone in your Discord channel. 😄

However, something has arisen that I am trying to wrap my mind around, and it has to do with how Proof-of-Work is prioritized. My interest here is possibly exploring how to modify how this is done in my own theoretical sidechain here through the amazingly impressive Stratis offering.

So it would seem, to start, that blocks are essentially a collection of transactions that have already been verified and validated by miners, and as having already been proven to be abiding by all the established rules of the protocol (no double-spending, etc). My confusion lies in the subsequent POW aspect. If every transaction within a block has already been validated and verified, why does it need further validation in the form of solving this hashing riddle?

It would seem to me that the riddle is in the current "view" of available broadcasted transactions at the current time of assembling this next block, such as this: if given 100 valid transactions currently broadcasted and available to a miner, how many can be sorted into this next block in a way that not only maximizes the number of transactions removed from the outstanding queue/view but also yields the highest average value in both aggregate sum and related fees?

It seems to me that a scoring system could then be derived from questioning such as this, and that the first participating party who claims the highest score in this regard based on the currently available set of verified/valid broadcasted unspent transactions would win the block, and can therefore add it to the chain. If several parties get the same configuration (or score) concurrently, then they split the reward evenly.

The other added benefit of POSt (sorry, it's not POS 😉) is that a vote could then be cast on that scored block/result based on the ownership of each staked participant, to verify and certify the result. When the cumulative total of available voting parties with stake reaches over 50%, then the block is officially certified and added into the chain.

There must be something obvious here I am overlooking, so I am presenting it here to see if it's even possible to consider such a notion for a sidechain.

Thank you again for your great work here. Very inspiring and compelling potential!

SignedMultisigTransactionBroadcaster component.

Signed multisig transactions will need to be broadcast to the target chain.

In order to broadcast a signed multi signature transaction to the target chain.
As a federated member leader
I want to send signed multi signature transactions that are not in the memory pool

Create an observer based on when the federated leader changes - which happens in Blockobserver.OnNextCore().

On observer change.
If the current leader (FederationGatewaySettings.PublicKey == ILeaderProvider.CurrentLeader).
Get signed transactions (CrossChainTransferStore.GetSignedTransactionsAsync()).
For each transaction, not in the memory pool, send.

Acceptance Criteria

  • Signed multisig transactions are received on the target chain.
  • Signed multisig transactions are not sent if already in the mempool.
  • Only the federated leader can send the signed transactions.

Block matured message exchange receiver

In order to receive deposit (or absence of deposit) information from A-node to B-node
As a federated member chain B node
I want receive messages sent from my A-node into my B-node.

NOTE: message structure is defined in issue #130

Acceptance Criteria

  • when a message containing information about new matured blocks is sent from A Chain, it is received and digested by the B node

Block observer with MaxReorg + 1 delay

This block observer should raise an event whenever a new block has passed MaxReorg + 1 maturity. Eventually, when this event happens, a message will be sent to the other chain's node to describe potential deposits, or the absence of deposits.

In order to build a message to send to chain B node
As a federated member chain A node
I want an event to be triggered when this a block matures

NOTE: message structure is defined in issue XX

Acceptance Criteria

  • if a blocks matures, a new event is sent, that event needs to contain enough information to build a message that will be sent to this federation member counter node (the node watching chain B).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.