Code Monkey home page Code Monkey logo

mainstay's Introduction

Mainstay

The mainstay repository is an application that implements the Mainstay protocol designed by CommerceBlock. It consists of a Go daemon that performs attestations of the Ocean network along with client commitments to Bitcoin in the form of a commitment merkle tree.

Mainstay is accompanied by a Confirmation tool that can be run in parallel with the Bitcoin network to confirm attestations and prove the commitment inclusion in Mainstay attestations.

Prerequisites

Instructions

Attestation Service

  • Install Go and the attestation service by following scripts/build.sh

  • Setup up database collections and roles using scripts/db-init.js

  • Setup conf.json file under /config by following config guidelines

  • Run service

    • Regtest mode
      • Run service: mainstay -regtest
      • Run signer: go run $GOPATH/src/mainstay/cmd/txsigningtool/txsigningtool.go -regtest
      • Insert commitments to "ClientCommitment" database collection in order to generate new attestations
    • Testnet/Mainnet mode
      • Download and run a full Bitcoin Node on testnet mode, fully indexed and in blocksonly mode.

      • Fund this wallet node, send all the funds to a single (m of n sig) P2SH address and store the TX_HASH, PRIVKEY_x and REDEEM_SCRIPT of this transaction, where x in [0, n-1].

        (In the case of an Ocean-type network the TX_HASH should be included in the genesis block using the config option attestationhash)

      • Follow the same procedure to generate a single (m of n sig) P2SH address used to topup the service and store the TOPUP_ADDRESS, TOPUP_PRIVKEY_x and TOPUP_SCRIPT.

      • Run the mainstay attestation service by:

        mainstay

        Command line parameters should be set in .conf file

      • Run transaction signers of the m-of-n multisig P2SH addresses for x in [0, n-1] by:

        go run $GOPATH/src/mainstay/cmd/txsigningtool/txsigningtool.go -pk PRIVKEY_x -pkTopup TOPUP_PRIVKEY_x -host SIGNER_HOST

        Command line parameters should be set in the corresponding signer .conf file

  • Unit Testing

    • /$GOPATH/src/mainstay/scripts/run-tests.sh

Tools

Along with the Mainstay daemon there is various tools offered serving utilities for both Mainstay operators and clients of Mainstay. These tools and their functionality are briefly summarized below:

  • Client Confirmation Tool

The confirmation tool cmd/confirmationtool can be used to confirm all the attestations of a client Ocean-type network to Bitcoin and wait for any new attestations that will be happening.

  • Commitment Tool

The commitment tool cmd/commitmenttool can be used to send hash commitments to the Mainstay API.

  • Transaction Signing Tool

The transaction signing tool cmd/txsigningtool is a dummy testing tool for signing multisig attestations.

  • Client Signup Tool

The client signup tool cmd/clientsignuptool can be used to sign up new clients to the Mainstay service.

  • Multisig Tool

The multisig tool cmd/multisigtool can be used to generate multisig scripts and P2SH addresses for Mainstay configuration.

For more information go to tool guidelines.

For example use cases go to docs.

mainstay's People

Contributors

nkostoulas avatar dhananjaypurohit avatar tomt1664 avatar lodenos avatar 86667 avatar nicosey avatar haael avatar

Stargazers

 avatar Rsync⚡️  avatar  avatar 22388o⚡️  avatar Will Pankiewicz avatar Riccardo Casatta avatar Wassim Alsindi avatar JasonP avatar  avatar  avatar  avatar  avatar  avatar Cryptopoly avatar

Watchers

James Cloos avatar Lawrence Deacon avatar  avatar  avatar  avatar  avatar KazFan29 avatar  avatar  avatar  avatar

mainstay's Issues

Refactor: Server / Models / Config

  • Deprecate request service and channel use

  • Rename and repackage

  • Remove side client and client keys from config

  • Prepare use with service interface

  • Prepare use with db interface

  • Remove regtest stuff from main

Service: Commitment Model

The Commitment Model will replace the latest Ocean hash being used so far for attestations. This will incorporate the hashes from all clients into a merle tree. Template:

type Commitment struct {
 commitments type map < position , hash >
 root type hash
 updated type bool
}
GetRoot() // calculate and update merkle root
GetHashForPosition(position) // get hash at position
UpdateHash(position, hash) // update commitments and trigger root update

Changes required:

  • Commitment model

  • Merkle tree util and testing

  • Attestation model to move from Hash to Commitment

  • AttestService to request/store/use Commitment instead of hash

  • Server to store latest Commitment not Hash per client

  • Commitment proofs

Service: missing commitment

example:

  • registered clients at positions 0, 1, 2
  • only client 0 and 2 have sent commitments

Mainstay will fail for missing a commitment in position 1. How do we handle this?

Multisig attestation

  • multisig socket communication
  • attestation client to generate multisig addresses and tweaking
  • client tool to manage hashes, redeem script and send signatures
  • signature collection, tx signing and send

Service: key derivation using xpub and chain code

  • tweak extended key and test

  • changes to client and service and test

  • add error handling for tweaking error. test tweaking and constructor errors.

  • config for chain code and changes to client

  • Modify verification tool and any other tools (?)

Listener - Initial Setup

New Listener class to be used by AttestService and replace the call to GetNextAttestationHash(). The service should get the latest hash by querying the Listener.

AttestListener, AttestListenerFake with single method GetNextHash() for now

AttestListenerFake will use dummy sidechainclientFake for unit-tests and AttestListener can do what
GetNextAttestationHash() is doing for now.

Update unit-tests and verify same behaviour

Service: consistent fees

Fees are currently estimated without the scriptSig, which accounts for 3/4 of the transaction size.

Thus our current limits of minimum 10sat/B and maximum 100sat/B actually correspond to 2.5sat/B and 25satB/ respectively.

It is not a real problem at the moment as fee limits can be set at will and transaction size is going to be pretty much constant throughout, but still something that should be taken into account.

Listener - API & Service communication

1. AttestServer

  • receive hash POST request from requestapi via request channel
  • verify clientId, store hash, reply ACK via response channel
  • nextHash requests
  • latestAttestation requests

2. AttestService

  • Send hash requests to AttestServer
  • Redirect commitment requests to AttestServer

Tools: PoIS

Staychain changes:

  • chain verifier to verify Proof and Tweaking given proof from API. Ocean client used only for block hash validation
  • Extend confirmation tool config options (i.e. client position, api, ...)
  • Guideline
  • forward / backward mode in confirmation tool
  • change chainfetcher to have a backward mode

Service: super secure

Steps towards making attestation service extra secure.

  • wallet failure handling (attestservice:stateInitWalletFailure())
  • deprecate using lastunspent / unconfirmed from mempool
  • store latest commitment on ipfs

Service: send ready to sign pre-image to Transaction Signers

Currently sending full transaction bytes

Send only pre-image (one per input) to signers

Any excess inputs are signed with topup key

More more than one input possibly use:
[size1] [pre-image1] [size2] [pre-image2]

similar to what we do with signatures on the other end.

Service: top-up process

  • Extend config to include top-up addr and top-up flag. Move staychain config in one category:
"staychain" : {
 "regtest" : ,
 "initTx" : ,
 "initScript" : ,
 "topupAddr" : ,
 "topupScript" : ,
}
  • Attest client changes
    Examine cases we've been assuming single vin so far
    Do creation, signing for multiple inputs
    Unit-tests

  • Attest service changes
    New DO_TOPUP state
    Fetch topup unspent and create attestation
    Fetch multiple sigs from clients
    Unit-tests

  • Unit-test top-up scenario paying to new address

  • Testing with txsigningtool (need additional -topupPk)

  • Raise warnings when funds below some value && raise error when below maxFee allowed

Listener - REST communication

1. Extend requestapi

  • New POST request commitment/send/{template} for clients to send commitments to service
    e.g. template
    {
    clientId: ""
    hash: ""
    height: ""
    }
    This request will be passed to requests channel, reach AttestListener, who will reply true/false depending on whether clientId was valid.
  • New GET request server/verify/{hash} to request whether a hash was attested
    This request will be passed to requests channel, reach AttestServer, who will reply true/false depending on whether hash has been attested yet. (see "/block/{blockId}")

2. Refactoring

  • In models, move Response/Request/Channel to separate files.
  • Create typed names for Request, e.g. type VerifyHashRequest = "VerifyHash". Replace hardcoded names in request routes.go with typed names. Replace hardcoded use of request in attest server.go with typed names. Request.name should be this typed name. Remove Request struct from Response struct.
  • Rename route handles to local, i.e. Block -> handleBlockRequest
  • Rename routes to /api/commitment/send, /api/server/verify/, etc..
  • Any changes to unit-test

logging system

Replace any remaining "fmt" calls with logger calls. Consider all info/warn/error levels.

Tool to rebuild wallet

Rebuild wallet from initial tx/pk
Similar concept to confirmation tool, but this also imports all derived keys to the wallet as well
Proof that in case of failure attestations can continue just with initial pk

Service: Fee estimation

Is using the fee estimation for 21.co ok long term? The company has migrated to earn.com so I doubt its a long term solution.

Integrate db permissions to deployment

We need separate permissions for the API and the mainstay daemon. I created this https://github.com/commerceblock/mainstay/blob/develop/scripts/db-init.js months back but I think we should integrate it now to the mongo deployment.

Basically two separate roles. Service role should only be used by the mainstay daemon. The API role should be used by the node web backend. Nobody else should have access or we could introduce a third read only role.

Compose files should be updated with the new users.

Service: Attestation schedule && fee bumping

  • Attestation schedule
    Different schedule for Attestations per hour via config
    Different schedule for confirmation wait time before fee bumping via config
    Different schedule for other state wait times, i.e. waiting for signatures

  • Extend unconfirmed handling
    If no unspent, do additional search in dB and check blockchain
    If not in mempool, do additional search in dB and check blockchain

  • Bump fee handling
    Fee struct with last fee, fee, bumpFee, upper fee limit
    GetFee(), BumpFee() methods in client
    do NewFee() on each new attestation

Create Testing for requesthandlers.go

Create testing function

  • HandleBlock
  • HandleBestBlock
  • HandleBestBlockHeight
  • HandleCommitmentSend
  • HandleIndex
  • HandleLatestAttestation
  • HandleServerVerify
  • HandleTransaction

Service: delay in sending a sig fills the mainstay service sub queue

Mainstay service subscribes to signers to get signatures. A slight delay from the signer causes mainstay to resubscribe possibly ending with 2 sigs in the queue. This leads to a cycle of fail-success attestations.

This was not evident before as in production we wait for 1 minute for signatures, which is never a problem. In local testing it was also never a problem as sigs were propagated in under 10 sec (the test waiting time). I noticed this because HSMs take their time.

There was a similar problem in the federation zmq connections. Solution: exhaust subscriber queue.

Service: deprecate signrawtransaction

"signrawtransaction was removed in v0.18"

Since signrawtransaction withwallet/withkey not supported in btcd and most of signing will not be done by a node anyway, deprecate and replace with dummy signing for testing.

Server: dB interface

  • Db config

  • Db insert interface

  • Db find interface

  • Full Db integration to server/service

  • Db integration testing

Listener - Basic client/service connectivity

1B. Listener

Simple demo of listener - client communication at cmd/listenerdemo.go

cmd/clientcommitmenttool/clientcommitmenttool.go

  • connect to sidechain
  • new dealerZmq to connect to listener router
  • send latest hash and wait for confirmation

AttestListener

  • new routerZmq to listen to client for received hash
  • store latest hash in the struct
  • reply latest hash to incoming request
  • send confirmation to client when attestation is confirmed

AttestService

  • Send message via requestChannel when requiring new block hash and wait for reply on responseChannel
  • Send confirmation via confirmationChannel when attestation is confirmed on the bitcoin blockchain

Listener main should run in a separate goroutine than attestservice. Functionality:

  • listen for received hash
  • return GetNextHash() if there is a request from attestservice (requestChannel, responseChannel)
  • reply to clients with confirmation if there is an attestation confirmation from attestservice (confirmationChannel)
for {
    select {
        case conf := <-confirmationChannel:
            sendConfirmation()
        case req := <-requestChannel:
            responseChannel <- GetNextHash()
        default:
            listen()
    }
}

zmq background
http://api.zeromq.org/2-1:zmq-socket
https://github.com/pebbe/zmq4/blob/master/examples/rtdealer.go
http://zguide.zeromq.org/php:chapter3#toc19

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.