From 0b625185aaca44581ec4a3440b2c624e243ec0ef Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 3 Feb 2017 13:53:48 -0600 Subject: [PATCH] Added siad for unit testing --- .../01 - Run Local.lnk | Bin 0 -> 698 bytes 3rd-party/Sia-v1.1.0-windows-amd64/LICENSE | 21 + 3rd-party/Sia-v1.1.0-windows-amd64/README.md | 106 ++ 3rd-party/Sia-v1.1.0-windows-amd64/doc/API.md | 1137 +++++++++++++++++ .../Sia-v1.1.0-windows-amd64/doc/Consensus.md | 399 ++++++ .../doc/Developers.md | 239 ++++ .../Sia-v1.1.0-windows-amd64/doc/Encoding.md | 74 ++ .../doc/File Contract Negotiation.md | 289 +++++ .../doc/Guide to Contributing to Sia.md | 250 ++++ .../Sia-v1.1.0-windows-amd64/doc/Modules.md | 35 + .../doc/Running and Writing Tests for Sia.md | 256 ++++ .../Sia-v1.1.0-windows-amd64/doc/Standard.md | 61 + .../doc/api/Consensus.md | 47 + .../doc/api/Daemon.md | 100 ++ .../doc/api/Gateway.md | 159 +++ .../Sia-v1.1.0-windows-amd64/doc/api/Host.md | 536 ++++++++ .../doc/api/HostDB.md | 290 +++++ .../Sia-v1.1.0-windows-amd64/doc/api/Miner.md | 124 ++ .../doc/api/Renter.md | 297 +++++ .../doc/api/Wallet.md | 521 ++++++++ .../doc/assets/codereview.png | Bin 0 -> 39674 bytes .../doc/assets/covertool.png | Bin 0 -> 87817 bytes .../doc/whitepaper.tex | 482 +++++++ 3rd-party/Sia-v1.1.0-windows-amd64/siac.exe | Bin 0 -> 8730112 bytes .../Sia-v1.1.0-windows-amd64/siac.exe.sig | Bin 0 -> 1024 bytes 3rd-party/Sia-v1.1.0-windows-amd64/siad.exe | Bin 0 -> 15522816 bytes .../Sia-v1.1.0-windows-amd64/siad.exe.sig | Bin 0 -> 1024 bytes 27 files changed, 5423 insertions(+) create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/01 - Run Local.lnk create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/LICENSE create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/README.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/API.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Consensus.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Developers.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Encoding.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/File Contract Negotiation.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Guide to Contributing to Sia.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Modules.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Running and Writing Tests for Sia.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/Standard.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Consensus.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Daemon.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Gateway.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Host.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/HostDB.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Miner.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Renter.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Wallet.md create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/assets/codereview.png create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/assets/covertool.png create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/doc/whitepaper.tex create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/siac.exe create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/siac.exe.sig create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/siad.exe create mode 100644 3rd-party/Sia-v1.1.0-windows-amd64/siad.exe.sig diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/01 - Run Local.lnk b/3rd-party/Sia-v1.1.0-windows-amd64/01 - Run Local.lnk new file mode 100644 index 0000000000000000000000000000000000000000..0221620ba3585349b2f3487fba3bad10e2224d01 GIT binary patch literal 698 zcmb7AK}#D!7=7DHVxomq163Nx2vX6yn@tsw913M)G(p(H(x|YMZnBFk#Rxl+NDF#a zg#Lm^Da{Y)S!l&`p^{TU4?VTC6s4Yf=rkoNBNhACCi+Rd^6#Uei&;7Ws>+MnGjDj6D zMTZjdvM?$a`zi3Cj#)D9!{z&f^5mYlouc>ROVJdUoe^;as8czF7oiF}OfjqcNUi2~ z@|v!$08g*=jLO@#QDKKd@6&05cp#FJCks9tsA!U!CZSW+qT2>sY|@ES?O=ndIhqs5 zpo#|&QOs0+6&d5c<7(cv2Rsa2JLKAF3)lJQN#b72(ohnYt}Z!x*d_oYgf&8jAmSB! zjv&@5VVH1}kQ~(0DcVg76fR|FTfU<<^P2d1%Wt@wEv`Bn?%b>$4VEM$n?54G8kuHc zpdjx>q&EIHiUbAYf=O+cl(z`adSkv8Ba0Pqz8*MDkE@NEsMB%h}sqw{;zkT@drH!hJXM7 literal 0 HcmV?d00001 diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/LICENSE b/3rd-party/Sia-v1.1.0-windows-amd64/LICENSE new file mode 100644 index 0000000..af0018d --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nebulous Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/README.md b/3rd-party/Sia-v1.1.0-windows-amd64/README.md new file mode 100644 index 0000000..a15b8d5 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/README.md @@ -0,0 +1,106 @@ +# [![Sia Logo](http://sia.tech/img/svg/sia-green-logo.svg)](http://sia.tech) v1.1.0 (Andromeda) +========= + +[![Build Status](https://travis-ci.org/NebulousLabs/Sia.svg?branch=master)](https://travis-ci.org/NebulousLabs/Sia) +[![GoDoc](https://godoc.org/github.com/NebulousLabs/Sia?status.svg)](https://godoc.org/github.com/NebulousLabs/Sia) +[![Go Report Card](https://goreportcard.com/badge/github.com/NebulousLabs/Sia)](https://goreportcard.com/report/github.com/NebulousLabs/Sia) + +Sia is a new decentralized cloud storage platform that radically alters the +landscape of cloud storage. By leveraging smart contracts, client-side +encryption, and sophisticated redundancy (via Reed-Solomon codes), Sia allows +users to safely store their data with hosts that they do not know or trust. +The result is a cloud storage marketplace where hosts compete to offer the +best service at the lowest price. And since there is no barrier to entry for +hosts, anyone with spare storage capacity can join the network and start +making money. + +Traditional cloud storage has a number of shortcomings. Users are limited to a +few big-name offerings: Google, Microsoft, Amazon. These companies have little +incentive to encrypt your data or make it easy to switch services later. Their +code is closed-source, and they can lock you out of your account at any time. + +We believe that users should own their data. Sia achieves this by replacing +the traditional monolithic cloud storage provider with a blockchain and a +swarm of hosts, each of which stores an encrypted fragment of your data. Since +the fragments are redundant, no single host can hold your data hostage: if +they jack up their price or go offline, you can simply download from a +different host. In other words, trust is removed from the equation, and +switching to a different host is painless. Stripped of these unfair +advantages, hosts must compete solely on the quality and price of the storage +they provide. + +Sia can serve as a replacement for personal backups, bulk archiving, content +distribution, and more. For developers, Sia is a low-cost alternative to +Amazon S3. Storage on Sia is a full order of magnitude cheaper than on S3, +with comparable bandwidth, latency, and durability. Sia works best for static +content, especially media like videos, music, and photos. + +Distributing data across many hosts automatically confers several advantages. +The most obvious is that, just like BitTorrent, uploads and downloads are +highly parallel. Given enough hosts, Sia can saturate your bandwidth. Another +advantage is that your data is spread across a wide geographic area, reducing +latency and safeguarding your data against a range of attacks. + +It is important to note that users have full control over which hosts they +use. You can tailor your host set for minimum latency, lowest price, widest +geographic coverage, or even a strict whitelist of IP addresses or public +keys. + +At the core of Sia is a blockchain that closely resembles Bitcoin. +Transactions are conducted in Siacoin, a cryptocurrency. The blockchain is +what allows Sia to enforce its smart contracts without relying on centralized +authority. To acquire siacoins, use an exchange such as [Poloniex](https://poloniex.com), [Yunbi](https://yunbi.com), or +[Bitsquare](https://bitsquare.io). + +To get started with Sia, check out the guides below: + +- [How to Store Data on Sia](https://medium.com/@jhowell1337/getting-started-with-private-decentralized-cloud-storage-c9565dc8c854) +- [How to Become a Sia Host](http://blog.sia.tech/2016/05/26/how-to-run-a-host-on-sia) +- [Using the Sia API](http://blog.sia.tech/2016/10/20/api-quickstart-guide) + + +Usage +----- + +Sia is ready for use with small sums of money and non-critical files, but +until the network has a more proven track record, we advise against using it +as a sole means of storing important data. + +This release comes with 2 binaries, siad and siac. siad is a background +service, or "daemon," that runs the Sia protocol and exposes an HTTP API on +port 9980. siac is a command-line client that can be used to interact with +siad in a user-friendly way. There is also a graphical client, [Sia-UI](https://github.com/NebulousLabs/Sia-UI), which +is the preferred way of using Sia for most users. For interested developers, +the siad API is documented [here](doc/API.md). + +siad and siac are run via command prompt. On Windows, you can just double- +click siad.exe if you don't need to specify any command-line arguments. +Otherwise, navigate to its containing folder and click File->Open command +prompt. Then, start the siad service by entering `siad` and pressing Enter. +The command prompt may appear to freeze; this means siad is waiting for +requests. Windows users may see a warning from the Windows Firewall; be sure +to check both boxes ("Private networks" and "Public networks") and click +"Allow access." You can now run `siac` (in a separate command prompt) or Sia- +UI to interact with siad. From here, you can send money, upload and download +files, and advertise yourself as a host. + +Building From Source +-------------------- + +To build from source, [Go 1.7 must be installed](https://golang.org/doc/install) +on the system. Then simply use `go get`: + +``` +go get -u github.com/NebulousLabs/Sia/... +``` + +This will download the Sia repo to your `$GOPATH/src` folder, and install the +`siad` and `siac` binaries in your `$GOPATH/bin` folder. + +To stay up-to-date, run the previous `go get` command again. Alternatively, you +can use the Makefile provided in this repo. Run `git pull origin master` to +pull the latest changes, and `make release-std` to build the new binaries. You +can also run `make test` and `make test-long` to run the short and full test +suites, respectively. Finally, `make cover` will generate code coverage reports +for each package; they are stored in the `cover` folder and can be viewed in +your browser. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/API.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/API.md new file mode 100644 index 0000000..544990b --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/API.md @@ -0,0 +1,1137 @@ +Siad API +======== + +Sia uses semantic versioning and is backwards compatible to version v1.0.0. + +API calls return either JSON or no content. Success is indicated by 2xx HTTP +status codes, while errors are indicated by 4xx and 5xx HTTP status codes. If +an endpoint does not specify its expected status code refer to +[#standard-responses](#standard-responses). + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Notes: +- Requests must set their User-Agent string to contain the substring "Sia-Agent". +- By default, siad listens on "localhost:9980". This can be changed using the + `--api-addr` flag when running siad. +- **Do not bind or expose the API to a non-loopback address unless you are + aware of the possible dangers.** + +Example GET curl call: +``` +curl -A "Sia-Agent" "localhost:9980/wallet/transactions?startheight=1&endheight=250" +``` + +Example POST curl call: +``` +curl -A "Sia-Agent" --data "amount=123&destination=abcd" "localhost:9980/wallet/siacoins" +``` + +Standard responses +------------------ + +#### Success + +The standard response indicating the request was successfully processed is HTTP +status code `204 No Content`. If the request was successfully processed and the +server responded with JSON the HTTP status code is `200 OK`. Specific endpoints +may specify other 2xx status codes on success. + +#### Error + +The standard error response indicating the request failed for any reason, is a +4xx or 5xx HTTP status code with an error JSON object describing the error. +```javascript +{ + "message": String + + // There may be additional fields depending on the specific error. +} +``` + +Authentication +-------------- + +API authentication can be enabled with the `--authenticate-api` siad flag. +Authentication is HTTP Basic Authentication as described in +[RFC 2617](https://tools.ietf.org/html/rfc2617), however, the username is the +empty string. The flag does not enforce authentication on all API endpoints. +Only endpoints that expose sensitive information or modify state require +authentication. + +For example, if the API password is "foobar" the request header should include +``` +Authorization: Basic OmZvb2Jhcg== +``` + +Units +----- + +Unless otherwise specified, all parameters should be specified in their +smallest possible unit. For example, size should always be specified in bytes +and Siacoins should be specified in hastings. JSON values returned by the API +will also use the smallest possible unit, unless otherwise specified. + +If a numbers is returned as a string in JSON, it should be treated as an +arbitrary-precision number (bignum), and it should be parsed with your +language's corresponding bignum library. Currency values are the most common +example where this is necessary. + +Table of contents +----------------- + +- [Daemon](#daemon) +- [Consensus](#consensus) +- [Gateway](#gateway) +- [Host](#host) +- [Host DB](#host-db) +- [Miner](#miner) +- [Renter](#renter) +- [Wallet](#wallet) + +Daemon +------ + +| Route | HTTP verb | +| ----------------------------------------- | --------- | +| [/daemon/constants](#daemonconstants-get) | GET | +| [/daemon/stop](#daemonstop-get) | GET | +| [/daemon/version](#daemonversion-get) | GET | + +For examples and detailed descriptions of request and response parameters, +refer to [Daemon.md](/doc/api/Daemon.md). + +#### /daemon/constants [GET] + +returns the set of constants in use. + +###### JSON Response [(with comments)](/doc/api/Daemon.md#json-response) +```javascript +{ + "genesistimestamp": 1257894000, // Unix time + "blocksizelimit": 2000000, // bytes + "blockfrequency": 600, // seconds per block + "targetwindow": 1000, // blocks + "mediantimestampwindow": 11, // blocks + "futurethreshold": 10800, // seconds + "siafundcount": "10000", + "siafundportion": "39/1000", + "maturitydelay": 144, // blocks + + "initialcoinbase": 300000, // Siacoins (see note in Daemon.md) + "minimumcoinbase": 30000, // Siacoins (see note in Daemon.md) + + "roottarget": [0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + "rootdepth": [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], + + "maxadjustmentup": "5/2", + "maxadjustmentdown": "2/5", + + "siacoinprecision": "1000000000000000000000000" // hastings per siacoin +} +``` + +#### /daemon/stop [GET] + +cleanly shuts down the daemon. May take a few seconds. + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /daemon/version [GET] + +returns the version of the Sia daemon currently running. + +###### JSON Response [(with comments)](/doc/api/Daemon.md#json-response-1) +```javascript +{ + "version": "1.0.0" +} +``` + +Consensus +--------- + +| Route | HTTP verb | +| ---------------------------- | --------- | +| [/consensus](#consensus-get) | GET | + +For examples and detailed descriptions of request and response parameters, +refer to [Consensus.md](/doc/api/Consensus.md). + +#### /consensus [GET] + +returns information about the consensus set, such as the current block height. + +###### JSON Response [(with comments)](/doc/api/Consensus.md#json-response) +```javascript +{ + "synced": true, + "height": 62248, + "currentblock": "00000000000008a84884ba827bdc868a17ba9c14011de33ff763bd95779a9cf1", + "target": [0,0,0,0,0,0,11,48,125,79,116,89,136,74,42,27,5,14,10,31,23,53,226,238,202,219,5,204,38,32,59,165] +} +``` + +Gateway +------- + +| Route | HTTP verb | +| ---------------------------------------------------------------------------------- | --------- | +| [/gateway](#gateway-get-example) | GET | +| [/gateway/connect/___:netaddress___](#gatewayconnectnetaddress-post-example) | POST | +| [/gateway/disconnect/___:netaddress___](#gatewaydisconnectnetaddress-post-example) | POST | + +For examples and detailed descriptions of request and response parameters, +refer to [Gateway.md](/doc/api/Gateway.md). + +#### /gateway [GET] [(example)](/doc/api/Gateway.md#gateway-info) + +returns information about the gateway, including the list of connected peers. + +###### JSON Response [(with comments)](/doc/api/Gateway.md#json-response) +```javascript +{ + "netaddress": String, + "peers": []{ + "netaddress": String, + "version": String, + "inbound": Boolean + } +} +``` + +#### /gateway/connect/___:netaddress___ [POST] [(example)](/doc/api/Gateway.md#connecting-to-a-peer) + +connects the gateway to a peer. The peer is added to the node list if it is not +already present. The node list is the list of all nodes the gateway knows +about, but is not necessarily connected to. + +###### Path Parameters [(with comments)](/doc/api/Gateway.md#path-parameters) +``` +:netaddress +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /gateway/disconnect/___:netaddress___ [POST] [(example)](/doc/api/Gateway.md#disconnecting-from-a-peer) + +disconnects the gateway from a peer. The peer remains in the node list. + +###### Path Parameters [(with comments)](/doc/api/Gateway.md#path-parameters-1) +``` +:netaddress +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +Host +---- + +| Route | HTTP verb | +| ------------------------------------------------------------------------------------- | --------- | +| [/host](#host-get) | GET | +| [/host](#host-post) | POST | +| [/host/announce](#hostannounce-post) | POST | +| [/host/storage](#hoststorage-get) | GET | +| [/host/storage/folders/add](#hoststoragefoldersadd-post) | POST | +| [/host/storage/folders/remove](#hoststoragefoldersremove-post) | POST | +| [/host/storage/folders/resize](#hoststoragefoldersresize-post) | POST | +| [/host/storage/sectors/delete/___:merkleroot___](#hoststoragesectorsdeletemerkleroot) | POST | + +For examples and detailed descriptions of request and response parameters, +refer to [Host.md](/doc/api/Host.md). + +#### /host [GET] + +fetches status information about the host. + +###### JSON Response [(with comments)](/doc/api/Host.md#json-response) +```javascript +{ + "externalsettings": { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, // bytes + "maxduration": 25920, // blocks + "maxrevisebatchsize": 17825792, // bytes + "netaddress": "123.456.789.0:9982", + "remainingstorage": 35000000000, // bytes + "sectorsize": 4194304, // bytes + "totalstorage": 35000000000, // bytes + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "windowsize": 144, // blocks + + "collateral": "57870370370", // hastings / byte / block + "maxcollateral": "100000000000000000000000000000", // hastings + + "contractprice": "30000000000000000000000000", // hastings + "downloadbandwidthprice": "250000000000000", // hastings / byte + "storageprice": "231481481481", // hastings / byte / block + "uploadbandwidthprice": "100000000000000", // hastings / byte + + "revisionnumber": 0, + "version": "1.0.0" + }, + + "financialmetrics": { + "contractcount": 2, + "contractcompensation": "123", // hastings + "potentialcontractcompensation": "123", // hastings + + "lockedstoragecollateral": "123", // hastings + "lostrevenue": "123", // hastings + "loststoragecollateral": "123", // hastings + "potentialstoragerevenue": "123", // hastings + "riskedstoragecollateral": "123", // hastings + "storagerevenue": "123", // hastings + "transactionfeeexpenses": "123", // hastings + + "downloadbandwidthrevenue": "123", // hastings + "potentialdownloadbandwidthrevenue": "123", // hastings + "potentialuploadbandwidthrevenue": "123", // hastings + "uploadbandwidthrevenue": "123" // hastings + }, + + "internalsettings": { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, // bytes + "maxduration": 25920, // blocks + "maxrevisebatchsize": 17825792, // bytes + "netaddress": "123.456.789.0:9982", + "windowsize": 144, // blocks + + "collateral": "57870370370", // hastings / byte / block + "collateralbudget": "2000000000000000000000000000000", // hastings + "maxcollateral": "100000000000000000000000000000", // hastings + + "mincontractprice": "30000000000000000000000000", // hastings + "mindownloadbandwidthprice": "250000000000000", // hastings / byte + "minstorageprice": "231481481481", // hastings / byte / block + "minuploadbandwidthprice": "100000000000000" // hastings / byte + }, + + "networkmetrics": { + "downloadcalls": 0, + "errorcalls": 1, + "formcontractcalls": 2, + "renewcalls": 3, + "revisecalls": 4, + "settingscalls": 5, + "unrecognizedcalls": 6 + } +} +``` + +#### /host [POST] + +configures hosting parameters. All parameters are optional; unspecified +parameters will be left unchanged. + +###### Query String Parameters [(with comments)](/doc/api/Host.md#query-string-parameters) +``` +acceptingcontracts // Optional, true / false +maxdownloadbatchsize // Optional, bytes +maxduration // Optional, blocks +maxrevisebatchsize // Optional, bytes +netaddress // Optional +windowsize // Optional, blocks + +collateral // Optional, hastings / byte / block +collateralbudget // Optional, hastings +maxcollateral // Optional, hastings + +mincontractprice // Optional, hastings +mindownloadbandwidthprice // Optional, hastings / byte +minstorageprice // Optional, hastings / byte / block +minuploadbandwidthprice // Optional, hastings / byte +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/announce [POST] + +Announces the host to the network as a source of storage. Generally only needs +to be called once. + +###### Query String Parameters [(with comments)](/doc/api/Host.md#query-string-parameters-1) +``` +netaddress string // Optional +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage [GET] + +gets a list of folders tracked by the host's storage manager. + +###### JSON Response [(with comments)](/doc/api/Host.md#json-response-1) +```javascript +{ + "folders": [ + { + "path": "/home/foo/bar", + "capacity": 50000000000, // bytes + "capacityremaining": 100000, // bytes + + "failedreads": 0, + "failedwrites": 1, + "successfulreads": 2, + "successfulwrites": 3 + } + ] +} +``` + +#### /host/storage/folders/add [POST] + +adds a storage folder to the manager. The manager may not check that there is +enough space available on-disk to support as much storage as requested + +###### Query String Parameters [(with comments)](/doc/api/Host.md#query-string-parameters-2) +``` +path // Required +size // bytes, Required +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage/folders/remove [POST] + +remove a storage folder from the manager. All storage on the folder will be +moved to other storage folders, meaning that no data will be lost. If the +manager is unable to save data, an error will be returned and the operation +will be stopped. + +###### Query String Parameters [(with comments)](/doc/api/Host.md#query-string-parameters-3) +``` +path // Required +force // bool, Optional, default is false +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage/folders/resize [POST] + +grows or shrink a storage folder in the manager. The manager may not check that +there is enough space on-disk to support growing the storage folder, but should +gracefully handle running out of space unexpectedly. When shrinking a storage +folder, any data in the folder that needs to be moved will be placed into other +storage folders, meaning that no data will be lost. If the manager is unable to +migrate the data, an error will be returned and the operation will be stopped. + +###### Query String Parameters [(with comments)](/doc/api/Host.md#query-string-parameters-4) +``` +path // Required +newsize // bytes, Required +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage/sectors/delete/___:merkleroot___ [POST] + +deletes a sector, meaning that the manager will be unable to upload that sector +and be unable to provide a storage proof on that sector. This endpoint is for +removing the data entirely, and will remove instances of the sector appearing +at all heights. The primary purpose is to comply with legal requests to remove +data. + +###### Path Parameters [(with comments)](/doc/api/Host.md#path-parameters) +``` +:merkleroot +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + + +Host DB +------- + +| Request | HTTP Verb | +| ------------------------------------------- | --------- | +| [/hostdb/active](#hostdbactive-get-example) | GET | +| [/hostdb/all](#hostdball-get-example) | GET | + +For examples and detailed descriptions of request and response parameters, +refer to [HostDB.md](/doc/api/HostDB.md). + +#### /hostdb/active [GET] [(example)](/doc/api/HostDB.md#active-hosts) + +lists all of the active hosts known to the renter, sorted by preference. + +###### Query String Parameters [(with comments)](/doc/api/HostDB.md#query-string-parameters) +``` +numhosts // Optional +``` + +###### JSON Response [(with comments)](/doc/api/HostDB.md#json-response) +```javascript +{ + "hosts": [ + { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, // bytes + "maxduration": 25920, // blocks + "maxrevisebatchsize": 17825792, // bytes + "netaddress": "123.456.789.2:9982", + "remainingstorage": 35000000000, // bytes + "sectorsize": 4194304, // bytes + "totalstorage": 35000000000, // bytes + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "windowsize": 144, // blocks + "publickey": { + "algorithm": "ed25519", + "key": "RW50cm9weSBpc24ndCB3aGF0IGl0IHVzZWQgdG8gYmU=" + } + } + ] +} +``` + +#### /hostdb/all [GET] [(example)](/doc/api/HostDB.md#all-hosts) + +lists all of the hosts known to the renter. Hosts are not guaranteed to be in +any particular order, and the order may change in subsequent calls. + +###### JSON Response [(with comments)](/doc/api/HostDB.md#json-response-1) +```javascript +{ + "hosts": [ + { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, // bytes + "maxduration": 25920, // blocks + "maxrevisebatchsize": 17825792, // bytes + "netaddress": "123.456.789.0:9982", + "remainingstorage": 35000000000, // bytes + "sectorsize": 4194304, // bytes + "totalstorage": 35000000000, // bytes + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "windowsize": 144, // blocks + "publickey": { + "algorithm": "ed25519", + "key": "RW50cm9weSBpc24ndCB3aGF0IGl0IHVzZWQgdG8gYmU=" + } + } + ] +} +``` + +Miner +----- + +| Route | HTTP verb | +| ---------------------------------- | --------- | +| [/miner](#miner-get) | GET | +| [/miner/start](#minerstart-get) | GET | +| [/miner/stop](#minerstop-get) | GET | +| [/miner/header](#minerheader-get) | GET | +| [/miner/header](#minerheader-post) | POST | + +For examples and detailed descriptions of request and response parameters, +refer to [Miner.md](/doc/api/Miner.md). + +#### /miner [GET] + +returns the status of the miner. + +###### JSON Response [(with comments)](/doc/api/Miner.md#json-response) +```javascript +{ + "blocksmined": 9001, + "cpuhashrate": 1337, + "cpumining": false, + "staleblocksmined": 0, +} +``` + +#### /miner/start [GET] + +starts a single threaded cpu miner. Does nothing if the cpu miner is already +running. + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /miner/stop [GET] + +stops the cpu miner. Does nothing if the cpu miner is not running. + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /miner/header [GET] + +provides a block header that is ready to be grinded on for work. + +###### Byte Response + +For efficiency the header for work is returned as a raw byte encoding of the +header, rather than encoded to JSON. Refer to +[Miner.md#byte-response](/doc/api/Miner.md#byte-response) for a detailed +description of the byte encoding. + +#### /miner/header [POST] + +submits a header that has passed the POW. + +###### Request Body Bytes + +For efficiency headers are submitted as raw byte encodings of the header in the +body of the request, rather than as a query string parameter or path parameter. +The request body should contain only the 80 bytes of the encoded header. The +encoding is the same encoding used in `/miner/header [GET]` endpoint. Refer to +[Miner.md#byte-response](/doc/api/Miner.md#byte-response) for a detailed +description of the byte encoding. + +Renter +------ + +| Route | HTTP verb | +| ------------------------------------------------------------- | --------- | +| [/renter](#renter-get) | GET | +| [/renter](#renter-post) | POST | +| [/renter/contracts](#rentercontracts-get) | GET | +| [/renter/downloads](#renterdownloads-get) | GET | +| [/renter/files](#renterfiles-get) | GET | +| [/renter/delete/___*siapath___](#renterdeletesiapath-post) | POST | +| [/renter/download/___*siapath___](#renterdownloadsiapath-get) | GET | +| [/renter/rename/___*siapath___](#renterrenamesiapath-post) | POST | +| [/renter/upload/___*siapath___](#renteruploadsiapath-post) | POST | + +For examples and detailed descriptions of request and response parameters, +refer to [Renter.md](/doc/api/Renter.md). + +#### /renter [GET] + +returns the current settings along with metrics on the renter's spending. + +###### JSON Response [(with comments)](/doc/api/Renter.md#json-response) +```javascript +{ + "settings": { + "allowance": { + "funds": "1234", // hastings + "hosts": 24, + "period": 6048, // blocks + "renewwindow": 3024 // blocks + } + }, + "financialmetrics": { + "contractspending": "1234", // hastings + "downloadspending": "5678", // hastings + "storagespending": "1234", // hastings + "uploadspending": "5678", // hastings + "unspent": "1234" // hastings + } +} +``` + +#### /renter [POST] + +modify settings that control the renter's behavior. + +###### Query String Parameters [(with comments)](/doc/api/Renter.md#query-string-parameters) +``` +funds // hastings +hosts +period // block height +renewwindow // block height +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /renter/contracts [GET] + +returns active contracts. Expired contracts are not included. + +###### JSON Response [(with comments)](/doc/api/Renter.md#json-response-1) +```javascript +{ + "contracts": [ + { + "endheight": 50000, // block height + "id": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "netaddress": "12.34.56.78:9", + "renterfunds": "1234", // hastings + "size": 8192 // bytes + } + ] +} +``` + +#### /renter/downloads [GET] + +lists all files in the download queue. + +###### JSON Response [(with comments)](/doc/api/Renter.md#json-response-2) +```javascript +{ + "downloads": [ + { + "siapath": "foo/bar.txt", + "destination": "/home/users/alice/bar.txt", + "filesize": 8192, // bytes + "received": 4096, // bytes + "starttime": "2009-11-10T23:00:00Z" // RFC 3339 time + } + ] +} +``` + +#### /renter/files [GET] + +lists the status of all files. + +###### JSON Response [(with comments)](/doc/api/Renter.md#json-response-3) +```javascript +{ + "files": [ + { + "siapath": "foo/bar.txt", + "filesize": 8192, // bytes + "available": true, + "renewing": true, + "redundancy": 5, + "uploadprogress": 100, // percent + "expiration": 60000 + } + ] +} +``` + +#### /renter/delete/___*siapath___ [POST] + +deletes a renter file entry. Does not delete any downloads or original files, +only the entry in the renter. + +###### Path Parameters [(with comments)](/doc/api/Renter.md#path-parameters) +``` +*siapath +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /renter/download/___*siapath___ [GET] + +downloads a file to the local filesystem. The call will block until the file +has been downloaded. + +###### Path Parameters [(with comments)](/doc/api/Renter.md#path-parameters-1) +``` +*siapath +``` + +###### Query String Parameters [(with comments)](/doc/api/Renter.md#query-string-parameters-1) +``` +destination +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /renter/rename/___*siapath___ [POST] + +renames a file. Does not rename any downloads or source files, only renames the +entry in the renter. An error is returned if `siapath` does not exist or +`newsiapath` already exists. + +###### Path Parameters [(with comments)](/doc/api/Renter.md#path-parameters-2) +``` +*siapath +``` + +###### Query String Parameters [(with comments)](/doc/api/Renter.md#query-string-parameters-2) +``` +newsiapath +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /renter/upload/___*siapath___ [POST] + +uploads a file to the network from the local filesystem. + +###### Path Parameters [(with comments)](/doc/api/Renter.md#path-parameters-3) +``` +*siapath +``` + +###### Query String Parameters [(with comments)](/doc/api/Renter.md#query-string-parameters-2) +``` +datapieces // int +paritypieces // int +source // string - a filepath +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + + +Wallet +------ + +| Route | HTTP verb | +| --------------------------------------------------------------- | --------- | +| [/wallet](#wallet-get) | GET | +| [/wallet/033x](#wallet033x-post) | POST | +| [/wallet/address](#walletaddress-get) | GET | +| [/wallet/addresses](#walletaddresses-get) | GET | +| [/wallet/backup](#walletbackup-get) | GET | +| [/wallet/init](#walletinit-post) | POST | +| [/wallet/lock](#walletlock-post) | POST | +| [/wallet/seed](#walletseed-post) | POST | +| [/wallet/seeds](#walletseeds-get) | GET | +| [/wallet/siacoins](#walletsiacoins-post) | POST | +| [/wallet/siafunds](#walletsiafunds-post) | POST | +| [/wallet/siagkey](#walletsiagkey-post) | POST | +| [/wallet/transaction/___:id___](#wallettransactionid-get) | GET | +| [/wallet/transactions](#wallettransactions-get) | GET | +| [/wallet/transactions/___:addr___](#wallettransactionsaddr-get) | GET | +| [/wallet/unlock](#walletunlock-post) | POST | + +For examples and detailed descriptions of request and response parameters, +refer to [Wallet.md](/doc/api/Wallet.md). + +#### /wallet [GET] + +returns basic information about the wallet, such as whether the wallet is +locked or unlocked. + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response) +```javascript +{ + "encrypted": true, + "unlocked": true, + + "confirmedsiacoinbalance": "123456", // hastings, big int + "unconfirmedoutgoingsiacoins": "0", // hastings, big int + "unconfirmedincomingsiacoins": "789", // hastings, big int + + "siafundbalance": "1", // siafunds, big int + "siacoinclaimbalance": "9001", // hastings, big int +} +``` + +#### /wallet/033x [POST] + +loads a v0.3.3.x wallet into the current wallet, harvesting all of the secret +keys. All spendable addresses in the loaded wallet will become spendable from +the current wallet. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters) +``` +source +encryptionpassword +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /wallet/address [GET] + +gets a new address from the wallet generated by the primary seed. An error will +be returned if the wallet is locked. + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-1) +```javascript +{ + "address": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab" +} +``` + +#### /wallet/addresses [GET] + +fetches the list of addresses from the wallet. + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-2) +```javascript +{ + "addresses": [ + "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ] +} +``` + +#### /wallet/backup [GET] + +creates a backup of the wallet settings file. Though this can easily be done +manually, the settings file is often in an unknown or difficult to find +location. The /wallet/backup call can spare users the trouble of needing to +find their wallet file. + +###### Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-1) +``` +destination +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /wallet/init [POST] + +initializes the wallet. After the wallet has been initialized once, it does not +need to be initialized again, and future calls to /wallet/init will return an +error. The encryption password is provided by the api call. If the password is +blank, then the password will be set to the same as the seed. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-2) +``` +encryptionpassword +dictionary // Optional, default is english. +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-3) +```javascript +{ + "primaryseed": "hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello" +} +``` + +#### /wallet/seed [POST] + +gives the wallet a seed to track when looking for incoming transactions. The +wallet will be able to spend outputs related to addresses created by the seed. +The seed is added as an auxiliary seed, and does not replace the primary seed. +Only the primary seed will be used for generating new addresses. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-3) +``` +encryptionpassword +dictionary +seed +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /wallet/seeds [GET] + +returns the list of seeds in use by the wallet. The primary seed is the only +seed that gets used to generate new addresses. This call is unavailable when +the wallet is locked. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-4) +``` +dictionary +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-4) +```javascript +{ + "primaryseed": "hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello", + "addressesremaining": 2500, + "allseeds": [ + "hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello", + "foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo", + ] +} +``` + +#### /wallet/siacoins [POST] + +sends siacoins to an address. The outputs are arbitrarily selected from +addresses in the wallet. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-5) +``` +amount // hastings +destination // address +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-5) +```javascript +{ + "transactionids": [ + "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ] +} +``` + +#### /wallet/siafunds [POST] + +sends siafunds to an address. The outputs are arbitrarily selected from +addresses in the wallet. Any siacoins available in the siafunds being sent (as +well as the siacoins available in any siafunds that end up in a refund address) +will become available to the wallet as siacoins after 144 confirmations. To +access all of the siacoins in the siacoin claim balance, send all of the +siafunds to an address in your control (this will give you all the siacoins, +while still letting you control the siafunds). + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-6) +``` +amount // siafunds +destination // address +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-6) +```javascript +{ + "transactionids": [ + "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ] +} +``` + +#### /wallet/siagkey [POST] + +loads a key into the wallet that was generated by siag. Most siafunds are +currently in addresses created by siag. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-7) +``` +encryptionpassword +keyfiles +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /wallet/lock [POST] + +locks the wallet, wiping all secret keys. After being locked, the keys are +encrypted. Queries for the seed, to send siafunds, and related queries become +unavailable. Queries concerning transaction history and balance are still +available. + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /wallet/transaction/___:id___ [GET] + +gets the transaction associated with a specific transaction id. + +###### Path Parameters [(with comments)](/doc/api/Wallet.md#path-parameters) +``` +:id +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-7) +```javascript +{ + "transaction": { + "transaction": { + // See types.Transaction in https://github.com/NebulousLabs/Sia/blob/master/types/transactions.go + }, + "transactionid": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "confirmationheight": 50000, + "confirmationtimestamp": 1257894000, + "inputs": [ + { + "fundtype": "siacoin input", + "walletaddress": false, + "relatedaddress": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "value": "1234", // hastings or siafunds, depending on fundtype, big int + } + ], + "outputs": [ + { + "fundtype": "siacoin output", + "maturityheight": 50000, + "walletaddress": false, + "relatedaddress": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "value": "1234", // hastings or siafunds, depending on fundtype, big int + } + ] + } +} +``` + +#### /wallet/transactions [GET] + +returns a list of transactions related to the wallet in chronological order. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-8) +``` +startheight // block height +endheight // block height +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-8) +```javascript +{ + "confirmedtransactions": [ + { + // See the documentation for '/wallet/transaction/:id' for more information. + } + ], + "unconfirmedtransactions": [ + { + // See the documentation for '/wallet/transaction/:id' for more information. + } + ] +} +``` + +#### /wallet/transactions/___:addr___ [GET] + +returns all of the transactions related to a specific address. + +###### Path Parameters [(with comments)](/doc/api/Wallet.md#path-parameters-1) +``` +:addr +``` + +###### JSON Response [(with comments)](/doc/api/Wallet.md#json-response-9) +```javascript +{ + "transactions": [ + { + // See the documentation for '/wallet/transaction/:id' for more information. + } + ] +} +``` + +#### /wallet/unlock [POST] + +unlocks the wallet. The wallet is capable of knowing whether the correct +password was provided. + +###### Query String Parameters [(with comments)](/doc/api/Wallet.md#query-string-parameters-9) +``` +encryptionpassword +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Consensus.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Consensus.md new file mode 100644 index 0000000..1062d9c --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Consensus.md @@ -0,0 +1,399 @@ +Consensus Rules +=============== + +This document is meant to provide a good high level overview of the Sia +cryptosystem, but does not fully explain all of the small details. The most +accurate explanation of the consensus rules is the consensus package (and all +dependencies). + +This document will be more understandable if you have a general understanding +of proof of work blockchains, and does not try to build up from first +principles. + +Cryptographic Algorithms +------------------------ + +Sia uses cryptographic hashing and cryptographic signing, each of which has +many potentially secure algorithms that can be used. We acknowledge our +inexperience, and that we have chosen these algorithms not because of our own +confidence in their properties, but because other people seem confident in +their properties. + +For hashing, our primary goal is to use an algorithm that cannot be merge mined +with Bitcoin, even partially. A secondary goal is hashing speed on consumer +hardware, including phones and other low power devices. + +For signing, our primary goal is verification speed. A secondary goal is an +algorithm that supports HD keys. A tertiary goal is an algorithm that supports +threshold signatures. + +#### Hashing: blake2b + + [blake2b](http://en.wikipedia.org/wiki/BLAKE_%28hash_function%29#BLAKE2 "Wiki page") has been chosen as a hashing algorithm because it is fast, it has had + substantial review, and it has invulnerability to length extension attacks. + Another particularly important feature of BLAKE2b is that it is not SHA-2. We + wish to avoid merge mining with Bitcoin, because that may result in many + apathetic Bitcoin miners mining on our blockchain, which may make soft forks + harder to coordinate. + +#### Signatures: variable type signatures + + Each public key will have an specifier (a 16 byte array) and a byte slice + containing an encoding of the public key. The specifier will tell the + signature verification which signing algorithm to use when verifying a + signature. Each signature will be a byte slice, the encoding can be + determined by looking at the specifier of the corresponding public key. + + This method allows new signature types to be easily added to the currency in + a way that does not invalidate existing outputs and keys. Adding a new + signature type requires a hard fork, but allows easy protection against + cryptographic breaks, and easy migration to new cryptography if there are any + breakthroughs in areas like verification speed, ring signatures, etc. + + Allowed algorithms: + + ed25519: The specifier must match the string "ed25519". The public key + must be encoded into 32 bytes. Signatures and public keys will need to + follow the ed25519 specification. More information can be found at + ed25519.cr.yp.to + + entropy: The specifier must match the string "entropy". The signature will + always be invalid. This provides a way to add entropy buffers to + SpendCondition objects to protect low entropy information, while being able + to prove that the entropy buffers are invalid public keys. + + There are plans to also add ECDSA secp256k1 and Schnorr secp256k1. New + signing algorithms can be added to Sia through a soft fork, because + unrecognized algorithm types are always considered to have valid signatures. + +Currency +-------- + +The Sia cryptosystem has two types of currency. The first is the Siacoin. +Siacoins are generated every block and distributed to the miners. These miners +can then use the siacoins to fund file contracts, or can send the siacoins to +other parties. The siacoin is represented by an infinite precision unsigned +integer. + +The second currency in the Sia cryptosystem is the Siafund, which is a special +asset limited to 10,000 indivisible units. Each time a file contract payout is +made, 3.9% of the payout is put into the siafund pool. The number of siacoins +in the siafund pool must always be divisible by 10,000; the number of coins +taken from the payout is rounded down to the nearest 10,000. The siafund is +also represented by an infinite precision unsigned integer. + +Siafund owners can collect the siacoins in the siafund pool. For every 10,000 +siacoins added to the siafund pool, a siafund owner can withdraw 1 siacoin. +Approx. 8790 siafunds are owned by Nebulous Inc. The remaining siafunds are +owned by early backers of the Sia project. + +There are future plans to enable sidechain compatibility with Sia. This would +allow other currencies such as Bitcoin to be spent in all the same places that +the Siacoin can be spent. + +Marshalling +----------- + +Many of the Sia types need to be hashed at some point, which requires having a +consistent algorithm for marshalling types into a set of bytes that can be +hashed. The following rules are used for hashing: + + - Integers are little-endian, and are always encoded as 8 bytes. + - Bools are encoded as one byte, where zero is false and one is true. + - Variable length types such as strings are prefaced by 8 bytes containing + their length. + - Arrays and structs are encoded as their individual elements concatenated + together. The ordering of the struct is determined by the struct definition. + There is only one way to encode each struct. + - The Currency type (an infinite precision integer) is encoded in big endian + using as many bytes as necessary to represent the underlying number. As it + is a variable length type, it is prefixed by 8 bytes containing the length. + +Block Size +---------- + +The maximum block size is 2e6 bytes. There is no limit on transaction size, +though it must fit inside of the block. Most miners enforce a size limit of +16e3 bytes per transaction. + +Block Timestamps +---------------- + +Each block has a minimum allowed timestamp. The minimum timestamp is found by +taking the median timestamp of the previous 11 blocks. If there are not 11 +previous blocks, the genesis timestamp is used repeatedly. + +Blocks will be rejected if they are timestamped more than three hours in the +future, but can be accepted again once enough time has passed. + +Block ID +-------- + +The ID of a block is derived using: + Hash(Parent Block ID + 64 bit Nonce + Block Merkle Root) + +The block Merkle root is obtained by creating a Merkle tree whose leaves are +the hash of the timestamp, the hashes of the miner outputs (one leaf per miner +output), and the hashes of the transactions (one leaf per transaction). + +Block Target +------------ + +For a block to be valid, the id of the block must be below a certain target. +The target is adjusted once every 500 blocks, and it is adjusted by looking at +the timestamps of the previous 1000 blocks. The expected amount of time passed +between the most recent block and the 1000th previous block is 10e3 minutes. If +more time has passed, the target is lowered. If less time has passed, the +target is increased. Each adjustment can adjust the target by up to 2.5x. + +The target is changed in proportion to the difference in time (If the time was +half of what was expected, the new target is 1/2 the old target). There is a +clamp on the adjustment. In one block, the target cannot adjust upwards by more +more than 1001/1000, and cannot adjust downwards by more than 999/1000. + +The new target is calculated using (expected time passed in seconds) / (actual +time passed in seconds) * (current target). The division and multiplication +should be done using infinite precision, and the result should be truncated. + +If there are not 1000 blocks, the genesis timestamp is used for comparison. +The expected time is (10 minutes * block height). + +Block Subsidy +------------- + +The coinbase for a block is (300,000 - height) * 10^24, with a minimum of +30,000 \* 10^24. Any miner fees get added to the coinbase to create the block +subsidy. The block subsidy is then given to multiple outputs, called the miner +payouts. The total value of the miner payouts must equal the block subsidy. + +The ids of the outputs created by the miner payouts is determined by taking the +block id and concatenating the index of the payout that the output corresponds +to. + +The outputs created by the block subsidy cannot be spent for 50 blocks, and are +not considered a part of the consensus set until 50 blocks have transpired. +This limitation is in place because a simple blockchain reorganization is +enough to invalidate the output; double spend attacks and false spend attacks +are much easier to execute. + +Transactions +------------ + +A Transaction is composed of the following: + +- Siacoin Inputs +- Siacoin Outputs +- File Contracts +- File Contract Revisions +- Storage Proofs +- Siafund Inputs +- Siafund Outputs +- Miner Fees +- Arbitrary Data +- Transaction Signatures + +The sum of all the siacoin inputs must equal the sum of all the miner fees, +siacoin outputs, and file contract payouts. There can be no leftovers. The sum +of all siafund inputs must equal the sum of all siafund outputs. + +Several objects have unlock hashes. An unlock hash is the Merkle root of the +'unlock conditions' object. The unlock conditions contain a timelock, a number +of required signatures, and a set of public keys that can be used during +signing. + +The Merkle root of the unlock condition objects is formed by taking the Merkle +root of a tree whose leaves are the timelock, the public keys (one leaf per +key), and the number of signatures. This ordering is chosen specifically +because the timelock and the number of signatures are low entropy. By using +random data as the first and last public key, you can make it safe to reveal +any of the public keys without revealing the low entropy items. + +The unlock conditions cannot be satisfied until enough signatures have +provided, and until the height of the blockchain is at least equal to the value +of the timelock. + +The unlock conditions contains a set of public keys which can each be used only +once when providing signatures. The same public key can be listed twice, which +means that it can be used twice. The number of required signatures indicates +how many public keys must be used to validate the input. If required signatures +is '0', the input is effectively 'anyone can spend'. If the required signature +count is greater than the number of public keys, the input is unspendable. +There must be exactly enough signatures. For example, if there are 3 public +keys and only two required signatures, then only two signatures can be included +into the transaction. + +Siacoin Inputs +-------------- + +Each input spends an output. The output being spent must exist in the consensus +set. The 'value' field of the output indicates how many siacoins must be used +in the outputs of the transaction. Valid outputs are miner fees, siacoin +outputs, and contract payouts. + +Siacoin Outputs +--------------- + +Siacoin outputs contain a value and an unlock hash (also called a coin +address). The unlock hash is the Merkle root of the spend conditions that must +be met to spend the output. + +File Contracts +-------------- + +A file contract is an agreement by some party to prove they have a file at a +given point in time. The contract contains the Merkle root of the data being +stored, and the size in bytes of the data being stored. + +The Merkle root is formed by breaking the file into 64 byte segments and +hashing each segment to form the leaves of the Merkle tree. The final segment +is not padded out. + +The storage proof must be submitted between the 'WindowStart' and 'WindowEnd' +fields of the contract. There is a 'Payout', which indicates how many siacoins +are given out when the storage proof is provided. 3.9% of this payout (rounded +down to the nearest 10,000) is put aside for the owners of siafunds. If the +storage proof is provided and is valid, the remaining payout is put in an +output spendable by the 'valid proof spend hash', and if a valid storage proof +is not provided to the blockchain by 'end', the remaining payout is put in an +output spendable by the 'missed proof spend hash'. + +All contracts must have a non-zero payout, 'start' must be before 'end', and +'start' must be greater than the current height of the blockchain. A storage +proof is acceptable if it is submitted in the block of height 'end'. + +File contracts are created with a 'Revision Hash', which is the Merkle root of +an unlock conditions object. A 'file contract revision' can be submitted which +fulfills the unlock conditions object, resulting in the file contract being +replaced by a new file contract, as specified in the revision. + +File Contract Revisions +----------------------- + +A file contract revision modifies a contract. File contracts have a revision +number, and any revision submitted to the blockchain must have a higher +revision number in order to be valid. Any field can be changed except for the +payout - siacoins cannot be added to or removed from the file contract during a +revision, though the destination upon a successful or unsuccessful storage +proof can be changed. + +The greatest application for file contract revisions is file-diff channels - a +file contract can be edited many times off-blockchain as a user uploads new or +different content to the host. This improves the overall scalability of Sia. + +Storage Proofs +-------------- + +A storage proof transaction is any transaction containing a storage proof. +Storage proof transactions are not allowed to have siacoin or siafund outputs, +and are not allowed to have file contracts. + +When creating a storage proof, you only prove that you have a single 64 byte +segment of the file. The piece that you must prove you have is chosen +randomly using the contract id and the id of the 'trigger block'. The +trigger block is the block at height 'Start' - 1, where 'Start' is the value +'Start' in the contract that the storage proof is fulfilling. + +The file is composed of 64 byte segments whose hashes compose the leaves of a +Merkle tree. When proving you have the file, you must prove you have one of the +leaves. To determine which leaf, take the hash of the contract id concatenated +to the trigger block id, then take the numerical value of the result modulus +the number of segments: + + Hash(file contract id + trigger block id) % num segments + +The proof is formed by providing the 64 byte segment, and then the missing +hashes required to fill out the remaining tree. The total size of the proof +will be 64 bytes + 32 bytes * log(num segments), and can be verified by anybody +who knows the root hash and the file size. + +Storage proof transactions are not allowed to have siacoin outputs, siafund +outputs, or contracts. All outputs created by the storage proofs cannot be +spent for 50 blocks. + +These limits are in place because a simple blockchain reorganization can change +the trigger block, which will invalidate the storage proof and therefore the +entire transaction. This makes double spend attacks and false spend attacks +significantly easier to execute. + +Siafund Inputs +-------------- + +A siafund input works similar to a siacoin input. It contains the id of a +siafund output being spent, and the unlock conditions required to spend the +output. + +A special output is created when a siafund output is used as input. All of the +siacoins that have accrued in the siafund since its last spend are sent to the +'claim spend hash' found in the siafund output, which is a normal siacoin +address. The value of the siacoin output is determined by taking the size of +the siacoin pool when the output was created and comparing it to the current +size of the siacoin pool. The equation is: + + ((Current Pool Size - Previous Pool Size) / 10,000) * siafund quantity + +Like the miner outputs and the storage proof outputs, the siafund output cannot +be spent for 50 blocks because the value of the output can change if the +blockchain reorganizes. Reorganizations will not however cause the transaction +to be invalidated, so the ban on contracts and outputs does not need to be in +place. + +Siafund Outputs +--------------- + +Like siacoin outputs, siafund outputs contain a value and an unlock hash. The +value indicates the number of siafunds that are put into the output, and the +unlock hash is the Merkle root of the unlock conditions object which allows the +output to be spent. + +Siafund outputs also contain a claim unlock hash field, which indicates the +unlock hash of the siacoin output that is created when the siafund output is +spent. The value of the output that gets created will depend on the growth of +the siacoin pool between the creation and the spending of the output. This +growth is measured by storing a 'claim start', which indicates the size of the +siafund pool at the moment the siafund output was created. + +Miner Fees +---------- + +A miner fee is a volume of siacoins that get added to the block subsidy. + +Arbitrary Data +-------------- + +Arbitrary data is a set of data that is ignored by consensus. In the future, it +may be used for soft forks, paired with 'anyone can spend' transactions. In the +meantime, it is an easy way for third party applications to make use of the +siacoin blockchain. + +Transaction Signatures +---------------------- + +Each signature points to a single public key index in a single unlock +conditions object. No two signatures can point to the same public key index for +the same set of unlock conditions. + +Each signature also contains a timelock, and is not valid until the blockchain +has reached a height equal to the timelock height. + +Signatures also have a 'covered fields' object, which indicates which parts of +the transaction get included in the signature. There is a 'whole transaction' +flag, which indicates that every part of the transaction except for the +signatures gets included, which eliminates any malleability outside of the +signatures. The signatures can also be individually included, to enforce that +your signature is only valid if certain other signatures are present. + +If the 'whole transaction' is not set, all fields need to be added manually, +and additional parties can add new fields, meaning the transaction will be +malleable. This does however allow other parties to add additional inputs, +fees, etc. after you have signed the transaction without invalidating your +signature. If the whole transaction flag is set, all other elements in the +covered fields object must be empty except for the signatures field. + +The covered fields object contains a slice of indexes for each element of the +transaction (siacoin inputs, miner fees, etc.). The slice must be sorted, and +there can be no repeated elements. + +Entirely nonmalleable transactions can be achieved by setting the 'whole +transaction' flag and then providing the last signature, including every other +signature in your signature. Because no frivolous signatures are allowed, the +transaction cannot be changed without your signature being invalidated. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Developers.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Developers.md new file mode 100644 index 0000000..d282326 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Developers.md @@ -0,0 +1,239 @@ +Developer Environment +===================== + +Sia is written in Go. To build and test Sia, you are going to need a working go +environment, including having both $GOROOT/bin and $GOPATH/bin in your $PATH. +For most Linux distributions, Go will be in the package manager, though it may +be an old version that is incompatible with Sia. Once you have a working Go +environment, you are set to build the project. If you plan on cross compiling +Sia, you may need to install Go from source. You can find information on that +[here](http://golang.org/doc/install/source). + +Sia has has a development build, an automated testing build, and a release +build. The release build is the only one that can synchronize to the full +network. To get the release build, it is usually sufficient to run `go get -u +github.com/NebulousLabs/Sia/...`. This will download Sia and its dependencies +and install binaries in $GOPATH/bin. + +After downloading, you can find the Sia source code in +$GOPATH/src/github.com/NebulousLabs/Sia. To build the release binary, run +`make release-std` from this directory. To build the release binary with a +(slow) race detector and an array of debugging asserts, run `make release`. To +build the developer binary (which has a different genesis block, faster block +times, and a few other tweaks), just run `make`. + +If you intend to contribute to Sia, you should start by forking the project on +GitHub, and then adding your fork as a "remote" in the Sia git repository via +`git remote add [fork name] [fork url]`. Now you can develop by pulling changes +from `origin`, pushing your modifications to `[fork name]`, and then making a +pull request on GitHub. + +If you see an error like the one below, it means that you either forgot to run +`make dependencies`, or you cloned the project into a path that the go tool +does not recognize (usually the wrong path, or symbolic links were somehow +involved). + +``` +consensus/fork.go:4:2: cannot find package "github.com/NebulousLabs/Sia/crypto" in any of: + /usr/lib/go/src/github.com/NebulousLabs/Sia/crypto (from $GOROOT) + /home/user/gopath/src/github.com/NebulousLabs/Sia/crypto (from $GOPATH) +``` + +Developer Conventions +===================== + +This file is meant to help a developer navigate the codebase and develop clean, +maintainable code. Knowing all of these conventions will also make it easier to +read and code review the Sia project. + +The primary purpose of the conventions within Sia is to keep the codebase +simple. Simpler constructions means easier code reviews, greater accessibility +to newcomers, and less potential for mistakes. It is also to keep things +uniform, much in the spirit of 'go fmt'. When everything looks the same, +everyone has an easier time reading and reviewing code they did not write +themselves. + +Documentation +------------- + +All structs, functions, and interfaces must have a docstring. + +Anytime that something is left unfinished, place a comment containing the +string 'TODO:'. This sends a clear message to other developers, and creates a +greppable way to find unfinished parts of the codebase. 'TODO' statements are +currently discouraged. As the codebase matures, 'TODO' statements will become +increasingly frowned upon. 'TODO' statements should not document feature +requests, but instead document incompleteness where the incompleteness causes +disruption to user experience or causes a security vulnerability. + +Documentation should give a sense of what each function does, but should also +give a sense of the overall architecture of the code. Where useful, examples +should be provided, and common pitfalls should be explained. Anything that +breaks other conventions in any way needs to have a comment, even if it is +obvious why the convention had to be broken. + +The goal of the codebase is to be accessible to newbies. Anything more advanced +than what you would expect to remember from an 'Intro to Data Structures' class +should have an explanation about what the concept it is and why it was picked +over other potential choices. + +Code that exists purely to be compatible with previous versions of the +software should be tagged with a 'COMPATvX.X.X' comment. Examples below. + +```go +// Find and sort the outputs. +outputs := getOutputs() +// TODO: actually sort the outputs. +``` + +```go +// Disallow unknown agents. +// +// COMPATv0.4.0: allow a blank agent to preserve compatibility with +// 'siac' v0.4.0, which did not set an agent. +if agent != "SiaAgent" && agent != "" { + return errors.New("unrecognized agent!") +} +``` + +Naming +------ + +Names are used to give readers and reviewers a sense of what is happening in +the code. When naming variables, you should assume that the person reading your +code is unfamiliar with the codebase. Short names (like 'cs' instead of +'consensusSet') should only be used when the context is immediately obvious. +For example 'cs := new(ConsensusSet)' is immediately obvious context for 'cs', +and so 'cs' is appropriate for the rest of the function. + +Data structures should never have shortened names. 'FileContract.mr' is +confusing to anyone who has not used the data structure extensively. The code +should be accessible to people who are unfamiliar with the codebase. One +exception is for the variable called 'mu', which is short for 'mutex'. This +exception is made because 'mu' appears in many data structures. + +When calling functions with obscure parameters, named variables should be used +to indicate what the parameters do. For example, 'm := NewMiner(1)' is +confusing. Instead, use 'threads := 1; m := NewMiner(threads)'. The name gives +readers a sense of what the parameter within 'NewMiner' does even when they are +not familiar with the 'NewMiner' function. Where possible, functions with +obscure, untyped inputs should be avoided. + +The most important thing to remember when choosing names is to cater to people +who are unfamiliar with the code. A reader should never have to ask 'What is +`cs`?' on their first pass through the code, even though to experienced +developers it is obvious that `cs` refers to a consensus.ConsensusSet. + +Control Flow +------------ + +Where possible, control structures should be minimized or avoided. This +includes avoiding nested if statements, and avoiding else statements where +possible. Sometimes, complex control structures are necessary, but where +possible use alternative code patterns and insert functions to break things up. + +Example: + +```go +// Do not do this: +if err != nil { + return +} else { + forkBlockchain(node) +} + +// Instead to this: +if err != nil { + return +} +forkBlockchain(node) +``` + +Mutexes +------- + +All exported functions from a package and/or object need to be thread safe. +Usually, this means that the first lines of the function contain a `Lock(); +defer Unlock()`. Simple locking schemes should be preferred over performant +locking schemes. As will everything else, anything unusual or convention +breaking should have a comment. + +Non-exported functions should not do any locking, unless they have a special +prefix to the name (explained below). The responsibility for thread-safety +comes from the exported functions which call the non-exported functions. +Maintaining this convention minimizes developer overhead when working with +complex objects. + +Functions prefixed 'threaded' (example 'threadedMine') are meant to be called +in their own goroutine (`go threadedMine()`) and will manage their own +thread-safety. + +Error Handling +-------------- + +All errors need to be checked as soon as they are received, even if they are +known to not cause problems. The statement that checks the error needs to be +`if err != nil`, and if there is a good reason to use an alternative statement +(such as `err == nil`), it must be documented. The body of the if statement +should be at most 4 lines, but usually only one. Anything requiring more lines +needs to be its own function. + +Example: + +```go +block, err := s.AcceptBlock() +if err != nil { + handleAcceptBlockErr(block, err) + return +} +``` + +Sanity Checks +------------- + +Some functions make assumptions. For example, the 'addTransaction' function +assumes that the transaction being added is not in conflict with any other +transactions. Where possible, these explicit assumptions should be validated. + +Example: + +```go +if build.DEBUG { + _, exists := tp.usedOutputs[input.OutputID] + if exists { + panic("incorrect use of addTransaction") + } +} +``` + +In the example, a panic is called for incorrect use of the function, but only +in debug mode. This failure will be invisible in production code, but the code +will have higher performance because the code should never fail anyway. + +If the code is continually checking items that should be universally true, +mistakes are easier to catch during testing, and side effects are less likely +to go unnoticed. + +Sanity checks and panics are purely to check for developer mistakes. A user +should not be able to trigger a panic, and no set of network communications or +real-world conditions should be able to trigger a panic. + +Testing +------- + +The test suite code should be the same quality as the rest of the codebase. +When writing new code in a pull request, the pull request should include test +coverage for the code. + +Most modules have a tester object, which can be created by calling +`createXXXTester`. Module testers typically have a consensus set, a miner, a +wallet, and a few other relevant modules that can be used to build +transactions, mine blocks, etc. + +In general, testing that uses exclusively exported functions to achieve full +coverage is preferred. These types of tests seem to find more bugs and trigger +more asserts. + +Any testing provided by a third party which is both maintainable and reasonably +quick will be accepted. There is little downside to more testing, even when the +testing is largely redundant. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Encoding.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Encoding.md new file mode 100644 index 0000000..6aa66f6 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Encoding.md @@ -0,0 +1,74 @@ +Encoding +======== + +The encoding package converts arbitrary objects into byte slices, and vice +versa. Objects are encoded as binary data, without type information. The +decoder will attempt to decode its input bytes into whatever type it is +passed. For example: + +```go +Marshal(int64(3)) == []byte{3, 0, 0, 0, 0, 0, 0, 0} + +var x int64 +Unmarshal([]byte{3, 0, 0, 0, 0, 0, 0, 0}, &x) +// x == 3 +``` + +Note that this leads to some ambiguity. Since an `int64` and a `uint64` are +both 8 bytes long, it is possible to encode an `int64` and successfully decode +it as a `uint64`. As a result, it is imperative that *the decoder knows +exactly what it is decoding*. Developers must rely on context to determine +what type to decode into. + +The specific rules for encoding Go's builtin types are as follows: + +Integers are little-endian, and are always encoded as 8 bytes, i.e. their +`int64` or `uint64` equivalent. + +Booleans are encoded as one byte, either zero (false) or one (true). No other +values may be used. + +Nil pointers are equivalent to "false," i.e. a single zero byte. Valid +pointers are represented by a "true" byte (0x01) followed by the encoding of +the dereferenced value. + +Variable-length types, such as strings and slices, are represented by an +8-byte unsigned length prefix followed by the encoded value. Strings are +encoded as their literal UTF-8 bytes. Slices are encoded as the concatenation +of their encoded elements. For example: + +```go +// slice len: 1 string len: 3 string data +Marshal([]string{"foo"}) == []byte{1,0,0,0,0,0,0,0, 3,0,0,0,0,0,0,0, 'f','o','o'} +``` + +Maps are not supported; attempting to encode a map will cause `Marshal` to +panic. This is because their elements are not ordered in a consistent way, and +it is imperative that this encoding scheme be deterministic. To encode a map, +either convert it to a slice of structs, or define a `MarshalSia` method (see +below). + +Arrays and structs are simply the concatenation of their encoded elements. +Byte slices are not subject to the 8-byte integer rule; they are encoded as +their literal representation, one byte per byte. + +All struct fields must be exported. (For some types this is a bit awkward, so +this rule is subject to change.) The ordering of struct fields is determined +by their type definition. For example: + +```go +type foo struct { + S string + I int +} + +Marshal(foo{"bar", 3}) == append(Marshal("bar"), Marshal(3)...) +``` + +Finally, if a type implements the SiaMarshaler interface, its MarshalSia +method will be used to encode the type. Similarly, if a type implements the +SiaUnmarshal interface, its UnmarshalSia method will be used to decode the +type. Note that unless a type implements both interfaces, it must conform to +the spec above. Otherwise, it may encode and decode itself however desired. +This may be an attractive option where speed is critical, since it allows for +more compact representations, and bypasses the use of reflection. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/File Contract Negotiation.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/File Contract Negotiation.md new file mode 100644 index 0000000..66fd5d2 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/File Contract Negotiation.md @@ -0,0 +1,289 @@ +File Contract Negotiation +========================= + +Securing data on Sia requires creating and revising file contracts in an +untrusted environment. Managing data on Sia happens through several protocols: + ++ Settings Request - the host sends the renter its settings. + ++ Revision Request - the renter will send the host a file contract id, and the + host will send the most recent file contract revision that it knows of for + that file contract, with the signatures. A challenge and response is also + performed to verify that the renter is able to create the signatures to + modify the file contract revision. + ++ File Contract Creation - no data is uploaded during the initial creation of a + file contract, but funds are allocated so that the file contract can be + iteratively revised in the future. + ++ File Contract Revision - an existing file contract is revised so that data + can be added to an arbitrary place, or removed from an arbitrary place. + ++ File Contract Renewal - an existing file contract is renewed, meaning that a + new file contract with a different id is created, but that has the same data. + New funds are added to this file contract, and it can now be modified + separately from the previous contract. + ++ Data Request - data is requested from the host by hash. + ++ (planned for later) Storage Proof Request - the renter requests that the host + perform an out-of-band storage proof. + ++ (planned for later) Metadata Request - the renter requests some metadata + about the file contract from the host, namely the list of hashes that compose + the file. This list of hashes is provided along with a cryptographic proof + that the hashes are valid. The proof is only needed if only a subset of + hashes are being sent. + +A frequently seen construction is 'acceptance'. The renter or host may have the +opportunity to accept or reject a communication, which takes the form of a +string. The acceptance string is always the same, and any string that is not +the acceptance string is a rejection. The rejection string can include reasons +why the rejection occurred, but most not exceed 255 bytes. After a rejection, +the connection is always closed. + +The protocols described below are numbered. The number indicates when the +communicator is switching. Each pair of numbers is a full round trip of +communications. + +All communications attempt to support slow connections and Tor connections. Any +connection with a throughput below 100kbps may struggle to perform the uploads +and downloads, and any connection with a rountrip latency greater than 2 +minutes may struggle to complete the protocols. + +Settings Request +---------------- + +The host signs the settings request to prove that the connection has opened to +the right party. Hosts announce on the blockchain and perform burn, therefore +identity is important. + +1. The renter makes an RPC to the host, opening a connection. The connection + deadline should be at least 120 seconds. + +2. The host sends the renter the most recent copy of its external settings, + signed by the host public key. The connection is then closed. + +Revision Request +---------------- + +The renter requests a recent revision from the host. Often, this request +precedes modifications. A file contract can only be open for revision with one +party at a time. To prevent DoS attacks, the party must authenticate here by +performing a challenge-response protocol during the revision request. Putting +this challenge-response requirement in the revision-request can help improve +privacy, though the host is under no cryptographic or incentive-based +obligation to preserve the privacy of the revision. + +1. The renter makes an RPC to the host, opening a connection. The connection + deadline should be at least 120 seconds. The renter sends the file contract + id for the revision being requested. + +2. The host writes 32 bytes of random data that the renter must sign for the + renter key in the corresponding file contract. + +3. The renter returns the signed challenge. + +4. The host verifies the signature from the renter and then sends the renter + the most recent file contract revision, along with the transaction + signatures from both the renter and the host. The connection is then closed. + +File Contract Creation +---------------------- + +A few decisions were made regarding the file contract protocol. The first is +that the renter should not sign the file contract until the host has formally +accepted the file contract. The second is that the host should be the last one +to sign the file contract, as the renter is the party with the strong +reputation system. + +Instead of sending a whole transaction each time, the transaction is sent +piecemeal, and only the new parts at each step are sent to the other party. +This minimizes the surface area of data for a malicious party to manipulate, +which means less verification code, which means less chances of having a bug in +the verification code. + +The renter pays for the siafund fee on the host's collateral and contract fee. +If a renter opens a file contract and then never uses it, the host does not +lose money. This does put the renter at risk, as they may open up a file +contract and then watch the host leave, but the renter is spreading the risk +over communications with many hosts, and has a reputation system that will help +ensure that the renter is only dealing with upstanding hosts. + +1. The renter makes an RPC to the host, opening a connection. The connection + deadline should be at least 360 seconds. + +2. The host sends the renter the most recent copy of its settings, signed. If + the host is not accepting new file contracts, the connection is closed. + +3. The renter sends a notice of acceptance or rejection. If the renter accepts, + the renter then sends a funded file contract transaction without a + signature, followed by the public key that will be used to create the + renter's portion of the UnlockConditions for the file contract. + +4. The host sends an acceptance or rejection of the file contract. If the host + accepts, the host will add collateral to the file contract, and will send + the renter the inputs + outputs for the collateral, followed by any new + parent transactions. The length of any of these may be zero. + +5. The renter indicates acceptance or rejection of the file contract. If the + renter accepts, the renter will sign the file contract and send the + transaction signatures to the host. The renter will also send a signature + for a no-op file contract revision that follows the file contract. + +6. The host may only reject the file contract in the event that the renter has + sent invalid signatures, so the acceptance step is skipped. The host signs + the file contract and sends the transaction signatures to the renter, and + the host creates and sends a signature for the no-op revision that follows + the file contract. The connection is closed. + +File Contract Revision +---------------------- + +1. The renter makes an RPC to the host, opening a connection. The minimum + deadline for the connection is 600 seconds. The renter then sends a file + contract ID, indicating the file contract that is getting revised during the + RPC. + +2. The host will respond with a 32 byte challenge - a random 32 bytes that the + renter will need to sign. + +3. The renter will sign the challenge with the renter key that protects the + file contract. This is to prove that the renter has access to the file + contract. + +4. The host will verify the challenge signature, then send an acceptance or + rejection. If accetped, the host will send the most recent file contract + revision for the file contract along with the transaction signagtures that + validate the revision. The host will lock the file contract, meaning no + other changes can be made to the revision file contract until this + connection has closed. + + A loop begins. The host sends the most recent revision of the host settings + to the renter, signed. The settings are sent after each iteration of the + loop to enable high resolution dynamic pricing for the host, especially for + bandwidth. + +6. The renter may reject or accept the settings + revision. A specific + rejection message will gracefully terminate the loop here. The renter will + send an unsigned file contract revision followed by a batch of modification + actions which the revision pays for. Batching allows the renter to send a + lot of data in a single, one-way connection, improving throughput. The + renter will send a number indicating how many modifications will be made in + a batch, and then sends each modification in order. + + A single modification can either be an insert, a modify, or a delete. An + insert is an index, indicating the index where the data is going to be + inserted. '0' indicates that the data is inserted at the very beginning, '1' + indicates that the data will be inserted between the first and second + existing sectors, etc. The index is followed by the 4MB of data. A modify is + an index indicating which sector is being modified, followed by an offset + indicating which data within the sector is being modified. Finally, some + data is provided indicating what the data in the sector should be replaced + with starting from that offset. The offset + len of the data should not + exceed the sector size of 4MB. A delete is an index indicating the index of + the sector that is being deleted. Each operation within a batch is atomic, + meaning if you are inserting 3 sectors at the front of the file contract, + the indexes of each should be '0', '1', '2'. + +7. The host indicates either acceptance or rejection of the new revision. + +8. The renter signs the revision and sends the signature to the host. + +9. The host signs the revision and sends the siganture to the renter. Both + parties submit the new revision to the transaction pool. The connection + deadline is reset to 600 seconds (unless the maximum deadline has been + reached), and the loop restarts. + +File Contract Renewal +--------------------- + +1. The renter makes an RPC to the host, opening a connection. The minimum + deadline for the connection is 600 seconds. The renter then sends a file + contract ID, indicating the file contract that is getting revised during the + RPC. + +2. The host will respond with a 32 byte challenge - a random 32 bytes that the + renter will need to sign. + +3. The renter will sign the challenge with the renter key that protects the + file contract. This is to prove that the renter has access to the file + contract. + +4. The host will verify the challenge signature, then send an acceptance or + rejection. If accetped, the host will send the most recent file contract + revision for the file contract along with the transaction signagtures that + validate the revision. The host will lock the file contract, meaning no + other changes can be made to the revision file contract until this + connection has closed. The host sends the most recent revision of the host + settings to the renter, signed. If the host is not accepting new file + contracts, the connection is closed. + +5. The renter either accepts or rejects the settings. If accepted, the renter + sends a funded, unsigned file contract to the host, containing the same + Merkle root as the previous file contract, and also containing a renewed + payout with conditional payments to the host to cover the host storing the + data for the extended duration. + +6. The host will accept or reject the renewed file contract. If accepted, the + host will add collateral (and miner fees if desired) and send the inputs + + outputs for the collateral, along with any new parent transactions. The + length of any of these may be zero. + +7. The renter will accept or reject the host's additions. If accepting, the + renter will send signatures for the transaction to the host. The renter will + also send a signature for a no-op file contract revision that follows the + file contract. + +8. The host may only reject the file contract in the event that the renter has + sent invalid signatures, so the acceptance step is skipped. The host signs + the file contract and sends the transaction signatures to the renter, and + the host creates and sends a signature for the no-op revision that follows + the file contract. The connection is closed. + +Data Request +------------ + +1. The renter makes an RPC to the host, opening a connection. The connection + deadline is at least 600 seconds. The renter will send a file contract id + corresponding to the file contract that will be used to pay for the + download. + +2. The host will respond with a 32 byte challenge - a random 32 bytes that the + renter will need to sign. + +3. The renter will sign the challenge with the public key that protects the + file contract being used to pay for the download. This proves that the + renter has access to the payment. + +4. The host will verify the challenge signature, and then send an acceptance or + rejection. If accepted, the host will send the most recent file contract + revision followed by the signautres that validate the revision. The host + will lock the file contract, preventing other connections from making + changes to the underlying storage obligation. + + A loop begins. The host sends the most recent external settings to the + renter, signed. The settings are sent each iteration to provide high + resolution dynamic bandwidth pricing. + +5. The host will send the renter the most recent file contract revision, along + with the signatures that validate the revision. + + A loop begins, which will allow the renter to download multiple batches of + data from the same connection. The host will send the host settings, and the + most recent file contract revision transaction. If there is no revision yet, + the host will send a blank transaction. The host is expected to always have + the most recent revision (the host signs last), the renter may not have the + most recent revision. + +6. The renter will accept or reject the host's settings. If accepting, the + renter will send a file contract revision, unsigned, to pay for the download + request. The renter will then send the download request itself. + +7. The host will either accept or reject the revision. + +8. The renter will send a signature for the file contract revision. + +9. The host sends a signature for the file contract revision, followed by the + data that was requested by the download request. The loop starts over, and + the connection deadline is reset to a minimum of 600 seconds. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Guide to Contributing to Sia.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Guide to Contributing to Sia.md new file mode 100644 index 0000000..6747563 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Guide to Contributing to Sia.md @@ -0,0 +1,250 @@ +# Contributing to Sia + +#### Table of Contents +* [Get started with Go](#go) + * [Install Go](#install-go) + * [Learn Go]("learn-go") +* [Build Sia](#build-sia) +* [Contribute to the codebase](#contribute) + * [Set up git](#setup-git) + * [Fork the Sia repository](#fork) + * [Write some code](#write) + * [Submit your code for review](#pull) + * [More git resources](#git-resources) +* [Where to start](#where-to-start) +* [Contact us](#contact) + + +## Get started with Go + + +### Install Go +To install Go on your computer, follow the +[official installation guide][install-go]. + +You should install the latest [official Go binary][binary] for your system (if +not available, [install from source][source]). If you plan to cross compile +Sia, see [Cross Compilation with Go 1.5][cross] by Dave Cheney. + +Now make a workspace directory in which you will store source code and +dependencies. You can choose any filepath except where you installed Go (don't +choose `/usr/local`). + +```bash +# make a working directory called golang in your home directory +$ mkdir $HOME/golang +# store base path in an environmental variable +$ echo 'export GOPATH=$HOME/golang' >> $HOME/.profile +# add bin subdirectory to PATH environmental variable +$ echo 'export PATH=$PATH:$GOPATH/bin' >> $HOME/.profile +``` + + +### Learn Go +* To get familiar with the language, start with the official [Tour of Go][tour]. +* Move onto [How to Write Go Code][how] to learn how to organize Go packages +and use the go tool. +* Finish with the [Effective Go][effective] guide. + + +## Build Sia +To build Sia on your machine, enter the following on the command line: + +```bash +# Download Sia and its dependencies +# Binaries will be installed in $GOPATH/bin +$ go get -u github.com/NebulousLabs/Sia/... + +# Switch to directory containing Sia source code +$ cd $GOPATH/src/github.com/NebulousLabs/Sia + +# You have three Sia builds to choose from. +# To build the standard release binary: +$ make release-std +# Or to build the release binary with race detection and an array debugging +# asserts: +$ make release +# Or to build the developer binary (with a different genesis block, faster +# block times, and other changes): +$ make +``` + + +## Contribute to the codebase + +### Set up git +Install git on your machine according to [these instructions][install-git] in +the Pro Git book. + +You will first need to set up global settings using the command line. +```bash +$ git config --global user.name "Your Name" +$ git config --global user.email you@somedomain.com + +# Tell git to remember your login information for a certain amount of time. +# Default time is 15 minutes: +$ git config --global credential.helper cache +# Or you can choose a different amount of time: +$ git config --global credential.helper "cache --timeout=[seconds]" + +``` + +### Fork the Sia repository +While logged into your Github account, navigate to the [Sia repository][sia] +and click the 'Fork' button in the upper righthand corner. Your account now +has a 'forked' copy of the original repo at +`https://github.com//Sia`. + +When you installed Sia using `go get`, the go tool put the Sia source code in +$GOPATH/src/github.com/NebulousLabs/Sia. Change to that directory and set up +your fork as a git [remote][remote]: + +```bash +$ cd $GOPATH/src/github.com/NebulousLabs/Sia +# Add your fork as a remote. Name it whatever is convenient, +# e.g your GitHub username +$ git remote add https://github.com//Sia.git +``` + + +### Write some code +Right now your git local repository only has one branch (called 'master' by +default). If you want to make changes, add a new branch and make your changes +there. You should maintain master as an up-to-date copy of the NebulousLabs/Sia +repository's master branch. + +To create and checkout a new branch: +```bash +# If you're not already in the right directory: +$ cd $GOPATH/src/NebulousLabs/Sia +# Make sure you're on branch master +$ git checkout master +# Create and checkout a new branch +$ git checkout -b +``` +Now write some code while the new branch is checked out. + +Only implement one logical change per branch. If you're working on several +things at once, make multiple branches. To switch between branches you're +working on, you have to stash the changes in the branch you're switching from +by running `git stash`, which tucks away all changes since the last +commit. + +```bash +# Stash changes to current branch. +$ git stash +# Checkout other branch. +$ git checkout +... +# Make changes +... +# Return to first branch: +$ git checkout +# View a list of stashes and their corresponding hashes. +$ git stash list +# Reapply changes from the stash you want to recover and remove that stash from. +# the list +$ git stash pop +``` + +To learn more about branching, see +[Using the Fork-and-Branch Git Workflow][branch] and +[Pro Git - Branches in a Nutshell][nutshell]. +For more on stashing, see [Pro Git - Stashing and Cleaning][stashing]. + +Be sure to follow the conventions detailed in +[docs/Developers.md][developers.md]. We will reject pull requests that do not +satisfy these best practices. + +Once you've finished making changes, stage and commit your changes then update +your fork on Github: + +```bash +# Make sure the code is up to date with the original repo: +$ git checkout master +$ git pull origin master +# Checkout branch with changes. +$ git checkout +$ git rebase master +# Before every pull request, you should run `make test-long` +# to test your code and fix formatting and style problems. +$ make test-long +# If all goes well, proceed to staging your changed files: +$ git add +# Use `git status` to see what files have been staged. +$ git status +# Commit your changes. If you just run `commit`, a text editor will pop up for +# you to enter a description of your changes. +$ git commit -m "Add new tests for CommitSync method" +# Push the changes to your fork on GitHub, which you should have set up as a +# remote already. +$ git push +``` + +### Submit your code for review +Once you've tested your new code and pushed changes to your fork, navigate to +your fork at `https://github.com//Sia` in your browser. +Switch to the branch you've made changes on by selecting it from the list on +the upper left. Then click 'New pull request' on the upper right. + +Once you have made the pull request, we will review your code. We will reject +code that is unsafe, difficult to read, or otherwise violates the conventions +outlined in [docs/Developers.md][developers.md]. + +Here's a sample code review comment: +![Screenshot](assets/codereview.png) + +If you want to tweak code for which you've already submitted a pull request, +push the updated code to your fork with `git push -f ` and +summarize the changes you've made in a comment on the pull request page on +GitHub. + +Once we have accepted your changes and merged them into the original repo, you +have some cleanup to do: + +```bash +# Update local master branch to reflect changes in origin (the original +# repo). +$ git pull origin master +# Delete the branch you made the pull request from. +$ git branch -d +# Delete the remote branch on your fork. +$ git push : +# Update your fork. +$ git push master +``` + +### More Git resources + * [How to into git (and Github)][luke] by Luke Champine + * [Official resources for learning Git][git] + + +## Where to start +If you'd like to contribute to Sia but don't have any specific ideas, writing +tests is a good way to get your feet wet. See [doc/Running and Writing Tests for Sia.md](Running\ and\ Writing\ Tests\ for\ Sia.md) to get started. + + +## Contact us +Feel free to ask for help on the #dev channel on [Slack][slack]. + +[cross]: http://dave.cheney.net/2015/08/22/cross-compilation-with-go-1-5 +[binary]: https://golang.org/dl/ +[source]: https://golang.org/doc/install/source +[tour]: https://tour.golang.org/welcome/1 +[how]: https://golang.org/doc/code.html +[luke]: https://gist.github.com/lukechampine/6418449 +[git]: https://git-scm.com/doc +[cheney]: http://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go +[install-go]: https://golang.org/doc/install +[signup]: https://github.com/join?source=header-home +[effective]: https://golang.org/doc/effective_go.html +[sia]: https://github.com/NebulousLabs/Sia +[branch]: http://blog.scottlowe.org/2015/01/27/using-fork-branch-git-workflow/ +[developers.md]: https://github.com/NebulousLabs/Sia/blob/master/doc/Developers.md +[gofmt]: https://golang.org/cmd/gofmt/ +[nutshell]: https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell +[slack]: http://slackin.siacoin.com +[install-git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git +[test-doc]: https://github.com/NebulousLabs/Sia/blob/master/doc/Testing.md +[stashing]: https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning +[remote]: https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Modules.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Modules.md new file mode 100644 index 0000000..a91097b --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Modules.md @@ -0,0 +1,35 @@ +Module Conventions +================== + +Each module has a file/directory where they store persistent data (if +necessary). When module.New is called, the module is responsible for creating +and populating that directory. The logic for saving and loading data belongs in +persist.go. + +Modules that depend on external information (such as the state of consensus) +have an update.go to manage fetching and integrating the external information. +If that information is coming from another module, a subscription should be +used. Module subscription uses a ModuleSubscriber interface (which the +subscriber must satisfy) and a ModuleSubscribe method (implemented by the +parent module). As the parent module gets updates, it will call +ReceiveModuleUpdate (the only method of the ModuleSubscriber interface) on all +subscribers, taking care that each subscriber always receives the updates in +the correct order. This method of subscription is chosen to keep information +flow simple and synchronized - a child module should never have information +that the parent module does not (it just causes problems). + +For testing, it is often important to know that an update has propagated to all +modules. Any module that subscribes to another must also implement a +ModuleNotify function in subscriptions.go. ModuleNotify returns a channel down +which a struct{} will be sent every time that module receives an update from a +parent module. To keep things simple, a module should not subscribe to the +parent of another module that it is subscribed to. For example, the transaction +pool is subscribed to the consensus set. Therefore, no module should subscribe +to both the transaction pool and the consensus set. All consensus set updates +should be received through the transaction pool. This helps with +synchronization and ensures that no child module ever has information that the +parent module has not yet received (desynchronization). + +#### Module Update Flow + +consensus -> (host, hostdb, renter, (transaction pool -> miner, wallet)) diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Running and Writing Tests for Sia.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Running and Writing Tests for Sia.md new file mode 100644 index 0000000..810c733 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Running and Writing Tests for Sia.md @@ -0,0 +1,256 @@ +# Running and Writing Tests for Sia +Improving test coverage is a great way to start contributing to Sia. + +This guide focuses on how to write tests. To learn about making pull requests +to submit the code you've written, see +[doc/Guide to Contributing to Sia.md][guide]. You should also read +[doc/Developers.md][developers] to learn about Sia code conventions and quality +standards. + + +#### Table of Contents +* [Running tests for Sia](#existing) + * [Updating code before testing](#update) + * [Testing the entire build](#entire) + * [Testing a particular package](#particular) +* [Writing new tests for Sia](#write) + * [A few guidelines](#naming) + * [Basic test format](#basic) + * [Table-driven tests](#table) +* [Questions?](#questions) + + +## Running tests for Sia +Go's comprehensive [test package][pkg/testing] makes testing straightforward, +particularly when you use the bundled tools included in the +[Sia makefile][makefile], including `make test`, `make cover`, `make bench`, +and their variants. + + +### Updating code before testing +If you just want to run existing tests on the codebase as is, you just need to +pull the latest version of the original repo to your master branch. (If that +sentence didn't make sense, go read +[doc/Guide to Contributing to Sia.md][guide].) + +```bash +# Make sure you are in the right directory. +$ cd $GOPATH/src/github.com//Sia +# Also make sure you're working with the right branch. +$ git checkout master +# Pull latest changes from origin, the original Sia repo. +$ git pull origin master +# Update your fork of the repo, which should be set up as a remote. +$ git push master +``` + +If you want to run tests on the new code you've added, first make sure the rest +of the code is up to date. New code should be on its own branch (again, see +[doc/Guide to Contributing to Sia.md][guide]). + +```bash +# Make sure you are in the right directory. +$ cd $GOPATH/src/github.com//Sia +# Checkout the branch you made the changes on. +$ git checkout +# Stash any tracked but uncommitted changes. +$ git stash +# Then switch back to `master` and update it to match the original repo. +$ git checkout master +$ git pull origin master +# Update your fork of the repo, which you should have set up as a remote. +$ git push master +# Make the updated `master` the new base of the branch you made the changes on, +# which involves reapplying all the commits made to that branch. Without the +# `--ignore-date` flag, git rebase changes the date on all the commits to the +# current date. +$ git checkout +$ git rebase master --ignore-date +# Restore the changes you stashed earlier. +$ git stash pop +``` +When you call `rebase`, you may run into some merge conflicts. Luke Champine's +['How to into git and GitHub'][luke] has more details (and many useful tricks). + +Once the branch you want to test is up to date, you're ready to run some tests. + + +### Testing the entire build +The `make test` command runs all tests (functions starting with `Test` in +`_test.go` files) for each package, setting off a panic for any test that runs +longer than 5s. For verbose output, run `make test-v` (which panics after 15s +instead of 5s). Finally, `make test-long` has verbose output, only panics when +a test takes 5 minutes, and also cleans up your code using `gofmt` and `golint`. +**You should run** `make test-long` **before each pull request.** + +Run `make cover` to run all tests for each package and generate color-coded +.html visualizations of test coverage by function for each source file. Open +`cover/.html` in a browser to inspect a module's test coverage. For +example, here's part of the html file generated for the persist package: + +![Screenshot](assets/covertool.png) + +Meanwhile, `make bench` will call `gofmt` on all packages, then run all +benchmarks (functions starting with `Benchmark` in `_test.go` files). + + +### Testing a particular package or function +To run tests for just a certain package, run `make test pkgs=./`. To run +a certain test function, run `make test pkgs=./ run=`. The same +goes for `make test-long`, `make cover` and `make bench`. + +For example, running `test-long` on the package persist produces this output: + +```bash +$ make test-long pkgs=./persist +rm -rf release doc/whitepaper.aux doc/whitepaper.log doc/whitepaper.pdf +gofmt -s -l -w ./persist +go install ./persist +go vet ./persist +go test -v -race -tags='testing debug' -timeout=300s ./persist -run=Test +=== RUN TestOpenDatabase +--- PASS: TestOpenDatabase (0.42s) +=== RUN TestSaveLoad +--- PASS: TestSaveLoad (0.00s) +=== RUN TestSaveLoadFile +--- PASS: TestSaveLoadFile (0.01s) +=== RUN TestSaveLoadFileSync +--- PASS: TestSaveLoadFileSync (0.00s) +=== RUN TestLogger +--- PASS: TestLogger (0.00s) +=== RUN TestLoggerCritical +--- PASS: TestLoggerCritical (0.00s) +=== RUN TestIntegrationRandomSuffix +--- PASS: TestIntegrationRandomSuffix (0.01s) +=== RUN TestAbsolutePathSafeFile +--- PASS: TestAbsolutePathSafeFile (0.00s) +=== RUN TestRelativePathSafeFile +--- PASS: TestRelativePathSafeFile (0.00s) +PASS +ok github.com/NebulousLabs/Sia/persist 1.485s +$ +``` + + +## Writing new tests for Sia +When you run `make cover`, you'll notice that many files have pretty low +coverage. We're working on fixing that, but we could use your help. + + +### A few guidelines +* The test functions for `filename.go` should go in `filename_test.go` in the + same directory and package. +* A test function name should start with `Test` and clearly convey what is + being tested. +* You should declare function-specific variables and constants locally (inside + the test function) instead of globally (outside the test function). [That + holds in general][global], not just for tests. +* As always, code should adhere to the standards and conventions laid out in + [doc/Developers.md][developers]. + + +### Basic test format +Suppose we'd like to test the Bar method belonging to type Foo. + +```go +// TestFoo checks that the Bar method on type Foo responds correctly to a normal +// input and returns the expected error when given a bad input. +func TestFoo(t *testing.T) { + foo, err := NewFoo() + if err != nil { + // If NewFoo failed, we can't continue testing. + t.Fatal(err) + } + + // Try a normal input; should succeed. + err := foo.Bar(3) + if err != nil { + // Report the error, but don't abort the test. + t.Error(err) + } + + // Try a bad input; should return an error. + // NOTE: Always prefer to compare to a specific error, rather than + // err == nil + err = Foo.Bar(0) + if err != errDivideByZero { + t.Errorf("expected errDivideByZero, got %v", err) + } +} + +``` + + +### Table-driven tests in Go +If you're looking to test a bunch of inputs, write a [table-driven test][table] +with a slice of anonymous structs. For example, see `TestParseFileSize` in +[siac/parse_test.go][parse_test]: + +```go +func TestParseFilesize(t *testing.T) { + // Define a table of test cases in the form of a slice of anonymous structs. + tests := []struct { + in, out string + err error + }{ + {"1b", "1", nil}, + {"1KB", "1000", nil}, + {"1MB", "1000000", nil}, + {"1GB", "1000000000", nil}, + {"1TB", "1000000000000", nil}, + {"1KiB", "1024", nil}, + {"1MiB", "1048576", nil}, + {"1GiB", "1073741824", nil}, + {"1TiB", "1099511627776", nil}, + {"", "", errUnableToParseSize}, + {"123", "123", nil}, + {"123TB", "123000000000000", nil}, + {"123GiB", "132070244352", nil}, + {"123BiB", "", errUnableToParseSize}, + {"GB", "", errUnableToParseSize}, + {"123G", "", errUnableToParseSize}, + {"123B99", "", errUnableToParseSize}, + {"12A3456", "", errUnableToParseSize}, + {"1.23KB", "1230", nil}, + {"1.234KB", "1234", nil}, + {"1.2345KB", "1234", nil}, + } + // Loop through the table of test cases to make sure ParseFileSize returns + // the expected output and error for each. + for _, test := range tests { + res, err := parseFilesize(test.in) + if res != test.out || err != test.err { + t.Errorf("parseFilesize(%v): expected %v %v, got %v %v", test.in, test.out, test.err, res, err) + } + } +} +``` + +## Questions? +Read these if you haven't already: +* [doc/Guide to Contributing to Sia.md][guide]: getting started with Go, Sia, + and git +* [doc/Developers.md][developers]: conventions and quality standards for Sia + code + +Some other useful resources, some of which have been linked to already: +* [Golang.org page on the go testing package][pkg/testing] +* [Writing Table-Driven Tests in Go][table] +* [How to Write Benchmarks in Go][cheney-benchmarks] +* [How to into git and GitHub][luke]: an essential introduction to git + +And feel free to ask questions on the [#dev channel][slack] on the Sia Slack. +Odds are, someone else is wondering the same thing. + +[pkg/testing]: https://golang.org/pkg/testing/ +[makefile]: https://github.com/NebulousLabs/Sia/blob/master/Makefile +[luke]: https://gist.github.com/lukechampine/6418449 +[guide]: https://github.com/NebulousLabs/Sia/blob/master/doc/Guide%20to%20Contributing%20to%20Sia.md +[developers]: https://github.com/NebulousLabs/Sia/blob/master/doc/Developers.md +[table]: http://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go +[boltdb_test.go]: https://github.com/NebulousLabs/Sia/blob/master/persist/boltdb_test.go +[cheney-benchmarks]: http://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go +[pkg/testing]: https://golang.org/pkg/testing/ +[slack]: https://siatalk.slack.com/messages/dev/ +[parse_test]: https://github.com/NebulousLabs/Sia/blob/master/siac/parse_test.go +[global]: http://c2.com/cgi/wiki?GlobalVariablesAreBad diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/Standard.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Standard.md new file mode 100644 index 0000000..c9c3f92 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/Standard.md @@ -0,0 +1,61 @@ +Standard Transaction Rules +========================== + +Some transactions will not be accepted by miners unless they appear in a block. +This is equivalent to the 'IsStandard' function in Bitcoin. This file dictates +the rules for standard Sia transactions. + +Transaction Size +---------------- + +Consensus rules limit the size of a block, but not the size of a transaction. +Standard rules however limit the size of a single transaction to 16kb. + +A chain of dependent transactions cannot exceed 500kb. + +Double Spend Rules +------------------ + +When two conflicting transactions are seen, the first transaction is the only +one that is kept. If the blockchain reorganizes, the transaction that is kept +is the transaction that was most recently in the blockchain. This is to +discourage double spending, and enforce that the first transaction seen is the +one that should be kept by the network. Other conflicts are thrown out. + +Transactions are currently included into blocks using a first-come first-serve +algorithm. Eventually, transactions will be rejected if the fee does not meet a +certain minimum. For the near future, there are no plans to prioritize +transactions with substantially higher fees. Other mining software may take +alternative approaches. + +File Contract Rules +------------------- + +File Contracts that start in less than 10 blocks time are not accepted into the +transaction pool. This is because a file contract becomes invalid if it is not +accepted into the blockchain by the start block, and this might result in a +cascade of invalidated unconfirmed transactions, which may make it easier to +launch double spend attacks on zero confirmation outputs. 10 blocks is plenty +of time on the other hand for a file contract to make it into the blockchain. + +Signature Algorithms +-------------------- + +Miners will reject transactions that have public keys using algorithms that the +miner does not understand. + +Arbitrary Data Usage +-------------------- + +Arbitrary data can be used to make verifiable announcements, or to have other +protocols sit on top of Sia. The arbitrary data can also be used for soft +forks, and for protocol relevant information. Any arbitrary data is allowed by +consensus, but only certain arbitrary data is considered standard. + +Arbitrary data that is prefixed by the string 'NonSia' is always allowed. This +indicates that the remaining data has no relevance to Sia protocol rules, and +never will. + +Arbitrary data that is prefixed by the string 'HostAnnouncement' is allowed, +but only if the data within accurately decodes to the HostAnnouncement struct +found in modules/hostdb.go, and contains no extra information. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Consensus.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Consensus.md new file mode 100644 index 0000000..2ef61d0 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Consensus.md @@ -0,0 +1,47 @@ +Consensus API +============= + +This document contains detailed descriptions of the consensus's API routes. For +an overview of the consensus' API routes, see +[API.md#consensus](/doc/API.md#consensus). For an overview of all API routes, +see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The consensus set manages everything related to consensus and keeps the +blockchain in sync with the rest of the network. The consensus set's API +endpoint returns information about the state of the blockchain. + +Index +----- + +| Route | HTTP verb | +| ---------------------------- | --------- | +| [/consensus](#consensus-get) | GET | + +#### /consensus [GET] + +returns information about the consensus set, such as the current block height. + +###### JSON Response +```javascript +{ + // True if the consensus set is synced with the network, i.e. it has downloaded the entire blockchain. + "synced": true, + + // Number of blocks preceding the current block. + "height": 62248, + + // Hash of the current block. + "currentblock": "00000000000008a84884ba827bdc868a17ba9c14011de33ff763bd95779a9cf1", + + // An immediate child block of this block must have a hash less than this + // target for it to be valid. + "target": [0,0,0,0,0,0,11,48,125,79,116,89,136,74,42,27,5,14,10,31,23,53,226,238,202,219,5,204,38,32,59,165] +} +``` diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Daemon.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Daemon.md new file mode 100644 index 0000000..6224040 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Daemon.md @@ -0,0 +1,100 @@ +Daemon API +=========== + +This document contains detailed descriptions of the daemon's API routes. For an +overview of the daemon's API routes, see [API.md#daemon](/doc/API.md#daemon). +For an overview of all API routes, see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The daemon is responsible for starting and stopping the modules which make up +the rest of Sia. It also provides endpoints for viewing build constants. + +Index +----- + +| Route | HTTP verb | +| ----------------------------------------- | --------- | +| [/daemon/constants](#daemonconstants-get) | GET | +| [/daemon/stop](#daemonstop-get) | GET | +| [/daemon/version](#daemonversion-get) | GET | + +#### /daemon/constants [GET] + +returns the set of constants in use. + +###### JSON Response +```javascript +{ + // Timestamp of the genesis block. + "genesistimestamp": 1433600000, // Unix time + // Maximum size, in bytes, of a block. Blocks larger than this will be + // rejected by peers. + "blocksizelimit": 2000000, // bytes + // Target for how frequently new blocks should be mined. + "blockfrequency": 600, // seconds per block + // Height of the window used to adjust the difficulty. + "targetwindow": 1000, // blocks + // Duration of the window used to adjust the difficulty. + "mediantimestampwindow": 11, // blocks + // How far in the future a block can be without being rejected. A block + // further into the future will not be accepted immediately, but the daemon + // will attempt to accept the block as soon as it is valid. + "futurethreshold": 10800, // seconds + // Total number of siafunds. + "siafundcount": "10000", + // Fraction of each file contract payout given to siafund holders. + "siafundportion": "39/1000", + // Number of children a block must have before it is considered "mature." + "maturitydelay": 144, // blocks + + // Number of coins given to the miner of the first block. Note that elsewhere + // in the API currency is typically returned in hastings and as a bignum. + // This is not the case here. + "initialcoinbase": 300000, // Siacoins. + // Minimum number of coins paid out to the miner of a block (the coinbase + // decreases with each block). Note that elsewhere in the API currency is + // typically returned in hastings and as a bignum. This is not the case + // here. + "minimumcoinbase": 30000, // Siacoins + + // Initial target. + "roottarget": [0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + // Initial depth. + "rootdepth": [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], + + // Largest allowed ratio between the old difficulty and the new difficulty. + "maxadjustmentup": "5/2", + // Smallest allowed ratio between the old difficulty and the new difficulty. + "maxadjustmentdown": "2/5", + + // Number of Hastings in one siacoin. + "siacoinprecision": "1000000000000000000000000" // hastings per siacoin +} +``` + +#### /daemon/stop [GET] + +cleanly shuts down the daemon. May take a few seconds. + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /daemon/version [GET] + +returns the version of the Sia daemon currently running. + +###### JSON Response +```javascript +{ + // Version number of the running Sia Daemon. This number is visible to its + // peers on the network. + "version": "1.0.0" +} +``` diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Gateway.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Gateway.md new file mode 100644 index 0000000..0992942 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Gateway.md @@ -0,0 +1,159 @@ +Gateway API +=========== + +This document contains detailed descriptions of the gateway's API routes. For +an overview of the gateway's API routes, see +[API.md#gateway](/doc/API.md#gateway). For an overview of all API routes, see +[API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The gateway maintains a peer to peer connection to the network and provides a +method for calling RPCs on connected peers. The gateway's API endpoints expose +methods for viewing the connected peers, manually connecting to peers, and +manually disconnecting from peers. The gateway may connect or disconnect from +peers on its own. + +Index +----- + +| Route | HTTP verb | Examples | +| ---------------------------------------------------------------------------------- | --------- | ------------------------------------------------------- | +| [/gateway](#gateway-get-example) | GET | [Gateway info](#gateway-info) | +| [/gateway/connect/___:netaddress___](#gatewayconnectnetaddress-post-example) | POST | [Connecting to a peer](#connecting-to-a-peer) | +| [/gateway/disconnect/___:netaddress___](#gatewaydisconnectnetaddress-post-example) | POST | [Disconnecting from a peer](#disconnecting-from-a-peer) | + +#### /gateway [GET] [(example)](#gateway-info) + +returns information about the gateway, including the list of connected peers. + +###### JSON Response +```javascript +{ + // netaddress is the network address of the gateway as seen by the rest of + // the network. The address consists of the external IP address and the + // port Sia is listening on. It represents a `modules.NetAddress`. + "netaddress": String, + + // peers is an array of peers the gateway is connected to. It represents + // an array of `modules.Peer`s. + "peers": []{ + // netaddress is the address of the peer. It represents a + // `modules.NetAddress`. + "netaddress": String, + + // version is the version number of the peer. + "version": String, + + // inbound is true when the peer initiated the connection. This field + // is exposed as outbound peers are generally trusted more than inbound + // peers, as inbound peers are easily manipulated by an adversary. + "inbound": Boolean + } +} +``` + +#### /gateway/connect/{netaddress} [POST] [(example)](#connecting-to-a-peer) + +connects the gateway to a peer. The peer is added to the node list if it is not +already present. The node list is the list of all nodes the gateway knows +about, but is not necessarily connected to. + +###### Path Parameters +``` +// netaddress is the address of the peer to connect to. It should be a +// reachable ip address and port number, of the form 'IP:port'. IPV6 addresses +// must be enclosed in square brackets. +// +// Example IPV4 address: 123.456.789.0:123 +// Example IPV6 address: [123::456]:789 +:netaddress +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /gateway/disconnect/{netaddress} [POST] [(example)](#disconnecting-from-a-peer) + +disconnects the gateway from a peer. The peer remains in the node list. +Disconnecting from a peer does not prevent the gateway from automatically +connecting to the peer in the future. + +###### Path Parameters +``` +// netaddress is the address of the peer to connect to. It should be a +// reachable ip address and port number, of the form 'IP:port'. IPV6 addresses +// must be enclosed in square brackets. +// +// Example IPV4 address: 123.456.789.0:123 +// Example IPV6 address: [123::456]:789 +:netaddress +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +Examples +-------- + +#### Gateway info + +###### Request +``` +/gateway +``` + +###### Expected Response Code +``` +200 OK +``` + +###### Example JSON Response +```json +{ + "netaddress":"333.333.333.333:9981", + "peers":[ + { + "netaddress":"222.222.222.222:9981", + "version":"1.0.0", + "inbound":false + }, + { + "netaddress":"111.111.111.111:9981", + "version":"0.6.0", + "inbound":true + } + ] +} +``` + +#### Connecting to a peer + +###### Request +``` +/gateway/connect/123.456.789.0:123 +``` + +###### Expected Response Code +``` +204 No Content +``` + +#### Disconnecting from a peer + +###### Request +``` +/gateway/disconnect/123.456.789.0:123 +``` + +###### Expected Response Code +``` +204 No Content +``` diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Host.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Host.md new file mode 100644 index 0000000..e49dac7 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Host.md @@ -0,0 +1,536 @@ +Host API +-------- + +This document contains detailed descriptions of the host's API routes. For an +overview of the host's API routes, see [API.md#host](/doc/API.md#host). For an +overview of all API routes, see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The host provides storage from local disks to the network. The host negotiates +file contracts with remote renters to earn money for storing other users' +files. The host's endpoints expose methods for viewing and modifying host +settings, announcing to the network, and managing how files are stored on disk. + +Index +----- + +| Route | HTTP verb | +| ------------------------------------------------------------------------------------- | --------- | +| [/host](#host-get) | GET | +| [/host](#host-post) | POST | +| [/host/announce](#hostannounce-post) | POST | +| [/host/storage](#hoststorage-get) | GET | +| [/host/storage/folders/add](#hoststoragefoldersadd-post) | POST | +| [/host/storage/folders/remove](#hoststoragefoldersremove-post) | POST | +| [/host/storage/folders/resize](#hoststoragefoldersresize-post) | POST | +| [/host/storage/sectors/delete/___:merkleroot___](#hoststoragesectorsdeletemerkleroot) | POST | + +#### /host [GET] + +fetches status information about the host. + +###### JSON Response +```javascript +{ + // The settings that get displayed to untrusted nodes querying the host's + // status. + "externalsettings": { + // Whether or not the host is accepting new contracts. + "acceptingcontracts": true, + + // The maximum size of a single download request from a renter. Each + // download request has multiple round trips of communication that + // exchange money. Larger batch sizes mean fewer round trips, but more + // financial risk for the host - the renter can get a free batch when + // downloading by refusing to provide a signature. + "maxdownloadbatchsize": 17825792, // bytes + + // The maximum duration that a host will allow for a file contract. The + // host commits to keeping files for the full duration under the threat + // of facing a large penalty for losing or dropping data before the + // duration is complete. The storage proof window of an incoming file + // contract must end before the current height + maxduration. + "maxduration": 25920, // blocks + + // The maximum size of a single batch of file contract revisions. The + // renter can perform DoS attacks on the host by uploading a batch of + // data then refusing to provide a signature to pay for the data. The + // host can reduce this exposure by limiting the batch size. Larger + // batch sizes allow for higher throughput as there is significant + // communication overhead associated with performing a batch upload. + "maxrevisebatchsize": 17825792, // bytes + + // The IP address or hostname (including port) that the host should be + // contacted at. + "netaddress": "123.456.789.0:9982", + + // The amount of unused storage capacity on the host in bytes. It + // should be noted that the host can lie. + "remainingstorage": 35000000000, // bytes + + // The smallest amount of data in bytes that can be uploaded or + // downloaded when performing calls to the host. + "sectorsize": 4194304, // bytes + + // The total amount of storage capacity on the host. It should be noted + // that the host can lie. + "totalstorage": 35000000000, // bytes + + // The unlock hash is the address at which the host can be paid when + // forming file contracts. + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + + // The storage proof window is the number of blocks that the host has + // to get a storage proof onto the blockchain. The window size is the + // minimum size of window that the host will accept in a file contract. + "windowsize": 144, // blocks + + // The maximum amount of money that the host will put up as collateral + // for storage that is contracted by the renter. + "collateral": "57870370370", // hastings / byte / block + + // The maximum amount of collateral that the host will put into a + // single file contract. + "maxcollateral": "100000000000000000000000000000", // hastings + + // The price that a renter has to pay to create a contract with the + // host. The payment is intended to cover transaction fees + // for the file contract revision and the storage proof that the host + // will be submitting to the blockchain. + "contractprice": "30000000000000000000000000", // hastings + + // The price that a renter has to pay when downloading data from the + // host. + "downloadbandwidthprice": "250000000000000", // hastings / byte + + // The price that a renter has to pay to store files with the host. + "storageprice": "231481481481", // hastings / byte / block + + // The price that a renter has to pay when uploading data to the host. + "uploadbandwidthprice": "100000000000000", // hastings / byte + + // The revision number indicates to the renter what iteration of + // settings the host is currently at. Settings are generally signed. + // If the renter has multiple conflicting copies of settings from the + // host, the renter can expect the one with the higher revision number + // to be more recent. + "revisionnumber": 0, + + // The version of external settings being used. This field helps + // coordinate updates while preserving compatibility with older nodes. + "version": "1.0.0" + }, + + // The financial status of the host. + "financialmetrics": { + // Number of open file contracts. + "contractcount": 2, + + // The amount of money that renters have given to the host to pay for + // file contracts. The host is required to submit a file contract + // revision and a storage proof for every file contract that gets created, + // and the renter pays for the miner fees on these objects. + "contractcompensation": "123", // hastings + + // The amount of money that renters have given to the host to pay for + // file contracts which have not been confirmed yet. The potential + // compensation becomes compensation after the storage proof is + // submitted. + "potentialcontractcompensation": "123", // hastings + + // The amount of storage collateral which the host has tied up in file + // contracts. The host has to commit collateral to a file contract even + // if there is no storage, but the locked collateral will be returned + // even if the host does not submit a storage proof - the collateral is + // not at risk, it is merely set aside so that it can be put at risk + // later. + "lockedstoragecollateral": "123", // hastings + + // The amount of revenue, including storage revenue and bandwidth + // revenue, that has been lost due to failed file contracts and + // failed storage proofs. + "lostrevenue": "123", // hastings + + // The amount of collateral that was put up to protect data which has + // been lost due to failed file contracts and missed storage proofs. + "loststoragecollateral": "123", // hastings + + // The amount of revenue that the host stands to earn if all storage + // proofs are submitted corectly and in time. + "potentialstoragerevenue": "123", // hastings + + // The amount of money that the host has risked on file contracts. If + // the host starts missing storage proofs, the host can forfeit up to + // this many coins. In the event of a missed storage proof, locked + // storage collateral gets returned, but risked storage collateral + // does not get returned. + "riskedstoragecollateral": "123", // hastings + + // The amount of money that the host has earned from storing data. This + // money has been locked down by successful storage proofs. + "storagerevenue": "123", // hastings + + // The amount of money that the host has spent on transaction fees when + // submitting host announcements, file contract revisions, and storage + // proofs. + "transactionfeeexpenses": "123", // hastings + + // The amount of money that the host has made from renters downloading + // their files. This money has been locked in by successsful storage + // proofs. + "downloadbandwidthrevenue": "123", // hastings + + // The amount of money that the host stands to make from renters that + // downloaded their files. The host will only realize this revenue if + // the host successfully submits storage proofs for the related file + // contracts. + "potentialdownloadbandwidthrevenue": "123", // hastings + + // The amount of money that the host stands to make from renters that + // uploaded files. The host will only realize this revenue if the host + // successfully submits storage proofs for the related file contracts. + "potentialuploadbandwidthrevenue": "123", // hastings + + // The amount of money that the host has made from renters uploading + // their files. This money has been locked in by successful storage + // proofs. + "uploadbandwidthrevenue": "123" // hastings + }, + + // The settings of the host. Most interactions between the user and the + // host occur by changing the internal settings. + "internalsettings": { + // When set to true, the host will accept new file contracts if the + // terms are reasonable. When set to false, the host will not accept new + // file contracts at all. + "acceptingcontracts": true, + + // The maximum size of a single download request from a renter. Each + // download request has multiple round trips of communication that + // exchange money. Larger batch sizes mean fewer round trips, but more + // financial risk for the host - the renter can get a free batch when + // downloading by refusing to provide a signature. + "maxdownloadbatchsize": 17825792, // bytes + + // The maximum duration of a file contract that the host will accept. + // The storage proof window must end before the current height + + // maxduration. + "maxduration": 25920, // blocks + + // The maximum size of a single batch of file contract revisions. The + // renter can perform DoS attacks on the host by uploading a batch of + // data then refusing to provide a signature to pay for the data. The + // host can reduce this exposure by limiting the batch size. Larger + // batch sizes allow for higher throughput as there is significant + // communication overhead associated with performing a batch upload. + "maxrevisebatchsize": 17825792, // bytes + + // The IP address or hostname (including port) that the host should be + // contacted at. If left blank, the host will automatically figure out + // its ip address and use that. If given, the host will use the address + // given. + "netaddress": "123.456.789.0:9982", + + // The storage proof window is the number of blocks that the host has + // to get a storage proof onto the blockchain. The window size is the + // minimum size of window that the host will accept in a file contract. + "windowsize": 144, // blocks + + // The maximum amount of money that the host will put up as collateral + // per byte per block of storage that is contracted by the renter. + "collateral": "57870370370", // hastings / byte / block + + // The total amount of money that the host will allocate to collateral + // across all file contracts. + "collateralbudget": "2000000000000000000000000000000", // hastings + + // The maximum amount of collateral that the host will put into a + // single file contract. + "maxcollateral": "100000000000000000000000000000", // hastings + + // The minimum price that the host will demand from a renter when + // forming a contract. Typically this price is to cover transaction + // fees on the file contract revision and storage proof, but can also + // be used if the host has a low amount of collateral. The price is a + // minimum because the host may automatically adjust the price upwards + // in times of high demand. + "mincontractprice": "30000000000000000000000000", // hastings + + // The minimum price that the host will demand from a renter when the + // renter is downloading data. If the host is saturated, the host may + // increase the price from the minimum. + "mindownloadbandwidthprice": "250000000000000", // hastings / byte + + // The minimum price that the host will demand when storing data for + // extended periods of time. If the host is low on space, the price of + // storage may be set higher than the minimum. + "minstorageprice": "231481481481", // hastings / byte / block + + // The minimum price that the host will demand from a renter when the + // renter is uploading data. If the host is saturated, the host may + // increase the price from the minimum. + "minuploadbandwidthprice": "100000000000000" // hastings / byte + }, + + // Information about the network, specifically various ways in which + // renters have contacted the host. + "networkmetrics": { + // The number of times that a renter has attempted to download + // something from the host. + "downloadcalls": 0, + + // The number of calls that have resulted in errors. A small number of + // errors are expected, but a large number of errors indicate either + // buggy software or malicious network activity. Usually buggy + // software. + "errorcalls": 1, + + // The number of times that a renter has tried to form a contract with + // the host. + "formcontractcalls": 2, + + // The number of times that a renter has tried to renew a contract with + // the host. + "renewcalls": 3, + + // The number of times that the renter has tried to revise a contract + // with the host. + "revisecalls": 4, + + // The number of times that a renter has queried the host for the + // host's settings. The settings include the price of bandwidth, which + // is a price that can adjust every few minutes. This value is usually + // very high compared to the others. + "settingscalls": 5, + + // The number of times that a renter has attempted to use an + // unrecognized call. Larger numbers typically indicate buggy software. + "unrecognizedcalls": 6 + } +} +``` + +#### /host [POST] + +configures hosting parameters. All parameters are optional; unspecified +parameters will be left unchanged. + +###### Query String Parameters +``` +// When set to true, the host will accept new file contracts if the +// terms are reasonable. When set to false, the host will not accept new +// file contracts at all. +acceptingcontracts // Optional, true / false + +// The maximum size of a single download request from a renter. Each +// download request has multiple round trips of communication that +// exchange money. Larger batch sizes mean fewer round trips, but more +// financial risk for the host - the renter can get a free batch when +// downloading by refusing to provide a signature. +maxdownloadbatchsize // Optional, bytes + +// The maximum duration of a file contract that the host will accept. +// The storage proof window must end before the current height + +// maxduration. +maxduration // Optional, blocks + +// The maximum size of a single batch of file contract revisions. The +// renter can perform DoS attacks on the host by uploading a batch of +// data then refusing to provide a signature to pay for the data. The +// host can reduce this exposure by limiting the batch size. Larger +// batch sizes allow for higher throughput as there is significant +// communication overhead associated with performing a batch upload. +maxrevisebatchsize // Optional, bytes + +// The IP address or hostname (including port) that the host should be +// contacted at. If left blank, the host will automatically figure out +// its ip address and use that. If given, the host will use the address +// given. +netaddress // Optional + +// The storage proof window is the number of blocks that the host has +// to get a storage proof onto the blockchain. The window size is the +// minimum size of window that the host will accept in a file contract. +windowsize // Optional, blocks + +// The maximum amount of money that the host will put up as collateral +// per byte per block of storage that is contracted by the renter. +collateral // Optional, hastings / byte / block + +// The total amount of money that the host will allocate to collateral +// across all file contracts. +collateralbudget // Optional, hastings + +// The maximum amount of collateral that the host will put into a +// single file contract. +maxcollateral // Optional, hastings + +// The minimum price that the host will demand from a renter when +// forming a contract. Typically this price is to cover transaction +// fees on the file contract revision and storage proof, but can also +// be used if the host has a low amount of collateral. The price is a +// minimum because the host may automatically adjust the price upwards +// in times of high demand. +mincontractprice // Optional, hastings + +// The minimum price that the host will demand from a renter when the +// renter is downloading data. If the host is saturated, the host may +// increase the price from the minimum. +mindownloadbandwidthprice // Optional, hastings / byte + +// The minimum price that the host will demand when storing data for +// extended periods of time. If the host is low on space, the price of +// storage may be set higher than the minimum. +minstorageprice // Optional, hastings / byte / block + +// The minimum price that the host will demand from a renter when the +// renter is uploading data. If the host is saturated, the host may +// increase the price from the minimum. +minuploadbandwidthprice // Optional, hastings / byte +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/announce [POST] + +Announce the host to the network as a source of storage. Generally only needs +to be called once. + +###### Query String Parameters +``` +// The address to be announced. If no address is provided, the automatically +// discovered address will be used instead. +netaddress string // Optional +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage [GET] + +gets a list of folders tracked by the host's storage manager. + +###### JSON Response +```javascript +{ + "folders": [ + { + // Absolute path to the storage folder on the local filesystem. + "path": "/home/foo/bar", + + // Maximum capacity of the storage folder. The host will not store more + // than this many bytes in the folder. This capacity is not checked + // against the drive's remaining capacity. Therefore, you must manually + // ensure the disk has sufficient capacity for the folder at all times. + // Otherwise you risk losing renter's data and failing storage proofs. + "capacity": 50000000000, // bytes + + // Unused capacity of the storage folder. + "capacityremaining": 100000, // bytes + + // Number of failed disk read & write operations. A large number of + // failed reads or writes indicates a problem with the filesystem or + // drive's hardware. + "failedreads": 0, + "failedwrites": 1, + + // Number of successful read & write operations. + "successfulreads": 2, + "successfulwrites": 3 + } + ] +} +``` + +#### /host/storage/folders/add [POST] + +adds a storage folder to the manager. The manager may not check that there is +enough space available on-disk to support as much storage as requested + +###### Query String Parameters +``` +// Local path on disk to the storage folder to add. +path // Required + +// Initial capacity of the storage folder. This value isn't validated so it is +// possible to set the capacity of the storage folder greater than the capacity +// of the disk. Do not do this. +size // bytes, Required +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage/folders/remove [POST] + +remove a storage folder from the manager. All storage on the folder will be +moved to other storage folders, meaning that no data will be lost. If the +manager is unable to save data, an error will be returned and the operation +will be stopped. + +###### Query String Parameters +``` +// Local path on disk to the storage folder to remove. +path // Required + +// If `force` is true, the storage folder will be removed even if the data in +// the storage folder cannot be moved to other storage folders, typically +// because they don't have sufficient capacity. If `force` is true and the data +// cannot be moved, data will be lost. +force // bool, Optional, default is false +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage/folders/resize [POST] + +grows or shrink a storage folder in the manager. The manager may not check that +there is enough space on-disk to support growing the storage folder, but should +gracefully handle running out of space unexpectedly. When shrinking a storage +folder, any data in the folder that needs to be moved will be placed into other +storage folders, meaning that no data will be lost. If the manager is unable to +migrate the data, an error will be returned and the operation will be stopped. + +###### Query String Parameters +``` +// Local path on disk to the storage folder to resize. +path // Required + +// Desired new size of the storage folder. This will be the new capacity of the +// storage folder. +newsize // bytes, Required +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). + +#### /host/storage/sectors/delete/___*merkleroot___ [POST] + +deletes a sector, meaning that the manager will be unable to upload that sector +and be unable to provide a storage proof on that sector. This endpoint is for +removing the data entirely, and will remove instances of the sector appearing +at all heights. The primary purpose is to comply with legal requests to remove +data. + +###### Path Parameters +``` +// Merkleroot of the sector to delete. +:merkleroot +``` + +###### Response +standard success or error response. See +[#standard-responses](#standard-responses). diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/HostDB.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/HostDB.md new file mode 100644 index 0000000..ab36600 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/HostDB.md @@ -0,0 +1,290 @@ +Host DB API +=========== + +This document contains detailed descriptions of the hostdb's API routes. For an +overview of the hostdb's API routes, see [API.md#host-db](/doc/API.md#host-db). +For an overview of all API routes, see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The hostdb maintains a database of all hosts known to the network. The database +identifies hosts by their public key and keeps track of metrics such as price. + +Index +----- + +| Request | HTTP Verb | Examples | +| ------------------------------------------- | --------- | ----------------------------- | +| [/hostdb/active](#hostdbactive-get-example) | GET | [Active hosts](#active-hosts) | +| [/hostdb/all](#hostdball-get-example) | GET | [All hosts](#all-hosts) | + +#### /hostdb/active [GET] [(example)](#active-hosts) + +lists all of the active hosts known to the renter, sorted by preference. + +###### Query String Parameters +``` +// Number of hosts to return. The actual number of hosts returned may be less +// if there are insufficient active hosts. Optional, the default is all active +// hosts. +numhosts +``` + +###### JSON Response +```javascript +{ + "hosts": [ + { + // true if the host is accepting new contracts. + "acceptingcontracts": true, + + // Maximum number of bytes that the host will allow to be requested by a + // single download request. + "maxdownloadbatchsize": 17825792, + + // Maximum duration in blocks that a host will allow for a file contract. + // The host commits to keeping files for the full duration under the + // threat of facing a large penalty for losing or dropping data before + // the duration is complete. The storage proof window of an incoming file + // contract must end before the current height + maxduration. + // + // There is a block approximately every 10 minutes. + // e.g. 1 day = 144 blocks + "maxduration": 25920, + + // Maximum size in bytes of a single batch of file contract + // revisions. Larger batch sizes allow for higher throughput as there is + // significant communication overhead associated with performing a batch + // upload. + "maxrevisebatchsize": 17825792, + + // Remote address of the host. It can be an IPv4, IPv6, or hostname, + // along with the port. IPv6 addresses are enclosed in square brackets. + "netaddress": "123.456.789.0:9982", + + // Unused storage capacity the host claims it has, in bytes. + "remainingstorage": 35000000000, + + // Smallest amount of data in bytes that can be uploaded or downloaded to + // or from the host. + "sectorsize": 4194304, + + // Total amount of storage capacity the host claims it has, in bytes. + "totalstorage": 35000000000, + + // Address at which the host can be paid when forming file contracts. + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + + // A storage proof window is the number of blocks that the host has to + // get a storage proof onto the blockchain. The window size is the + // minimum size of window that the host will accept in a file contract. + "windowsize": 144, + + // Public key used to identify and verify hosts. + "publickey": { + // Algorithm used for signing and verification. Typically "ed25519". + "algorithm": "ed25519", + + // Key used to verify signed host messages. + "key": "RW50cm9weSBpc24ndCB3aGF0IGl0IHVzZWQgdG8gYmU=" + } + } + ] +} +``` + +#### /hostdb/all [GET] [(example)](#all-hosts) + +lists all of the hosts known to the renter. Hosts are not guaranteed to be in +any particular order, and the order may change in subsequent calls. + +###### JSON Response +```javascript +{ + "hosts": [ + { + // true if the host is accepting new contracts. + "acceptingcontracts": true, + + // Maximum number of bytes that the host will allow to be requested by a + // single download request. + "maxdownloadbatchsize": 17825792, + + // Maximum duration in blocks that a host will allow for a file contract. + // The host commits to keeping files for the full duration under the + // threat of facing a large penalty for losing or dropping data before + // the duration is complete. The storage proof window of an incoming file + // contract must end before the current height + maxduration. + // + // There is a block approximately every 10 minutes. + // e.g. 1 day = 144 blocks + "maxduration": 25920, + + // Maximum size in bytes of a single batch of file contract + // revisions. Larger batch sizes allow for higher throughput as there is + // significant communication overhead associated with performing a batch + // upload. + "maxrevisebatchsize": 17825792, + + // Remote address of the host. It can be an IPv4, IPv6, or hostname, + // along with the port. IPv6 addresses are enclosed in square brackets. + "netaddress": "123.456.789.0:9982", + + // Unused storage capacity the host claims it has, in bytes. + "remainingstorage": 35000000000, + + // Smallest amount of data in bytes that can be uploaded or downloaded to + // or from the host. + "sectorsize": 4194304, + + // Total amount of storage capacity the host claims it has, in bytes. + "totalstorage": 35000000000, + + // Address at which the host can be paid when forming file contracts. + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + + // A storage proof window is the number of blocks that the host has to + // get a storage proof onto the blockchain. The window size is the + // minimum size of window that the host will accept in a file contract. + "windowsize": 144, + + // Public key used to identify and verify hosts. + "publickey": { + // Algorithm used for signing and verification. Typically "ed25519". + "algorithm": "ed25519", + + // Key used to verify signed host messages. + "key": "RW50cm9weSBpc24ndCB3aGF0IGl0IHVzZWQgdG8gYmU=" + } + } + ] +} +``` + +Examples +-------- + +#### Active hosts + +###### Request +``` +/hostdb/active?numhosts=2 +``` + +###### Expected Response Code +``` +200 OK +``` + +###### Example JSON Response +```javascript +{ + "hosts": [ + { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, + "maxduration": 25920, + "maxrevisebatchsize": 17825792, + "netaddress": "123.456.789.0:9982", + "remainingstorage": 35000000000, + "sectorsize": 4194304, + "totalstorage": 35000000000, + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "windowsize": 144, + "publickey": { + "algorithm": "ed25519", + "key": "RW50cm9weSBpc24ndCB3aGF0IGl0IHVzZWQgdG8gYmU=" + } + }, + { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, + "maxduration": 25920, + "maxrevisebatchsize": 17825792, + "netaddress": "123.456.789.1:9982", + "remainingstorage": 314, + "sectorsize": 4194304, + "totalstorage": 314159265359, + "unlockhash": "ba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210", + "windowsize": 144, + "publickey": { + "algorithm": "ed25519", + "key": "WWVzIEJydWNlIFNjaG5laWVyIGNhbiByZWFkIHRoaXM=" + } + } + ] +} +``` + +#### All hosts + +###### Request +``` +/hostdb/all +``` + +###### Expected Response Code +``` +200 OK +``` + +###### Example JSON Response +```javascript +{ + "hosts": [ + { + "acceptingcontracts": false, + "maxdownloadbatchsize": 17825792, + "maxduration": 25920, + "maxrevisebatchsize": 17825792, + "netaddress": "123.456.789.2:9982", + "remainingstorage": 314, + "sectorsize": 4194304, + "totalstorage": 314159265359, + "unlockhash": "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789", + "windowsize": 144, + "publickey": { + "algorithm": "ed25519", + "key": "SSByYW4gb3V0IG9mIDMyIGNoYXIgbG9uZyBqb2tlcy4=" + } + }, + { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, + "maxduration": 25920, + "maxrevisebatchsize": 17825792, + "netaddress": "123.456.789.0:9982", + "remainingstorage": 35000000000, + "sectorsize": 4194304, + "totalstorage": 35000000000, + "unlockhash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "windowsize": 144, + "publickey": { + "algorithm": "ed25519", + "key": "RW50cm9weSBpc24ndCB3aGF0IGl0IHVzZWQgdG8gYmU=" + } + }, + { + "acceptingcontracts": true, + "maxdownloadbatchsize": 17825792, + "maxduration": 25920, + "maxrevisebatchsize": 17825792, + "netaddress": "123.456.789.1:9982", + "remainingstorage": 314, + "sectorsize": 4194304, + "totalstorage": 314159265359, + "unlockhash": "ba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210", + "windowsize": 144, + "publickey": { + "algorithm": "ed25519", + "key": "WWVzIEJydWNlIFNjaG5laWVyIGNhbiByZWFkIHRoaXM=" + } + } + ] +} +``` diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Miner.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Miner.md new file mode 100644 index 0000000..458737e --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Miner.md @@ -0,0 +1,124 @@ +Miner API +========= + +This document contains detailed descriptions of the miner's API routes. For an +overview of the miner's API routes, see [API.md#miner](/doc/API.md#miner). For +an overview of all API routes, see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The miner provides endpoints for getting headers for work and submitting solved +headers to the network. The miner also provides endpoints for controlling a +basic CPU mining implementation. + +Index +----- + +| Route | HTTP verb | +| ---------------------------------- | --------- | +| [/miner](#miner-get) | GET | +| [/miner/start](#minerstart-get) | GET | +| [/miner/stop](#minerstop-get) | GET | +| [/miner/header](#minerheader-get) | GET | +| [/miner/header](#minerheader-post) | POST | + +#### /miner [GET] + +returns the status of the miner. + +###### JSON Response +```javascript +{ + // Number of mined blocks. This value is remembered after restarting. + "blocksmined": 9001, + + // How fast the cpu is hashing, in hashes per second. + "cpuhashrate": 1337, + + // true if the cpu miner is active. + "cpumining": false, + + // Number of mined blocks that are stale, indicating that they are not + // included in the current longest chain, likely because some other block at + // the same height had its chain extended first. + "staleblocksmined": 0, +} +``` + +#### /miner/start [GET] + +starts a single threaded cpu miner. Does nothing if the cpu miner is already +running. + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /miner/stop [GET] + +stops the cpu miner. Does nothing if the cpu miner is not running. + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /miner/header [GET] + +provides a block header that is ready to be grinded on for work. + +###### Byte Response + +For efficiency the header for work is returned as a raw byte encoding of the +header, rather than encoded to JSON. + +Blocks are mined by repeatedly changing the nonce of the header, hashing the +header's bytes, and comparing the resulting hash to the target. The block with +that nonce is valid if the hash is less than the target. If none of the 2^64 +possible nonces result in a header with a hash less than the target, call +`/miner/header [GET]` again to get a new block header with a different merkle +root. The above process can then be repeated for the new block header. + +The other fields can generally be ignored. The parent block ID field is the +hash of the parent block's header. Modifying this field will result in an +orphan block. The timestamp is the time at which the block was mined and is set +by the Sia Daemon. Modifying this field can result in invalid block. The merkle +root is the merkle root of a merkle tree consisting of the timestamp, the miner +outputs (one leaf per payout), and the transactions (one leaf per transaction). +Modifying this field will result in an invalid block. + +| Field | Byte range within response | Byte range within header | +| --------------- | -------------------------- | ------------------------ | +| target | [0-32) | | +| header | [32-112) | | +| parent block ID | [32-64) | [0-32) | +| nonce | [64-72) | [32-40) | +| timestamp | [72-80) | [40-48) | +| merkle root | [80-112) | [48-80) | + +``` +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (returned bytes) +tttttttttttttttttttttttttttttttt (target) + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh (header) + pppppppppppppppppppppppppppppppp (parent block ID) + nnnnnnnn (nonce) + ssssssss (timestamp) + mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm (merkle root) +``` + +#### /miner/header [POST] + +submits a header that has passed the POW. + +###### Request Body Bytes + +For efficiency headers are submitted as raw byte encodings of the header in the +body of the request, rather than as a query string parameter or path parameter. +The request body should contain only the 80 bytes of the encoded header. The +encoding is the same encoding used in `/miner/header [GET]` endpoint. Refer to +[#byte-response](#byte-response) for a detailed description of the byte +encoding. diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Renter.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Renter.md new file mode 100644 index 0000000..454b210 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Renter.md @@ -0,0 +1,297 @@ +Renter API +========== + +This document contains detailed descriptions of the renter's API routes. For an +overview of the renter's API routes, see [API.md#renter](/doc/API.md#renter). For +an overview of all API routes, see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The renter manages the user's files on the network. The renter's API endpoints +expose methods for managing files on the network and managing the renter's +allocated funds. + +Index +----- + +| Route | HTTP verb | +| ------------------------------------------------------------- | --------- | +| [/renter](#renter-get) | GET | +| [/renter](#renter-post) | POST | +| [/renter/contracts](#rentercontracts-get) | GET | +| [/renter/downloads](#renterdownloads-get) | GET | +| [/renter/files](#renterfiles-get) | GET | +| [/renter/delete/___*siapath___](#renterdeletesiapath-post) | POST | +| [/renter/download/___*siapath___](#renterdownloadsiapath-get) | GET | +| [/renter/rename/___*siapath___](#renterrenamesiapath-post) | POST | +| [/renter/upload/___*siapath___](#renteruploadsiapath-post) | POST | + +#### /renter [GET] + +returns the current settings along with metrics on the renter's spending. + +###### JSON Response +```javascript +{ + // Settings that control the behavior of the renter. + "settings": { + // Allowance dictates how much the renter is allowed to spend in a given + // period. Note that funds are spent on both storage and bandwidth. + "allowance": { + // Amount of money allocated for contracts. Funds are spent on both + // storage and bandwidth. + "funds": "1234", // hastings + + // Number of hosts that contracts will be formed with. + "hosts":24, + + // Duration of contracts formed, in number of blocks. + "period": 6048, // blocks + + // If the current blockheight + the renew window >= the height the + // contract is scheduled to end, the contract is renewed automatically. + // Is always nonzero. + "renewwindow": 3024 // blocks + } + }, + + // Metrics about how much the Renter has spent on storage, uploads, and + // downloads. + "financialmetrics": { + // How much money, in hastings, the Renter has spent on file contracts, + // including fees. + "contractspending": "1234", // hastings + + // Amount of money spent on downloads. + "downloadspending": "5678", // hastings + + // Amount of money spend on storage. + "storagespending": "1234", // hastings + + // Amount of money spent on uploads. + "uploadspending": "5678", // hastings + + // Amount of money in the allowance that has not been spent. + "unspent": "1234" // hastings + } +} +``` + +#### /renter [POST] + +modify settings that control the renter's behavior. + +###### Query String Parameters +``` +// Number of hastings allocated for file contracts in the given period. +funds // hastings + +// Number of hosts that contracts should be formed with. Files cannot be +// uploaded to more hosts than you have contracts with, and it's generally good +// to form a few more contracts than you need. +hosts + +// Duration of contracts formed. Must be nonzero. +period // block height + +// Renew window specifies how many blocks before the expriation of the current +// contracts the renter will wait before renewing the contracts. A smaller +// renew window means that Sia must be run more frequently, but also means +// fewer total transaction fees. Storage spending is not affected by the renew +// window size. +renewwindow // block height +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /renter/contracts [GET] + +returns active contracts. Expired contracts are not included. + +###### JSON Response +```javascript +{ + "contracts": [ + { + // Block height that the file contract ends on. + "endheight": 50000, // block height + + // ID of the file contract. + "id": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + + // Address of the host the file contract was formed with. + "netaddress": "12.34.56.78:9", + + // Remaining funds left for the renter to spend on uploads & downloads. + "renterfunds": "1234", // hastings + + // Size of the file contract, which is typically equal to the number of + // bytes that have been uploaded to the host. + "size": 8192 // bytes + } + ] +} +``` + +#### /renter/downloads [GET] + +lists all files in the download queue. + +###### JSON Response +```javascript +{ + "downloads": [ + { + // Siapath given to the file when it was uploaded. + "siapath": "foo/bar.txt", + + // Local path that the file will be downloaded to. + "destination": "/home/users/alice", + + // Size, in bytes, of the file being downloaded. + "filesize": 8192, // bytes + + // Number of bytes downloaded thus far. + "received": 4096, // bytes + + // Time at which the download was initiated. + "starttime": "2009-11-10T23:00:00Z" // RFC 3339 time + } + ] +} +``` + +#### /renter/files [GET] + +lists the status of all files. + +###### JSON Response +```javascript +{ + "files": [ + { + // Path to the file in the renter on the network. + "siapath": "foo/bar.txt", + + // Size of the file in bytes. + "filesize": 8192, // bytes + + // true if the file is available for download. Files may be available + // before they are completely uploaded. + "available": true, + + // true if the file's contracts will be automatically renewed by the + // renter. + "renewing": true, + + // Average redundancy of the file on the network. Redundancy is + // calculated by dividing the amount of data uploaded in the file's open + // contracts by the size of the file. Redundancy does not necessarily + // correspond to availability. Specifically, a redundancy >= 1 does not + // indicate the file is available as there could be a chunk of the file + // with 0 redundancy. + "redundancy": 5, + + // Percentage of the file uploaded, including redundancy. Uploading has + // completed when uploadprogress is 100. Files may be available for + // download before upload progress is 100. + "uploadprogress": 100, // percent + + // Block height at which the file ceases availability. + "expiration": 60000 + } + ] +} +``` + +#### /renter/delete/___*siapath___ [POST] + +deletes a renter file entry. Does not delete any downloads or original files, +only the entry in the renter. + +###### Path Parameters +``` +// Location of the file in the renter on the network. +*siapath +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /renter/download/___*siapath___ [GET] + +downloads a file to the local filesystem. The call will block until the file +has been downloaded. + +###### Path Parameters +``` +// Location of the file in the renter on the network. +*siapath +``` + +###### Query String Parameters +``` +// Location on disk that the file will be downloaded to. +destination +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /renter/rename/___*siapath___ [POST] + +renames a file. Does not rename any downloads or source files, only renames the +entry in the renter. An error is returned if `siapath` does not exist or +`newsiapath` already exists. + +###### Path Parameters +``` +// Current location of the file in the renter on the network. +*siapath +``` + +###### Query String Parameters +``` +// New location of the file in the renter on the network. +newsiapath +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /renter/upload/___*siapath___ [POST] + +uploads a file to the network from the local filesystem. + +###### Path Parameters +``` +// Location where the file will reside in the renter on the network. +*siapath +``` + +###### Query String Parameters +``` +// The number of data pieces to use when erasure coding the file. +datapieces // int + +// The number of parity pieces to use when erasure coding the file. Total +// redundancy of the file is (datapieces+paritypieces)/datapieces. +paritypieces // int + +// Location on disk of the file being uploaded. +source // string - a filepath +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Wallet.md b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Wallet.md new file mode 100644 index 0000000..b58eb61 --- /dev/null +++ b/3rd-party/Sia-v1.1.0-windows-amd64/doc/api/Wallet.md @@ -0,0 +1,521 @@ +Wallet +====== + +This document contains detailed descriptions of the wallet's API routes. For an +overview of the wallet's API routes, see [API.md#wallet](/doc/API.md#wallet). +For an overview of all API routes, see [API.md](/doc/API.md) + +There may be functional API calls which are not documented. These are not +guaranteed to be supported beyond the current release, and should not be used +in production. + +Overview +-------- + +The wallet stores and manages siacoins and siafunds. The wallet's API endpoints +expose methods for creating and loading wallets, locking and unlocking, sending +siacoins and siafunds, and getting the wallet's balance. + +You must create a wallet before you can use the wallet's API endpoints. You can +create a wallet with the `/wallet/init` endpoint. Wallets are always encrypted +on disk. Calls to some wallet API endpoints will fail until the wallet is +unlocked. The wallet can be unlocked with the `/wallet/unlock` endpoint. Once +the wallet is unlocked calls to the API endpoints will succeed until the wallet +is locked again with `/wallet/lock`, or Siad is restarted. The host and renter +require the miner to be unlocked. + +Index +----- + +| Route | HTTP verb | +| --------------------------------------------------------------- | --------- | +| [/wallet](#wallet-get) | GET | +| [/wallet/033x](#wallet033x-post) | POST | +| [/wallet/address](#walletaddress-get) | GET | +| [/wallet/addresses](#walletaddresses-get) | GET | +| [/wallet/backup](#walletbackup-get) | GET | +| [/wallet/init](#walletinit-post) | POST | +| [/wallet/lock](#walletlock-post) | POST | +| [/wallet/seed](#walletseed-post) | POST | +| [/wallet/seeds](#walletseeds-get) | GET | +| [/wallet/siacoins](#walletsiacoins-post) | POST | +| [/wallet/siafunds](#walletsiafunds-post) | POST | +| [/wallet/siagkey](#walletsiagkey-post) | POST | +| [/wallet/transaction/___:id___](#wallettransactionid-get) | GET | +| [/wallet/transactions](#wallettransactions-get) | GET | +| [/wallet/transactions/___:addr___](#wallettransactionsaddr-get) | GET | +| [/wallet/unlock](#walletunlock-post) | POST | + +#### /wallet [GET] + +returns basic information about the wallet, such as whether the wallet is +locked or unlocked. + +###### JSON Response +```javascript +{ + // Indicates whether the wallet has been encrypted or not. If the wallet + // has not been encrypted, then no data has been generated at all, and the + // first time the wallet is unlocked, the password given will be used as + // the password for encrypting all of the data. 'encrypted' will only be + // set to false if the wallet has never been unlocked before (the unlocked + // wallet is still encryped - but the encryption key is in memory). + "encrypted": true, + + // Indicates whether the wallet is currently locked or unlocked. Some calls + // become unavailable when the wallet is locked. + "unlocked": true, + + // Number of siacoins, in hastings, available to the wallet as of the most + // recent block in the blockchain. + "confirmedsiacoinbalance": "123456", // hastings, big int + + // Number of siacoins, in hastings, that are leaving the wallet according + // to the set of unconfirmed transactions. Often this number appears + // inflated, because outputs are frequently larger than the number of coins + // being sent, and there is a refund. These coins are counted as outgoing, + // and the refund is counted as incoming. The difference in balance can be + // calculated using 'unconfirmedincomingsiacoins' - 'unconfirmedoutgoingsiacoins' + "unconfirmedoutgoingsiacoins": "0", // hastings, big int + + // Number of siacoins, in hastings, are entering the wallet according to + // the set of unconfirmed transactions. This number is often inflated by + // outgoing siacoins, because outputs are frequently larger than the amount + // being sent. The refund will be included in the unconfirmed incoming + // siacoins balance. + "unconfirmedincomingsiacoins": "789", // hastings, big int + + // Number of siafunds available to the wallet as of the most recent block + // in the blockchain. + "siafundbalance": "1", // big int + + // Number of siacoins, in hastings, that can be claimed from the siafunds + // as of the most recent block. Because the claim balance increases every + // time a file contract is created, it is possible that the balance will + // increase before any claim transaction is confirmed. + "siacoinclaimbalance": "9001", // hastings, big int +} +``` + +#### /wallet/033x [POST] + +loads a v0.3.3.x wallet into the current wallet, harvesting all of the secret +keys. All spendable addresses in the loaded wallet will become spendable from +the current wallet. An error will be returned if the given `encryptionpassword` +is incorrect. + +###### Query String Parameters +``` +// Path on disk to the v0.3.3.x wallet to be loaded. +source + +// Encryption key of the wallet. +encryptionpassword +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /wallet/address [GET] + +gets a new address from the wallet generated by the primary seed. An error will +be returned if the wallet is locked. + +###### JSON Response +```javascript +{ + // Wallet address that can receive siacoins or siafunds. Addresses are 76 character long hex strings. + "address": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab" +} +``` + +#### /wallet/addresses [GET] + +fetches the list of addresses from the wallet. + +###### JSON Response +```javascript +{ + // Array of wallet addresses owned by the wallet. + "addresses": [ + "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ] +} +``` + +#### /wallet/backup [GET] + +creates a backup of the wallet settings file. Though this can easily be done +manually, the settings file is often in an unknown or difficult to find +location. The /wallet/backup call can spare users the trouble of needing to +find their wallet file. The destination file is overwritten if it already +exists. + +###### Query String Parameters +``` +// path to the location on disk where the backup file will be saved. +destination +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /wallet/init [POST] + +initializes the wallet. After the wallet has been initialized once, it does not +need to be initialized again, and future calls to /wallet/init will return an +error. The encryption password is provided by the api call. If the password is +blank, then the password will be set to the same as the seed. + +###### Query String Parameters +``` +// Password that will be used to encrypt the wallet. All subsequent calls +// should use this password. If left blank, the seed that gets returned will +// also be the encryption password. +encryptionpassword + +// Name of the dictionary that should be used when encoding the seed. 'english' +// is the most common choice when picking a dictionary. +dictionary // Optional, default is english. +``` + +###### JSON Response +```javascript +{ + // Wallet seed used to generate addresses that the wallet is able to spend. + "primaryseed": "hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello" +} +``` + +#### /wallet/seed [POST] + +gives the wallet a seed to track when looking for incoming transactions. The +wallet will be able to spend outputs related to addresses created by the seed. +The seed is added as an auxiliary seed, and does not replace the primary seed. +Only the primary seed will be used for generating new addresses. + +###### Query String Parameters +``` +// Key used to encrypt the new seed when it is saved to disk. +encryptionpassword + +// Name of the dictionary that should be used when encoding the seed. 'english' +// is the most common choice when picking a dictionary. +dictionary + +// Dictionary-encoded phrase that corresponds to the seed being added to the +// wallet. +seed +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /wallet/seeds [GET] + +returns a list of seeds in use by the wallet. The primary seed is the only seed +that gets used to generate new addresses. This call is unavailable when the +wallet is locked. + +A seed is an encoded version of a 128 bit random seed. The output is 15 words +chosen from a small dictionary as indicated by the input. The most common +choice for the dictionary is going to be 'english'. The underlying seed is the +same no matter what dictionary is used for the encoding. The encoding also +contains a small checksum of the seed, to help catch simple mistakes when +copying. The library +[entropy-mnemonics](https://github.com/NebulousLabs/entropy-mnemonics) is used +when encoding. + +###### Query String Parameters +``` +// Name of the dictionary that should be used when encoding the seed. 'english' +// is the most common choice when picking a dictionary. +dictionary +``` + +###### JSON Response +```javascript +{ + // Seed that is actively being used to generate new addresses for the wallet. + "primaryseed": "hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello", + + // Number of addresses that remain in the primary seed until exhaustion has + // been reached. Once exhaustion has been reached, new addresses will + // continue to be generated but they will be more difficult to recover in the + // event of a lost wallet file or encryption password. + "addressesremaining": 2500, + + // Array of all seeds that the wallet references when scanning the blockchain + // for outputs. The wallet is able to spend any output generated by any of + // the seeds, however only the primary seed is being used to generate new + // addresses. + "allseeds": [ + "hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello", + "foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo", + ] +} +``` + +#### /wallet/siacoins [POST] + +Function: Send siacoins to an address. The outputs are arbitrarily selected +from addresses in the wallet. + +###### Query String Parameters +``` +// Number of hastings being sent. A hasting is the smallest unit in Sia. There +// are 10^24 hastings in a siacoin. +amount // hastings + +// Address that is receiving the coins. +destination // address +``` + +###### JSON Response +```javascript +{ + // Array of IDs of the transactions that were created when sending the coins. + // The last transaction contains the output headed to the 'destination'. + // Transaction IDs are 64 character long hex strings. + transactionids [ + "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ] +} +``` + +#### /wallet/siafunds [POST] + +sends siafunds to an address. The outputs are arbitrarily selected from +addresses in the wallet. Any siacoins available in the siafunds being sent (as +well as the siacoins available in any siafunds that end up in a refund address) +will become available to the wallet as siacoins after 144 confirmations. To +access all of the siacoins in the siacoin claim balance, send all of the +siafunds to an address in your control (this will give you all the siacoins, +while still letting you control the siafunds). + +###### Query String Parameters +``` +// Number of siafunds being sent. +amount // siafunds + +// Address that is receiving the funds. +destination // address +``` + +###### JSON Response +```javascript +{ + // Array of IDs of the transactions that were created when sending the coins. + // The last transaction contains the output headed to the 'destination'. + // Transaction IDs are 64 character long hex strings. + "transactionids": [ + "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + ] +} +``` + +#### /wallet/siagkey [POST] + +Function: Load a key into the wallet that was generated by siag. Most siafunds +are currently in addresses created by siag. + +###### Query String Parameters +``` +// Key that is used to encrypt the siag key when it is imported to the wallet. +encryptionpassword + +// List of filepaths that point to the keyfiles that make up the siag key. +// There should be at least one keyfile per required signature. The filenames +// need to be commna separated (no spaces), which means filepaths that contain +// a comma are not allowed. +keyfiles +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /wallet/lock [POST] + +locks the wallet, wiping all secret keys. After being locked, the keys are +encrypted. Queries for the seed, to send siafunds, and related queries become +unavailable. Queries concerning transaction history and balance are still +available. + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). + +#### /wallet/transaction/___:id___ [GET] + +gets the transaction associated with a specific transaction id. + +###### Path Parameters +``` +// ID of the transaction being requested. +:id +``` + +###### JSON Response +```javascript +{ + "transaction": { + // Raw transaction. The rest of the fields in the resposne are determined + // from this raw transaction. It is left undocumented here as the processed + // transaction (the rest of the fields in this object) are usually what is + // desired. + "transaction": { + // See types.Transaction in https://github.com/NebulousLabs/Sia/blob/master/types/transactions.go + }, + + // ID of the transaction from which the wallet transaction was derived. + "transactionid": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + + // Block height at which the transaction was confirmed. If the transaction + // is unconfirmed the height will be the max value of an unsigned 64-bit + // integer. + "confirmationheight": 50000, + + // Time, in unix time, at which a transaction was confirmed. If the + // transaction is unconfirmed the timestamp will be the max value of an + // unsigned 64-bit integer. + "confirmationtimestamp": 1257894000, + + // Array of processed inputs detailing the inputs to the transaction. + "inputs": [ + { + // Type of fund represented by the input. Possible values are + // 'siacoin input' and 'siafund input'. + "fundtype": "siacoin input", + + // true if the address is owned by the wallet. + "walletaddress": false, + + // Address that is affected. For inputs (outgoing money), the related + // address is usually not important because the wallet arbitrarily + // selects which addresses will fund a transaction. + "relatedaddress": "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab", + + // Amount of funds that have been moved in the input. + "value": "1234", // hastings or siafunds, depending on fundtype, big int + } + ], + // Array of processed outputs detailing the outputs of the transaction. + // Outputs related to file contracts are excluded. + "outputs": [ + { + // Type of fund is represented by the output. Possible values are + // 'siacoin output', 'siafund output', 'claim output', and 'miner + // payout'. Siacoin outputs and claim outputs both relate to siacoins. + // Siafund outputs relate to siafunds. Miner payouts point to siacoins + // that have been spent on a miner payout. Because the destination of + // the miner payout is determined by the block and not the transaction, + // the data 'maturityheight', 'walletaddress', and 'relatedaddress' are + // left blank. + "fundtype": "siacoin output", + + // Block height the output becomes available to be spent. Siacoin + // outputs and siafund outputs mature immediately - their maturity + // height will always be the confirmation height of the transaction. + // Claim outputs cannot be spent until they have had 144 confirmations, + // thus the maturity height of a claim output will always be 144 larger + // than the confirmation height of the transaction. + "maturityheight": 50000, + + // true if the address is owned by the wallet. + "walletaddress": false, + + // Address that is affected. For outputs (incoming money), the related + // address field can be used to determine who has sent money to the + // wallet. + "relatedaddress": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + + // Amount of funds that have been moved in the output. + "value": "1234", // hastings or siafunds, depending on fundtype, big int + } + ] + } +} +``` + +#### /wallet/transactions [GET] + +returns a list of transactions related to the wallet. + +###### Query String Parameters +``` +// Height of the block where transaction history should begin. +startheight // block height + +// Height of of the block where the transaction history should end. If +// 'endheight' is greater than the current height, all transactions up to and +// including the most recent block will be provided. +endheight // block height +``` + +###### JSON Response +```javascript +{ + // All of the confirmed transactions appearing between height 'startheight' + // and height 'endheight' (inclusive). + "confirmedtransactions": [ + { + // See the documentation for '/wallet/transaction/:id' for more information. + } + ], + + // All of the unconfirmed transactions. + "unconfirmedtransactions": [ + { + // See the documentation for '/wallet/transaction/:id' for more information. + } + ] +} +``` + +#### /wallet/transactions/___:addr___ [GET] + +returns all of the transactions related to a specific address. + +###### Path Parameters +``` +// Unlock hash (i.e. wallet address) whose transactions are being requested. +:addr +``` + +###### JSON Response +```javascript +{ + // Array of processed transactions that relate to the supplied address. + "transactions": [ + { + // See the documentation for '/wallet/transaction/:id' for more information. + } + ] +} +``` + +#### /wallet/unlock [POST] + +unlocks the wallet. The wallet is capable of knowing whether the correct +password was provided. + +###### Query String Parameters +``` +// Password that gets used to decrypt the file. Most frequently, the encryption +// password is the same as the primary wallet seed. +encryptionpassword string +``` + +###### Response +standard success or error response. See +[API.md#standard-responses](/doc/API.md#standard-responses). diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/assets/codereview.png b/3rd-party/Sia-v1.1.0-windows-amd64/doc/assets/codereview.png new file mode 100644 index 0000000000000000000000000000000000000000..8296730f12fc425cc0e342fb50d2d47ed1ca4665 GIT binary patch literal 39674 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ð6 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 SuW|gIi11I-YE-G)zWOgZ{#k4Q literal 0 HcmV?d00001 diff --git a/3rd-party/Sia-v1.1.0-windows-amd64/doc/assets/covertool.png b/3rd-party/Sia-v1.1.0-windows-amd64/doc/assets/covertool.png new file mode 100644 index 0000000000000000000000000000000000000000..6ffa2d2ab2c3af2072f25425c94b5ddc6fecf1aa GIT binary patch literal 87817 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%0DLtY7j)WUwE5Sq(nTdST(4%VoTM^Lywt=6HE> z=0Kgp+9G@%PPy!Z529QGH??#+Ervogc#>`(RKktp)`*XXIqJ`EkmTE0i-U3;@80U) ze1!RP{>doT#Yo&C-E7PH`-b21=9}E7z#mwDyyL7F?=oaqvjZI0V;`~p+9RBSQZ1f0 zj{d`wYOYrF>=wjxM8!@Gda(830YH2GdL_Qb^L_4a>$GvBlKiqk(J^+6-!YyaWoX)D zlVIS%3B4~=vE;05(%S$uAzFT0afopz;A*iZ0%`vd zKl?ckxPQ!}Y<5L4aQdBbjepB>VR7T`d&hgMIYa(RP)&wE^(ZsPOQ}8cBW&iYwY~`V zxLZ~y@xz!i$Mw6r$3pP=q2cW1sya&e?58E8TH3pit!IOxlOJ^V$HH_Ho0(FPFId@i zvs)!=2#aMLLE`X34KKbzkgET4_w5L1qo7*qgwK9|eD8atXN2zk)#J*sp6ctLU>qsh z_>JI28}T-7Zr-?Ad*0yr@VeK-d&J0n%0Ahhciz=)mCv)!vM|YA2Xr^LE7(bSEp5zJ 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 IeA+($2Ys0=n!JurzA2oYSKAjre`+O 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