diff --git a/circle.yml~ b/circle.yml~ new file mode 100644 index 0000000000000000000000000000000000000000..086a86050453708a7cf5096b1d3b0849ebd77f69 --- /dev/null +++ b/circle.yml~ @@ -0,0 +1,33 @@ +machine: + post: + - rm -rf ${GOPATH%%:*}/src/github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME} + - mkdir -p ${GOPATH%%:*}/src/github.com/${CIRCLE_PROJECT_USERNAME} + - cp -r ${HOME}/${CIRCLE_PROJECT_REPONAME} ${GOPATH%%:*}/src/github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME} + - git config --global user.email "billings@erisindustries.com" + - git config --global user.name "Billings the Bot" + +dependencies: + pre: + - sudo curl -L -o /usr/bin/docker 'http://s3-external-1.amazonaws.com/circle-downloads/docker-1.6.0-circleci'; chmod 0755 /usr/bin/docker; true + - sudo service docker start + - "sudo apt-get update && sudo apt-get install -y libgmp3-dev" + + override: + - "cd ./cmd/erisdb && go get -d && go build" + - "mv ~/eris-db/cmd/erisdb/erisdb ~/bin" + - chmod +x ~/bin/erisdb + +test: + override: + - go test -v ./... +<<<<<<< HEAD + +deployment: + master: + branch: master + commands: + - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS quay.io + - DOCKER/build.sh + - docker push quay.io/eris/erisdb +======= +>>>>>>> master diff --git a/erisdb/methods.go b/erisdb/methods.go index 7a27628da3939ec2b4edb1ae0102017fa8c006b4..0609f69ead0322e3f19762fea210a0296808c12c 100644 --- a/erisdb/methods.go +++ b/erisdb/methods.go @@ -42,6 +42,8 @@ const ( SIGN_TX = SERVICE_NAME + ".signTx" TRANSACT = SERVICE_NAME + ".transact" TRANSACT_AND_HOLD = SERVICE_NAME + ".transactAndHold" + SEND = SERVICE_NAME + ".send" + SEND_AND_HOLD = SERVICE_NAME + ".sendAndHold" TRANSACT_NAMEREG = SERVICE_NAME + ".transactNameReg" EVENT_SUBSCRIBE = SERVICE_NAME + ".eventSubscribe" // Events EVENT_UNSUBSCRIBE = SERVICE_NAME + ".eventUnsubscribe" @@ -96,6 +98,8 @@ func (this *ErisDbMethods) getMethods() map[string]RequestHandlerFunc { dhMap[SIGN_TX] = this.SignTx dhMap[TRANSACT] = this.Transact dhMap[TRANSACT_AND_HOLD] = this.TransactAndHold + dhMap[SEND] = this.Send + dhMap[SEND_AND_HOLD] = this.SendAndHold dhMap[TRANSACT_NAMEREG] = this.TransactNameReg // Namereg dhMap[GET_NAMEREG_ENTRY] = this.NameRegEntry @@ -415,6 +419,32 @@ func (this *ErisDbMethods) TransactAndHold(request *rpc.RPCRequest, requester in return ce, 0, nil } +func (this *ErisDbMethods) Send(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + param := &SendParam{} + err := this.codec.DecodeBytes(param, request.Params) + if err != nil { + return nil, rpc.INVALID_PARAMS, err + } + receipt, errC := this.pipe.Transactor().Send(param.PrivKey, param.ToAddress, param.Amount) + if errC != nil { + return nil, rpc.INTERNAL_ERROR, errC + } + return receipt, 0, nil +} + +func (this *ErisDbMethods) SendAndHold(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + param := &SendParam{} + err := this.codec.DecodeBytes(param, request.Params) + if err != nil { + return nil, rpc.INVALID_PARAMS, err + } + rec, errC := this.pipe.Transactor().SendAndHold(param.PrivKey, param.ToAddress, param.Amount) + if errC != nil { + return nil, rpc.INTERNAL_ERROR, errC + } + return rec, 0, nil +} + func (this *ErisDbMethods) TransactNameReg(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &TransactNameRegParam{} err := this.codec.DecodeBytes(param, request.Params) diff --git a/erisdb/params.go b/erisdb/params.go index eb1db8d808a03015a8c9e68ba38283eff964c356..2046756577d4ff3a0527180be8569f168d905b5f 100644 --- a/erisdb/params.go +++ b/erisdb/params.go @@ -90,6 +90,13 @@ type ( GasLimit int64 `json:"gas_limit"` } + // Used when sending a 'Send' transaction. + SendParam struct { + PrivKey []byte `json:"priv_key"` + ToAddress []byte `json:"to_address"` + Amount int64 `json:"amount"` + } + NameRegEntryParam struct { Name string `json:"name"` } diff --git a/erisdb/pipe/blockchain.go b/erisdb/pipe/blockchain.go index 2f564135289e1735ee2d73dbf70e9d333a0a6865..cb01eb4bce238fb7315707d5a7532c27262bbc99 100644 --- a/erisdb/pipe/blockchain.go +++ b/erisdb/pipe/blockchain.go @@ -219,7 +219,7 @@ func getHeightMinMax(fda []*FilterData, height int) (int, int, []*FilterData, er } switch fd.Op { case "==": - if val > height && val < 0 { + if val > height || val < 0 { return 0, 0, nil, fmt.Errorf("No such block: %d (chain height: %d\n", val, height) } min = val diff --git a/erisdb/pipe/pipe.go b/erisdb/pipe/pipe.go index 58603661ccfd87f5a3523900c9c8bc81e676ae9c..5f05711cbbd3119b9523069a52361a87b622ebb1 100644 --- a/erisdb/pipe/pipe.go +++ b/erisdb/pipe/pipe.go @@ -69,6 +69,8 @@ type ( Call(fromAddress, toAddress, data []byte) (*Call, error) CallCode(fromAddress, code, data []byte) (*Call, error) BroadcastTx(tx types.Tx) (*Receipt, error) + Send(privKey, toAddress []byte, amount int64) (*Receipt, error) + SendAndHold(privKey, toAddress []byte, amount int64) (*Receipt, error) Transact(privKey, address, data []byte, gasLimit, fee int64) (*Receipt, error) TransactAndHold(privKey, address, data []byte, gasLimit, fee int64) (*types.EventDataCall, error) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*Receipt, error) @@ -98,6 +100,7 @@ func NewPipe(tNode *node.Node) Pipe { namereg := newNamereg(tNode.ConsensusState()) net := newNetwork(tNode.Switch()) txs := newTransactor(tNode.EventSwitch(), tNode.ConsensusState(), tNode.MempoolReactor(), events) + return &PipeImpl{ tNode, accounts, diff --git a/erisdb/pipe/transactor.go b/erisdb/pipe/transactor.go index b8693485ee9ce8b05e8c163cc31df66b36ecec15..d21b5d148d83bf096713ba880b371ea5714efda5 100644 --- a/erisdb/pipe/transactor.go +++ b/erisdb/pipe/transactor.go @@ -144,7 +144,6 @@ func (this *transactor) Transact(privKey, address, data []byte, gasLimit, fee in } else { sequence = acc.Sequence + 1 } - // fmt.Printf("Sequence %d\n", sequence) txInput := &types.TxInput{ Address: pa.Address, Amount: 1, @@ -208,6 +207,94 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, return ret, rErr } +func (this *transactor) Send(privKey, toAddress []byte, amount int64) (*Receipt, error) { + var toAddr []byte + if len(toAddress) == 0 { + toAddr = nil + } else if len(toAddress) != 20 { + return nil, fmt.Errorf("To-address is not of the right length: %d\n", len(toAddress)) + } else { + toAddr = toAddress + } + + if len(privKey) != 64 { + return nil, fmt.Errorf("Private key is not of the right length: %d\n", len(privKey)) + } + + pk := &[64]byte{} + copy(pk[:], privKey) + this.txMtx.Lock() + defer this.txMtx.Unlock() + pa := account.GenPrivAccountFromPrivKeyBytes(pk) + cache := this.mempoolReactor.Mempool.GetCache() + acc := cache.GetAccount(pa.Address) + var sequence int + if acc == nil { + sequence = 1 + } else { + sequence = acc.Sequence + 1 + } + + tx := types.NewSendTx() + + txInput := &types.TxInput{ + Address: pa.Address, + Amount: amount, + Sequence: sequence, + PubKey: pa.PubKey, + } + + tx.Inputs = append(tx.Inputs, txInput) + + txOutput := &types.TxOutput{toAddr, amount} + + tx.Outputs = append(tx.Outputs, txOutput); + + // Got ourselves a tx. + txS, errS := this.SignTx(tx, []*account.PrivAccount{pa}) + if errS != nil { + return nil, errS + } + return this.BroadcastTx(txS) +} + +func (this *transactor) SendAndHold(privKey, toAddress []byte, amount int64) (*Receipt, error) { + rec, tErr := this.Send(privKey, toAddress, amount) + if tErr != nil { + return nil, tErr + } + + wc := make(chan *types.SendTx) + subId := fmt.Sprintf("%X", rec.TxHash) + + this.eventEmitter.Subscribe(subId, types.EventStringAccOutput(toAddress), func(evt interface{}) { + event := evt.(*types.SendTx) + wc <- event + }) + + timer := time.NewTimer(300 * time.Second) + toChan := timer.C + + var rErr error + + // FOR NOW + pk := &[64]byte{} + copy(pk[:], privKey) + pa := account.GenPrivAccountFromPrivKeyBytes(pk) + + select { + case <-toChan: + rErr = fmt.Errorf("Transaction timed out. Hash: " + subId) + case e := <-wc: + if bytes.Equal(e.Inputs[0].Address, pa.Address) && e.Inputs[0].Amount == amount { + timer.Stop() + this.eventEmitter.Unsubscribe(subId) + return rec, rErr + } + } + return nil, rErr +} + func (this *transactor) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*Receipt, error) { if len(privKey) != 64 { diff --git a/erisdb/serve.go b/erisdb/serve.go index 5727c4a402c8ad4b04c43d50f431a057e2517afc..cab5a49f555d3768432af66b857cb6d0c8606b4d 100644 --- a/erisdb/serve.go +++ b/erisdb/serve.go @@ -14,7 +14,6 @@ import ( "path" ) -const ERISDB_VERSION = "0.11.5" const TENDERMINT_VERSION = "0.5.0" var log = log15.New("module", "eris/erisdb_server") diff --git a/erisdb/wsService.go b/erisdb/wsService.go index f146a50e9eefc9cffe67d15d57af2a18cf13741b..624a2dd52066e47b1fd4a386baf54b84c935fde1 100644 --- a/erisdb/wsService.go +++ b/erisdb/wsService.go @@ -75,15 +75,15 @@ func (this *ErisDbWsService) writeError(msg, id string, code int, session *serve } // Convenience method for writing responses. -func (this *ErisDbWsService) writeResponse(id string, result interface{}, session *server.WSSession) { +func (this *ErisDbWsService) writeResponse(id string, result interface{}, session *server.WSSession) error { response := rpc.NewRPCResponse(id, result) bts, err := this.codec.EncodeBytes(response) log.Debug("RESPONSE: %v\n", response) if err != nil { this.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, session) - return + return err } - session.Write(bts) + return session.Write(bts) } // *************************************** Events ************************************ @@ -103,8 +103,11 @@ func (this *ErisDbWsService) EventSubscribe(request *rpc.RPCRequest, requester i if errSID != nil { return nil, rpc.INTERNAL_ERROR, errSID } - callback := func(ret types.EventData) { - this.writeResponse(subId, ret, session) + callback := func(ret interface{}) { + writeErr := this.writeResponse(subId, ret, session) + if(writeErr != nil){ + this.pipe.Events().Unsubscribe(subId); + } } _, errC := this.pipe.Events().Subscribe(subId, eventId, callback) if errC != nil { diff --git a/license.md b/license.md new file mode 100644 index 0000000000000000000000000000000000000000..8dada3edaf50dbc082c9a125058f25def75e625a --- /dev/null +++ b/license.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/test/mock/pipe.go b/test/mock/pipe.go index 8408236bab4da78d199eadb66fc251c6961739d3..8c7328cb24c44ba1517c9e678d41bbc9d8d5301b 100644 --- a/test/mock/pipe.go +++ b/test/mock/pipe.go @@ -244,6 +244,15 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, return nil, nil } + +func (this *transactor) Send(privKey, toAddress []byte, amount int64) (*ep.Receipt, error) { + return nil, nil +} + +func (this *transactor) SendAndHold(privKey, toAddress []byte, amount int64) (*ep.Receipt, error) { + return nil, nil +} + func (this *transactor) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*ep.Receipt, error) { return this.testData.TransactNameReg.Output, nil } diff --git a/version/version.go b/version/version.go index 2deaf3ad32b1d4de51baab5a0cbb7f9cb9ce9008..24821fee09cb924fd408aa46acced2f66b9404ed 100644 --- a/version/version.go +++ b/version/version.go @@ -1,3 +1,7 @@ package version -const VERSION = "0.10.4" +import ( + +) + +const Version = "0.11.6"