From 511f528240fc1393f923958f8ceb31acc240d1f0 Mon Sep 17 00:00:00 2001 From: Jaeyoung Jung Date: Fri, 13 Apr 2018 14:26:09 +0900 Subject: [PATCH 01/69] net: fix bug when dispatcher got unknown message type. --- net/dispatcher.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/dispatcher.go b/net/dispatcher.go index 2f16b6559..b5d4c94c4 100644 --- a/net/dispatcher.go +++ b/net/dispatcher.go @@ -102,6 +102,9 @@ func (dp *Dispatcher) loop() { msgType := msg.MessageType() v, _ := dp.subscribersMap.Load(msgType) + if v == nil { + continue + } m, _ := v.(*sync.Map) m.Range(func(key, value interface{}) bool { From d3c2dbd91fade716c016ef05ce8228a451fcb4f4 Mon Sep 17 00:00:00 2001 From: ChengOrangeJu Date: Thu, 12 Apr 2018 17:57:02 +0800 Subject: [PATCH 02/69] update case --- nebtestkit/cases/contract/contract.bankvault.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nebtestkit/cases/contract/contract.bankvault.test.js b/nebtestkit/cases/contract/contract.bankvault.test.js index 7a704e0bd..92e60136e 100644 --- a/nebtestkit/cases/contract/contract.bankvault.test.js +++ b/nebtestkit/cases/contract/contract.bankvault.test.js @@ -191,7 +191,7 @@ function testSave(testInput, testExpect, done) { }); return neb.api.estimateGas(from.getAddressString(), contractAddr, - testInput.value, txInfo.nonce, 0, testInput.gasLimit, txInfo.call); + testInput.value, txInfo.nonce, testInput.gasPrice, testInput.gasLimit, txInfo.call); }).then(function(resp){ expect(resp).to.have.property('gas'); gasUsed = resp.gas; @@ -282,7 +282,7 @@ function testTakeout(testInput, testExpect, done) { tx.signTransaction(); neb.api.estimateGas(from.getAddressString(), contractAddr, - testInput.value, parseInt(state.nonce) + 1, 0, testInput.gasLimit, call).then(function(resp){ + testInput.value, parseInt(state.nonce) + 1, testInput.gasPrice, testInput.gasLimit, call).then(function(resp){ expect(resp).to.have.property('gas'); gasUsed = resp.gas; }).catch(function(err) { From 797b642cd386b30eec4916a5c734b0fac97f883e Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Tue, 17 Apr 2018 01:10:58 +0800 Subject: [PATCH 03/69] contract: add 'accept' func --- core/address.go | 4 +++ core/event.go | 3 ++ core/transaction.go | 7 +++- core/transaction_binary_payload.go | 52 ++++++++++++++++++++++++++++++ core/transaction_call_payload.go | 2 +- core/types.go | 5 +++ nf/nvm/blockchain.go | 32 ++++++++++++++++++ nf/nvm/event.go | 12 +++++++ nf/nvm/types.go | 2 ++ rpc/api_service.go | 4 +-- 10 files changed, 119 insertions(+), 4 deletions(-) diff --git a/core/address.go b/core/address.go index 37e9c926b..2c62f7c85 100644 --- a/core/address.go +++ b/core/address.go @@ -31,6 +31,7 @@ type AddressType byte const ( AccountAddress AddressType = 0x57 + iota ContractAddress + UnkownAddress AddressType = 0x00 ) // const @@ -151,6 +152,9 @@ func (a *Address) Equals(b *Address) bool { // Type return the type of address. func (a *Address) Type() AddressType { + if len(a.address) <= AddressTypeIndex { + return UnkownAddress + } return AddressType(a.address[AddressTypeIndex]) } diff --git a/core/event.go b/core/event.go index 744b3ec66..a533b77e5 100644 --- a/core/event.go +++ b/core/event.go @@ -46,6 +46,9 @@ const ( // TopicDropTransaction drop tx (1): smaller nonce (2) expire txLifeTime TopicDropTransaction = "chain.dropTransaction" + + // TopicTransferFromContract transfer from contract + TopicTransferFromContract = "chain.transferFromContract" ) // EventSubscriber subscriber object diff --git a/core/transaction.go b/core/transaction.go index be1dffd1b..e921762df 100644 --- a/core/transaction.go +++ b/core/transaction.go @@ -554,7 +554,8 @@ func (tx *Transaction) simulateExecution(block *Block) (*SimulateResult, error) ) // try run smart contract if payload is. - if tx.data.Type == TxPayloadCallType || tx.data.Type == TxPayloadDeployType { + if tx.data.Type == TxPayloadCallType || tx.data.Type == TxPayloadDeployType || + (tx.data.Type == TxPayloadBinaryType && tx.to.Type() == ContractAddress) { // transfer value to smart contract. toAcc, err := ws.GetOrCreateUserAccount(tx.to.address) @@ -710,6 +711,10 @@ func CheckContract(addr *Address, ws WorldState) (state.Account, error) { return nil, ErrNilArgument } + if addr.Type() != ContractAddress { + return nil, ErrContractCheckFailed + } + contract, err := ws.GetContractAccount(addr.Bytes()) if err != nil { return nil, err diff --git a/core/transaction_binary_payload.go b/core/transaction_binary_payload.go index 44304e3c0..a88bf511d 100644 --- a/core/transaction_binary_payload.go +++ b/core/transaction_binary_payload.go @@ -19,6 +19,8 @@ package core import ( + "fmt" + "github.com/nebulasio/go-nebulas/util" ) @@ -51,5 +53,55 @@ func (payload *BinaryPayload) BaseGasCount() *util.Uint128 { // Execute the payload in tx func (payload *BinaryPayload) Execute(limitedGas *util.Uint128, tx *Transaction, block *Block, ws WorldState) (*util.Uint128, string, error) { + if block == nil || tx == nil || tx.to == nil { + return util.NewUint128(), "", ErrNilArgument + } + + // transfer to contract + if tx.to.Type() == ContractAddress { + // payloadGasLimit <= 0, v8 engine not limit the execution instructions + if limitedGas.Cmp(util.NewUint128()) <= 0 { + return util.NewUint128(), "", ErrOutOfGasLimit + } + + // contract address is tx.to. + contract, err := CheckContract(tx.to, ws) + if err != nil { + return util.NewUint128(), "", err + } + + birthTx, err := GetTransaction(contract.BirthPlace(), ws) + if err != nil { + return util.NewUint128(), "", err + } + deploy, err := LoadDeployPayload(birthTx.data.Payload) // ToConfirm: move deploy payload in ctx. + if err != nil { + return util.NewUint128(), "", err + } + + engine, err := block.nvm.CreateEngine(block, tx, contract, ws) + if err != nil { + return util.NewUint128(), "", err + } + defer engine.Dispose() + + if err := engine.SetExecutionLimits(limitedGas.Uint64(), DefaultLimitsOfTotalMemorySize); err != nil { + return util.NewUint128(), "", err + } + + result, exeErr := engine.Call(deploy.Source, deploy.SourceType, ContractDefaultFunc, "") + gasCout := engine.ExecutionInstructions() + instructions, err := util.NewUint128FromInt(int64(gasCout)) + if err != nil { + return util.NewUint128(), "", err + } + if exeErr == ErrExecutionFailed && len(result) > 0 { + exeErr = fmt.Errorf("Binary: %s", result) + } + if exeErr != nil { + return instructions, "", exeErr + } + } + return util.NewUint128(), "", nil } diff --git a/core/transaction_call_payload.go b/core/transaction_call_payload.go index be899ad3c..cacda201d 100644 --- a/core/transaction_call_payload.go +++ b/core/transaction_call_payload.go @@ -115,7 +115,7 @@ func (payload *CallPayload) Execute(limitedGas *util.Uint128, tx *Transaction, b if err != nil { return util.NewUint128(), "", err } - if exeErr != nil && exeErr == ErrExecutionFailed && len(result) > 0 { + if exeErr == ErrExecutionFailed && len(result) > 0 { exeErr = fmt.Errorf("Call: %s", result) } return instructions, result, exeErr diff --git a/core/types.go b/core/types.go index d38a76015..012263710 100644 --- a/core/types.go +++ b/core/types.go @@ -51,6 +51,11 @@ const ( SourceTypeTypeScript = "ts" ) +// Const +const ( + ContractDefaultFunc = "accept" +) + var ( // PublicFuncNameChecker in smart contract PublicFuncNameChecker = regexp.MustCompile("^[a-zA-Z$][A-Za-z0-9_$]*$") diff --git a/nf/nvm/blockchain.go b/nf/nvm/blockchain.go index 31e2f5baf..16a3aedde 100644 --- a/nf/nvm/blockchain.go +++ b/nf/nvm/blockchain.go @@ -26,6 +26,7 @@ import ( "encoding/json" "github.com/nebulasio/go-nebulas/core" + "github.com/nebulasio/go-nebulas/core/state" "github.com/nebulasio/go-nebulas/util" "github.com/nebulasio/go-nebulas/util/byteutils" "github.com/nebulasio/go-nebulas/util/logging" @@ -180,6 +181,37 @@ func TransferFunc(handler unsafe.Pointer, to *C.char, v *C.char, gasCnt *C.size_ } } + if engine.ctx.block.Height() >= TransferFromContractEventCompatibilityHeight { + cAddr, err := core.AddressParseFromBytes(engine.ctx.contract.Address()) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "txhash": engine.ctx.tx.Hash().String(), + "address": engine.ctx.contract.Address(), + "err": err, + }).Debug("failed to parse contract address") + return TransferRecordEventFailed + } + + event := &TransferFromContractEvent{ + Amount: amount.String(), + From: cAddr.String(), + To: addr.String(), + } + + eData, err := json.Marshal(event) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "from": cAddr.String(), + "to": addr.String(), + "amount": amount.String(), + "err": err, + }).Debug("failed to marshal TransferFromContractEvent") + return TransferRecordEventFailed + } + + engine.ctx.state.RecordEvent(engine.ctx.tx.Hash(), &state.Event{Topic: core.TopicTransferFromContract, Data: string(eData)}) + } + return TransferFuncSuccess } diff --git a/nf/nvm/event.go b/nf/nvm/event.go index 25fdb587f..2c796a12b 100644 --- a/nf/nvm/event.go +++ b/nf/nvm/event.go @@ -32,6 +32,18 @@ const ( EventBaseGasCount = 20 ) +const ( + // TransferFromContractEventCompatibilityHeight record event 'TransferFromContractEvent' after this height + TransferFromContractEventCompatibilityHeight uint64 = 200000 +) + +// TransferFromContractEvent event for transfer in contract +type TransferFromContractEvent struct { + Amount string `json:"amount"` + From string `json:"from"` + To string `json:"to"` +} + // EventTriggerFunc export EventTriggerFunc //export EventTriggerFunc func EventTriggerFunc(handler unsafe.Pointer, topic, data *C.char, gasCnt *C.size_t) { diff --git a/nf/nvm/types.go b/nf/nvm/types.go index ead9b4634..6de4944a2 100644 --- a/nf/nvm/types.go +++ b/nf/nvm/types.go @@ -48,6 +48,7 @@ const ( TransferStringToBigIntErr TransferSubBalance TransferAddBalance + TransferRecordEventFailed ) // Block interface breaks cycle import dependency and hides unused services. @@ -71,6 +72,7 @@ type Transaction interface { // Account interface breaks cycle import dependency and hides unused services. type Account interface { + Address() byteutils.Hash Balance() *util.Uint128 Nonce() uint64 AddBalance(value *util.Uint128) error diff --git a/rpc/api_service.go b/rpc/api_service.go index 23631a782..f7b1cca08 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -147,7 +147,7 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T ) if reqTx.Contract != nil { - if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 { // TODO: reqTx.DeployContract, reqTx.CallContract + if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 && fromAddr.Equals(toAddr) { payloadType = core.TxPayloadDeployType payloadObj, err := core.NewDeployPayload(reqTx.Contract.Source, reqTx.Contract.SourceType, reqTx.Contract.Args) if err != nil { @@ -156,7 +156,7 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T if payload, err = payloadObj.ToBytes(); err != nil { return nil, err } - } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 { + } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 && toAddr.Type() == core.ContractAddress { payloadType = core.TxPayloadCallType callpayload, err := core.NewCallPayload(reqTx.Contract.Function, reqTx.Contract.Args) if err != nil { From e790675ae719b0bda4c1cbc38a5c95cff9d93684 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Tue, 17 Apr 2018 10:15:43 +0800 Subject: [PATCH 04/69] rename vars and consts --- core/address.go | 6 ++++-- core/transaction_binary_payload.go | 2 +- core/types.go | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/core/address.go b/core/address.go index 2c62f7c85..0e5535c49 100644 --- a/core/address.go +++ b/core/address.go @@ -27,11 +27,13 @@ import ( // AddressType address type type AddressType byte +// UndefinedAddressType undefined +const UndefinedAddressType AddressType = 0x00 + // address type enum const ( AccountAddress AddressType = 0x57 + iota ContractAddress - UnkownAddress AddressType = 0x00 ) // const @@ -153,7 +155,7 @@ func (a *Address) Equals(b *Address) bool { // Type return the type of address. func (a *Address) Type() AddressType { if len(a.address) <= AddressTypeIndex { - return UnkownAddress + return UndefinedAddressType } return AddressType(a.address[AddressTypeIndex]) } diff --git a/core/transaction_binary_payload.go b/core/transaction_binary_payload.go index a88bf511d..4ad3d9521 100644 --- a/core/transaction_binary_payload.go +++ b/core/transaction_binary_payload.go @@ -89,7 +89,7 @@ func (payload *BinaryPayload) Execute(limitedGas *util.Uint128, tx *Transaction, return util.NewUint128(), "", err } - result, exeErr := engine.Call(deploy.Source, deploy.SourceType, ContractDefaultFunc, "") + result, exeErr := engine.Call(deploy.Source, deploy.SourceType, ContractAcceptFunc, "") gasCout := engine.ExecutionInstructions() instructions, err := util.NewUint128FromInt(int64(gasCout)) if err != nil { diff --git a/core/types.go b/core/types.go index 012263710..196e16317 100644 --- a/core/types.go +++ b/core/types.go @@ -53,7 +53,7 @@ const ( // Const const ( - ContractDefaultFunc = "accept" + ContractAcceptFunc = "accept" ) var ( From 4b0e85a9f860e55712a557611e58d84bf651cc62 Mon Sep 17 00:00:00 2001 From: ChengOrangeJu Date: Wed, 18 Apr 2018 10:07:13 +0800 Subject: [PATCH 05/69] nebtestkit: refactor bankvault --- .../cases/contract/contract.bankvault.test.js | 198 +++++++++++------- 1 file changed, 123 insertions(+), 75 deletions(-) diff --git a/nebtestkit/cases/contract/contract.bankvault.test.js b/nebtestkit/cases/contract/contract.bankvault.test.js index 92e60136e..f8077bb02 100644 --- a/nebtestkit/cases/contract/contract.bankvault.test.js +++ b/nebtestkit/cases/contract/contract.bankvault.test.js @@ -2,7 +2,7 @@ var HttpRequest = require("../../node-request"); -var Wallet = require("../../../cmd/console/neb.js/lib/wallet"); +var Wallet = require("nebulas"); var Account = Wallet.Account; var Transaction = Wallet.Transaction; var Utils = Wallet.Utils; @@ -24,6 +24,7 @@ var coinState; var redeploy = process.env.REDEPLOY || true; var scriptType = process.env.script || 'js'; var env = process.env.NET || 'local'; +var blockInterval = 15; // mocha cases/contract/xxx testneb1 -t 200000 var args = process.argv.splice(2); @@ -36,8 +37,8 @@ console.log("env:", env); if (env === 'local') { neb.setRequest(new HttpRequest("http://127.0.0.1:8685"));//https://testnet.nebulas.io ChainID = 100; - sourceAccount = new Wallet.Account("a6e5eb290e1438fce79f5cb8774a72621637c2c9654c8b2525ed1d7e4e73653f"); - coinbase = "eb31ad2d8a89a0ca6935c308d5425730430bc2d63f2573b8"; + sourceAccount = new Wallet.Account("1d3fe06a53919e728315e2ccca41d4aa5b190845a79007797517e62dbc0df454"); + coinbase = "n1QZMXSZtW7BUerroSms4axNfyBGyFGkrh5"; if (!redeploy) { contractAddr = "e5a02995444628cf7935e3ef8b613299a2d97e6d188ce808"; //js // contractAddr = "557fccaf2f05d4b46156e9b98ca9726f1c9e91d95d3830a7"; //ts @@ -55,8 +56,8 @@ if (env === 'local') { } else if (env === "testneb2") { neb.setRequest(new HttpRequest("http://34.205.26.12:8685")); ChainID = 1002; - sourceAccount = new Wallet.Account("43181d58178263837a9a6b08f06379a348a5b362bfab3631ac78d2ac771c5df3"); - coinbase = "0b9cd051a6d7129ab44b17833c63fe4abead40c3714cde6d"; + sourceAccount = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); + coinbase = "n1SAeQRVn33bamxN4ehWUT7JGdxipwn8b17"; if (!redeploy) { contractAddr = ""; } @@ -83,11 +84,12 @@ var initFromBalance = 10; * set this value according to the status of your testnet. * the smaller the value, the faster the test, with the risk of causing error */ -var maxCheckTime = 100; +var maxCheckTime = 15; var checkTimes = 0; var beginCheckTime; function checkTransaction(hash, callback) { + console.log("==>checkTransaction"); if (checkTimes === 0) { beginCheckTime = new Date().getTime(); } @@ -104,29 +106,32 @@ function checkTransaction(hash, callback) { if (resp.status === 2) { setTimeout(function(){ checkTransaction(hash, callback) - }, 2000) + }, 5000) } else { checkTimes = 0; var endCheckTime = new Date().getTime(); console.log("check tx time: : " + (endCheckTime - beginCheckTime) / 1000); callback(resp); + return } }).catch(function (err) { console.log("fail to get tx receipt hash: '" + hash + "' probably being packing, continue checking...") - console.log(err.error) + console.log(err); + console.log(err.error); setTimeout(function(){ checkTransaction(hash, callback) - }, 2000) + }, 5000) }); } function deployContract(testInput, done) { + console.log("==> deployContract"); neb.api.getAccountState(from.getAddressString()).then(function(state){ fromState = state; console.log("from state: " + JSON.stringify(fromState)); }).then(function(){ - var filepath = "./nf/nvm/test/bank_vault_contract." + testInput.contractType; + var filepath = "../nf/nvm/test/bank_vault_contract." + testInput.contractType; console.log("deploying contract: " + filepath); var bankvault = FS.readFileSync(filepath, "utf-8"); var contract = { @@ -142,6 +147,7 @@ function deployContract(testInput, done) { console.log(err.error); done(err); }).then(function(resp){ + console.log("111: result", resp); expect(resp).to.be.have.property('txhash'); expect(resp).to.be.have.property('contract_address'); contractAddr = resp.contract_address; @@ -168,6 +174,7 @@ var fromBalanceBefore, txInfo = {}; function testSave(testInput, testExpect, done) { + console.log("==> testSave"); var call = { "function": testInput.func, @@ -192,6 +199,7 @@ function testSave(testInput, testExpect, done) { return neb.api.estimateGas(from.getAddressString(), contractAddr, testInput.value, txInfo.nonce, testInput.gasPrice, testInput.gasLimit, txInfo.call); + }).then(function(resp){ expect(resp).to.have.property('gas'); gasUsed = resp.gas; @@ -259,6 +267,7 @@ function testSave(testInput, testExpect, done) { } function testTakeout(testInput, testExpect, done) { + console.log("==>testTakeout"); neb.api.getAccountState(contractAddr).then(function(state){ console.log("[before take] contract state: " + JSON.stringify(state)); contractBalanceBefore = new BigNumber(state.balance); @@ -293,67 +302,73 @@ function testTakeout(testInput, testExpect, done) { }).then(function(resp){ expect(resp).to.have.property('txhash'); checkTransaction(resp.txhash, function(receipt){ + try { + console.log("22: receipt", receipt); + if (testExpect.canExecuteTx) { + expect(receipt).to.have.property('status').equal(1); + } else { + expect(receipt).to.have.property('status').equal(0); + } - if (testExpect.canExecuteTx) { - expect(receipt).to.have.property('status').equal(1); - } else { - expect(receipt).to.not.have.property('status'); - } - - neb.api.getAccountState(receipt.from).then(function(state){ + console.log("333"); + neb.api.getAccountState(receipt.from).then(function (state) { - // from balance change - fromBalanceChange = new BigNumber(state.balance).sub(new BigNumber(fromBalanceBefore)); - console.log("[after take] from state: " + JSON.stringify(state) + ", balance change: " + fromBalanceChange); + // from balance change + fromBalanceChange = new BigNumber(state.balance).sub(new BigNumber(fromBalanceBefore)); + console.log("[after take] from state: " + JSON.stringify(state) + ", balance change: " + fromBalanceChange); - return neb.api.getAccountState(receipt.to); - }).then(function(cstate){ - + return neb.api.getAccountState(receipt.to); + }).then(function (cstate) { - return neb.api.getAccountState(coinbase).then(function(state){ - - var coinbalancechange = new BigNumber(state.balance).sub(new BigNumber(coinBalanceBefore)) - .mod(new BigNumber(1.4269).mul(new BigNumber(10).pow(new BigNumber(18)))); - console.log("[after take] coinbase state:" + JSON.stringify(state) + ", balance change: " + coinbalancechange); + return neb.api.getAccountState(coinbase).then(function (state) { - var chg = contractBalanceBefore.sub(new BigNumber(cstate.balance)); - console.log("[after take] contract state: " + JSON.stringify(cstate) + ", balance change: " + chg); + var coinbalancechange = new BigNumber(state.balance).sub(new BigNumber(coinBalanceBefore)) + .mod(new BigNumber(1.4269).mul(new BigNumber(10).pow(new BigNumber(18)))); + console.log("[after take] coinbase state:" + JSON.stringify(state) + ", balance change: " + coinbalancechange); - if (testExpect.canExecuteTx) { - var isEqual = chg.equals(new BigNumber(testExpect.takeBalance)); - expect(isEqual).to.be.true; - } - - return neb.api.getEventsByHash(receipt.hash); - - }); - - }).then(function(evtResp){ + var chg = contractBalanceBefore.sub(new BigNumber(cstate.balance)); + console.log("[after take] contract state: " + JSON.stringify(cstate) + ", balance change: " + chg); - if (!testExpect.canExecuteTx) { - expect(evtResp.events[0].topic).to.equal(testExpect.eventTopic); - done(); - } else { - neb.api.gasPrice().then(function(resp){ - expect(resp).to.have.property('gas_price'); - console.log("[after take] gas price:" + resp['gas_price'] + ", gas used: " + gasUsed); - gasPrice = resp['gas_price']; - - var t = new BigNumber(testExpect.takeBalance).sub(new BigNumber(gasUsed) - .mul(new BigNumber(gasPrice))); - var isEqual = fromBalanceChange.equals(t); - - expect(isEqual).to.be.true; - done(); - }).catch(function(err){ - done(err); + if (testExpect.canExecuteTx) { + var isEqual = chg.equals(new BigNumber(testExpect.takeBalance)); + expect(isEqual).to.be.true; + } + + return neb.api.getEventsByHash(receipt.hash); }); - } - }).catch(function(err){ - console.log(err.error); + + }).then(function (evtResp) { + + if (!testExpect.canExecuteTx) { + + expect(evtResp.events[0].topic).to.equal(testExpect.eventTopic); + done(); + + } else { + neb.api.gasPrice().then(function (resp) { + expect(resp).to.have.property('gas_price'); + console.log("[after take] gas price:" + resp['gas_price'] + ", gas used: " + gasUsed); + gasPrice = resp['gas_price']; + + var t = new BigNumber(testExpect.takeBalance).sub(new BigNumber(gasUsed) + .mul(new BigNumber(gasPrice))); + var isEqual = fromBalanceChange.equals(t); + + expect(isEqual).to.be.true; + done(); + }).catch(function (err) { + done(err); + }); + } + }).catch(function (err) { + console.log(err.error); + done(err) + }); + } catch (err) { + console.log(JSON.stringify(err)); done(err) - }); - }); + } + }) }).catch(function(err){ console.log(err.error); if (testExpect.hasError) { @@ -370,6 +385,7 @@ function testTakeout(testInput, testExpect, done) { } function testVerifyAddress(testInput, testExpect, done) { + console.log("==> testVerifyAddress"); neb.api.getAccountState(contractAddr).then(function(state){ console.log("[before verify] contract state: " + JSON.stringify(state)); contractBalanceBefore = new BigNumber(state.balance); @@ -388,7 +404,7 @@ function testVerifyAddress(testInput, testExpect, done) { "function": testInput.func, "args": testInput.args } - return neb.api.call(from.getAddressString(), contractAddr, testInput.value, parseInt(state.nonce) + 1, 0, testInput.gasLimit, call); + return neb.api.call(from.getAddressString(), contractAddr, testInput.value, parseInt(state.nonce) + 1, testInput.gasPrice, testInput.gasLimit, call); }).then(resp => { console.log("response: " + JSON.stringify(resp)); expect(resp).to.have.property('result') @@ -398,6 +414,7 @@ function testVerifyAddress(testInput, testExpect, done) { } function claimNas(contractType, done) { + console.log("==> claimNas"); from = Account.NewAccount(); console.log("from addr:" + from.getAddressString()); @@ -419,7 +436,8 @@ function claimNas(contractType, done) { if (redeploy) { var testInput = { contractType: contractType, - gasLimit: 2000000 + gasLimit: 2000000, + gasPrice: 1000000, }; redeploy = false; deployContract(testInput, done); @@ -444,14 +462,16 @@ describe('bankvault.' + scriptType, function() { it('save before take', function(done){ var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "save", args: "[0]", value: 20000000000, - } + }; var testExpect = { canExecuteTx: true - } + }; testSave(testInput, testExpect, done); }); @@ -461,6 +481,8 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "takeout", args: "[10000000000]", value: "0" //no use @@ -483,6 +505,8 @@ describe('bankvault.' + scriptType, function() { it('save before take', function(done){ var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "save", args: "[0]", value: 20000000000, @@ -499,6 +523,7 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, func: "takeout", args: "[40000000000]", value: "0" //no use @@ -507,7 +532,8 @@ describe('bankvault.' + scriptType, function() { var testExpect = { canExecuteTx: false, // actually, should be `false` takeBalance: '40000000000', // same with testInput.args[0] - eventTopic: 'chain.executeTxFailed', + // eventTopic: 'chain.executeTxFailed', + eventTopic: 'chain.transactionResult', hasError: true, errorMsg: 'execution failed' } @@ -519,6 +545,8 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "takeout", args: "[0]", value: "0" //no use @@ -536,6 +564,8 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "takeout", args: "[-40000000000]", value: "0" //no use @@ -544,7 +574,8 @@ describe('bankvault.' + scriptType, function() { var testExpect = { canExecuteTx: false, // actually, should be `false` takeBalance: '-40000000000', // same with testInput.args[0] - eventTopic: 'chain.executeTxFailed', + // eventTopic: 'chain.executeTxFailed', + eventTopic: 'chain.transactionResult', hasError: true, errorMsg: 'execution failed' } @@ -561,6 +592,8 @@ describe('bankvault.' + scriptType, function() { it('save(40) before take', done => { var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "save", args: "[15]", value: 20000000000, @@ -577,15 +610,18 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "takeout", args: "[10000000000]", value: "0" //no use } var testExpect = { - canExecuteTx: false, // actually, should be `false` + canExecuteTx: false, takeBalance: '10000000000', // same with testInput.args[0] - eventTopic: 'chain.executeTxFailed' + // eventTopic: 'chain.executeTxFailed' + eventTopic: 'chain.transactionResult' } testTakeout(testInput, testExpect, done); @@ -595,19 +631,21 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "takeout", args: "[10000000000]", value: "0" //no use } var testExpect = { - canExecuteTx: true, // actually, should be `false` + canExecuteTx: true, takeBalance: '10000000000' // same with testInput.args[0] } setTimeout(() => { testTakeout(testInput, testExpect, done); - }, 25 * 5 * 1000); + }, 25 * blockInterval * 1000); }); }); @@ -622,6 +660,8 @@ describe('bankvault.' + scriptType, function() { // take var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "takeout", args: "[10000000000]", value: "0" //no use @@ -630,7 +670,8 @@ describe('bankvault.' + scriptType, function() { var testExpect = { canExecuteTx: false , takeBalance: '0', - eventTopic: 'chain.executeTxFailed' + // eventTopic: 'chain.executeTxFailed' + eventTopic: 'chain.transactionResult' } testTakeout(testInput, testExpect, done); @@ -645,6 +686,8 @@ describe('bankvault.' + scriptType, function() { it('5-1. save non-negative value', function(done){ var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "save", args: "[0]", value: 10000000000, @@ -660,6 +703,8 @@ describe('bankvault.' + scriptType, function() { it('5-2. save negative value', function(done){ var testInput = { gasLimit: 2000000, + gasPrice: 1000000, + func: "save", args: "[0]", value: -20000000000, @@ -667,7 +712,7 @@ describe('bankvault.' + scriptType, function() { var testExpect = { hasError: true, - errorMsg: "uint128: underflow" + errorMsg: "invalid value" } testSave(testInput, testExpect, done); @@ -676,6 +721,7 @@ describe('bankvault.' + scriptType, function() { it('5-3. save negative height', done => { var testInput = { gasLimit: 2000000, + gasPrice: 1000000, func: "save", args: "[-500]", value: 20000000000, @@ -699,8 +745,9 @@ describe('bankvault.' + scriptType, function() { var testInput = { value: "0", gasLimit: 2000000, + gasPrice: 1000000, func: "verifyAddress", - args: "[\"d2e558ebf403d10cc435e7ddff5906fcb2c8d033d74cc305\"]" + args: "[\"n1QZMXSZtW7BUerroSms4axNfyBGyFGkrh5\"]" } var testExpect = { @@ -714,6 +761,7 @@ describe('bankvault.' + scriptType, function() { var testInput = { value: "0", gasLimit: 2000000, + gasPrice: 1000000, func: "verifyAddress", args: "[\"slfjlsalfksdflsfjks\"]" } From 06bd60060364a188a31af2b091408200003996a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=9A=E4=B9=A6?= Date: Thu, 19 Apr 2018 16:43:38 +0800 Subject: [PATCH 06/69] Update Makefile make sure all *.so will be deployed. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 20bb80ffc..c92e7fa91 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ deploy-v8: $(LDCONFIG) deploy-libs: - $(INSTALL) nf/nvm/native-lib/libnebulasv8$(DYLIB) /usr/local/lib/ + $(INSTALL) nf/nvm/native-lib/*$(DYLIB) /usr/local/lib/ $(INSTALL) native-lib/*$(DYLIB) /usr/local/lib/ $(LDCONFIG) From 410a73c4efb90e35f435901fa11c7f507e636473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=9A=E4=B9=A6?= Date: Thu, 19 Apr 2018 16:59:42 +0800 Subject: [PATCH 07/69] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d25c9711..8227c772e 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ make dep 4. Install dependent libraries. ```bash -make deploy-libs +make deploy-v8 ``` 5. Build the neb binary. From 0983ed128fa4cf9fa42d1f0fe1eab3761292e683 Mon Sep 17 00:00:00 2001 From: fengzi Date: Thu, 19 Apr 2018 18:19:02 +0800 Subject: [PATCH 08/69] metrics:add heap release metrics --- metrics/metrics.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/metrics/metrics.go b/metrics/metrics.go index 213686136..776167e67 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -95,11 +95,14 @@ func collectSystemMetrics() { } allocs := metrics.GetOrRegisterMeter("system_allocs", nil) + // totalAllocs := metrics.GetOrRegisterMeter("system_total_allocs", nil) sys := metrics.GetOrRegisterMeter("system_sys", nil) frees := metrics.GetOrRegisterMeter("system_frees", nil) heapInuse := metrics.GetOrRegisterMeter("system_heapInuse", nil) stackInuse := metrics.GetOrRegisterMeter("system_stackInuse", nil) + releases := metrics.GetOrRegisterMeter("system_release", nil) + for i := 1; ; i++ { select { case <-quitCh: @@ -107,10 +110,13 @@ func collectSystemMetrics() { default: runtime.ReadMemStats(memstats[i%2]) allocs.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc)) + sys.Mark(int64(memstats[i%2].Sys - memstats[(i-1)%2].Sys)) frees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees)) heapInuse.Mark(int64(memstats[i%2].HeapInuse - memstats[(i-1)%2].HeapInuse)) stackInuse.Mark(int64(memstats[i%2].StackInuse - memstats[(i-1)%2].StackInuse)) + releases.Mark(int64(memstats[i%2].HeapReleased - memstats[(i-1)%2].HeapReleased)) + time.Sleep(2 * time.Second) } } From 6ec2563a7db4d7dc4d3e98897ee30f287efe1a85 Mon Sep 17 00:00:00 2001 From: Roy Shang Date: Fri, 20 Apr 2018 17:07:19 +0800 Subject: [PATCH 09/69] update dockerfiles. --- Dockerfile | 43 --------------------------------- conf/default/config.conf | 4 +-- dockerfiles/centos/Dockerfile | 38 +++++++++++++++++++++++++++++ dockerfiles/ubuntu/Dockerfile | 37 ++++++++++++++++++++++++++++ dockerfiles/ubuntu/sources.list | 17 +++++++++++++ 5 files changed, 94 insertions(+), 45 deletions(-) delete mode 100644 Dockerfile create mode 100644 dockerfiles/centos/Dockerfile create mode 100644 dockerfiles/ubuntu/Dockerfile create mode 100644 dockerfiles/ubuntu/sources.list diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 90ee860c1..000000000 --- a/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# Stage 1 of 2 stage [build] -FROM golang:stretch - -ENV GOPATH /go -ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH - -RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" - -WORKDIR /go/src/github.com/nebulasio/go-nebulas - -RUN apt-get update && \ - apt-get -yy -q install git build-essential protobuf-compiler sudo - -# Build Nebulas -COPY . /go/src/github.com/nebulasio/go-nebulas - -RUN go get -u github.com/golang/dep/cmd/dep && \ - go get -u golang.org/x/tools/cmd/goimports && \ - make dep && \ - make deploy-v8 && \ - make build - -# Stage 2 of 2 [copy assets to thin image] -FROM debian:stretch - -WORKDIR /nebulas - -ENV PATH /usr/local/bin:$PATH - -# Copy v8 libs from builder -COPY --from=0 /usr/local/lib /usr/local/lib -RUN ldconfig - -# Copy neb and crash reporter from builder -COPY --from=0 /go/src/github.com/nebulasio/go-nebulas/neb /usr/local/bin/neb -COPY --from=0 /go/src/github.com/nebulasio/go-nebulas/nebulas_crashreporter /usr/local/bin/nebulas_crashreporter - -# Copy conf & keydir to enable bootstrapping -COPY --from=0 /go/src/github.com/nebulasio/go-nebulas/keydir /nebulas/keydir -COPY --from=0 /go/src/github.com/nebulasio/go-nebulas/conf /nebulas/conf - -ENTRYPOINT ["/usr/local/bin/neb"] - diff --git a/conf/default/config.conf b/conf/default/config.conf index 8a86ec135..c5f263a9a 100644 --- a/conf/default/config.conf +++ b/conf/default/config.conf @@ -21,7 +21,7 @@ rpc { http_listen: ["127.0.0.1:8685"] http_module: ["api","admin"] # HTTP CORS allowed origins - # http_cors: [] + http_cors: ["*"] } app { @@ -29,7 +29,7 @@ app { log_file: "logs" enable_crash_report: true crash_report_url: "https://crashreport.nebulas.io" - pprof:{ + pprof:{ http_listen: "0.0.0.0:8888" } } diff --git a/dockerfiles/centos/Dockerfile b/dockerfiles/centos/Dockerfile new file mode 100644 index 000000000..8afb020f6 --- /dev/null +++ b/dockerfiles/centos/Dockerfile @@ -0,0 +1,38 @@ +FROM centos + +RUN yum -y update && yum -y install epel-release +RUN yum -y update && yum -y install which make git protobuf-compiler gflags-devel snappy-devel zlib-devel bzip2-devel gcc-c++ libstdc++-devel wget + +RUN wget https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz +RUN tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz + +RUN mkdir go +ENV GOPATH /go +ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH + +RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" + +# Install RocksDB +RUN mkdir /dependency && cd /dependency +RUN git clone https://github.com/facebook/rocksdb.git +RUN cd rocksdb && make shared_lib && make install-shared +ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:/usr/local/lib + +# Build Nebulas +RUN go get -u github.com/golang/dep/cmd/dep && \ + go get -u golang.org/x/tools/cmd/goimports + +WORKDIR /go/src/github.com/nebulasio +RUN git clone https://github.com/nebulasio/go-nebulas.git + +WORKDIR /go/src/github.com/nebulasio/go-nebulas +RUN git checkout master + +# Install dependency +RUN wget http://ory7cn4fx.bkt.clouddn.com/vendor.tar.gz +RUN tar xzf vendor.tar.gz +## Or use `make dep` if you have ladders. + +RUN install nf/nvm/native-lib/*.so /usr/local/lib/ && make build + +ENTRYPOINT ["/go/src/github.com/nebulasio/go-nebulas/neb"] diff --git a/dockerfiles/ubuntu/Dockerfile b/dockerfiles/ubuntu/Dockerfile new file mode 100644 index 000000000..56d4cad88 --- /dev/null +++ b/dockerfiles/ubuntu/Dockerfile @@ -0,0 +1,37 @@ +FROM ubuntu:16.04 + +COPY sources.list /etc/apt/sources.list +RUN apt-get update && apt-get -y install git build-essential protobuf-compiler sudo libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev wget make + +RUN wget https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz +RUN tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz + +RUN mkdir go +ENV GOPATH /go +ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH + +RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" + +# Install RocksDB +RUN git clone https://github.com/facebook/rocksdb.git +RUN cd rocksdb && make shared_lib && make install-shared +ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:/usr/local/lib + +# Build Nebulas +RUN go get -u github.com/golang/dep/cmd/dep && \ + go get -u golang.org/x/tools/cmd/goimports + +WORKDIR /go/src/github.com/nebulasio +RUN git clone https://github.com/nebulasio/go-nebulas.git + +WORKDIR /go/src/github.com/nebulasio/go-nebulas +RUN git checkout master + +# Install dependency +RUN wget http://ory7cn4fx.bkt.clouddn.com/vendor.tar.gz +RUN tar xzf vendor.tar.gz +## Or use `make dep` if you have ladders. + +RUN make deploy-v8 && make build + +ENTRYPOINT ["/go/src/github.com/nebulasio/go-nebulas/neb"] diff --git a/dockerfiles/ubuntu/sources.list b/dockerfiles/ubuntu/sources.list new file mode 100644 index 000000000..dea0a3a5f --- /dev/null +++ b/dockerfiles/ubuntu/sources.list @@ -0,0 +1,17 @@ +deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe +deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse +deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse +deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties +deb http://archive.canonical.com/ubuntu xenial partner +deb-src http://archive.canonical.com/ubuntu xenial partner +deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted +deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties +deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe +deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse \ No newline at end of file From 0a32356573ceb91f8738a51edaa71d30fffbeccc Mon Sep 17 00:00:00 2001 From: fengzi Date: Sat, 21 Apr 2018 12:03:34 +0800 Subject: [PATCH 10/69] metrics:add rocksdb metrics --- common/mvccdb/mvccdb_test.go | 2 +- neblet/neblet.go | 2 +- storage/metrics.go | 5 ++++ storage/rocks_storage.go | 49 ++++++++++++++++++++++++++++++++--- storage/rocks_storage_test.go | 6 ++--- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/common/mvccdb/mvccdb_test.go b/common/mvccdb/mvccdb_test.go index 12c944506..48c35362a 100644 --- a/common/mvccdb/mvccdb_test.go +++ b/common/mvccdb/mvccdb_test.go @@ -524,7 +524,7 @@ func TestMVCCDB_ParallelsExeTowTx(t *testing.T) { } func TestPerformance(t *testing.T) { - store, _ := storage.NewRocksStorage("test.db") + store, _ := storage.NewRocksStorage("test.db", false) defer os.RemoveAll("test.db") db, _ := NewMVCCDB(store, true) diff --git a/neblet/neblet.go b/neblet/neblet.go index 9f76b15fe..dc822bb46 100644 --- a/neblet/neblet.go +++ b/neblet/neblet.go @@ -114,7 +114,7 @@ func (n *Neblet) Setup() { // storage // n.storage, err = storage.NewDiskStorage(n.config.Chain.Datadir) // n.storage, err = storage.NewMemoryStorage() - n.storage, err = storage.NewRocksStorage(n.config.Chain.Datadir) + n.storage, err = storage.NewRocksStorage(n.config.Chain.Datadir, n.config.Stats.EnableMetrics) if err != nil { logging.CLog().WithFields(logrus.Fields{ "dir": n.config.Chain.Datadir, diff --git a/storage/metrics.go b/storage/metrics.go index 2187ef7f9..d7761ee7e 100644 --- a/storage/metrics.go +++ b/storage/metrics.go @@ -27,4 +27,9 @@ var ( // rocksdb metrics metricsRocksdbFlushTime = metrics.NewGauge("neb.rocksdb.flushtime") metricsRocksdbFlushLen = metrics.NewGauge("neb.rocksdb.flushlen") + + metricsBlocksdbCacheSize = metrics.NewGauge("neb.rocksdb.cache.size") //block_cache->GetUsage() + metricsBlocksdbCachePinnedSize = metrics.NewGauge("neb.rocksdb.cachepinned.size") //block_cache->GetPinnedUsage() + metricsBlocksdbTableReaderMem = metrics.NewGauge("neb.rocksdb.tablereader.mem") //estimate-table-readers-mem + metricsBlocksdbAllMemTables = metrics.NewGauge("neb.rocksdb.alltables.mem") //cur-size-all-mem-tables ) diff --git a/storage/rocks_storage.go b/storage/rocks_storage.go index 7d7105fed..538c7335a 100644 --- a/storage/rocks_storage.go +++ b/storage/rocks_storage.go @@ -18,15 +18,19 @@ type RocksStorage struct { ro *gorocksdb.ReadOptions wo *gorocksdb.WriteOptions + + cache *gorocksdb.Cache } // NewRocksStorage init a storage -func NewRocksStorage(path string) (*RocksStorage, error) { +func NewRocksStorage(path string, enableMetrics bool) (*RocksStorage, error) { filter := gorocksdb.NewBloomFilter(10) bbto := gorocksdb.NewDefaultBlockBasedTableOptions() bbto.SetFilterPolicy(filter) - bbto.SetBlockCache(gorocksdb.NewLRUCache(512 << 20)) + + cache := gorocksdb.NewLRUCache(512 << 20) + bbto.SetBlockCache(cache) opts := gorocksdb.NewDefaultOptions() opts.SetBlockBasedTableFactory(bbto) opts.SetCreateIfMissing(true) @@ -39,13 +43,19 @@ func NewRocksStorage(path string) (*RocksStorage, error) { return nil, err } - return &RocksStorage{ + storage := &RocksStorage{ db: db, + cache: cache, enableBatch: false, batchOpts: make(map[string]*batchOpt), ro: gorocksdb.NewDefaultReadOptions(), wo: gorocksdb.NewDefaultWriteOptions(), - }, nil + } + + if enableMetrics { + go RecordMetrics(storage) + } + return storage, nil } // Get return value to the key in Storage @@ -151,3 +161,34 @@ func (storage *RocksStorage) DisableBatch() { storage.enableBatch = false } + +// RecordMetrics record rocksdb metrics +func RecordMetrics(storage *RocksStorage) { + metricsUpdateChan := time.NewTicker(5 * time.Second).C + + for { + select { + case <-metricsUpdateChan: + + readersMemStr := storage.db.GetProperty("rocksdb.estimate-table-readers-mem") + allMemTablesStr := storage.db.GetProperty("rocksdb.cur-size-all-mem-tables") + cacheSize := storage.cache.GetUsage() + pinnedSize := storage.cache.GetPinnedUsage() + + readersMemByte, err := byteutils.FromHex(readersMemStr) + if err != nil { + break + } + + allMemTablesByte, err := byteutils.FromHex(allMemTablesStr) + if err != nil { + break + } + + metricsBlocksdbAllMemTables.Update(byteutils.Int64(allMemTablesByte)) + metricsBlocksdbTableReaderMem.Update(byteutils.Int64(readersMemByte)) + metricsBlocksdbCacheSize.Update(int64(cacheSize)) + metricsBlocksdbCachePinnedSize.Update(int64(pinnedSize)) + } + } +} diff --git a/storage/rocks_storage_test.go b/storage/rocks_storage_test.go index ecbf89c21..0d09c3d00 100644 --- a/storage/rocks_storage_test.go +++ b/storage/rocks_storage_test.go @@ -17,11 +17,11 @@ func TestNewRocksStorage(t *testing.T) { want *RocksStorage wantErr bool }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewRocksStorage(tt.args.path) + got, err := NewRocksStorage(tt.args.path, false) if (err != nil) != tt.wantErr { t.Errorf("NewRocksStorage() error = %v, wantErr %v", err, tt.wantErr) return @@ -32,7 +32,7 @@ func TestNewRocksStorage(t *testing.T) { }) } - s, err := NewRocksStorage("./rock.db/") + s, err := NewRocksStorage("./rock.db/", false) assert.Nil(t, err) key := []byte("key") From cfd74c1c380a5d2365fd2f147d111bea4f2d19a5 Mon Sep 17 00:00:00 2001 From: ChengOrangeJu Date: Sat, 21 Apr 2018 14:09:44 +0800 Subject: [PATCH 11/69] update stress test case --- nebtestkit/cases/stress/stress.test.dag.js | 196 ++++++++++++++++----- 1 file changed, 152 insertions(+), 44 deletions(-) diff --git a/nebtestkit/cases/stress/stress.test.dag.js b/nebtestkit/cases/stress/stress.test.dag.js index c08c3125b..053bf5cd2 100644 --- a/nebtestkit/cases/stress/stress.test.dag.js +++ b/nebtestkit/cases/stress/stress.test.dag.js @@ -1,37 +1,23 @@ 'use strict'; -var Wallet = require('../../../cmd/console/neb.js/lib/wallet.js'); -var HttpRequest = require("../../node-request"); +var Wallet = require("nebulas"); +//var HttpRequest = Wallet.HttpRequest +var HttpRequest = require("../../node-request.js"); +var utils = Wallet.Utils; var schedule = require('node-schedule'); var sleep = require("system-sleep"); -var env="testneb3"; // local testneb1 testneb2 -var AddressNumber = 100; -var EachAccountSendTimes = 100; -var ChainID = 1003; +var env; // local testneb1 testneb2 +var AddressNumber = 300; +var EachAccountSendTimes = 50; var args = process.argv.splice(2); - -if (args.length != 3) { - // give default config - env = "testneb3"; - AddressNumber = 100; -} else { - env = args[0]; // local testneb1 testneb2 - - AddressNumber = parseInt(args[1]); - EachAccountSendTimes = parseInt(args[2]); -} - -if (AddressNumber <= 0 || EachAccountSendTimes <= 0) { - - console.log("please input correct AddressNumber and SendTimes"); - return; -} +env = args[0]; var Neb = Wallet.Neb; var neb = new Neb(); +var ChainID; var from; var accountArray; // var to = Wallet.Account.NewAccount(); @@ -42,32 +28,141 @@ var startTime; var nodes = new Array(); -neb.setRequest(new HttpRequest("http://35.177.214.138:8685")); -ChainID = 1003; -from = new Wallet.Account("43181d58178263837a9a6b08f06379a348a5b362bfab3631ac78d2ac771c5df3"); -nodes.push("http://35.177.214.138:8685"); +console.log(args); + +//local +if (env === 'local') { + neb.setRequest(new HttpRequest("http://127.0.0.1:8685")); //https://testnet.nebulas.io + ChainID = 100; + from = new Wallet.Account("a6e5eb290e1438fce79f5cb8774a72621637c2c9654c8b2525ed1d7e4e73653f"); + nodes.push("http://127.0.0.1:8685"); +} else if (env === 'testneb1') { + neb.setRequest(new HttpRequest("http://35.182.48.19:8685")); + ChainID = 1001; + from = new Wallet.Account("43181d58178263837a9a6b08f06379a348a5b362bfab3631ac78d2ac771c5df3"); + nodes.push("http://35.182.48.19:8685"); + nodes.push("http://13.57.245.249:8685"); + nodes.push("http://54.219.151.126:8685"); + nodes.push("http://18.218.165.90:8685"); + nodes.push("http://18.219.28.97:8685"); + nodes.push("http://13.58.44.3:8685"); + nodes.push("http://35.177.214.138:8685"); + nodes.push("http://35.176.94.224:8685"); +} else if (env === "testneb2") { + neb.setRequest(new HttpRequest("http://34.205.26.12:8685")); + ChainID = 1002; + from = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); + nodes.push("http://34.205.26.12:8685"); + // nodes.push("http://54.206.9.246:8685"); + // nodes.push("http://54.252.158.117:8685"); + // nodes.push("http://34.206.53.244:8685"); + // nodes.push("http://34.205.53.3:8685"); + // nodes.push("http://52.3.226.40:8685"); + +} else if (env === "testneb3") { + + //neb.setRequest(new HttpRequest("http://52.47.199.42:8685")); + neb.setRequest(new HttpRequest("http://35.177.214.138:8685")); + //neb.setRequest(new HttpRequest("http://13.127.227.177:8685")); + ChainID = 1003; + from = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); + //nodes.push("http://13.127.227.177:8685"); + nodes.push("http://35.177.214.138:8685"); + //nodes.push("http://52.47.199.42:8685"); + +} else if (env === "testneb4") { + neb.setRequest(new HttpRequest("http://34.208.233.164:8685")); + ChainID = 1004; + from = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); + nodes.push("http://34.208.233.164:8685"); + nodes.push("http://54.245.29.152:8685"); + nodes.push("http://52.34.73.0:8685"); + nodes.push("http://54.71.175.99:8685"); + nodes.push("http://34.213.130.120:8685"); + nodes.push("http://18.197.107.228:8685"); + nodes.push("http://18.197.106.150:8685"); + nodes.push("http://54.93.121.146:8685"); + nodes.push("http://18.195.159.210:8685"); + nodes.push("http://18.197.157.46:8685"); + nodes.push("http://18.228.3.118:8685"); + nodes.push("http://18.231.173.99:8685"); + nodes.push("http://18.231.124.140:8685"); + nodes.push("http://18.231.183.193:8685"); + nodes.push("http://18.231.162.23:8685"); + nodes.push("http://34.253.237.122:8685"); + nodes.push("http://34.244.129.30:8685"); + nodes.push("http://54.229.241.235:8685"); + nodes.push("http://54.229.177.109:8685"); + nodes.push("http://34.250.18.201:8685"); + nodes.push("http://13.127.227.177:8685"); + +} else if (env === "liuliang") { + neb.setRequest(new HttpRequest("http://35.154.108.11:8685")); + ChainID = 1001; + from = new Wallet.Account("c75402f6ffe6edcc2c062134b5932151cb39b6486a7beb984792bb9da3f38b9f"); + nodes.push("http://35.154.108.11:8685"); + +} else if (env === "maintest"){ + ChainID = 2; + from = new Wallet.Account("d2319a8a63b1abcb0cc6d4183198e5d7b264d271f97edf0c76cfdb1f2631848c"); + neb.setRequest(new HttpRequest("http://54.149.15.132:8685")); + nodes.push("http://54.149.15.132:8685"); + nodes.push("http://18.188.27.35:8685"); + nodes.push("http://34.201.23.199:8685"); + nodes.push("http://13.251.33.39:8685"); + nodes.push("http://52.56.55.238:8685"); + +} else if (env === "testnet_cal_super") { + neb.setRequest(new HttpRequest("http://13.57.96.40:8685")); + ChainID = 1001; + from = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); + // from = new Wallet.Account("d2319a8a63b1abcb0cc6d4183198e5d7b264d271f97edf0c76cfdb1f2631848c"); + + nodes.push("http://52.60.150.236:8685"); + nodes.push("http://13.57.96.40:8685"); + +} else { + console.log("please input correct env local testneb1 testneb2"); + return; +} + + +var count = AddressNumber * EachAccountSendTimes; + +var interval = setInterval(function () { + + if (count >= AddressNumber * EachAccountSendTimes) { + count = 0; + + console.log("sending request to ", env); + neb.api.getAccountState(from.getAddressString()).then(function (resp) { + console.log("master accountState resp:" + JSON.stringify(resp)); + //lastnonce = parseInt(resp.result.nonce); + lastnonce = parseInt(resp.nonce); + console.log("lastnonce:", lastnonce); + + claimTokens(lastnonce); + }); + } + +}, 20000); + + -neb.api.getAccountState(from.getAddressString()).then(function (resp) { - console.log("master accountState resp:" + JSON.stringify(resp)); - lastnonce = parseInt(resp.nonce); - console.log("lastnonce:", lastnonce); - claimTokens(lastnonce); -}); function claimTokens(nonce) { console.log("initializing " + AddressNumber + " accounts with coins !!!") + console.log(from.getAddressString()); + accountArray = new Array(); for (var i = 0; i < AddressNumber; i++) { var account = Wallet.Account.NewAccount(); accountArray.push(account); - sendTransaction(0, 1, from, account, "1000000000000000", ++nonce); - - sleep(10); + sleep(5); } - checkClaimTokens(); } @@ -79,19 +174,33 @@ function sendTransaction(index, totalTimes, from, to, value, nonce, randomToAddr to = accountArray[randomTo]; } - var transaction = new Wallet.Transaction(1003, from, to, value, nonce); + var transaction = new Wallet.Transaction(ChainID, from, to, value, nonce); transaction.signTransaction(); var rawTx = transaction.toProtoString(); + var i = Math.floor((Math.random() * nodes.length)); + var node = nodes[i]; + neb.setRequest(new HttpRequest(node)); + count ++; neb.api.sendRawTransaction(rawTx).then(function (resp) { - console.log("send raw transaction resp:" + JSON.stringify(resp)); + console.log("send raw tx resp:" + JSON.stringify(resp) + " (" + index + "/" + totalTimes + ")"); + //if (resp.result.txhash) { if (resp.txhash) { if (nonce % 10 === 0){ - sleep(10); + sleep(20); } sendTransaction(++index, totalTimes, from, to, value, ++nonce, randomToAddr); } }); + + // .catch(function (err) { + // console.log(err); + // console.log(JSON.stringify(err)); + // console.log("send tx error, retry: " + "from:" + from.getAddressString() + " tx_index: (" + index + "/" + totalTimes + ")" + " node:" + node); + // sleep(10); + // sendTransaction(index, totalTimes, from, to, value, nonce, randomToAddr); + // } + // ); } } @@ -99,9 +208,9 @@ function checkClaimTokens() { var interval = setInterval(function () { neb.api.getAccountState(from.getAddressString()).then(function (resp) { console.log("master accountState resp:" + JSON.stringify(resp)); + //if (resp.result.nonce >= lastnonce + AddressNumber) { if (resp.nonce >= lastnonce + AddressNumber) { clearInterval(interval); - sendTransactionsForTps(); } }); @@ -115,11 +224,10 @@ function sendTransactionsForTps() { startTime = new Date().getTime(); for (var i = 0; i < AddressNumber; i++) { - var node = nodes[i % nodes.length]; neb.setRequest(new HttpRequest(node)); - var randomValue = Math.floor((Math.random() * 10)); + var randomValue = Math.floor((Math.random() * 100)); sendTransaction(0, EachAccountSendTimes, accountArray[i], null, randomValue, 1, true /*random to addr*/); - sleep(10); + sleep(5); } } From e6c72efeefa6af539cb1225b8675a5259a248458 Mon Sep 17 00:00:00 2001 From: Leon Date: Sat, 21 Apr 2018 16:41:35 +0800 Subject: [PATCH 12/69] net: optimize network message compress. --- net/neb_message.go | 15 ++++++--------- net/stream.go | 25 ++++++++++++++++++------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/net/neb_message.go b/net/neb_message.go index 66173089a..8d5c773b5 100644 --- a/net/neb_message.go +++ b/net/neb_message.go @@ -80,8 +80,9 @@ const ( // Error types var ( - MagicNumber = []byte{0x4e, 0x45, 0x42, 0x31} - DefaultReserved = []byte{0x80, 0x0, 0x0} + MagicNumber = []byte{0x4e, 0x45, 0x42, 0x31} + DefaultReserved = []byte{0x0, 0x0, 0x0} + CompressReserved = []byte{0x80, 0x0, 0x0} ErrInsufficientMessageHeaderLength = errors.New("insufficient message header length") ErrInsufficientMessageDataLength = errors.New("insufficient message data length") @@ -172,14 +173,10 @@ func (message *NebMessage) Length() uint64 { } // NewNebMessage new neb message -func NewNebMessage(s *Stream, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { - chainID := s.node.config.ChainID - // if remote peer version >= compress version, compress message data. +func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { if messageName != HELLO { - if v, ok := s.compressFlag.Load(s.pid.Pretty()); ok { - if (v.(byte) & 0x80) > 0 { - data = snappy.Encode(nil, data) - } + if (reserved[0] & 0x80) > 0 { + data = snappy.Encode(nil, data) } } diff --git a/net/stream.go b/net/stream.go index 758d4a022..8dea99b59 100644 --- a/net/stream.go +++ b/net/stream.go @@ -80,7 +80,7 @@ type Stream struct { latestReadAt int64 latestWriteAt int64 msgCount map[string]int - compressFlag *sync.Map + compressFlag byte } // NewStream return a new Stream @@ -110,7 +110,7 @@ func newStreamInstance(pid peer.ID, addr ma.Multiaddr, stream libnet.Stream, nod latestReadAt: 0, latestWriteAt: 0, msgCount: make(map[string]int), - compressFlag: new(sync.Map), + compressFlag: 0x80 & 0x80, } } @@ -175,7 +175,13 @@ func (s *Stream) SendProtoMessage(messageName string, pb proto.Message, priority // SendMessage send msg to buffer func (s *Stream) SendMessage(messageName string, data []byte, priority int) error { - message, err := NewNebMessage(s, DefaultReserved, 0, messageName, data) + var reserved []byte + if s.compressFlag > 0 { + reserved = CompressReserved + } else { + reserved = DefaultReserved + } + message, err := NewNebMessage(s.node.config.ChainID, reserved, 0, messageName, data) if err != nil { return err } @@ -280,7 +286,13 @@ func (s *Stream) WriteProtoMessage(messageName string, pb proto.Message) error { // WriteMessage write raw msg in the stream func (s *Stream) WriteMessage(messageName string, data []byte) error { - message, err := NewNebMessage(s, DefaultReserved, 0, messageName, data) + var reserved []byte + if s.compressFlag > 0 { + reserved = CompressReserved + } else { + reserved = DefaultReserved + } + message, err := NewNebMessage(s.node.config.ChainID, reserved, 0, messageName, data) if err != nil { return err } @@ -443,15 +455,14 @@ func (s *Stream) writeLoop() { func (s *Stream) handleMessage(message *NebMessage) error { messageName := message.MessageName() - compressFlag := message.Reserved()[0] & 0x80 - s.compressFlag.Store(s.pid.Pretty(), compressFlag) + s.compressFlag = message.Reserved()[0] & 0x80 s.msgCount[messageName]++ // Network data compression compatible with old clients. // uncompress message data. var data = message.Data() if messageName != HELLO { - if compressFlag > 0 { + if s.compressFlag > 0 { var err error data, err = snappy.Decode(nil, message.Data()) if err != nil { From 1393996544a80c2c64672ae13470a6c4c756cd25 Mon Sep 17 00:00:00 2001 From: Roy Shang Date: Sat, 21 Apr 2018 16:09:13 +0800 Subject: [PATCH 13/69] add dockerfile. --- README.md | 97 +++++++++++++++++++++------------ conf/default/config.conf | 4 +- docker-compose.yml | 20 +++++++ docker/CHANGLOG.md | 12 ++++ docker/Dockerfile | 26 +++++++++ docker/README.md | 16 ++++++ docker/scripts/neb.bash | 30 ++++++++++ dockerfiles/centos/Dockerfile | 38 ------------- dockerfiles/ubuntu/Dockerfile | 37 ------------- dockerfiles/ubuntu/sources.list | 17 ------ storage/rocks_storage_test.go | 2 +- 11 files changed, 168 insertions(+), 131 deletions(-) create mode 100644 docker-compose.yml create mode 100644 docker/CHANGLOG.md create mode 100644 docker/Dockerfile create mode 100644 docker/README.md create mode 100755 docker/scripts/neb.bash delete mode 100644 dockerfiles/centos/Dockerfile delete mode 100644 dockerfiles/ubuntu/Dockerfile delete mode 100644 dockerfiles/ubuntu/sources.list diff --git a/README.md b/README.md index 8227c772e..64c6e39ce 100644 --- a/README.md +++ b/README.md @@ -48,48 +48,45 @@ Or use the stable testnet release in __testnet__. git checkout testnet ``` -2. Install rocksdb && dependencies. +2. Install rocksdb. * **OS X**: - * Install latest C++ compiler that supports C++ 11: - * Update XCode: run `xcode-select --install` (or install it from XCode App's settting). - * Install via [homebrew](http://brew.sh/). - * If you're first time developer in MacOS, you still need to run: `xcode-select --install` in your command line. - * run `brew tap homebrew/versions; brew install gcc48 --use-llvm` to install gcc 4.8 (or higher). + * Install via [homebrew](http://brew.sh/). * run `brew install rocksdb` * **Linux - Ubuntu** - * Install rocksdb by source code: (https://github.com/facebook/rocksdb/blob/master/INSTALL.md) - `git clone https://github.com/facebook/rocksdb.git` - `cd rocksdb & make shared_lib` - * Upgrade your gcc to version at least 4.8 to get C++11 support. - * Install gflags. First, try: `sudo apt-get install libgflags-dev` - If this doesn't work and you're using Ubuntu, here's a nice tutorial: - (http://askubuntu.com/questions/312173/installing-gflags-12-04) - * Install snappy. This is usually as easy as: - `sudo apt-get install libsnappy-dev`. - * Install zlib. Try: `sudo apt-get install zlib1g-dev`. - * Install bzip2: `sudo apt-get install libbz2-dev`. - * Install lz4: `sudo apt-get install liblz4-dev`. - * Install zstandard: `sudo apt-get install libzstd-dev`. + * Install Dependencies + ```bash + apt-get update + apt-get -y build-essential libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev + ``` + * Install rocksdb by source code: + ```bash + git clone https://github.com/facebook/rocksdb.git + cd rocksdb & make shared_lib && make install-shared + ``` +* **Linux - Centos** + * Install Dependencies + ```bash + yum -y install epel-release && yum -y update + yum -y install gflags-devel snappy-devel zlib-devel bzip2-devel gcc-c++ libstdc++-devel + ``` + * Install rocksdb by source code: + ```bash + git clone https://github.com/facebook/rocksdb.git + cd rocksdb & make shared_lib && make install-shared + ``` 3. Install dependencies packages. + * all golang dependencies will be stored in ./vendor. + * run `make dep` to install dependencies. + * If you failed to run this, please download our [vendor.tar.gz](http://ory7cn4fx.bkt.clouddn.com/vendor.tar.gz) directly. -```bash -make dep -``` - -4. Install dependent libraries. - -```bash -make deploy-v8 -``` +4. Install v8 libraries. + * run `make deploy-v8` 5. Build the neb binary. - -```bash -make build -``` + * run `make build` ## Run @@ -142,12 +139,40 @@ From the log, we can see the binary execution starts neblet, starts network serv ## Docker ### Build - -`docker build -t nebulas .` +* pull from dockerhub directly + ```bash + docker pull bkbabydp/go-nebulas + ``` +* build locally + ```bash + docker-compose up + ``` ### Run - -`docker run -it -v $(pwd)/data.db:/nebulas/data.db nebulas` +* edit [your conf path] in docker-compose.yml +```yml + # node: + # image: bkbabydp/go-nebulas + # build: + # context: ./docker + # ports: + # - '8680' + # - '8684' + # - '8685' + # - '8888' + # - '8086' + # volumes: + # - .:/go/src/github.com/nebulasio/go-nebulas + # environment: + # - TZ=Asia/Shanghai + # - NEBULAS_BRANCH=master + # command: bash docker/scripts/neb.bash -c [your conf path] +``` +* start the node +```bash + cd /path/to/go-nebulas + docker-compose up node +``` ## TestNet diff --git a/conf/default/config.conf b/conf/default/config.conf index c5f263a9a..15b310cee 100644 --- a/conf/default/config.conf +++ b/conf/default/config.conf @@ -17,8 +17,8 @@ chain { } rpc { - rpc_listen: ["127.0.0.1:8684"] - http_listen: ["127.0.0.1:8685"] + rpc_listen: ["0.0.0.0:8684"] + http_listen: ["0.0.0.0:8685"] http_module: ["api","admin"] # HTTP CORS allowed origins http_cors: ["*"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..672e6db3c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3' + +services: + + # node: + # image: bkbabydp/go-nebulas + # build: + # context: ./docker + # ports: + # - '8680' + # - '8684' + # - '8685' + # - '8888' + # - '8086' + # volumes: + # - .:/go/src/github.com/nebulasio/go-nebulas + # environment: + # - TZ=Asia/Shanghai + # - NEBULAS_BRANCH=master + # command: bash docker/scripts/neb.bash -c [your conf path] diff --git a/docker/CHANGLOG.md b/docker/CHANGLOG.md new file mode 100644 index 000000000..9f11e257c --- /dev/null +++ b/docker/CHANGLOG.md @@ -0,0 +1,12 @@ +## CHANGLOGS + +### 2018-04-21 + +* Added docker-compose.yml to run node directly + +* Included go1.9.2 and rocksdb5.13 in Dockerfile + +* New Feature: + If you want to download vender instead of running `make dep`, + you can create `nodep` file with `touch nodep` in root directory + and then run `docker-compose up node` diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 000000000..cb2c4d434 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,26 @@ +FROM ubuntu:16.04 + +ENV GOPATH /go +ENV PATH ${GOPATH}/bin:/usr/local/go/bin:${PATH} + +RUN apt update && \ + apt install -y git build-essential protobuf-compiler sudo wget + +# Install Go1.9.2 +RUN wget https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz && \ + tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz && \ + mkdir go + +# Install RocksDB +ENV ROCKSDB_SRC=/usr/local/src/rocksdb +RUN apt-get install -y gcc g++ libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev && \ + git clone https://github.com/facebook/rocksdb.git ${ROCKSDB_SRC} +RUN cd ${ROCKSDB_SRC} && \ + make shared_lib && \ + make install-shared + +ENV NEBULAS_SRC=${GOPATH}/src/github.com/nebulasio/go-nebulas +WORKDIR ${NEBULAS_SRC} + +RUN go get -u github.com/golang/dep/cmd/dep && \ + go get -u golang.org/x/tools/cmd/goimports diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..0d731aeb5 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,16 @@ +# Install docker-compose + +## Pull image +```bash +docker pull bkbabydp/go-nebulas +``` +## Edit configuration +```bash +edit [your conf path] in /path/to/go-nebulas/docker-compose.yml +``` + +## Launch node +```bash +docker-compose up node +``` + diff --git a/docker/scripts/neb.bash b/docker/scripts/neb.bash new file mode 100755 index 000000000..700d206c1 --- /dev/null +++ b/docker/scripts/neb.bash @@ -0,0 +1,30 @@ +#! /usr/bin/env bash + +declare NEBULAS_SRC=${GOPATH}/src/github.com/nebulasio/go-nebulas + +[ -z ${NEBULAS_BRANCH} ] && NEBULAS_BRANCH=master + +# git clone https://github.com/nebulasio/go-nebulas ${NEBULAS_SRC} +echo NEBULAS_BRANCH=${NEBULAS_BRANCH} +cd ${NEBULAS_SRC} && \ + git checkout ${NEBULAS_BRANCH} + +if [[ -d ${NEBULAS_SRC}/vendor ]]; then + echo './vendor exists.' +else + echo './vendor not found. Createing ./vendor...' + if [[ -f ${NEBULAS_SRC}/nodep ]]; then + echo './nodep exists. Downloading vendor...' + wget http://ory7cn4fx.bkt.clouddn.com/vendor.tar.gz + tar -vxzf vendor.tar.gz + else + echo './nodep not found. Run dep...' + make dep + fi +fi + +make deploy-v8 +make clean && make build + +echo 'Run ./neb '$@ +./neb $@ diff --git a/dockerfiles/centos/Dockerfile b/dockerfiles/centos/Dockerfile deleted file mode 100644 index 8afb020f6..000000000 --- a/dockerfiles/centos/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM centos - -RUN yum -y update && yum -y install epel-release -RUN yum -y update && yum -y install which make git protobuf-compiler gflags-devel snappy-devel zlib-devel bzip2-devel gcc-c++ libstdc++-devel wget - -RUN wget https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz -RUN tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz - -RUN mkdir go -ENV GOPATH /go -ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH - -RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" - -# Install RocksDB -RUN mkdir /dependency && cd /dependency -RUN git clone https://github.com/facebook/rocksdb.git -RUN cd rocksdb && make shared_lib && make install-shared -ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:/usr/local/lib - -# Build Nebulas -RUN go get -u github.com/golang/dep/cmd/dep && \ - go get -u golang.org/x/tools/cmd/goimports - -WORKDIR /go/src/github.com/nebulasio -RUN git clone https://github.com/nebulasio/go-nebulas.git - -WORKDIR /go/src/github.com/nebulasio/go-nebulas -RUN git checkout master - -# Install dependency -RUN wget http://ory7cn4fx.bkt.clouddn.com/vendor.tar.gz -RUN tar xzf vendor.tar.gz -## Or use `make dep` if you have ladders. - -RUN install nf/nvm/native-lib/*.so /usr/local/lib/ && make build - -ENTRYPOINT ["/go/src/github.com/nebulasio/go-nebulas/neb"] diff --git a/dockerfiles/ubuntu/Dockerfile b/dockerfiles/ubuntu/Dockerfile deleted file mode 100644 index 56d4cad88..000000000 --- a/dockerfiles/ubuntu/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM ubuntu:16.04 - -COPY sources.list /etc/apt/sources.list -RUN apt-get update && apt-get -y install git build-essential protobuf-compiler sudo libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev wget make - -RUN wget https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz -RUN tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz - -RUN mkdir go -ENV GOPATH /go -ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH - -RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" - -# Install RocksDB -RUN git clone https://github.com/facebook/rocksdb.git -RUN cd rocksdb && make shared_lib && make install-shared -ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:/usr/local/lib - -# Build Nebulas -RUN go get -u github.com/golang/dep/cmd/dep && \ - go get -u golang.org/x/tools/cmd/goimports - -WORKDIR /go/src/github.com/nebulasio -RUN git clone https://github.com/nebulasio/go-nebulas.git - -WORKDIR /go/src/github.com/nebulasio/go-nebulas -RUN git checkout master - -# Install dependency -RUN wget http://ory7cn4fx.bkt.clouddn.com/vendor.tar.gz -RUN tar xzf vendor.tar.gz -## Or use `make dep` if you have ladders. - -RUN make deploy-v8 && make build - -ENTRYPOINT ["/go/src/github.com/nebulasio/go-nebulas/neb"] diff --git a/dockerfiles/ubuntu/sources.list b/dockerfiles/ubuntu/sources.list deleted file mode 100644 index dea0a3a5f..000000000 --- a/dockerfiles/ubuntu/sources.list +++ /dev/null @@ -1,17 +0,0 @@ -deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by software-properties -deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted -deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted multiverse universe #Added by software-properties -deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted -deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted multiverse universe #Added by software-properties -deb http://mirrors.aliyun.com/ubuntu/ xenial universe -deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe -deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse -deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse -deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse #Added by software-properties -deb http://archive.canonical.com/ubuntu xenial partner -deb-src http://archive.canonical.com/ubuntu xenial partner -deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted -deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted multiverse universe #Added by software-properties -deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe -deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse \ No newline at end of file diff --git a/storage/rocks_storage_test.go b/storage/rocks_storage_test.go index 0d09c3d00..283be16d2 100644 --- a/storage/rocks_storage_test.go +++ b/storage/rocks_storage_test.go @@ -17,7 +17,7 @@ func TestNewRocksStorage(t *testing.T) { want *RocksStorage wantErr bool }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 5f89b021a0dc99c336d5cdba926faa1f4ccc246e Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 23 Apr 2018 15:05:08 +0800 Subject: [PATCH 14/69] net: optimize network message compress. --- net/neb_message.go | 7 ------- net/stream.go | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/net/neb_message.go b/net/neb_message.go index 8d5c773b5..e94967639 100644 --- a/net/neb_message.go +++ b/net/neb_message.go @@ -24,7 +24,6 @@ import ( "hash/crc32" "time" - "github.com/golang/snappy" byteutils "github.com/nebulasio/go-nebulas/util/byteutils" "github.com/nebulasio/go-nebulas/util/logging" "github.com/sirupsen/logrus" @@ -174,12 +173,6 @@ func (message *NebMessage) Length() uint64 { // NewNebMessage new neb message func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { - if messageName != HELLO { - if (reserved[0] & 0x80) > 0 { - data = snappy.Encode(nil, data) - } - } - if len(data) > MaxNebMessageDataLength { logging.VLog().WithFields(logrus.Fields{ "messageName": messageName, diff --git a/net/stream.go b/net/stream.go index 8dea99b59..b7b15bdf5 100644 --- a/net/stream.go +++ b/net/stream.go @@ -178,9 +178,13 @@ func (s *Stream) SendMessage(messageName string, data []byte, priority int) erro var reserved []byte if s.compressFlag > 0 { reserved = CompressReserved + if messageName != HELLO { + data = snappy.Encode(nil, data) + } } else { reserved = DefaultReserved } + message, err := NewNebMessage(s.node.config.ChainID, reserved, 0, messageName, data) if err != nil { return err @@ -289,9 +293,13 @@ func (s *Stream) WriteMessage(messageName string, data []byte) error { var reserved []byte if s.compressFlag > 0 { reserved = CompressReserved + if messageName != HELLO { + data = snappy.Encode(nil, data) + } } else { reserved = DefaultReserved } + message, err := NewNebMessage(s.node.config.ChainID, reserved, 0, messageName, data) if err != nil { return err From e6f1bf299848d503a7c614fe00019d96ab796c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=9A=E4=B9=A6?= Date: Mon, 23 Apr 2018 15:20:35 +0800 Subject: [PATCH 15/69] Update neb.bash update branch in dockerfile. --- docker/scripts/neb.bash | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker/scripts/neb.bash b/docker/scripts/neb.bash index 700d206c1..893b2262f 100755 --- a/docker/scripts/neb.bash +++ b/docker/scripts/neb.bash @@ -1,8 +1,7 @@ #! /usr/bin/env bash declare NEBULAS_SRC=${GOPATH}/src/github.com/nebulasio/go-nebulas - -[ -z ${NEBULAS_BRANCH} ] && NEBULAS_BRANCH=master +declare NEBULAS_BRANCH=develop # git clone https://github.com/nebulasio/go-nebulas ${NEBULAS_SRC} echo NEBULAS_BRANCH=${NEBULAS_BRANCH} From 67600b0b6df18eb17b957ffb07513b5451403af2 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Tue, 24 Apr 2018 01:57:42 +0800 Subject: [PATCH 16/69] nebtestkit: add test cases for accept func --- .../contract/contract.feature.accept.test.js | 446 ++++++++++++++++++ nebtestkit/cases/testnet_config.js | 2 +- nebtestkit/package.json | 8 +- nf/nvm/test/contract_accept_func_standard.js | 107 +++++ nf/nvm/test/contract_accept_func_with_args.js | 30 ++ .../test/contract_accept_func_with_args_2.js | 56 +++ 6 files changed, 644 insertions(+), 5 deletions(-) create mode 100644 nebtestkit/cases/contract/contract.feature.accept.test.js create mode 100644 nf/nvm/test/contract_accept_func_standard.js create mode 100644 nf/nvm/test/contract_accept_func_with_args.js create mode 100644 nf/nvm/test/contract_accept_func_with_args_2.js diff --git a/nebtestkit/cases/contract/contract.feature.accept.test.js b/nebtestkit/cases/contract/contract.feature.accept.test.js new file mode 100644 index 000000000..0d0033bb4 --- /dev/null +++ b/nebtestkit/cases/contract/contract.feature.accept.test.js @@ -0,0 +1,446 @@ +'use strict'; + +var sleep = require('system-sleep'); +var FS = require('fs'); +var expect = require('chai').expect; +var BigNumber = require('bignumber.js'); +var HttpRequest = require('../../node-request'); +var TestnetConfig = require('../testnet_config'); +var Wallet = require('nebulas'); + +var Account = Wallet.Account; +var Transaction = Wallet.Transaction; +var env = process.argv.splice(2)[1]; +var testnetConfig = new TestnetConfig(env); +var originSource = testnetConfig.sourceAccount; +var ChainID = testnetConfig.ChainId; +var coinbase = testnetConfig.coinbase; +var neb = new Wallet.Neb(); +neb.setRequest(new HttpRequest(testnetConfig.apiEndPoint)); + + +var deploy, from, contractAddr, source, fromState, coinState; +var caseIndex = 0, lastnonce = 0; + +function prepareSource(done) { + console.log("originSource address: " + originSource.getAddressString()); + neb.api.getAccountState(originSource.getAddressString()).then(function (resp) { + console.log("prepare source account state:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + + source = Account.NewAccount(); + + var tx = new Transaction(ChainID, originSource, source, neb.nasToBasic(1000), nonce + 1, "1000000", "200000"); + tx.signTransaction(); + + console.log("cliam source tx:", tx.toString()); + + return neb.api.sendRawTransaction(tx.toProtoString()); + }).then(function (resp) { + console.log("send Raw Tx:" + JSON.stringify(resp)); + expect(resp).to.be.have.property('txhash'); + checkTransaction(resp.txhash, 0, function (receipt) { + console.log("tx receipt : " + JSON.stringify(receipt)); + expect(receipt).to.be.have.property('status').equal(1); + + done(); + }); + }).catch(function (err) { + done(err); + }); +} + +function cliamTokens(accounts, values, done) { + for (var i = 0; i < accounts.length; i++) { + console.log("acc:"+accounts[i].getAddressString()+" value:"+values[i]); + sendTransaction(source, accounts[i], values[i], ++lastnonce); + sleep(30); + } + checkCliamTokens(done); +} + + +function sendTransaction(from, address, value, nonce) { + var transaction = new Transaction(ChainID, from, address, value, nonce, "1000000", "200000"); + transaction.signTransaction(); + var rawTx = transaction.toProtoString(); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("send raw transaction resp:" + JSON.stringify(resp)); + }); +} + +function checkCliamTokens(done) { + var intervalAccount = setInterval(function () { + neb.api.getAccountState(source.getAddressString()).then(function (resp) { + // console.log("master accountState resp:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + console.log("check cliam tokens nonce:", lastnonce); + + if (lastnonce <= nonce){ + console.log("cliam tokens success"); + clearInterval(intervalAccount); + done(); + } + }); + }, 2000); +} + +function checkTransaction(txhash, retry, done){ + + var maxRetry = 45; + + // contract status and get contract_address + var interval = setTimeout(function () { + neb.api.getTransactionReceipt(txhash).then(function (resp) { + retry++; + + console.log("check transaction status:" + resp.status); + if(resp.status && resp.status === 1) { + // clearInterval(interval); + + if (resp.contract_address) { + console.log("deploy private key:" + deploy.getPrivateKeyString()); + console.log("deploy address:" + deploy.getAddressString()); + console.log("deploy contract address:" + resp.contract_address); + + contractAddr = resp.contract_address; + } + + done(resp); + } else if (resp.status && resp.status === 2) { + if (retry > maxRetry) { + console.log("check transaction time out"); + // clearInterval(interval); + done(resp); + } else { + checkTransaction(txhash, retry++, done); + } + } else { + // clearInterval(interval); + console.log("transaction execution failed"); + done(resp); + } + }).catch(function (err) { + retry++; + console.log("check transaction not found retry " + retry); + if (retry > maxRetry) { + console.log(JSON.stringify(err.error)); + // clearInterval(interval); + done(err); + } else { + checkTransaction(txhash, retry++, done); + } + }); + + }, 2000); +} + + +function deployContract(done, caseGroup) { + console.log("start deploying contract: " + caseGroup.groupname); + + neb.api.getAccountState(source.getAddressString()).then(function (resp) { + console.log("source account state:" + JSON.stringify(resp)); + + var accounts = new Array(); + var values = new Array(); + deploy = Account.NewAccount(); + accounts.push(deploy); + values.push(neb.nasToBasic(1)); + + from = Account.NewAccount(); + accounts.push(from); + var fromBalance = (typeof caseGroup.fromBalance === "undefined") ? neb.nasToBasic(1) : caseGroup.fromBalance; + values.push(fromBalance); + + cliamTokens(accounts, values, () => { + try { + var source = FS.readFileSync("../../../nf/nvm/test/" + caseGroup.filename, "utf-8"); + var contract = { + "source": source, + "sourceType": caseGroup.type, + "args": "" + }; + + var tx = new Transaction(testnetConfig.ChainId, deploy, deploy, "0", 1, "10000000", "2000000", contract); + tx.signTransaction(); + var rawTx = tx.toProtoString(); + + // console.log("contract:" + rawTx); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("deploy contract " + caseGroup.groupname + " return: " + JSON.stringify(resp)); + + checkTransaction(resp.txhash, 0, (ret) => { + if (ret.status && ret.status === 1) { + done(); + } else { + done(ret); + } + }); + }); + } catch (err) { + done(err); + }; + }); + + }).catch (err => done(err)); +} + +function testBinary(testInput, testExpect, done) { + var fromAcc = (typeof testInput.from === "undefined") ? from : testInput.from; + var to = (typeof testInput.to === "undefined") ? Account.fromAddress(contractAddr) : testInput.to; + + var fromBalanceBefore, toBalanceBefore; + + neb.api.getAccountState(to.getAddressString()).then(function (resp) { + console.log("contractAddr state before: " + JSON.stringify(resp)); + toBalanceBefore = resp.balance; + return neb.api.getAccountState(from.getAddressString()); + }).then(resp => { + fromState = resp; + fromBalanceBefore = resp.balanece; + console.log("from state before: ", JSON.stringify(resp)); + return neb.api.getAccountState(coinbase); + }).then(function (resp) { + console.log("coin state before: ", JSON.stringify(resp)); + coinState = resp; + + var tx = new Transaction(ChainID, fromAcc, to, testInput.value, parseInt(fromState.nonce) + testInput.nonce, testInput.gasPrice, testInput.gasLimit); + tx.from.address = fromAcc.address; + tx.to.address = to.address; + tx.gasPrice = new BigNumber(testInput.gasPrice); + tx.gasLimit = new BigNumber(testInput.gasLimit); + tx.signTransaction(); + console.log("binary tx raw before send: ", tx.toString()); + return neb.api.sendRawTransaction(tx.toProtoString()); + }).then(function (rawResp) { + console.log("send Raw Tx return:" + JSON.stringify(rawResp)); + expect(rawResp).to.be.have.property('txhash'); + + checkTransaction(rawResp.txhash, 0, function (receipt) { + console.log("tx receipt : " + JSON.stringify(receipt)); + try { + expect(receipt).to.not.be.a('undefined'); + if (true === testExpect.canExcuteTx) { + expect(receipt).to.be.have.property('status').equal(1); + } else { + expect(receipt).to.be.have.property('status').equal(0); + } + + neb.api.getAccountState(receipt.from).then(function (state) { + + console.log("from state after: " + JSON.stringify(state)); + // expect(state.balance).to.equal(testExpect.fromBalanceAfterTx); + return neb.api.getAccountState(contractAddr); + }).then(function (state) { + + console.log("contractAddr state after: " + JSON.stringify(state)); + var change = new BigNumber(state.balance).minus(new BigNumber(toBalanceBefore)); + // expect(change.toString()).to.equal(testExpect.toBalanceChange); + return neb.api.getAccountState(coinbase); + }).then(function (state) { + + console.log("get coinbase account state before tx:" + JSON.stringify(coinState)); + console.log("get coinbase account state after tx:" + JSON.stringify(state)); + var reward = new BigNumber(state.balance).sub(coinState.balance); + reward = reward.mod(new BigNumber(1.42694).mul(new BigNumber(10).pow(18))); + // The transaction should be only + // expect(reward.toString()).to.equal(testExpect.transferReward); + console.log("coinbase reward: " + reward.toString()); + if (receipt.gasUsed) { + var txCost = new BigNumber(receipt.gasUsed).mul(receipt.gasPrice).toString(10); + // expect(txCost).to.equal(testExpect.transferReward); + console.log("tx cost gas: " + txCost.toString()); + } + + return neb.api.getEventsByHash(receipt.hash); + }).then(function (events) { + for (var i = 0; i < events.events.length; i++) { + var event = events.events[i]; + //console.log("tx event:", JSON.stringify(event,null,'\t')); + console.log("tx event:", event.data); + if (event.topic === "chain.transactionResult") { + var result = JSON.parse(event.data); + expect(result.status).to.equal(testExpect.status); + + if (testExpect.hasOwnProperty("eventErr")){ + console.log("Event error checked."); + expect(result.error).to.equal(testExpect.eventErr); + } + } + } + done(); + }).catch(function (err) { + console.log("exe tx err:", err); + done(err); + }); + } catch (err) { + console.log("submit tx err:", err.message); + done(err); + } + }); + }).catch(function (err) { + console.log("send tx err"); + done(err); + }); +} + +var testCaseGroups = []; +var caseGroup = { + "filename": "contract_accept_func_with_args.js", + "type": "js", + "groupname": "case group 0: accept takes some args with execution error", + "groupIndex": 0, + + cases: [ + { + "name": "0-1. value = 0, invalid args", + "testInput": { + // from: from, + // to: contractAddr, + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000 + }, + "testExpect": { + canExcuteTx: false, + toBalanceChange: "0", + status: 0, + eventErr: "Binary: BigNumber Error: plus() not a number: undefined" + } + } + ] +}; +testCaseGroups.push(caseGroup); + +caseGroup = { + "filename": "contract_accept_func_with_args_2.js", + "type": "js", + "groupname": "case group 1: accept takes some args witchout execution error", + "groupIndex": 1, + + cases: [ + { + "name": "1-1. value = 0", + "testInput": { + // from: from, + // to: contractAddr, + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000 + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "0", + status: 1 + } + }, + + { + "name": "1-2. value > 0", + "testInput": { + // from: from, + // to: contractAddr, + value: "100", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000 + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "100", + status: 1 + } + } + ] +}; +testCaseGroups.push(caseGroup); + +caseGroup = { + "filename": "bank_vault_contract.js", + "type": "js", + "groupname": "case group 2: bankvault without accept func", + "groupIndex": 2, + + cases: [ + { + "name": "2-1. value > 0", + "testInput": { + // from: from, + // to: contractAddr, + value: "100", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000 + }, + "testExpect": { + canExcuteTx: false, + toBalanceChange: "0", + status: 0, + eventErr: "Binary: TypeError: Cannot read property 'apply' of undefined" + } + } + ] +}; +testCaseGroups.push(caseGroup); + +caseGroup = { + "filename": "contract_accept_func_standard.js", + "type": "js", + "groupname": "case group 3: bankvault with standard accept func", + "groupIndex": 3, + + cases: [ + { + "name": "3-1. value > 0", + "testInput": { + // from: from, + // to: contractAddr, + value: "100", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000 + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "100", + status: 1 + } + } + ] +}; +testCaseGroups.push(caseGroup); + +describe('accept func test', () => { + + before(done => prepareSource(done)); + + for (var i = 0; i < testCaseGroups.length; i++) { + + if (i != 3) {continue;} // selectively run tests + + let caseGroup = testCaseGroups[i]; + describe(caseGroup.groupname, () => { + before(done => { + deployContract(done, caseGroup); + caseIndex = 0; + }); + + + for (var j = 0; j < caseGroup.cases.length; j++) { + let testCase = caseGroup.cases[j]; + it(testCase.name, done => { + console.log("===> running case: " + JSON.stringify(testCase)); + testBinary(testCase.testInput, testCase.testExpect, done); + }); + } + + afterEach(() => { + caseIndex++; + console.log("case group: " + caseGroup.groupIndex + ", index: " + caseIndex); + }); + }); + } +}); \ No newline at end of file diff --git a/nebtestkit/cases/testnet_config.js b/nebtestkit/cases/testnet_config.js index 09fafb10e..f53559abc 100644 --- a/nebtestkit/cases/testnet_config.js +++ b/nebtestkit/cases/testnet_config.js @@ -59,7 +59,7 @@ var TestNet = function (env) { // throw new Error("invalid env (" + env + ")."); this.ChainId = 100; - this.sourceAccount = new Wallet.Account("d80f115bdbba5ef215707a8d7053c16f4e65588fd50b0f83369ad142b99891b5"); + this.sourceAccount = new Wallet.Account("1d3fe06a53919e728315e2ccca41d4aa5b190845a79007797517e62dbc0df454"); this.coinbase = "n1QZMXSZtW7BUerroSms4axNfyBGyFGkrh5"; this.apiEndPoint = "http://127.0.0.1:8685"; diff --git a/nebtestkit/package.json b/nebtestkit/package.json index 9059f495a..2a6c52174 100644 --- a/nebtestkit/package.json +++ b/nebtestkit/package.json @@ -18,13 +18,13 @@ "grpc": "^1.10.0", "lodash": "^4.17.5", "minimist": "^1.2.0", - "nebulas": "^0.3.7", + "nebulas": "^0.4.6", "node-schedule": "^1.3.0", "protobufjs": "^6.8.6", + "request": "^2.85.0", + "request-promise": "^4.2.2", "shelljs": "^0.7.8", "sync-request": "^4.1.0", - "system-sleep": "^1.3.6", - "request": "^2.85.0", - "request-promise": "^4.2.2" + "system-sleep": "^1.3.6" } } diff --git a/nf/nvm/test/contract_accept_func_standard.js b/nf/nvm/test/contract_accept_func_standard.js new file mode 100644 index 000000000..c5ca72a81 --- /dev/null +++ b/nf/nvm/test/contract_accept_func_standard.js @@ -0,0 +1,107 @@ + +"use strict"; + +var DepositeContent = function (text) { + if (text) { + var o = JSON.parse(text); + this.balance = new BigNumber(o.balance); + this.expiryHeight = new BigNumber(o.expiryHeight); + } else { + this.balance = new BigNumber(0); + this.expiryHeight = new BigNumber(0); + } +}; + +DepositeContent.prototype = { + toString: function () { + return JSON.stringify(this); + } +}; + +var BankVaultContract = function () { + LocalContractStorage.defineMapProperty(this, "bankVault", { + parse: function (text) { + return new DepositeContent(text); + }, + stringify: function (o) { + return o.toString(); + } + }); +}; + +// save value to contract, only after height of block, users can takeout +BankVaultContract.prototype = { + init: function () { + //TODO: + }, + + // enables accepting NAS via 'binary' + accept: function() {}, + + save: function (height) { + var from = Blockchain.transaction.from; + var value = Blockchain.transaction.value; + var bk_height = new BigNumber(Blockchain.block.height); + + var orig_deposit = this.bankVault.get(from); + if (orig_deposit) { + value = value.plus(orig_deposit.balance); + } + + var deposit = new DepositeContent(); + deposit.balance = value; + deposit.expiryHeight = bk_height.plus(height); + + this.bankVault.put(from, deposit); + }, + + takeout: function (value) { + var from = Blockchain.transaction.from; + var bk_height = new BigNumber(Blockchain.block.height); + var amount = new BigNumber(value); + + var deposit = this.bankVault.get(from); + if (!deposit) { + throw new Error("No deposit before."); + } + + if (bk_height.lt(deposit.expiryHeight)) { + throw new Error("Can not takeout before expiryHeight."); + } + + if (amount.gt(deposit.balance)) { + throw new Error("Insufficient balance."); + } + + var result = Blockchain.transfer(from, amount); + if (!result) { + throw new Error("transfer failed."); + } + Event.Trigger("BankVault", { + Transfer: { + from: Blockchain.transaction.to, + to: from, + value: amount.toString() + } + }); + + deposit.balance = deposit.balance.sub(amount); + this.bankVault.put(from, deposit); + }, + + balanceOf: function () { + var from = Blockchain.transaction.from; + return this.bankVault.get(from); + }, + + verifyAddress: function (address) { + // 1-valid, 0-invalid + var result = Blockchain.verifyAddress(address); + return { + valid: result == 0 ? false : true + }; + } +}; + +module.exports = BankVaultContract; + diff --git a/nf/nvm/test/contract_accept_func_with_args.js b/nf/nvm/test/contract_accept_func_with_args.js new file mode 100644 index 000000000..7ab08cd57 --- /dev/null +++ b/nf/nvm/test/contract_accept_func_with_args.js @@ -0,0 +1,30 @@ + +"use strict"; + +// save value to contract, only after height of block, users can takeout +BankVaultContract.prototype = { + init: function () { + //TODO: + }, + + // enables accepting NAS via 'binary' + accept: function (height) { + var from = Blockchain.transaction.from; + var value = Blockchain.transaction.value; + var bk_height = new BigNumber(Blockchain.block.height); + + var orig_deposit = this.bankVault.get(from); + if (orig_deposit) { + value = value.plus(orig_deposit.balance); + } + + var deposit = new DepositeContent(); + deposit.balance = value; + deposit.expiryHeight = bk_height.plus(height); + + this.bankVault.put(from, deposit); + } +}; + +module.exports = BankVaultContract; + diff --git a/nf/nvm/test/contract_accept_func_with_args_2.js b/nf/nvm/test/contract_accept_func_with_args_2.js new file mode 100644 index 000000000..83c2026c5 --- /dev/null +++ b/nf/nvm/test/contract_accept_func_with_args_2.js @@ -0,0 +1,56 @@ + +"use strict"; + +var DepositeContent = function (text) { + if (text) { + var o = JSON.parse(text); + this.balance = new BigNumber(o.balance); + this.expiryHeight = new BigNumber(o.expiryHeight); + } else { + this.balance = new BigNumber(0); + this.expiryHeight = new BigNumber(0); + } +}; + +DepositeContent.prototype = { + toString: function () { + return JSON.stringify(this); + } +}; + +var BankVaultContract = function () { + LocalContractStorage.defineMapProperty(this, "bankVault", { + parse: function (text) { + return new DepositeContent(text); + }, + stringify: function (o) { + return o.toString(); + } + }); +}; + +// save value to contract, only after height of block, users can takeout +BankVaultContract.prototype = { + init: function () { + //TODO: + }, + + // enables accepting NAS via 'binary' + accept: function (height) { + var from = Blockchain.transaction.from; + var value = Blockchain.transaction.value; + var bk_height = new BigNumber(Blockchain.block.height); + + console.log("accept height: " + height); + + return { + height: height, + from: from, + value: value, + bk_height: bk_height + }; + } +}; + +module.exports = BankVaultContract; + From 9bb937dd4996f364008e603e4de8f5c809ea683c Mon Sep 17 00:00:00 2001 From: fengzi Date: Tue, 24 Apr 2018 19:38:21 +0800 Subject: [PATCH 17/69] rpc: remove verify send raw tranaction --- rpc/api_service.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/rpc/api_service.go b/rpc/api_service.go index 23631a782..fd83dd22e 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -192,11 +192,6 @@ func handleTransactionResponse(neb core.Neblet, tx *core.Transaction) (resp *rpc } }() - err = tx.VerifyIntegrity(neb.BlockChain().ChainID()) - if err != nil { - return nil, err - } - tailBlock := neb.BlockChain().TailBlock() acc, err := tailBlock.GetAccount(tx.From().Bytes()) if err != nil { From cb7d471a7002dd774df1b5cfb79c752d02810439 Mon Sep 17 00:00:00 2001 From: fengzi Date: Tue, 24 Apr 2018 19:40:32 +0800 Subject: [PATCH 18/69] rpc: remove verify send raw transaction --- rpc/api_service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/api_service.go b/rpc/api_service.go index 291eb3355..fd83dd22e 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -147,7 +147,7 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T ) if reqTx.Contract != nil { - if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 && fromAddr.Equals(toAddr) { + if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 { // TODO: reqTx.DeployContract, reqTx.CallContract payloadType = core.TxPayloadDeployType payloadObj, err := core.NewDeployPayload(reqTx.Contract.Source, reqTx.Contract.SourceType, reqTx.Contract.Args) if err != nil { @@ -156,7 +156,7 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T if payload, err = payloadObj.ToBytes(); err != nil { return nil, err } - } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 && toAddr.Type() == core.ContractAddress { + } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 { payloadType = core.TxPayloadCallType callpayload, err := core.NewCallPayload(reqTx.Contract.Function, reqTx.Contract.Args) if err != nil { From eadcbddb5af03fab4e6aedcf2b85b40aeff7dc34 Mon Sep 17 00:00:00 2001 From: fengzi Date: Tue, 24 Apr 2018 19:44:19 +0800 Subject: [PATCH 19/69] rpc:api_service.go update parseTransaction func --- rpc/api_service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/api_service.go b/rpc/api_service.go index fd83dd22e..291eb3355 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -147,7 +147,7 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T ) if reqTx.Contract != nil { - if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 { // TODO: reqTx.DeployContract, reqTx.CallContract + if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 && fromAddr.Equals(toAddr) { payloadType = core.TxPayloadDeployType payloadObj, err := core.NewDeployPayload(reqTx.Contract.Source, reqTx.Contract.SourceType, reqTx.Contract.Args) if err != nil { @@ -156,7 +156,7 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T if payload, err = payloadObj.ToBytes(); err != nil { return nil, err } - } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 { + } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 && toAddr.Type() == core.ContractAddress { payloadType = core.TxPayloadCallType callpayload, err := core.NewCallPayload(reqTx.Contract.Function, reqTx.Contract.Args) if err != nil { From 80a8fe000a3c0ee9b4ae9cac8cf2e35d272551b2 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Wed, 25 Apr 2018 13:49:26 +0800 Subject: [PATCH 20/69] nvm: add 'Date' & testcase --- .../contract/contract.feature.accept.test.js | 2 +- .../contract/contract.feature.date.test.js | 373 ++++++++++++++++++ nf/nvm/test/contract_date_and_random.js | 51 +++ nf/nvm/v8/lib/execution_env.js | 38 +- 4 files changed, 460 insertions(+), 4 deletions(-) create mode 100644 nebtestkit/cases/contract/contract.feature.date.test.js create mode 100644 nf/nvm/test/contract_date_and_random.js diff --git a/nebtestkit/cases/contract/contract.feature.accept.test.js b/nebtestkit/cases/contract/contract.feature.accept.test.js index 0d0033bb4..5c8fd9e47 100644 --- a/nebtestkit/cases/contract/contract.feature.accept.test.js +++ b/nebtestkit/cases/contract/contract.feature.accept.test.js @@ -419,7 +419,7 @@ describe('accept func test', () => { for (var i = 0; i < testCaseGroups.length; i++) { - if (i != 3) {continue;} // selectively run tests + // if (i != 3) {continue;} // selectively run tests let caseGroup = testCaseGroups[i]; describe(caseGroup.groupname, () => { diff --git a/nebtestkit/cases/contract/contract.feature.date.test.js b/nebtestkit/cases/contract/contract.feature.date.test.js new file mode 100644 index 000000000..fb618c0ee --- /dev/null +++ b/nebtestkit/cases/contract/contract.feature.date.test.js @@ -0,0 +1,373 @@ +'use strict'; + +var sleep = require('system-sleep'); +var FS = require('fs'); +var expect = require('chai').expect; +var BigNumber = require('bignumber.js'); +var HttpRequest = require('../../node-request'); +var TestnetConfig = require('../testnet_config'); +var Wallet = require('nebulas'); + +var Account = Wallet.Account; +var Transaction = Wallet.Transaction; +var env = process.argv.splice(2)[1]; +var testnetConfig = new TestnetConfig(env); +var originSource = testnetConfig.sourceAccount; +var ChainID = testnetConfig.ChainId; +var coinbase = testnetConfig.coinbase; +var neb = new Wallet.Neb(); +neb.setRequest(new HttpRequest(testnetConfig.apiEndPoint)); + + +var deploy, from, contractAddr, source, fromState, coinState; +var caseIndex = 0, lastnonce = 0; + +function prepareSource(done) { + console.log("originSource address: " + originSource.getAddressString()); + neb.api.getAccountState(originSource.getAddressString()).then(function (resp) { + console.log("prepare source account state:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + + source = Account.NewAccount(); + + var tx = new Transaction(ChainID, originSource, source, neb.nasToBasic(1000), nonce + 1, "1000000", "200000"); + tx.signTransaction(); + + console.log("cliam source tx:", tx.toString()); + + return neb.api.sendRawTransaction(tx.toProtoString()); + }).then(function (resp) { + console.log("send Raw Tx:" + JSON.stringify(resp)); + expect(resp).to.be.have.property('txhash'); + checkTransaction(resp.txhash, 0, function (receipt) { + console.log("tx receipt : " + JSON.stringify(receipt)); + expect(receipt).to.be.have.property('status').equal(1); + + done(); + }); + }).catch(function (err) { + done(err); + }); +} + +function cliamTokens(accounts, values, done) { + for (var i = 0; i < accounts.length; i++) { + console.log("acc:"+accounts[i].getAddressString()+" value:"+values[i]); + sendTransaction(source, accounts[i], values[i], ++lastnonce); + sleep(30); + } + checkCliamTokens(done); +} + + +function sendTransaction(from, address, value, nonce) { + var transaction = new Transaction(ChainID, from, address, value, nonce, "1000000", "200000"); + transaction.signTransaction(); + var rawTx = transaction.toProtoString(); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("send raw transaction resp:" + JSON.stringify(resp)); + }); +} + +function checkCliamTokens(done) { + var intervalAccount = setInterval(function () { + neb.api.getAccountState(source.getAddressString()).then(function (resp) { + // console.log("master accountState resp:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + console.log("check cliam tokens nonce:", lastnonce); + + if (lastnonce <= nonce){ + console.log("cliam tokens success"); + clearInterval(intervalAccount); + done(); + } + }); + }, 2000); +} + +function checkTransaction(txhash, retry, done){ + + var maxRetry = 45; + + // contract status and get contract_address + var interval = setTimeout(function () { + neb.api.getTransactionReceipt(txhash).then(function (resp) { + retry++; + + console.log("check transaction status:" + resp.status); + if(resp.status && resp.status === 1) { + // clearInterval(interval); + + if (resp.contract_address) { + console.log("deploy private key:" + deploy.getPrivateKeyString()); + console.log("deploy address:" + deploy.getAddressString()); + console.log("deploy contract address:" + resp.contract_address); + + contractAddr = resp.contract_address; + } + + done(resp); + } else if (resp.status && resp.status === 2) { + if (retry > maxRetry) { + console.log("check transaction time out"); + // clearInterval(interval); + done(resp); + } else { + checkTransaction(txhash, retry++, done); + } + } else { + // clearInterval(interval); + console.log("transaction execution failed"); + done(resp); + } + }).catch(function (err) { + retry++; + console.log("check transaction not found retry " + retry); + if (retry > maxRetry) { + console.log(JSON.stringify(err.error)); + // clearInterval(interval); + done(err); + } else { + checkTransaction(txhash, retry++, done); + } + }); + + }, 2000); +} + + +function deployContract(done, caseGroup) { + console.log("start deploying contract: " + caseGroup.groupname); + + neb.api.getAccountState(source.getAddressString()).then(function (resp) { + console.log("source account state:" + JSON.stringify(resp)); + + var accounts = new Array(); + var values = new Array(); + deploy = Account.NewAccount(); + accounts.push(deploy); + values.push(neb.nasToBasic(1)); + + from = Account.NewAccount(); + accounts.push(from); + var fromBalance = (typeof caseGroup.fromBalance === "undefined") ? neb.nasToBasic(1) : caseGroup.fromBalance; + values.push(fromBalance); + + cliamTokens(accounts, values, () => { + try { + var source = FS.readFileSync("../../../nf/nvm/test/" + caseGroup.filename, "utf-8"); + var contract = { + "source": source, + "sourceType": caseGroup.type, + "args": "" + }; + + var tx = new Transaction(testnetConfig.ChainId, deploy, deploy, "0", 1, "10000000", "2000000", contract); + tx.signTransaction(); + var rawTx = tx.toProtoString(); + + // console.log("contract:" + rawTx); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("deploy contract " + caseGroup.groupname + " return: " + JSON.stringify(resp)); + + checkTransaction(resp.txhash, 0, (ret) => { + if (ret.status && ret.status === 1) { + done(); + } else { + done(ret); + } + }); + }); + } catch (err) { + done(err); + }; + }); + + }).catch (err => done(err)); +} + +function runTest(testInput, testExpect, done) { + var fromAcc = (typeof testInput.from === "undefined") ? from : testInput.from; + var to = (typeof testInput.to === "undefined") ? Account.fromAddress(contractAddr) : testInput.to; + + var fromBalanceBefore, toBalanceBefore; + + neb.api.getAccountState(to.getAddressString()).then(function (resp) { + console.log("contractAddr state before: " + JSON.stringify(resp)); + toBalanceBefore = resp.balance; + return neb.api.getAccountState(from.getAddressString()); + }).then(resp => { + fromState = resp; + fromBalanceBefore = resp.balanece; + console.log("from state before: ", JSON.stringify(resp)); + return neb.api.getAccountState(coinbase); + }).then(function (resp) { + console.log("coin state before: ", JSON.stringify(resp)); + coinState = resp; + + var tx = new Transaction(ChainID, fromAcc, to, testInput.value, parseInt(fromState.nonce) + testInput.nonce, testInput.gasPrice, testInput.gasLimit, testInput.contract); + tx.from.address = fromAcc.address; + tx.to.address = to.address; + tx.gasPrice = new BigNumber(testInput.gasPrice); + tx.gasLimit = new BigNumber(testInput.gasLimit); + tx.signTransaction(); + console.log("binary tx raw before send: ", tx.toString()); + return neb.api.sendRawTransaction(tx.toProtoString()); + }).then(function (rawResp) { + console.log("send Raw Tx return:" + JSON.stringify(rawResp)); + expect(rawResp).to.be.have.property('txhash'); + + checkTransaction(rawResp.txhash, 0, function (receipt) { + console.log("tx receipt : " + JSON.stringify(receipt)); + try { + expect(receipt).to.not.be.a('undefined'); + if (true === testExpect.canExcuteTx) { + expect(receipt).to.be.have.property('status').equal(1); + } else { + expect(receipt).to.be.have.property('status').equal(0); + } + + neb.api.getAccountState(receipt.from).then(function (state) { + + console.log("from state after: " + JSON.stringify(state)); + // expect(state.balance).to.equal(testExpect.fromBalanceAfterTx); + return neb.api.getAccountState(contractAddr); + }).then(function (state) { + + console.log("contractAddr state after: " + JSON.stringify(state)); + var change = new BigNumber(state.balance).minus(new BigNumber(toBalanceBefore)); + // expect(change.toString()).to.equal(testExpect.toBalanceChange); + return neb.api.getAccountState(coinbase); + }).then(function (state) { + + console.log("get coinbase account state before tx:" + JSON.stringify(coinState)); + console.log("get coinbase account state after tx:" + JSON.stringify(state)); + var reward = new BigNumber(state.balance).sub(coinState.balance); + reward = reward.mod(new BigNumber(1.42694).mul(new BigNumber(10).pow(18))); + // The transaction should be only + // expect(reward.toString()).to.equal(testExpect.transferReward); + console.log("coinbase reward: " + reward.toString()); + if (receipt.gasUsed) { + var txCost = new BigNumber(receipt.gasUsed).mul(receipt.gasPrice).toString(10); + // expect(txCost).to.equal(testExpect.transferReward); + console.log("tx cost gas: " + txCost.toString()); + } + + return neb.api.getEventsByHash(receipt.hash); + }).then(function (events) { + for (var i = 0; i < events.events.length; i++) { + var event = events.events[i]; + //console.log("tx event:", JSON.stringify(event,null,'\t')); + console.log("tx event:", event.data); + if (event.topic === "chain.transactionResult") { + var result = JSON.parse(event.data); + expect(result.status).to.equal(testExpect.status); + + if (testExpect.hasOwnProperty("eventErr")){ + console.log("Event error checked."); + expect(result.error).to.equal(testExpect.eventErr); + } + } + if (event.topic === "chain.contract.Date") { + var result = JSON.parse(event.data); + expect(result.data.equalBlockTime).to.equal(testExpect.equalBlockTime); + console.log("check equalBlockTime success"); + } + } + done(); + }).catch(function (err) { + console.log("exe tx err:", err); + done(err); + }); + } catch (err) { + console.log("submit tx err:", err.message); + done(err); + } + }); + }).catch(function (err) { + console.log("send tx err"); + done(err); + }); +} + +var testCaseGroups = []; +var caseGroup = { + "filename": "contract_date_and_random.js", + "type": "js", + "groupname": "case group 0: Date", + "groupIndex": 0, + + cases: [ + { + "name": "0-1. test 'new Date()'", + "testInput": { + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000, + contract: { + function: "testDate", + args: "" + } + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "0", + status: 1, + equalBlockTime: true + } + }, + { + "name": "0-2. test 'new Date('1995-12-17T03:24:00')'", + "testInput": { + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000, + contract: { + function: "testDate", + args: "[\"1995-12-17T03:24:00\"]" + } + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "0", + status: 1, + equalBlockTime: false + } + } + ] +}; +testCaseGroups.push(caseGroup); + +describe('Contract Date test', () => { + + before(done => prepareSource(done)); + + for (var i = 0; i < testCaseGroups.length; i++) { + + // if (i != 3) {continue;} // selectively run tests + + let caseGroup = testCaseGroups[i]; + describe(caseGroup.groupname, () => { + before(done => { + deployContract(done, caseGroup); + caseIndex = 0; + }); + + + for (var j = 0; j < caseGroup.cases.length; j++) { + let testCase = caseGroup.cases[j]; + it(testCase.name, done => { + console.log("===> running case: " + JSON.stringify(testCase)); + runTest(testCase.testInput, testCase.testExpect, done); + }); + } + + afterEach(() => { + caseIndex++; + console.log("case group: " + caseGroup.groupIndex + ", index: " + caseIndex); + }); + }); + } +}); \ No newline at end of file diff --git a/nf/nvm/test/contract_date_and_random.js b/nf/nvm/test/contract_date_and_random.js new file mode 100644 index 000000000..50688924c --- /dev/null +++ b/nf/nvm/test/contract_date_and_random.js @@ -0,0 +1,51 @@ +"use strict"; + +var Contract = function() { + +}; + +Contract.prototype = { + init: function(){}, + accept: function(){}, + + testDate: function() { + + Event.Trigger("testDate.arguments", { + args: arguments + }); + + var date = arguments.length == 0 ? new Date() : new Date(arguments[0]); + var data = { + now: Date.now(), + height: Blockchain.block.height, + timestamp: Blockchain.block.timestamp, + valueOf: date.valueOf(), + date_toString: date.toString(), + date_getTime: date.getTime(), + date_getFullYear: date.getFullYear(), + equalBlockTime: Blockchain.block.timestamp == (date.getTime() / 1000) + }; + Event.Trigger("Date", { + data: data + }); + + date.setFullYear(2000); + Event.Trigger("Date.modi", { + data: { + valueOf: date.valueOf(), + date_toString: date.toString(), + date_getTime: date.getTime(), + date_getFullYear: date.getFullYear(), + equalBlockTime: Blockchain.block.timestamp == (date.getTime() / 1000) + } + }); + + return data; + }, + + testRandom: function() { + // TODO + } +}; + +module.exports = Contract; \ No newline at end of file diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index d9fbf5ce5..ba836cd75 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -16,9 +16,6 @@ // along with the go-nebulas library. If not, see . // -const Date = function () { - throw new Error("Date is not allowed in nvm."); -}; Math.random = function () { throw new Error("Math.random func is not allowed in nvm."); @@ -116,3 +113,38 @@ const GlobalContractStorage = ContractStorage.gcs; const BigNumber = require('bignumber.js'); const Blockchain = require('blockchain.js'); const Event = require('event.js'); + +var Date = (function(Date) { + function NebDate() { + if (!Blockchain) { + throw new Error("'Blockchain' is not defined."); + } + if (!Blockchain.block) { + throw new Error("'Blockchain.block' is not defined."); + } + + var date = new(Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))))(); + if (arguments.length == 0) { + // unit of timestamp is second + date.setTime(Blockchain.block.timestamp * 1000); + } + Object.setPrototypeOf(date, NebDate.prototype); + return date; + } + NebDate.now = function() { + return new NebDate().getTime(); + } + NebDate.UTC = function() { + return Date.UTC.apply(null, arguments); + } + NebDate.parse = function(dateString) { + return Date.parse(dateString); + } + NebDate.prototype = new Proxy(NebDate.prototype, { + getPrototypeOf: function(target) { + throw new Error("Not supported method!"); + }, + }); + Object.setPrototypeOf(NebDate.prototype, Date.prototype); + return NebDate; +})(Date); \ No newline at end of file From 7d0caee5509db6d5946f8ad3ac9ac29219737fbb Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Wed, 25 Apr 2018 17:04:41 +0800 Subject: [PATCH 21/69] nvm: modify testcase --- nf/nvm/engine_v8_test.go | 2 +- nf/nvm/test/test_date.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/nf/nvm/engine_v8_test.go b/nf/nvm/engine_v8_test.go index d96381ca4..2d52f5eaf 100644 --- a/nf/nvm/engine_v8_test.go +++ b/nf/nvm/engine_v8_test.go @@ -123,7 +123,7 @@ func TestRunScriptSource(t *testing.T) { {"test/test_storage_class.js", nil, "\"\""}, {"test/test_storage.js", nil, "\"\""}, {"test/test_eval.js", core.ErrExecutionFailed, "EvalError: Code generation from strings disallowed for this context"}, - {"test/test_date.js", core.ErrExecutionFailed, "TypeError: Date.now is not a function"}, + {"test/test_date.js", nil, "\"\""}, {"test/test_bignumber_random.js", core.ErrExecutionFailed, "Error: BigNumber.random is not allowed in nvm."}, {"test/test_random.js", core.ErrExecutionFailed, "Error: Math.random func is not allowed in nvm."}, } diff --git a/nf/nvm/test/test_date.js b/nf/nvm/test/test_date.js index 9572371a4..98fc4baad 100644 --- a/nf/nvm/test/test_date.js +++ b/nf/nvm/test/test_date.js @@ -16,6 +16,9 @@ // along with the go-nebulas library. If not, see . // +Blockchain.block = { + timestamp: 10000000000 +}; console.log(Date.now()); console.log(Date.UTC()); From badf187f9224e51fa9aa7500cb93faf2082d8499 Mon Sep 17 00:00:00 2001 From: Roy Shang Date: Wed, 25 Apr 2018 18:05:06 +0800 Subject: [PATCH 22/69] nf/nvm: engine_v8_test.go. add inner test case framework. --- nf/nvm/engine_v8_test.go | 346 +++++++++++++++++++++++++++++++++++++++ nf/nvm/keydir | 1 + 2 files changed, 347 insertions(+) create mode 120000 nf/nvm/keydir diff --git a/nf/nvm/engine_v8_test.go b/nf/nvm/engine_v8_test.go index 2d52f5eaf..9b4d56a7f 100644 --- a/nf/nvm/engine_v8_test.go +++ b/nf/nvm/engine_v8_test.go @@ -28,8 +28,15 @@ import ( "strings" "sync" "testing" + "time" + + "github.com/gogo/protobuf/proto" + "github.com/nebulasio/go-nebulas/account" + "github.com/nebulasio/go-nebulas/net" "github.com/nebulasio/go-nebulas/consensus/dpos" + "github.com/nebulasio/go-nebulas/core/pb" + "github.com/nebulasio/go-nebulas/neblet/pb" "encoding/json" @@ -1229,3 +1236,342 @@ func TestRequireModule(t *testing.T) { }) } } + +type Neb struct { + config *nebletpb.Config + chain *core.BlockChain + ns net.Service + am *account.Manager + genesis *corepb.Genesis + storage storage.Storage + consensus core.Consensus + emitter *core.EventEmitter + nvm core.NVM +} + +func mockNeb(t *testing.T) *Neb { + // storage, _ := storage.NewDiskStorage("test.db") + // storage, err := storage.NewRocksStorage("rocks.db") + // assert.Nil(t, err) + storage, _ := storage.NewMemoryStorage() + eventEmitter := core.NewEventEmitter(1024) + genesisConf := MockGenesisConf() + consensus := dpos.NewDpos() + nvm := NewNebulasVM() + neb := &Neb{ + genesis: genesisConf, + storage: storage, + emitter: eventEmitter, + consensus: consensus, + nvm: nvm, + config: &nebletpb.Config{ + Chain: &nebletpb.ChainConfig{ + ChainId: genesisConf.Meta.ChainId, + Keydir: "keydir", + StartMine: true, + Coinbase: "n1dYu2BXgV3xgUh8LhZu8QDDNr15tz4hVDv", + Miner: "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE", + Passphrase: "passphrase", + }, + }, + ns: mockNetService{}, + } + + am, _ := account.NewManager(neb) + neb.am = am + + chain, err := core.NewBlockChain(neb) + assert.Nil(t, err) + neb.chain = chain + assert.Nil(t, consensus.Setup(neb)) + assert.Nil(t, chain.Setup(neb)) + + var ns mockNetService + neb.ns = ns + neb.chain.BlockPool().RegisterInNetwork(ns) + + eventEmitter.Start() + return neb +} + +func (n *Neb) Config() *nebletpb.Config { + return n.config +} + +func (n *Neb) BlockChain() *core.BlockChain { + return n.chain +} + +func (n *Neb) NetService() net.Service { + return n.ns +} + +func (n *Neb) IsActiveSyncing() bool { + return true +} + +func (n *Neb) AccountManager() core.AccountManager { + return n.am +} + +func (n *Neb) Genesis() *corepb.Genesis { + return n.genesis +} + +func (n *Neb) Storage() storage.Storage { + return n.storage +} + +func (n *Neb) EventEmitter() *core.EventEmitter { + return n.emitter +} + +func (n *Neb) Consensus() core.Consensus { + return n.consensus +} + +func (n *Neb) Nvm() core.NVM { + return n.nvm +} + +func (n *Neb) StartActiveSync() {} + +func (n *Neb) StartPprof(string) error { return nil } + +func (n *Neb) SetGenesis(genesis *corepb.Genesis) { + n.genesis = genesis +} + +var ( + DefaultOpenDynasty = []string{ + "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE", + "n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s", + "n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so", + "n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf", + "n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS", + "n1LmP9K8pFF33fgdgHZonFEMsqZinJ4EUqk", + "n1MNXBKm6uJ5d76nJTdRvkPNVq85n6CnXAi", + "n1NrMKTYESZRCwPFDLFKiKREzZKaN1nhQvz", + "n1NwoSCDFwFL2981k6j9DPooigW33hjAgTa", + "n1PfACnkcfJoNm1Pbuz55pQCwueW1BYs83m", + "n1Q8mxXp4PtHaXtebhY12BnHEwu4mryEkXH", + "n1RYagU8n3JSuV4R7q4Qs5gQJ3pEmrZd6cJ", + "n1SAQy3ix1pZj8MPzNeVqpAmu1nCVqb5w8c", + "n1SHufJdxt2vRWGKAxwPETYfEq3MCQXnEXE", + "n1SSda41zGr9FKF5DJNE2ryY1ToNrndMauN", + "n1TmQtaCn3PNpk4f4ycwrBxCZFSVKvwBtzc", + "n1UM7z6MqnGyKEPvUpwrfxZpM1eB7UpzmLJ", + "n1UnCsJZjQiKyQiPBr7qG27exqCLuWUf1d7", + "n1XkoVVjswb5Gek3rRufqjKNpwrDdsnQ7Hq", + "n1cYKNHTeVW9v1NQRWuhZZn9ETbqAYozckh", + "n1dYu2BXgV3xgUh8LhZu8QDDNr15tz4hVDv", + } +) + +// MockGenesisConf return mock genesis conf +func MockGenesisConf() *corepb.Genesis { + dynasty := []string{} + for _, v := range DefaultOpenDynasty { + dynasty = append(dynasty, v) + } + return &corepb.Genesis{ + Meta: &corepb.GenesisMeta{ChainId: 0}, + Consensus: &corepb.GenesisConsensus{ + Dpos: &corepb.GenesisConsensusDpos{ + Dynasty: dynasty, + }, + }, + TokenDistribution: []*corepb.GenesisTokenDistribution{ + &corepb.GenesisTokenDistribution{ + Address: "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE", + Value: "5000000000000000000000000", + }, + &corepb.GenesisTokenDistribution{ + Address: "n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s", + Value: "5000000000000000000000000", + }, + &corepb.GenesisTokenDistribution{ + Address: "n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so", + Value: "5000000000000000000000000", + }, + &corepb.GenesisTokenDistribution{ + Address: "n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf", + Value: "5000000000000000000000000", + }, + &corepb.GenesisTokenDistribution{ + Address: "n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS", + Value: "5000000000000000000000000", + }, + &corepb.GenesisTokenDistribution{ + Address: "n1LmP9K8pFF33fgdgHZonFEMsqZinJ4EUqk", + Value: "5000000000000000000000000", + }, + }, + } +} + +var ( + received = []byte{} +) + +type mockNetService struct{} + +func (n mockNetService) Start() error { return nil } +func (n mockNetService) Stop() {} + +func (n mockNetService) Node() *net.Node { return nil } + +func (n mockNetService) Sync(net.Serializable) error { return nil } + +func (n mockNetService) Register(...*net.Subscriber) {} +func (n mockNetService) Deregister(...*net.Subscriber) {} + +func (n mockNetService) Broadcast(name string, msg net.Serializable, priority int) { + pb, _ := msg.ToProto() + bytes, _ := proto.Marshal(pb) + received = bytes +} +func (n mockNetService) Relay(name string, msg net.Serializable, priority int) { + pb, _ := msg.ToProto() + bytes, _ := proto.Marshal(pb) + received = bytes +} +func (n mockNetService) SendMsg(name string, msg []byte, target string, priority int) error { + received = msg + return nil +} + +func (n mockNetService) SendMessageToPeers(messageName string, data []byte, priority int, filter net.PeerFilterAlgorithm) []string { + return make([]string, 0) +} +func (n mockNetService) SendMessageToPeer(messageName string, data []byte, priority int, peerID string) error { + return nil +} + +func (n mockNetService) ClosePeer(peerID string, reason error) {} + +func (n mockNetService) BroadcastNetworkID([]byte) {} + +type contract struct { + contractPath string + sourceType string + initArgs string +} + +type call struct { + function string + args string +} + +func TestInnerTransactions(t *testing.T) { + tests := []struct { + name string + contracts []contract + call call + }{ + { + "deploy test_require_module.js", + []contract{ + contract{ + "./test/bank_vault_contract.js", + "js", + "", + }, + contract{ + "./test/bank_vault_contract.js", + "js", + "", + }, + }, + call{ + "save", + "[1]", + }, + }, + } + + for _, tt := range tests { + neb := mockNeb(t) + tail := neb.chain.TailBlock() + manager, err := account.NewManager(neb) + assert.Nil(t, err) + + a, _ := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE") + assert.Nil(t, manager.Unlock(a, []byte("passphrase"), keystore.YearUnlockDuration)) + b, _ := core.AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") + assert.Nil(t, manager.Unlock(b, []byte("passphrase"), keystore.YearUnlockDuration)) + c, _ := core.AddressParse("n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so") + assert.Nil(t, manager.Unlock(c, []byte("passphrase"), keystore.YearUnlockDuration)) + + elapsedSecond := dpos.BlockIntervalInMs / dpos.SecondInMs + consensusState, err := tail.WorldState().NextConsensusState(elapsedSecond) + assert.Nil(t, err) + block, err := core.NewBlock(neb.chain.ChainID(), b, tail) + assert.Nil(t, err) + block.WorldState().SetConsensusState(consensusState) + block.SetTimestamp(consensusState.TimeStamp()) + + contractsAddr := []string{} + + t.Run(tt.name, func(t *testing.T) { + for k, v := range tt.contracts { + data, err := ioutil.ReadFile(v.contractPath) + assert.Nil(t, err, "contract path read error") + source := string(data) + sourceType := "js" + argsDeploy := "" + deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) + payloadDeploy, _ := deploy.ToBytes() + + value, _ := util.NewUint128FromInt(0) + gasLimit, _ := util.NewUint128FromInt(200000) + txDeploy, err := core.NewTransaction(neb.chain.ChainID(), a, a, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) + assert.Nil(t, err) + assert.Nil(t, manager.SignTransaction(a, txDeploy)) + assert.Nil(t, neb.chain.TransactionPool().Push(txDeploy)) + + contractAddr, err := txDeploy.GenerateContractAddress() + assert.Nil(t, err) + contractsAddr = append(contractsAddr, contractAddr.String()) + } + }) + + block.CollectTransactions((time.Now().Unix() + 1) * dpos.SecondInMs) + assert.Nil(t, block.Seal()) + assert.Nil(t, manager.SignBlock(b, block)) + assert.Nil(t, neb.chain.BlockPool().Push(block)) + + for _, v := range contractsAddr { + contract, err := core.AddressParse(v) + assert.Nil(t, err) + _, err = neb.chain.TailBlock().CheckContract(contract) + assert.Nil(t, err) + } + + elapsedSecond = dpos.BlockIntervalInMs / dpos.SecondInMs + tail = neb.chain.TailBlock() + consensusState, err = tail.WorldState().NextConsensusState(elapsedSecond) + assert.Nil(t, err) + block, err = core.NewBlock(neb.chain.ChainID(), c, tail) + assert.Nil(t, err) + block.WorldState().SetConsensusState(consensusState) + block.SetTimestamp(consensusState.TimeStamp()) + + callPayload, _ := core.NewCallPayload(tt.call.function, tt.call.args) + payloadCall, _ := callPayload.ToBytes() + + value, _ := util.NewUint128FromInt(0) + gasLimit, _ := util.NewUint128FromInt(200000) + txCall, err := core.NewTransaction(neb.chain.ChainID(), a, a, value, uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit) + assert.Nil(t, err) + assert.Nil(t, manager.SignTransaction(a, txCall)) + assert.Nil(t, neb.chain.TransactionPool().Push(txCall)) + + block.CollectTransactions((time.Now().Unix() + 1) * dpos.SecondInMs) + assert.Nil(t, block.Seal()) + assert.Nil(t, manager.SignBlock(c, block)) + assert.Nil(t, neb.chain.BlockPool().Push(block)) + + // check + } +} diff --git a/nf/nvm/keydir b/nf/nvm/keydir new file mode 120000 index 000000000..188b3b5d4 --- /dev/null +++ b/nf/nvm/keydir @@ -0,0 +1 @@ +../../keydir/ \ No newline at end of file From cacd3c531094dbfe5616b2a4bd763180147b7de3 Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 25 Apr 2018 20:08:18 +0800 Subject: [PATCH 23/69] nvm: add negative number check in nrc20.js --- nf/nvm/test/NRC20.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/nf/nvm/test/NRC20.js b/nf/nvm/test/NRC20.js index c2f3e4e44..9575ad7ef 100644 --- a/nf/nvm/test/NRC20.js +++ b/nf/nvm/test/NRC20.js @@ -124,6 +124,9 @@ StandardToken.prototype = { transfer: function (to, value) { value = new BigNumber(value); + if (value.lt(0)) { + throw new Error("invalid value."); + } var from = Blockchain.transaction.from; var balance = this.balances.get(from) || new BigNumber(0); @@ -140,18 +143,18 @@ StandardToken.prototype = { }, transferFrom: function (from, to, value) { - var txFrom = Blockchain.transaction.from; + var spender = Blockchain.transaction.from; var balance = this.balances.get(from) || new BigNumber(0); var allowed = this.allowed.get(from) || new Allowed(); - var allowedValue = allowed.get(txFrom) || new BigNumber(0); + var allowedValue = allowed.get(spender) || new BigNumber(0); - if (balance.gte(value) && allowedValue.gte(value)) { + if (value.gte(0) && balance.gte(value) && allowedValue.gte(value)) { this.balances.set(from, balance.sub(value)); // update allowed value - allowed.set(txFrom, allowedValue.sub(value)); + allowed.set(spender, allowedValue.sub(value)); this.allowed.set(from, allowed); var toBalance = this.balances.get(to) || new BigNumber(0); @@ -183,8 +186,8 @@ StandardToken.prototype = { } var balance = new BigNumber(this.balanceOf(from)); - if (balance.lt(value)) { - throw new Error("approve value bigger than balance."); + if (value.lt(0) || balance.lt(value)) { + throw new Error("invalid value."); } var owned = this.allowed.get(from) || new Allowed(); From 60c7eda9f782cc6218bd7091fc870f05ca846dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=9A=E4=B9=A6?= Date: Thu, 26 Apr 2018 13:04:10 +0800 Subject: [PATCH 24/69] Update README.md fix typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64c6e39ce..436b94dc2 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ git checkout testnet * Install Dependencies ```bash apt-get update - apt-get -y build-essential libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev + apt-get -y install build-essential libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev ``` * Install rocksdb by source code: ```bash From e42b9d7a8816cbd0e51712983521954ae97f1efb Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 26 Apr 2018 15:37:44 +0800 Subject: [PATCH 25/69] net: optimize network compression. --- net/neb_message.go | 35 ++++++++++++--- net/stream.go | 104 ++++++++++++++++++++------------------------- 2 files changed, 75 insertions(+), 64 deletions(-) diff --git a/net/neb_message.go b/net/neb_message.go index e94967639..ed18146ba 100644 --- a/net/neb_message.go +++ b/net/neb_message.go @@ -24,6 +24,7 @@ import ( "hash/crc32" "time" + "github.com/golang/snappy" byteutils "github.com/nebulasio/go-nebulas/util/byteutils" "github.com/nebulasio/go-nebulas/util/logging" "github.com/sirupsen/logrus" @@ -75,13 +76,16 @@ const ( // Consider that a block is too large in sync. MaxNebMessageDataLength = 512 * 1024 * 1024 // 512m. MaxNebMessageNameLength = 24 - 12 // 12. + + DefaultReservedFlag = 0x0 + ReservedCompressionEnableFlag = 0x80 ) // Error types var ( - MagicNumber = []byte{0x4e, 0x45, 0x42, 0x31} - DefaultReserved = []byte{0x0, 0x0, 0x0} - CompressReserved = []byte{0x80, 0x0, 0x0} + MagicNumber = []byte{0x4e, 0x45, 0x42, 0x31} + DefaultReserved = []byte{DefaultReservedFlag, DefaultReservedFlag, DefaultReservedFlag} + CurrentReserved = []byte{DefaultReservedFlag | ReservedCompressionEnableFlag, DefaultReservedFlag, DefaultReservedFlag} ErrInsufficientMessageHeaderLength = errors.New("insufficient message header length") ErrInsufficientMessageDataLength = errors.New("insufficient message data length") @@ -90,6 +94,7 @@ var ( ErrInvalidDataCheckSum = errors.New("invalid data checksum") ErrExceedMaxDataLength = errors.New("exceed max data length") ErrExceedMaxMessageNameLength = errors.New("exceed max message name length") + ErrUncompressMessageFailed = errors.New("uncompress message failed") ) //NebMessage struct @@ -157,7 +162,21 @@ func (message *NebMessage) HeaderWithoutCheckSum() []byte { } // Data return data -func (message *NebMessage) Data() []byte { +func (message *NebMessage) Data() ([]byte, error) { + reserved := message.Reserved() + data := message.content[NebMessageHeaderLength:] + if message.Version() >= CompressionEnabledVersion && ((reserved[0] & 0x80) > 0) { + var err error + data, err = snappy.Decode(nil, data) + if err != nil { + return nil, ErrUncompressMessageFailed + } + } + return data, nil +} + +// OriginalData return original data +func (message *NebMessage) OriginalData() []byte { return message.content[NebMessageHeaderLength:] } @@ -173,6 +192,11 @@ func (message *NebMessage) Length() uint64 { // NewNebMessage new neb message func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { + // Process message compression + if (reserved[0] & ReservedCompressionEnableFlag) > 0 { + data = snappy.Encode(nil, data) + } + if len(data) > MaxNebMessageDataLength { logging.VLog().WithFields(logrus.Fields{ "messageName": messageName, @@ -189,7 +213,6 @@ func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName st "limits": MaxNebMessageNameLength, }).Debug("Exceeded max message name length.") return nil, ErrExceedMaxMessageNameLength - } dataCheckSum := crc32.ChecksumIEEE(data) @@ -281,7 +304,7 @@ func (message *NebMessage) VerifyHeader() error { // VerifyData verify message data func (message *NebMessage) VerifyData() error { - expectedCheckSum := crc32.ChecksumIEEE(message.Data()) + expectedCheckSum := crc32.ChecksumIEEE(message.OriginalData()) if expectedCheckSum != message.DataCheckSum() { logging.VLog().WithFields(logrus.Fields{ "expect": expectedCheckSum, diff --git a/net/stream.go b/net/stream.go index b7b15bdf5..3cdd17c98 100644 --- a/net/stream.go +++ b/net/stream.go @@ -21,12 +21,9 @@ package net import ( "errors" "fmt" - "hash/crc32" "sync" "time" - "github.com/golang/snappy" - "github.com/gogo/protobuf/proto" libnet "github.com/libp2p/go-libp2p-net" peer "github.com/libp2p/go-libp2p-peer" @@ -38,14 +35,16 @@ import ( // Stream Message Type const ( - ClientVersion = "0.3.0" - NebProtocolID = "/neb/1.0.0" - HELLO = "hello" - OK = "ok" - BYE = "bye" - SYNCROUTE = "syncroute" - ROUTETABLE = "routetable" - RECVEDMSG = "recvedmsg" + ClientVersion = "0.3.0" + NebProtocolID = "/neb/1.0.0" + HELLO = "hello" + OK = "ok" + BYE = "bye" + SYNCROUTE = "syncroute" + ROUTETABLE = "routetable" + RECVEDMSG = "recvedmsg" + CurrentVersion = 0x1 + CompressionEnabledVersion = 0x1 ) // Stream Status @@ -59,7 +58,6 @@ const ( var ( ErrShouldCloseConnectionAndExitLoop = errors.New("should close connection and exit loop") ErrStreamIsNotConnected = errors.New("stream is not connected") - ErrUncompressMessageFailed = errors.New("uncompress message failed") ) // Stream define the structure of a stream in p2p network @@ -80,7 +78,7 @@ type Stream struct { latestReadAt int64 latestWriteAt int64 msgCount map[string]int - compressFlag byte + reservedFlag []byte } // NewStream return a new Stream @@ -110,7 +108,7 @@ func newStreamInstance(pid peer.ID, addr ma.Multiaddr, stream libnet.Stream, nod latestReadAt: 0, latestWriteAt: 0, msgCount: make(map[string]int), - compressFlag: 0x80 & 0x80, + reservedFlag: DefaultReserved, } } @@ -175,17 +173,7 @@ func (s *Stream) SendProtoMessage(messageName string, pb proto.Message, priority // SendMessage send msg to buffer func (s *Stream) SendMessage(messageName string, data []byte, priority int) error { - var reserved []byte - if s.compressFlag > 0 { - reserved = CompressReserved - if messageName != HELLO { - data = snappy.Encode(nil, data) - } - } else { - reserved = DefaultReserved - } - - message, err := NewNebMessage(s.node.config.ChainID, reserved, 0, messageName, data) + message, err := NewNebMessage(s.node.config.ChainID, s.reservedFlag, CurrentVersion, messageName, data) if err != nil { return err } @@ -290,17 +278,7 @@ func (s *Stream) WriteProtoMessage(messageName string, pb proto.Message) error { // WriteMessage write raw msg in the stream func (s *Stream) WriteMessage(messageName string, data []byte) error { - var reserved []byte - if s.compressFlag > 0 { - reserved = CompressReserved - if messageName != HELLO { - data = snappy.Encode(nil, data) - } - } else { - reserved = DefaultReserved - } - - message, err := NewNebMessage(s.node.config.ChainID, reserved, 0, messageName, data) + message, err := NewNebMessage(s.node.config.ChainID, s.reservedFlag, CurrentVersion, messageName, data) if err != nil { return err } @@ -463,27 +441,13 @@ func (s *Stream) writeLoop() { func (s *Stream) handleMessage(message *NebMessage) error { messageName := message.MessageName() - s.compressFlag = message.Reserved()[0] & 0x80 s.msgCount[messageName]++ - // Network data compression compatible with old clients. - // uncompress message data. - var data = message.Data() - if messageName != HELLO { - if s.compressFlag > 0 { - var err error - data, err = snappy.Decode(nil, message.Data()) - if err != nil { - return ErrUncompressMessageFailed - } - } - } - switch messageName { case HELLO: - return s.onHello(message, data) + return s.onHello(message) case OK: - return s.onOk(message, data) + return s.onOk(message) case BYE: return s.onBye(message) } @@ -497,12 +461,15 @@ func (s *Stream) handleMessage(message *NebMessage) error { case SYNCROUTE: return s.onSyncRoute(message) case ROUTETABLE: - return s.onRouteTable(message, data) + return s.onRouteTable(message) default: + data, err := message.Data() + if err != nil { + return err + } s.node.netService.PutMessage(NewBaseMessage(message.MessageName(), s.pid.Pretty(), data)) // record recv message. - dataCheckSum := crc32.ChecksumIEEE(data) - RecordRecvMessage(s, dataCheckSum) + RecordRecvMessage(s, message.DataCheckSum()) } return nil @@ -559,7 +526,11 @@ func (s *Stream) Hello() error { return s.WriteProtoMessage(HELLO, msg) } -func (s *Stream) onHello(message *NebMessage, data []byte) error { +func (s *Stream) onHello(message *NebMessage) error { + data, err := message.Data() + if err != nil { + return err + } msg, err := netpb.HelloMessageFromProto(data) if err != nil { return ErrShouldCloseConnectionAndExitLoop @@ -576,6 +547,10 @@ func (s *Stream) onHello(message *NebMessage, data []byte) error { return ErrShouldCloseConnectionAndExitLoop } + if message.Version() >= CompressionEnabledVersion { + s.reservedFlag = CurrentReserved + } + // add to route table. s.node.routeTable.AddPeerStream(s) @@ -596,7 +571,12 @@ func (s *Stream) Ok() error { return s.WriteProtoMessage(OK, resp) } -func (s *Stream) onOk(message *NebMessage, data []byte) error { +func (s *Stream) onOk(message *NebMessage) error { + data, err := message.Data() + if err != nil { + return err + } + msg, err := netpb.OKMessageFromProto(data) if err != nil { return ErrShouldCloseConnectionAndExitLoop @@ -613,6 +593,10 @@ func (s *Stream) onOk(message *NebMessage, data []byte) error { return ErrShouldCloseConnectionAndExitLoop } + if message.Version() >= CompressionEnabledVersion { + s.reservedFlag = CurrentReserved + } + // add to route table. s.node.routeTable.AddPeerStream(s) @@ -660,7 +644,11 @@ func (s *Stream) RouteTable() error { return s.SendProtoMessage(ROUTETABLE, msg, MessagePriorityHigh) } -func (s *Stream) onRouteTable(message *NebMessage, data []byte) error { +func (s *Stream) onRouteTable(message *NebMessage) error { + data, err := message.Data() + if err != nil { + return err + } peers := new(netpb.Peers) if err := proto.Unmarshal(data, peers); err != nil { logging.VLog().WithFields(logrus.Fields{ From 44c14c63a36b287d31b0f883af2e4e822e70f4b6 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 26 Apr 2018 17:45:09 +0800 Subject: [PATCH 26/69] net: optimize network message compression and change clientVersion to be compatible. --- net/neb_message.go | 7 ++++--- net/stream.go | 35 ++++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/net/neb_message.go b/net/neb_message.go index ed18146ba..4cac081a1 100644 --- a/net/neb_message.go +++ b/net/neb_message.go @@ -79,13 +79,14 @@ const ( DefaultReservedFlag = 0x0 ReservedCompressionEnableFlag = 0x80 + ReservedCompressionClientFlag = 0x1 ) // Error types var ( MagicNumber = []byte{0x4e, 0x45, 0x42, 0x31} DefaultReserved = []byte{DefaultReservedFlag, DefaultReservedFlag, DefaultReservedFlag} - CurrentReserved = []byte{DefaultReservedFlag | ReservedCompressionEnableFlag, DefaultReservedFlag, DefaultReservedFlag} + CurrentReserved = []byte{DefaultReservedFlag | ReservedCompressionEnableFlag, DefaultReservedFlag, DefaultReservedFlag | ReservedCompressionClientFlag} ErrInsufficientMessageHeaderLength = errors.New("insufficient message header length") ErrInsufficientMessageDataLength = errors.New("insufficient message data length") @@ -165,7 +166,7 @@ func (message *NebMessage) HeaderWithoutCheckSum() []byte { func (message *NebMessage) Data() ([]byte, error) { reserved := message.Reserved() data := message.content[NebMessageHeaderLength:] - if message.Version() >= CompressionEnabledVersion && ((reserved[0] & 0x80) > 0) { + if ((reserved[2] & ReservedCompressionClientFlag) > 0) && ((reserved[0] & ReservedCompressionEnableFlag) > 0) { var err error data, err = snappy.Decode(nil, data) if err != nil { @@ -193,7 +194,7 @@ func (message *NebMessage) Length() uint64 { // NewNebMessage new neb message func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { // Process message compression - if (reserved[0] & ReservedCompressionEnableFlag) > 0 { + if ((reserved[2] & ReservedCompressionClientFlag) > 0) && ((reserved[0] & ReservedCompressionEnableFlag) > 0) { data = snappy.Encode(nil, data) } diff --git a/net/stream.go b/net/stream.go index 3cdd17c98..0542e78e3 100644 --- a/net/stream.go +++ b/net/stream.go @@ -21,6 +21,7 @@ package net import ( "errors" "fmt" + "strings" "sync" "time" @@ -35,16 +36,15 @@ import ( // Stream Message Type const ( - ClientVersion = "0.3.0" - NebProtocolID = "/neb/1.0.0" - HELLO = "hello" - OK = "ok" - BYE = "bye" - SYNCROUTE = "syncroute" - ROUTETABLE = "routetable" - RECVEDMSG = "recvedmsg" - CurrentVersion = 0x1 - CompressionEnabledVersion = 0x1 + ClientVersion = "0.3.0" + NebProtocolID = "/neb/1.0.0" + HELLO = "hello" + OK = "ok" + BYE = "bye" + SYNCROUTE = "syncroute" + ROUTETABLE = "routetable" + RECVEDMSG = "recvedmsg" + CurrentVersion = 0x0 ) // Stream Status @@ -547,7 +547,7 @@ func (s *Stream) onHello(message *NebMessage) error { return ErrShouldCloseConnectionAndExitLoop } - if message.Version() >= CompressionEnabledVersion { + if (message.Reserved()[2] & ReservedCompressionClientFlag) > 0 { s.reservedFlag = CurrentReserved } @@ -593,7 +593,7 @@ func (s *Stream) onOk(message *NebMessage) error { return ErrShouldCloseConnectionAndExitLoop } - if message.Version() >= CompressionEnabledVersion { + if (message.Reserved()[2] & ReservedCompressionClientFlag) > 0 { s.reservedFlag = CurrentReserved } @@ -672,6 +672,15 @@ func (s *Stream) finishHandshake() { } // CheckClientVersionCompatibility if two clients are compatible +// If the clientVersion of node A is X.Y.Z, then node B must be X.Y.{} to be compatible with A. func CheckClientVersionCompatibility(v1, v2 string) bool { - return v1 == v2 + s1 := strings.Split(v1, ".") + s2 := strings.Split(v1, ".") + if len(s1) != 3 || len(s2) != 3 { + return false + } + if s1[0] != s2[0] || s1[1] != s2[1] { + return false + } + return true } From c5fcc65976a1cfb6225373cbd775ed4e66710469 Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 27 Apr 2018 18:06:35 +0800 Subject: [PATCH 27/69] nvm: fix string value to bigNumber. --- nf/nvm/test/NRC721.js | 229 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 nf/nvm/test/NRC721.js diff --git a/nf/nvm/test/NRC721.js b/nf/nvm/test/NRC721.js new file mode 100644 index 000000000..c78b037de --- /dev/null +++ b/nf/nvm/test/NRC721.js @@ -0,0 +1,229 @@ +// Copyright (C) 2017 go-nebulas authors +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + +'use strict'; + +var Allowed = function (obj) { + this.allowed = {}; + this.parse(obj); +} + +Allowed.prototype = { + toString: function () { + return JSON.stringify(this.allowed); + }, + + parse: function (obj) { + if (typeof obj != "undefined") { + var data = JSON.parse(obj); + for (var key in data) { + this.allowed[key] = new BigNumber(data[key]); + } + } + }, + + get: function (key) { + return this.allowed[key]; + }, + + set: function (key, value) { + this.allowed[key] = new BigNumber(value); + } +} + +var StandardToken = function () { + LocalContractStorage.defineProperties(this, { + _name: null, + _symbol: null, + _allTokens: { + parse: function (value) { + var arr = JSON.parse(value); + var ret = new Array(); + arr.forEach(function(v) { + ret.push(new BigNumber(v)); + }, this); + return ret; + }, + stringify: function (o) { + return JSON.stringify(o); + } + }, + }); + + LocalContractStorage.defineMapProperties(this, { + "tokenOwner": null, + "ownedTokensCount": { + parse: function (value) { + return new BigNumber(value); + }, + stringify: function (o) { + return o.toString(10); + } + }, + "ownedTokens": { + parse: function (value) { + var arr = JSON.parse(value); + var ret = new Array(); + arr.forEach(function(v) { + ret.push(new BigNumber(v)); + }, this); + return ret; + }, + stringify: function (o) { + return JSON.stringify(o); + } + }, + "ownedTokensIndex": { + parse: function (value) { + return new BigNumber(value); + }, + stringify: function (o) { + return o.toString(10); + } + } + }); +}; + +StandardToken.prototype = { + init: function (name, symbol) { + this._name = name; + this._symbol = symbol; + }, + + // Returns the name of the token + name: function () { + return this._name; + }, + + // Returns the symbol of the token + symbol: function () { + return this._symbol; + }, + + totalSupply: function () { + return this._allTokens.length; + }, + + balanceOf: function (owner) { + var balance = this.balances.get(owner); + + if (balance instanceof BigNumber) { + return balance.toString(10); + } else { + return "0"; + } + }, + + transfer: function (to, value) { + value = new BigNumber(value); + + var from = Blockchain.transaction.from; + var balance = this.balances.get(from) || new BigNumber(0); + + if (balance.lt(value)) { + throw new Error("transfer failed."); + } + + this.balances.set(from, balance.sub(value)); + var toBalance = this.balances.get(to) || new BigNumber(0); + this.balances.set(to, toBalance.add(value)); + + this.transferEvent(true, from, to, value); + }, + + transferFrom: function (from, to, value) { + var txFrom = Blockchain.transaction.from; + var balance = this.balances.get(from) || new BigNumber(0); + + var allowed = this.allowed.get(from) || new Allowed(); + var allowedValue = allowed.get(txFrom) || new BigNumber(0); + + if (balance.gte(value) && allowedValue.gte(value)) { + + this.balances.set(from, balance.sub(value)); + + // update allowed value + allowed.set(txFrom, allowedValue.sub(value)); + this.allowed.set(from, allowed); + + var toBalance = this.balances.get(to) || new BigNumber(0); + this.balances.set(to, toBalance.add(value)); + + this.transferEvent(true, from, to, value); + } else { + throw new Error("transfer failed."); + } + }, + + transferEvent: function (status, from, to, value) { + Event.Trigger(this.name(), { + Status: status, + Transfer: { + from: from, + to: to, + value: value + } + }); + }, + + approve: function (spender, currentValue, value) { + var from = Blockchain.transaction.from; + + var oldValue = this.allowance(from, spender); + if (oldValue != currentValue.toString()) { + throw new Error("current approve value mistake."); + } + + var balance = new BigNumber(this.balanceOf(from)); + if (balance.lt(value)) { + throw new Error("approve value bigger than balance."); + } + + var owned = this.allowed.get(from) || new Allowed(); + owned.set(spender, new BigNumber(value)); + + this.allowed.set(from, owned); + + this.approveEvent(true, from, spender, value); + }, + + approveEvent: function (status, from, spender, value) { + Event.Trigger(this.name(), { + Status: status, + Approve: { + owner: from, + spender: spender, + value: value + } + }); + }, + + allowance: function (owner, spender) { + var owned = this.allowed.get(owner); + + if (owned instanceof Allowed) { + var spender = owned.get(spender); + if (typeof spender != "undefined") { + return spender.toString(10); + } + } + return "0"; + } +}; + +module.exports = StandardToken; From 4fd7f1bb2f53a1d4eb5224400689f049be5d23ea Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Fri, 27 Apr 2018 18:07:15 +0800 Subject: [PATCH 28/69] crypto: add VRF --- core/compatibility.go | 30 ++ .../vrf/secp256k1VRF/secp256k1VRF.go | 329 ++++++++++++++++++ .../vrf/secp256k1VRF/secp256k1VRF_test.go | 311 +++++++++++++++++ .../secp256k1/vrf/secp256k1VRF/unmarshal.go | 89 +++++ crypto/keystore/secp256k1/vrf/vrf.go | 35 ++ crypto/keystore/secp256k1/vrf/vrf_test.go | 98 ++++++ nf/nvm/blockchain.go | 2 +- nf/nvm/event.go | 5 - nf/nvm/lib/random.js | 1 + nf/nvm/v8/lib/execution_env.js | 16 +- nf/nvm/v8/lib/random.js | 122 +++++++ 11 files changed, 1030 insertions(+), 8 deletions(-) create mode 100644 core/compatibility.go create mode 100644 crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go create mode 100644 crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go create mode 100644 crypto/keystore/secp256k1/vrf/secp256k1VRF/unmarshal.go create mode 100644 crypto/keystore/secp256k1/vrf/vrf.go create mode 100644 crypto/keystore/secp256k1/vrf/vrf_test.go create mode 120000 nf/nvm/lib/random.js create mode 100644 nf/nvm/v8/lib/random.js diff --git a/core/compatibility.go b/core/compatibility.go new file mode 100644 index 000000000..e8a55c60a --- /dev/null +++ b/core/compatibility.go @@ -0,0 +1,30 @@ +// Copyright (C) 2018 go-nebulas authors +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + +package core + +const ( + // TransferFromContractEventCompatibleHeight record event 'TransferFromContractEvent' since this height + TransferFromContractEventCompatibleHeight uint64 = 200000 + + // RandomSeedAvailableCompatibleHeight make 'random' available in contract since this height + RandomSeedAvailableCompatibleHeight uint64 = 200000 + + // CheckRandomSeedCompatibleHeight random seed need be check since this height + CheckRandomSeedCompatibleHeight = RandomSeedAvailableCompatibleHeight + 1 +) diff --git a/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go new file mode 100644 index 000000000..864870d9b --- /dev/null +++ b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go @@ -0,0 +1,329 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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. + +// Implements a verifiable random function using curve secp256k1. + +package secp256k1VRF + +// Discrete Log based VRF from Appendix A of CONIKS: +// http://www.jbonneau.com/doc/MBBFF15-coniks.pdf +// based on "Unique Ring Signatures, a Practical Construction" +// http://fc13.ifca.ai/proc/5-1.pdf + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "crypto/sha512" + "encoding/binary" + "errors" + "io" + "math/big" + + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/bitelliptic" + + "github.com/google/keytransparency/core/crypto/vrf" +) + +var ( + curve = bitelliptic.S256() + params = curve.Params() + + // ErrPointNotOnCurve occurs when a public key is not on the curve. + ErrPointNotOnCurve = errors.New("point is not on the P256 curve") + // ErrWrongKeyType occurs when a key is not an ECDSA key. + ErrWrongKeyType = errors.New("not an ECDSA key") + // ErrNoPEMFound occurs when attempting to parse a non PEM data structure. + ErrNoPEMFound = errors.New("no PEM block found") + // ErrInvalidVRF occurs when the VRF does not validate. + ErrInvalidVRF = errors.New("invalid VRF proof") +) + +// PublicKey holds a public VRF key. +type PublicKey struct { + *ecdsa.PublicKey +} + +// PrivateKey holds a private VRF key. +type PrivateKey struct { + *ecdsa.PrivateKey +} + +// GenerateKey generates a fresh keypair for this VRF +func GenerateKey() (vrf.PrivateKey, vrf.PublicKey) { + key, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, nil + } + + return &PrivateKey{key}, &PublicKey{&key.PublicKey} +} + +// H1 hashes m to a curve point +func H1(m []byte) (x, y *big.Int) { + h := sha512.New() + var i uint32 + byteLen := (params.BitSize + 7) >> 3 + for x == nil && i < 100 { + // TODO: Use a NIST specified DRBG. + h.Reset() + binary.Write(h, binary.BigEndian, i) + h.Write(m) + r := []byte{2} // Set point encoding to "compressed", y=0. + r = h.Sum(r) + x, y = Unmarshal(curve, r[:byteLen+1]) + i++ + } + return +} + +var one = big.NewInt(1) + +// H2 hashes to an integer [1,N-1] +func H2(m []byte) *big.Int { + // NIST SP 800-90A § A.5.1: Simple discard method. + byteLen := (params.BitSize + 7) >> 3 + h := sha512.New() + for i := uint32(0); ; i++ { + // TODO: Use a NIST specified DRBG. + h.Reset() + binary.Write(h, binary.BigEndian, i) + h.Write(m) + b := h.Sum(nil) + k := new(big.Int).SetBytes(b[:byteLen]) + if k.Cmp(new(big.Int).Sub(params.N, one)) == -1 { + return k.Add(k, one) + } + } +} + +// Evaluate returns the verifiable unpredictable function evaluated at m +func (k PrivateKey) Evaluate(m []byte) (index [32]byte, proof []byte) { + nilIndex := [32]byte{} + // Prover chooses r <-- [1,N-1] + r, _, _, err := generateKeyFromCurve(curve, rand.Reader) + if err != nil { + return nilIndex, nil + } + ri := new(big.Int).SetBytes(r) + + // H = H1(m) + Hx, Hy := H1(m) + + // VRF_k(m) = [k]H + sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes()) + + // vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes. + vrf := curve.Marshal(sHx, sHy) // 65 bytes. + + // G is the base point + // s = H2(G, H, [k]G, VRF, [r]G, [r]H) + rGx, rGy := curve.ScalarBaseMult(r) + rHx, rHy := curve.ScalarMult(Hx, Hy, r) + var b bytes.Buffer + b.Write(curve.Marshal(params.Gx, params.Gy)) + b.Write(curve.Marshal(Hx, Hy)) + b.Write(curve.Marshal(k.PublicKey.X, k.PublicKey.Y)) + b.Write(vrf) + b.Write(curve.Marshal(rGx, rGy)) + b.Write(curve.Marshal(rHx, rHy)) + s := H2(b.Bytes()) + + // t = r−s*k mod N + t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D)) + t.Mod(t, params.N) + + // Index = H(vrf) + index = sha256.Sum256(vrf) + + // Write s, t, and vrf to a proof blob. Also write leading zeros before s and t + // if needed. + var buf bytes.Buffer + buf.Write(make([]byte, 32-len(s.Bytes()))) + buf.Write(s.Bytes()) + buf.Write(make([]byte, 32-len(t.Bytes()))) + buf.Write(t.Bytes()) + buf.Write(vrf) + + return index, buf.Bytes() +} + +// ProofToHash asserts that proof is correct for m and outputs index. +func (pk *PublicKey) ProofToHash(m, proof []byte) (index [32]byte, err error) { + nilIndex := [32]byte{} + // verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m)) + if got, want := len(proof), 64+65; got != want { + return nilIndex, ErrInvalidVRF + } + + // Parse proof into s, t, and vrf. + s := proof[0:32] + t := proof[32:64] + vrf := proof[64 : 64+65] + + // uHx, uHy := elliptic.Unmarshal(curve, vrf) + uHx, uHy := curve.Unmarshal(vrf) //////??? + if uHx == nil { + return nilIndex, ErrInvalidVRF + } + + // [t]G + [s]([k]G) = [t+ks]G + tGx, tGy := curve.ScalarBaseMult(t) + ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s) + tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy) + + // H = H1(m) + // [t]H + [s]VRF = [t+ks]H + Hx, Hy := H1(m) + tHx, tHy := curve.ScalarMult(Hx, Hy, t) + sHx, sHy := curve.ScalarMult(uHx, uHy, s) + tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy) + + // H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF) + // = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H) + // = H2(G, H, [k]G, VRF, [r]G, [r]H) + var b bytes.Buffer + b.Write(curve.Marshal(params.Gx, params.Gy)) + b.Write(curve.Marshal(Hx, Hy)) + b.Write(curve.Marshal(pk.X, pk.Y)) + b.Write(vrf) + b.Write(curve.Marshal(tksGx, tksGy)) + b.Write(curve.Marshal(tksHx, tksHy)) + h2 := H2(b.Bytes()) + + // Left pad h2 with zeros if needed. This will ensure that h2 is padded + // the same way s is. + var buf bytes.Buffer + buf.Write(make([]byte, 32-len(h2.Bytes()))) + buf.Write(h2.Bytes()) + + if !hmac.Equal(s, buf.Bytes()) { + return nilIndex, ErrInvalidVRF + } + return sha256.Sum256(vrf), nil +} + +// NewFromWrappedKey creates a VRF signer object from an encrypted private key. +// The opaque private key must resolve to an `ecdsa.PrivateKey` in order to work. +// func NewFromWrappedKey(ctx context.Context, wrapped proto.Message) (vrf.PrivateKey, error) { +// // Unwrap. +// signer, err := keys.NewSigner(ctx, wrapped) +// if err != nil { +// return nil, err +// } + +// switch key := signer.(type) { +// case *ecdsa.PrivateKey: +// return NewVRFSigner(key) +// default: +// return nil, fmt.Errorf("NewSigner().type: %T, want ecdsa.PrivateKey", key) +// } +// } + +// NewVRFSigner creates a signer object from a private key. +func NewVRFSigner(key *ecdsa.PrivateKey) (vrf.PrivateKey, error) { + if *(key.Params()) != *curve.Params() { + return nil, ErrPointNotOnCurve + } + if !curve.IsOnCurve(key.X, key.Y) { + return nil, ErrPointNotOnCurve + } + return &PrivateKey{key}, nil +} + +// Public returns the corresponding public key as bytes. +func (k PrivateKey) Public() crypto.PublicKey { + return &k.PublicKey +} + +// NewVRFVerifier creates a verifier object from a public key. +func NewVRFVerifier(pubkey *ecdsa.PublicKey) (vrf.PublicKey, error) { + if *(pubkey.Params()) != *curve.Params() { + return nil, ErrPointNotOnCurve + } + if !curve.IsOnCurve(pubkey.X, pubkey.Y) { + return nil, ErrPointNotOnCurve + } + return &PublicKey{pubkey}, nil +} + +// NewVRFSignerFromPEM creates a vrf private key from a PEM data structure. +// func NewVRFSignerFromPEM(b []byte) (vrf.PrivateKey, error) { +// p, _ := pem.Decode(b) +// if p == nil { +// return nil, ErrNoPEMFound +// } +// return NewVRFSignerFromRawKey(p.Bytes) +// } + +// NewVRFSignerFromRawKey returns the private key from a raw private key bytes. +func NewVRFSignerFromRawKey(b []byte) (vrf.PrivateKey, error) { + k, err := secp256k1.ToECDSAPrivateKey(b) + if err != nil { + return nil, err + } + return NewVRFSigner(k) +} + +// NewVRFVerifierFromPEM creates a vrf public key from a PEM data structure. +// func NewVRFVerifierFromPEM(b []byte) (vrf.PublicKey, error) { +// p, _ := pem.Decode(b) +// if p == nil { +// return nil, ErrNoPEMFound +// } +// return NewVRFVerifierFromRawKey(p.Bytes) +// } + +// NewVRFVerifierFromRawKey returns the public key from a raw public key bytes. +func NewVRFVerifierFromRawKey(b []byte) (vrf.PublicKey, error) { + k, err := secp256k1.ToECDSAPublicKey(b) + if err != nil { + return nil, err + } + return NewVRFVerifier(k) +} + +var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} + +func generateKeyFromCurve(curve *bitelliptic.BitCurve, rand io.Reader) (priv []byte, x, y *big.Int, err error) { + N := curve.Params().N + bitSize := N.BitLen() + byteLen := (bitSize + 7) >> 3 + priv = make([]byte, byteLen) + + for x == nil { + _, err = io.ReadFull(rand, priv) + if err != nil { + return + } + // We have to mask off any excess bits in the case that the size of the + // underlying field is not a whole number of bytes. + priv[0] &= mask[bitSize%8] + // This is because, in tests, rand will return all zeros and we don't + // want to get the point at infinity and loop forever. + priv[1] ^= 0x42 + + // If the scalar is out of range, sample another random number. + if new(big.Int).SetBytes(priv).Cmp(N) >= 0 { + continue + } + + x, y = curve.ScalarBaseMult(priv) + } + return +} diff --git a/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go new file mode 100644 index 000000000..43b1af1e1 --- /dev/null +++ b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go @@ -0,0 +1,311 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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. + +package secp256k1VRF + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "fmt" + "math" + "testing" + "time" + + "github.com/nebulasio/go-nebulas/util/byteutils" + // _ "github.com/google/trillian/crypto/keys/der/proto" +) + +const ( + // private key in hex + privKey = `b02b430d4a9d7120b65038452a6da3f3c716829e5be3665adf934d4798d96ed7` + // public key in hex + pubKey = `04e4d0dde330c0b8d8d8b1b2071aa75c3e94f200a3d11ca1d908644eee50c8833a816dc0b2d003fc66187ef6750a56e1b3004d32e6159008400ab92f2ded7b4544` +) + +func TestH1(t *testing.T) { + for i := 0; i < 10000; i++ { + m := make([]byte, 100) + if _, err := rand.Read(m); err != nil { + t.Fatalf("Failed generating random message: %v", err) + } + x, y := H1(m) + if x == nil { + t.Errorf("H1(%v)=%v, want curve point", m, x) + } + // attention: should not use curve.Params(), that will use elliptic.IsOnCurve() + if got := curve.IsOnCurve(x, y); !got { + t.Errorf("H1(%v)=[%v, %v], is not on curve", m, x, y) + } + } +} + +func TestH2(t *testing.T) { + l := 32 + for i := 0; i < 10000; i++ { + m := make([]byte, 100) + if _, err := rand.Read(m); err != nil { + t.Fatalf("Failed generating random message: %v", err) + } + x := H2(m) + if got := len(x.Bytes()); got < 1 || got > l { + t.Errorf("len(h2(%v)) = %v, want: 1 <= %v <= %v", m, got, got, l) + } + } +} + +func TestEmmm(t *testing.T) { + k, pk := GenerateKey() + m1 := []byte("da30b4ed14affb62b3719fb5e6952d3733e84e53fe6e955f8e46da503300c985") + index1, proof1 := k.Evaluate(m1) + fmt.Println("evaluate index = ", index1) + fmt.Println("evaluate proof = ", proof1) + + start := time.Now() + for i := 0; i < 100; i++ { + _, _ = k.Evaluate(m1) + } + end := time.Now() + fmt.Println("evaluate x100 total time: ", end.Sub(start)) + + index, _ := pk.ProofToHash(m1, proof1) + fmt.Println("proof index = ", index) + + start = time.Now() + for i := 0; i < 100; i++ { + _, _ = pk.ProofToHash(m1, proof1) + } + end = time.Now() + fmt.Println("proof x100 total time: ", end.Sub(start)) +} + +func TestVRF(t *testing.T) { + k, pk := GenerateKey() + + m1 := []byte("data1") + m2 := []byte("data2") + m3 := []byte("data2") + index1, proof1 := k.Evaluate(m1) + index2, proof2 := k.Evaluate(m2) + index3, proof3 := k.Evaluate(m3) + for _, tc := range []struct { + m []byte + index [32]byte + proof []byte + err error + }{ + {m1, index1, proof1, nil}, + {m2, index2, proof2, nil}, + {m3, index3, proof3, nil}, + {m3, index3, proof2, nil}, + {m3, index3, proof1, ErrInvalidVRF}, + } { + index, err := pk.ProofToHash(tc.m, tc.proof) + if got, want := err, tc.err; got != want { + t.Errorf("ProofToHash(%s, %x): %v, want %v", tc.m, tc.proof, got, want) + } + if err != nil { + continue + } + if got, want := index, tc.index; got != want { + t.Errorf("ProofToInex(%s, %x): %x, want %x", tc.m, tc.proof, got, want) + } + } +} + +func TestProofToHash(t *testing.T) { + bytes, _ := byteutils.FromHex(pubKey) + pk, err := NewVRFVerifierFromRawKey(bytes) + if err != nil { + t.Errorf("NewVRFSigner failure: %v", err) + } + + for _, tc := range []struct { + m []byte + index [32]byte + proof []byte + }{ + { + m: []byte("data1"), + index: h2i("a2f4f844d46240a86790c177f21422f430b2803c7590f32625079fc13a5fe601"), + proof: h2b("cc23d0e1e01a20bcee479e944c94febabb8e762fa64b9443fc9dc31d3332e3a7024f4adc2cda4e8847fe67f47ab0084b677996e9325d31840531a2f91d6a5d7d04e54044c12dd5ab7b90a57117a85d6307125496ada896d9823c860c4f492c0096c714705d58ee7d66ee6cffb5f1320c5eab7f92490b0f5759145588efa0b0537d"), + }, + { + m: []byte("data2"), + index: h2i("008a288a33a2620458a26b6c995d9c16ca46c293562db76985bd1b2a159efc76"), + proof: h2b("888e0d3191af542c40d0d8b15255e106a133ec9b219b6e26900e07a252e6ab60e510423c34bf74cc602ae2be214bffadfd639793d0a3dccd0e7303be8d0de57604322cef265dfe906cebf30de74b14aa33723435eccea3153fedb5bea70e5c58a8969af97c27e50223bc3b9a8dd8f4a60ec363a78c957f366af075cf83cc43e61c"), + }, + { + m: []byte("data3"), + index: h2i("9bb53b519519a85c8c6c6739349168c42ae208aed7dadeababf5a067a6ac1313"), + proof: h2b("96004eb1450c68fcb1ac83e0f09c5311089829762a5e8aecdba1c51d703250d79bc9ffeb72c0c5645da6c3d2d59a5c6428b1d3a0075d75b89bae8b539453e3af044a472b26f259bd5a84f05ec8fe1d7858d6f5606adcb6febeef113a2ff4ff69d5166ebbd3c3a78c451d751490eeb37fd39358fb2fad8ae218e3fc5177fe2e9b37"), + }, + } { + + bytes, _ := byteutils.FromHex(privKey) + k, err := NewVRFSignerFromRawKey(bytes) + idx, proof := k.Evaluate(tc.m) + fmt.Println("=======") + fmt.Println(byteutils.Hex(idx[0:])) + fmt.Println(byteutils.Hex(proof)) + + index, err := pk.ProofToHash(tc.m, tc.proof) + if err != nil { + t.Errorf("ProofToHash(%s, %x): %v, want nil", tc.m, tc.proof, err) + continue + } + if got, want := index, tc.index; got != want { + t.Errorf("ProofToHash(%s, %x): %x, want %x", tc.m, tc.proof, got, want) + } + } +} + +func TestReadFromOpenSSL(t *testing.T) { + for _, tc := range []struct { + priv string + pub string + }{ + {privKey, pubKey}, + } { + // Private VRF Key + bytes, _ := byteutils.FromHex(tc.priv) + signer, err := NewVRFSignerFromRawKey(bytes) + if err != nil { + t.Errorf("NewVRFSigner failure: %v", err) + } + + // Public VRF key + bytes, _ = byteutils.FromHex(tc.pub) + verifier, err := NewVRFVerifierFromRawKey(bytes) + if err != nil { + t.Errorf("NewVRFSigner failure: %v", err) + } + + // Evaluate and verify. + m := []byte("M") + _, proof := signer.Evaluate(m) + if _, err := verifier.ProofToHash(m, proof); err != nil { + t.Errorf("Failed verifying VRF proof") + } + } +} + +func TestRightTruncateProof(t *testing.T) { + k, pk := GenerateKey() + + data := []byte("data") + _, proof := k.Evaluate(data) + proofLen := len(proof) + for i := 0; i < proofLen; i++ { + proof = proof[:len(proof)-1] + if _, err := pk.ProofToHash(data, proof); err == nil { + t.Errorf("Verify unexpectedly succeeded after truncating %v bytes from the end of proof", i) + } + } +} + +func TestLeftTruncateProof(t *testing.T) { + k, pk := GenerateKey() + + data := []byte("data") + _, proof := k.Evaluate(data) + proofLen := len(proof) + for i := 0; i < proofLen; i++ { + proof = proof[1:] + if _, err := pk.ProofToHash(data, proof); err == nil { + t.Errorf("Verify unexpectedly succeeded after truncating %v bytes from the beginning of proof", i) + } + } +} + +func TestBitFlip(t *testing.T) { + k, pk := GenerateKey() + + data := []byte("data") + _, proof := k.Evaluate(data) + for i := 0; i < len(proof)*8; i++ { + // Flip bit in position i. + if _, err := pk.ProofToHash(data, flipBit(proof, i)); err == nil { + t.Errorf("Verify unexpectedly succeeded after flipping bit %v of vrf", i) + } + } +} + +func flipBit(a []byte, pos int) []byte { + index := int(math.Floor(float64(pos) / 8)) + b := byte(a[index]) + b ^= (1 << uint(math.Mod(float64(pos), 8.0))) + + var buf bytes.Buffer + buf.Write(a[:index]) + buf.Write([]byte{b}) + buf.Write(a[index+1:]) + return buf.Bytes() +} + +func TestVectors(t *testing.T) { + bytes, _ := byteutils.FromHex(privKey) + k, err := NewVRFSignerFromRawKey(bytes) + if err != nil { + t.Errorf("NewVRFSigner failure: %v", err) + } + bytes, _ = byteutils.FromHex(pubKey) + pk, err := NewVRFVerifierFromRawKey(bytes) + if err != nil { + t.Errorf("NewVRFSigner failure: %v", err) + } + for _, tc := range []struct { + m []byte + index [32]byte + }{ + { + m: []byte("test"), + index: h2i("c095a258b89a5fbf0790e45cd2b1a31c1723f0f99c7df3df98e03eef2a4a25af"), + }, + { + m: nil, + index: h2i("19a1da136a3dadfd4ffb2e95d0b236b72e7bd448541a46fde595acd5052775cb"), + }, + } { + index, proof := k.Evaluate(tc.m) + if got, want := index, tc.index; got != want { + t.Errorf("Evaluate(%s).Index: %x, want %x", tc.m, got, want) + } + index2, err := pk.ProofToHash(tc.m, proof) + if err != nil { + t.Errorf("ProofToHash(%s): %v", tc.m, err) + } + if got, want := index2, index; got != want { + t.Errorf("ProofToHash(%s): %x, want %x", tc.m, got, want) + } + } +} + +func h2i(h string) [32]byte { + b, err := hex.DecodeString(h) + if err != nil { + panic("Invalid hex") + } + var i [32]byte + copy(i[:], b) + return i +} + +func h2b(h string) []byte { + b, err := hex.DecodeString(h) + if err != nil { + panic("Invalid hex") + } + return b +} diff --git a/crypto/keystore/secp256k1/vrf/secp256k1VRF/unmarshal.go b/crypto/keystore/secp256k1/vrf/secp256k1VRF/unmarshal.go new file mode 100644 index 000000000..c30ac11b9 --- /dev/null +++ b/crypto/keystore/secp256k1/vrf/secp256k1VRF/unmarshal.go @@ -0,0 +1,89 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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. + +package secp256k1VRF + +// This file implements compressed point unmarshaling. Preferably this +// functionality would be in a standard library. Code borrowed from: +// https://go-review.googlesource.com/#/c/1883/2/src/crypto/elliptic/elliptic.go + +import ( + "crypto/elliptic" + "math/big" +) + +// Unmarshal a compressed point in the form specified in section 4.3.6 of ANSI X9.62. +func Unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) { + byteLen := (curve.Params().BitSize + 7) >> 3 + if (data[0] &^ 1) != 2 { + return // unrecognized point encoding + } + if len(data) != 1+byteLen { + return + } + + // Based on Routine 2.2.4 in NIST Mathematical routines paper + params := curve.Params() + tx := new(big.Int).SetBytes(data[1 : 1+byteLen]) + y2 := y2(params, tx) + sqrt := defaultSqrt + ty := sqrt(y2, params.P) + if ty == nil { + return // "y^2" is not a square: invalid point + } + var y2c big.Int + y2c.Mul(ty, ty).Mod(&y2c, params.P) + if y2c.Cmp(y2) != 0 { + return // sqrt(y2)^2 != y2: invalid point + } + if ty.Bit(0) != uint(data[0]&1) { + ty.Sub(params.P, ty) + } + + x, y = tx, ty // valid point: return it + return +} + +// Use the curve equation to calculate y² given x. +// only applies to curves of the form y² = x³ - 3x + b. +func y2(curve *elliptic.CurveParams, x *big.Int) *big.Int { + + // y² = x³ - 3x + b + // x3 := new(big.Int).Mul(x, x) + // x3.Mul(x3, x) + + // threeX := new(big.Int).Lsh(x, 1) + // threeX.Add(threeX, x) + + // x3.Sub(x3, threeX) + // x3.Add(x3, curve.B) + // x3.Mod(x3, curve.P) + + // change to bitelliptic : y² = x³ + b + x3 := new(big.Int).Mul(x, x) + x3.Mul(x3, x) + + x3.Add(x3, curve.B) + x3.Mod(x3, curve.P) + + return x3 +} + +func defaultSqrt(x, p *big.Int) *big.Int { + var r big.Int + if nil == r.ModSqrt(x, p) { + return nil // x is not a square + } + return &r +} diff --git a/crypto/keystore/secp256k1/vrf/vrf.go b/crypto/keystore/secp256k1/vrf/vrf.go new file mode 100644 index 000000000..28c522254 --- /dev/null +++ b/crypto/keystore/secp256k1/vrf/vrf.go @@ -0,0 +1,35 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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. + +// Package vrf defines the interface to a verifiable random function. + +// http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=814584 + +package vrf + +import "crypto" + +// PrivateKey supports evaluating the VRF function. +type PrivateKey interface { + // Evaluate returns the output of H(f_k(m)) and its proof. + Evaluate(m []byte) (index [32]byte, proof []byte) + // Public returns the corresponding public key. + Public() crypto.PublicKey +} + +// PublicKey supports verifying output from the VRF function. +type PublicKey interface { + // ProofToHash verifies the NP-proof supplied by Proof and outputs Index. + ProofToHash(m, proof []byte) (index [32]byte, err error) +} diff --git a/crypto/keystore/secp256k1/vrf/vrf_test.go b/crypto/keystore/secp256k1/vrf/vrf_test.go new file mode 100644 index 000000000..ac1ebd53d --- /dev/null +++ b/crypto/keystore/secp256k1/vrf/vrf_test.go @@ -0,0 +1,98 @@ +// Copyright (C) 2018 go-nebulas + +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + +package vrf + +import ( + "bytes" + "testing" + + "github.com/nebulasio/go-nebulas/util/byteutils" + + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" +) + +const ( + // private key in hex + privKey = `b02b430d4a9d7120b65038452a6da3f3c716829e5be3665adf934d4798d96ed7` + // public key in hex + pubKey = `04e4d0dde330c0b8d8d8b1b2071aa75c3e94f200a3d11ca1d908644eee50c8833a816dc0b2d003fc66187ef6750a56e1b3004d32e6159008400ab92f2ded7b4544` +) + +func TestVRF(t *testing.T) { + // priv, _ := crypto.NewPrivateKey(keystore.SECP256K1, nil) + // seckey, err := priv.Encoded() + // if err != nil { + // t.Errorf("new priv err: %v", err) + // } + // seckeypub, err := priv.PublicKey().Encoded() + // if err != nil { + // t.Errorf("pub of new priv err: %v", err) + // } + // fmt.Println("1:", byteutils.Hex(seckey)) + // fmt.Println("2:", byteutils.Hex(seckeypub)) + + seckey, err := byteutils.FromHex(privKey) + if err != nil { + t.Errorf("load priv err: %v", err) + } + ecdsaPriv, err := secp256k1.ToECDSAPrivateKey(seckey) + if err != nil { + t.Errorf("ecdsa err: %v", err) + } + + signer, err := secp256k1VRF.NewVRFSigner(ecdsaPriv) + if err != nil { + t.Errorf("new signer err: %v", err) + } + + data := []byte("b10c1203d5ae6d4d069d5f520eb060f2f5fb74e942f391e7cadbc2b5148dfbcb") + sIndex, proof := signer.Evaluate(data) + + seckeyPub, err := byteutils.FromHex(pubKey) + + priv := new(secp256k1.PrivateKey) + err = priv.Decode(seckey) + if err != nil { + t.Errorf("decode priv err: %v", err) + } + + epub, err := priv.PublicKey().Encoded() + if err != nil { + t.Errorf("encode pub err: %v", err) + } + if !bytes.Equal(seckeyPub, epub) { + t.Errorf("mismatched priv/pub err: %v", err) + } + + verifier, err := secp256k1VRF.NewVRFVerifierFromRawKey(seckeyPub) + if err != nil { + t.Errorf("new verifier err: %v", err) + } + + vIndex, err := verifier.ProofToHash(data, proof) + if err != nil { + t.Errorf("exec proof err: %v", err) + } + + if !bytes.Equal(sIndex[0:], vIndex[0:]) { + t.Errorf("verification failed") + } +} diff --git a/nf/nvm/blockchain.go b/nf/nvm/blockchain.go index 16a3aedde..d5639346d 100644 --- a/nf/nvm/blockchain.go +++ b/nf/nvm/blockchain.go @@ -181,7 +181,7 @@ func TransferFunc(handler unsafe.Pointer, to *C.char, v *C.char, gasCnt *C.size_ } } - if engine.ctx.block.Height() >= TransferFromContractEventCompatibilityHeight { + if engine.ctx.block.Height() >= core.TransferFromContractEventCompatibleHeight { cAddr, err := core.AddressParseFromBytes(engine.ctx.contract.Address()) if err != nil { logging.VLog().WithFields(logrus.Fields{ diff --git a/nf/nvm/event.go b/nf/nvm/event.go index 2c796a12b..3f3bac940 100644 --- a/nf/nvm/event.go +++ b/nf/nvm/event.go @@ -32,11 +32,6 @@ const ( EventBaseGasCount = 20 ) -const ( - // TransferFromContractEventCompatibilityHeight record event 'TransferFromContractEvent' after this height - TransferFromContractEventCompatibilityHeight uint64 = 200000 -) - // TransferFromContractEvent event for transfer in contract type TransferFromContractEvent struct { Amount string `json:"amount"` diff --git a/nf/nvm/lib/random.js b/nf/nvm/lib/random.js new file mode 120000 index 000000000..6d184e127 --- /dev/null +++ b/nf/nvm/lib/random.js @@ -0,0 +1 @@ +../v8/lib/random.js \ No newline at end of file diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index ba836cd75..bbf4573ff 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -142,9 +142,21 @@ var Date = (function(Date) { } NebDate.prototype = new Proxy(NebDate.prototype, { getPrototypeOf: function(target) { - throw new Error("Not supported method!"); + throw new Error("Unsupported method!"); }, }); Object.setPrototypeOf(NebDate.prototype, Date.prototype); return NebDate; -})(Date); \ No newline at end of file +})(Date); + +// Blockchain.block = { +// // seed: 20000000 +// } + +// Math.random = require('random.js'); + +// var arr = []; +// for (var i = 0; i<10; ++i) { +// arr.push(Math.random()); +// } +// throw new Error(arr); \ No newline at end of file diff --git a/nf/nvm/v8/lib/random.js b/nf/nvm/v8/lib/random.js new file mode 100644 index 000000000..e66bd7665 --- /dev/null +++ b/nf/nvm/v8/lib/random.js @@ -0,0 +1,122 @@ +// Copyright (C) 2018 go-nebulas +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + +// A port of an algorithm by Johannes Baagøe , 2010 +// http://baagoe.com/en/RandomMusings/javascript/ +// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror +// Original work is under MIT license - + +// Other seeded random number generators for JavaScript, see https://github.com/davidbau/seedrandom. + + +'use strict'; + +function Alea(seed) { + var me = this, mash = Mash(); + + me.next = function () { + var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32 + me.s0 = me.s1; + me.s1 = me.s2; + return me.s2 = t - (me.c = t | 0); + }; + + // Apply the seeding algorithm from Baagoe. + me.c = 1; + me.s0 = mash(' '); + me.s1 = mash(' '); + me.s2 = mash(' '); + me.s0 -= mash(seed); + if (me.s0 < 0) { me.s0 += 1; } + me.s1 -= mash(seed); + if (me.s1 < 0) { me.s1 += 1; } + me.s2 -= mash(seed); + if (me.s2 < 0) { me.s2 += 1; } + mash = null; +} + +function copy(f, t) { + t.c = f.c; + t.s0 = f.s0; + t.s1 = f.s1; + t.s2 = f.s2; + return t; +} + +function impl(seed, opts) { + var xg = new Alea(seed), + state = opts && opts.state, + prng = xg.next; + prng.int32 = function () { return (xg.next() * 0x100000000) | 0; } + prng.double = function () { + return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 + }; + prng.quick = prng; + if (state) { + if (typeof (state) == 'object') copy(state, xg); + prng.state = function () { return copy(xg, {}); } + } + return prng; +} + +function Mash() { + var n = 0xefc8249d; + + var mash = function (data) { + data = data.toString(); + for (var i = 0; i < data.length; i++) { + n += data.charCodeAt(i); + var h = 0.02519603282416938 * n; + n = h >>> 0; + h -= n; + h *= n; + n = h >>> 0; + h -= n; + n += h * 0x100000000; // 2^32 + } + return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 + }; + + return mash; +} + +module.exports = (function(){ + + if (!Blockchain) { + throw new Error("'Blockchain' is not defined."); + } + if (!Blockchain.block) { + throw new Error("'Blockchain.block' is not defined."); + } + + if (!Blockchain.block.seed) { + throw new Error("random seed not found."); + } + + var arng = new impl(Blockchain.block.seed); + return function() { + // Get a 32 bit (signed) integer. + // arng.int32() + + // Gets 56 bits of randomness. + // arng.double() + + // By default provides 32 bits of randomness in a float. + return arng(); + } +})(); \ No newline at end of file From 93d2b0c973ec245bed083bf45e8c68c64ebb5118 Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 27 Apr 2018 18:16:59 +0800 Subject: [PATCH 29/69] nvm: change string value to bigNumber. --- nf/nvm/test/NRC20.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nf/nvm/test/NRC20.js b/nf/nvm/test/NRC20.js index 9575ad7ef..1443867cc 100644 --- a/nf/nvm/test/NRC20.js +++ b/nf/nvm/test/NRC20.js @@ -148,6 +148,7 @@ StandardToken.prototype = { var allowed = this.allowed.get(from) || new Allowed(); var allowedValue = allowed.get(spender) || new BigNumber(0); + value = new BigNumber(value); if (value.gte(0) && balance.gte(value) && allowedValue.gte(value)) { @@ -186,12 +187,14 @@ StandardToken.prototype = { } var balance = new BigNumber(this.balanceOf(from)); + var value = new BigNumber(value); + if (value.lt(0) || balance.lt(value)) { throw new Error("invalid value."); } var owned = this.allowed.get(from) || new Allowed(); - owned.set(spender, new BigNumber(value)); + owned.set(spender, value); this.allowed.set(from, owned); From 19e307c3c3daa48dc4b4aaaf0a4dfd0ef9241e75 Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 27 Apr 2018 18:42:08 +0800 Subject: [PATCH 30/69] update Gopkg.lock --- Gopkg.lock | 258 ++++++++--------------------------------------------- 1 file changed, 37 insertions(+), 221 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 10d98d44f..f85651ca2 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -10,11 +10,7 @@ [[projects]] branch = "master" name = "github.com/agl/ed25519" - packages = [ - ".", - "edwards25519", - "extra25519" - ] + packages = [".","edwards25519","extra25519"] revision = "5312a61534124124185d41f09206b9fef1d88403" [[projects]] @@ -44,10 +40,7 @@ [[projects]] branch = "master" name = "github.com/docker/spdystream" - packages = [ - ".", - "spdy" - ] + packages = [".","spdy"] revision = "bc6354cbbc295e925e4c611ffe90c1f287ee54db" [[projects]] @@ -58,10 +51,7 @@ [[projects]] name = "github.com/gogo/protobuf" - packages = [ - "io", - "proto" - ] + packages = ["io","proto"] revision = "100ba4e885062801d56799d78530b73b178a78f3" version = "v0.4" @@ -74,16 +64,7 @@ [[projects]] branch = "master" name = "github.com/golang/protobuf" - packages = [ - "jsonpb", - "proto", - "protoc-gen-go/descriptor", - "ptypes", - "ptypes/any", - "ptypes/duration", - "ptypes/struct", - "ptypes/timestamp" - ] + packages = ["jsonpb","proto","protoc-gen-go/descriptor","ptypes","ptypes/any","ptypes/duration","ptypes/struct","ptypes/timestamp"] revision = "ae59567b9aab61b50b2590679a62c3c044030b61" [[projects]] @@ -92,6 +73,12 @@ packages = ["."] revision = "553a641470496b2327abcac10b36396bd98e45c9" +[[projects]] + branch = "master" + name = "github.com/google/keytransparency" + packages = ["core/crypto/vrf"] + revision = "e5573858922e6a9456ab5557779b37d30af56c4c" + [[projects]] name = "github.com/gorilla/websocket" packages = ["."] @@ -131,33 +118,18 @@ [[projects]] branch = "master" name = "github.com/hashicorp/golang-lru" - packages = [ - ".", - "simplelru" - ] + packages = [".","simplelru"] revision = "0a025b7e63adc15a622f29b0b2c4c3848243bbf6" [[projects]] branch = "master" name = "github.com/huin/goupnp" - packages = [ - ".", - "dcps/internetgateway1", - "dcps/internetgateway2", - "httpu", - "scpd", - "soap", - "ssdp" - ] + packages = [".","dcps/internetgateway1","dcps/internetgateway2","httpu","scpd","soap","ssdp"] revision = "5b7801abd885f2f7458add715aee47e7df5370a0" [[projects]] name = "github.com/influxdata/influxdb" - packages = [ - "client", - "models", - "pkg/escape" - ] + packages = ["client","models","pkg/escape"] revision = "6d2685d1738277a1c2672fc58df7994627769be6" version = "v1.4.2" @@ -200,12 +172,7 @@ [[projects]] branch = "master" name = "github.com/jbenet/goprocess" - packages = [ - ".", - "context", - "periodic", - "ratelimit" - ] + packages = [".","context","periodic","ratelimit"] revision = "b497e2f366b8624394fb2e89c10ab607bebdde0b" [[projects]] @@ -229,20 +196,13 @@ [[projects]] branch = "master" name = "github.com/libp2p/go-libp2p" - packages = [ - "p2p/host/basic", - "p2p/protocol/identify", - "p2p/protocol/identify/pb" - ] + packages = ["p2p/host/basic","p2p/protocol/identify","p2p/protocol/identify/pb"] revision = "edb6434ddf456f58fbe2538d5336435a23915bd9" [[projects]] branch = "master" name = "github.com/libp2p/go-libp2p-circuit" - packages = [ - ".", - "pb" - ] + packages = [".","pb"] revision = "4730183d80def7bc574e1b486b1f6e97a5c67bb9" [[projects]] @@ -253,10 +213,7 @@ [[projects]] name = "github.com/libp2p/go-libp2p-crypto" - packages = [ - ".", - "pb" - ] + packages = [".","pb"] revision = "e89e1de117dd65c6129d99d1d853f48bc847cf17" [[projects]] @@ -284,10 +241,7 @@ [[projects]] branch = "master" name = "github.com/libp2p/go-libp2p-kbucket" - packages = [ - ".", - "keyspace" - ] + packages = [".","keyspace"] revision = "5ce3bb926eeeadf90708fec12343cbf858ed24b6" [[projects]] @@ -299,11 +253,7 @@ [[projects]] branch = "master" name = "github.com/libp2p/go-libp2p-metrics" - packages = [ - ".", - "conn", - "stream" - ] + packages = [".","conn","stream"] revision = "1ac87496e992290629575655bea4330dd4ab211e" [[projects]] @@ -324,10 +274,7 @@ [[projects]] name = "github.com/libp2p/go-libp2p-peerstore" - packages = [ - ".", - "addr" - ] + packages = [".","addr"] revision = "89838b9577a2b83eb3e1632c162cfd0daeee58e3" [[projects]] @@ -339,10 +286,7 @@ [[projects]] branch = "master" name = "github.com/libp2p/go-libp2p-secio" - packages = [ - ".", - "pb" - ] + packages = [".","pb"] revision = "0cdc8339ad2e4f7f32e67b6a481bfbd48be5c704" [[projects]] @@ -365,10 +309,7 @@ [[projects]] branch = "master" name = "github.com/libp2p/go-msgio" - packages = [ - ".", - "mpool" - ] + packages = [".","mpool"] revision = "d82125c9907e1365775356505f14277d47dfd4d6" [[projects]] @@ -380,11 +321,7 @@ [[projects]] branch = "master" name = "github.com/libp2p/go-reuseport" - packages = [ - ".", - "poll", - "singlepoll" - ] + packages = [".","poll","singlepoll"] revision = "2a863ed0ff1167e16ff48dd1de862b180af3bf27" [[projects]] @@ -449,10 +386,7 @@ [[projects]] branch = "master" name = "github.com/multiformats/go-multicodec" - packages = [ - ".", - "json" - ] + packages = [".","json"] revision = "fd289ac41fba9e574f214ab2a808a1678ef8810c" [[projects]] @@ -476,11 +410,7 @@ [[projects]] branch = "master" name = "github.com/nebulasio/grpc-gateway" - packages = [ - "runtime", - "runtime/internal", - "utilities" - ] + packages = ["runtime","runtime/internal","utilities"] revision = "9ed0e3fde466911904aef99bf3ecc8197d54b21d" [[projects]] @@ -504,10 +434,7 @@ [[projects]] branch = "master" name = "github.com/rcrowley/go-metrics" - packages = [ - ".", - "exp" - ] + packages = [".","exp"] revision = "1f30fe9094a513ce4c700b9a54458bbb0c96996c" [[projects]] @@ -519,15 +446,7 @@ [[projects]] branch = "master" name = "github.com/robertkrimen/otto" - packages = [ - ".", - "ast", - "dbg", - "file", - "parser", - "registry", - "token" - ] + packages = [".","ast","dbg","file","parser","registry","token"] revision = "68a29f5e29b18d7367e686c43cf74eba1900f548" [[projects]] @@ -557,29 +476,13 @@ [[projects]] branch = "master" name = "github.com/stretchr/testify" - packages = [ - "assert", - "require" - ] + packages = ["assert","require"] revision = "890a5c3458b43e6104ff5da8dfa139d013d77544" [[projects]] branch = "master" name = "github.com/syndtr/goleveldb" - packages = [ - "leveldb", - "leveldb/cache", - "leveldb/comparer", - "leveldb/errors", - "leveldb/filter", - "leveldb/iterator", - "leveldb/journal", - "leveldb/memdb", - "leveldb/opt", - "leveldb/storage", - "leveldb/table", - "leveldb/util" - ] + packages = ["leveldb","leveldb/cache","leveldb/comparer","leveldb/errors","leveldb/filter","leveldb/iterator","leveldb/journal","leveldb/memdb","leveldb/opt","leveldb/storage","leveldb/table","leveldb/util"] revision = "b89cc31ef7977104127d34c1bd31ebd1a9db2199" [[projects]] @@ -594,12 +497,6 @@ revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" version = "v1.20.0" -[[projects]] - branch = "master" - name = "github.com/vrischmann/go-metrics-influxdb" - packages = ["."] - revision = "43af8332c303f62ef62663b02b3b7d8a9802002a" - [[projects]] branch = "master" name = "github.com/whyrusleeping/go-logging" @@ -669,129 +566,48 @@ [[projects]] branch = "master" name = "golang.org/x/crypto" - packages = [ - "blake2s", - "blowfish", - "pbkdf2", - "ripemd160", - "scrypt", - "sha3", - "ssh/terminal" - ] + packages = ["blake2s","blowfish","pbkdf2","ripemd160","scrypt","sha3","ssh/terminal"] revision = "faadfbdc035307d901e69eea569f5dda451a3ee3" [[projects]] branch = "master" name = "golang.org/x/net" - packages = [ - "context", - "html", - "html/atom", - "html/charset", - "http2", - "http2/hpack", - "idna", - "internal/timeseries", - "lex/httplex", - "netutil", - "trace" - ] + packages = ["context","html","html/atom","html/charset","http2","http2/hpack","idna","internal/timeseries","lex/httplex","netutil","trace"] revision = "8351a756f30f1297fe94bbf4b767ec589c6ea6d0" [[projects]] branch = "master" name = "golang.org/x/sys" - packages = [ - "unix", - "windows" - ] + packages = ["unix","windows"] revision = "062cd7e4e68206d8bab9b18396626e855c992658" [[projects]] branch = "master" name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "encoding", - "encoding/charmap", - "encoding/htmlindex", - "encoding/internal", - "encoding/internal/identifier", - "encoding/japanese", - "encoding/korean", - "encoding/simplifiedchinese", - "encoding/traditionalchinese", - "encoding/unicode", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "internal/utf8internal", - "language", - "runes", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable" - ] + packages = ["collate","collate/build","encoding","encoding/charmap","encoding/htmlindex","encoding/internal","encoding/internal/identifier","encoding/japanese","encoding/korean","encoding/simplifiedchinese","encoding/traditionalchinese","encoding/unicode","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","internal/utf8internal","language","runes","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"] revision = "1cbadb444a806fd9430d14ad08967ed91da4fa0a" [[projects]] branch = "master" name = "google.golang.org/genproto" - packages = [ - "googleapis/api/annotations", - "googleapis/rpc/status" - ] + packages = ["googleapis/api/annotations","googleapis/rpc/status"] revision = "f676e0f3ac6395ff1a529ae59a6670878a8371a6" [[projects]] name = "google.golang.org/grpc" - packages = [ - ".", - "balancer", - "balancer/base", - "balancer/roundrobin", - "codes", - "connectivity", - "credentials", - "encoding", - "grpclb/grpc_lb_v1/messages", - "grpclog", - "internal", - "keepalive", - "metadata", - "naming", - "peer", - "reflection", - "reflection/grpc_reflection_v1alpha", - "resolver", - "resolver/dns", - "resolver/passthrough", - "stats", - "status", - "tap", - "transport" - ] + packages = [".","balancer","balancer/base","balancer/roundrobin","codes","connectivity","credentials","encoding","grpclb/grpc_lb_v1/messages","grpclog","internal","keepalive","metadata","naming","peer","reflection","reflection/grpc_reflection_v1alpha","resolver","resolver/dns","resolver/passthrough","stats","status","tap","transport"] revision = "6b51017f791ae1cfbec89c52efdf444b13b550ef" version = "v1.9.2" [[projects]] name = "gopkg.in/sourcemap.v1" - packages = [ - ".", - "base64vlq" - ] + packages = [".","base64vlq"] revision = "6e83acea0053641eff084973fee085f0c193c61a" version = "v1.0.5" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "3cbb9060c41566687af55087832faa959bbf5e39cb4349bb1de287051e43b585" + inputs-digest = "105cf7ff893a2ebe6f3323ec78756a46b9bc5f7dc0708b4ff00a04bef0f8faaf" solver-name = "gps-cdcl" solver-version = 1 From daea43892b1b3deac992c66f6d8416e5e44e11d6 Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 27 Apr 2018 18:45:43 +0800 Subject: [PATCH 31/69] net: optimize network message compression --- net/neb_message.go | 6 +- net/stream.go | 71 +++++++++---- nf/nvm/test/NRC721.js | 229 ------------------------------------------ 3 files changed, 55 insertions(+), 251 deletions(-) delete mode 100644 nf/nvm/test/NRC721.js diff --git a/net/neb_message.go b/net/neb_message.go index 4cac081a1..c92e29a3d 100644 --- a/net/neb_message.go +++ b/net/neb_message.go @@ -86,7 +86,7 @@ const ( var ( MagicNumber = []byte{0x4e, 0x45, 0x42, 0x31} DefaultReserved = []byte{DefaultReservedFlag, DefaultReservedFlag, DefaultReservedFlag} - CurrentReserved = []byte{DefaultReservedFlag | ReservedCompressionEnableFlag, DefaultReservedFlag, DefaultReservedFlag | ReservedCompressionClientFlag} + CurrentReserved = []byte{DefaultReservedFlag | ReservedCompressionEnableFlag, DefaultReservedFlag, DefaultReservedFlag} ErrInsufficientMessageHeaderLength = errors.New("insufficient message header length") ErrInsufficientMessageDataLength = errors.New("insufficient message data length") @@ -166,7 +166,7 @@ func (message *NebMessage) HeaderWithoutCheckSum() []byte { func (message *NebMessage) Data() ([]byte, error) { reserved := message.Reserved() data := message.content[NebMessageHeaderLength:] - if ((reserved[2] & ReservedCompressionClientFlag) > 0) && ((reserved[0] & ReservedCompressionEnableFlag) > 0) { + if (reserved[0] & ReservedCompressionEnableFlag) > 0 { var err error data, err = snappy.Decode(nil, data) if err != nil { @@ -194,7 +194,7 @@ func (message *NebMessage) Length() uint64 { // NewNebMessage new neb message func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { // Process message compression - if ((reserved[2] & ReservedCompressionClientFlag) > 0) && ((reserved[0] & ReservedCompressionEnableFlag) > 0) { + if (reserved[0] & ReservedCompressionEnableFlag) > 0 { data = snappy.Encode(nil, data) } diff --git a/net/stream.go b/net/stream.go index 0542e78e3..99dd2fd45 100644 --- a/net/stream.go +++ b/net/stream.go @@ -262,7 +262,7 @@ func (s *Stream) WriteNebMessage(message *NebMessage) error { } // WriteProtoMessage write proto msg in the stream -func (s *Stream) WriteProtoMessage(messageName string, pb proto.Message) error { +func (s *Stream) WriteProtoMessage(messageName string, pb proto.Message, reservedClientFlag byte) error { data, err := proto.Marshal(pb) if err != nil { logging.VLog().WithFields(logrus.Fields{ @@ -273,11 +273,16 @@ func (s *Stream) WriteProtoMessage(messageName string, pb proto.Message) error { return err } - return s.WriteMessage(messageName, data) + return s.WriteMessage(messageName, data, reservedClientFlag) } // WriteMessage write raw msg in the stream -func (s *Stream) WriteMessage(messageName string, data []byte) error { +func (s *Stream) WriteMessage(messageName string, data []byte, reservedClientFlag byte) error { + // hello and ok messages come with the client flag bit. + if reservedClientFlag == ReservedCompressionClientFlag { + s.reservedFlag[2] = s.reservedFlag[2] | reservedClientFlag + } + message, err := NewNebMessage(s.node.config.ChainID, s.reservedFlag, CurrentVersion, messageName, data) if err != nil { return err @@ -463,7 +468,7 @@ func (s *Stream) handleMessage(message *NebMessage) error { case ROUTETABLE: return s.onRouteTable(message) default: - data, err := message.Data() + data, err := s.getData(message) if err != nil { return err } @@ -506,7 +511,7 @@ func (s *Stream) close(reason error) { // Bye say bye in the stream func (s *Stream) Bye() { - s.WriteMessage(BYE, []byte{}) + s.WriteMessage(BYE, []byte{}, DefaultReservedFlag) s.close(errors.New("bye: force close")) } @@ -523,15 +528,11 @@ func (s *Stream) Hello() error { NodeId: s.node.id.String(), ClientVersion: ClientVersion, } - return s.WriteProtoMessage(HELLO, msg) + return s.WriteProtoMessage(HELLO, msg, ReservedCompressionClientFlag) } func (s *Stream) onHello(message *NebMessage) error { - data, err := message.Data() - if err != nil { - return err - } - msg, err := netpb.HelloMessageFromProto(data) + msg, err := netpb.HelloMessageFromProto(message.OriginalData()) if err != nil { return ErrShouldCloseConnectionAndExitLoop } @@ -568,16 +569,11 @@ func (s *Stream) Ok() error { ClientVersion: ClientVersion, } - return s.WriteProtoMessage(OK, resp) + return s.WriteProtoMessage(OK, resp, ReservedCompressionClientFlag) } func (s *Stream) onOk(message *NebMessage) error { - data, err := message.Data() - if err != nil { - return err - } - - msg, err := netpb.OKMessageFromProto(data) + msg, err := netpb.OKMessageFromProto(message.OriginalData()) if err != nil { return ErrShouldCloseConnectionAndExitLoop } @@ -645,10 +641,11 @@ func (s *Stream) RouteTable() error { } func (s *Stream) onRouteTable(message *NebMessage) error { - data, err := message.Data() + data, err := s.getData(message) if err != nil { return err } + peers := new(netpb.Peers) if err := proto.Unmarshal(data, peers); err != nil { logging.VLog().WithFields(logrus.Fields{ @@ -671,16 +668,52 @@ func (s *Stream) finishHandshake() { s.handshakeSucceedCh <- true } +func (s *Stream) getData(message *NebMessage) ([]byte, error) { + var data []byte + if ByteSliceEqualBCE(s.reservedFlag, CurrentReserved) { + var err error + data, err = message.Data() + if err != nil { + return nil, err + } + } else { + data = message.OriginalData() + } + return data, nil +} + // CheckClientVersionCompatibility if two clients are compatible // If the clientVersion of node A is X.Y.Z, then node B must be X.Y.{} to be compatible with A. func CheckClientVersionCompatibility(v1, v2 string) bool { s1 := strings.Split(v1, ".") s2 := strings.Split(v1, ".") + if len(s1) != 3 || len(s2) != 3 { return false } + if s1[0] != s2[0] || s1[1] != s2[1] { return false } return true } + +// ByteSliceEqualBCE determines whether two byte arrays are equal. +func ByteSliceEqualBCE(a, b []byte) bool { + if len(a) != len(b) { + return false + } + + if (a == nil) != (b == nil) { + return false + } + + b = b[:len(a)] + for i, v := range a { + if v != b[i] { + return false + } + } + + return true +} diff --git a/nf/nvm/test/NRC721.js b/nf/nvm/test/NRC721.js deleted file mode 100644 index c78b037de..000000000 --- a/nf/nvm/test/NRC721.js +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (C) 2017 go-nebulas authors -// -// This file is part of the go-nebulas library. -// -// the go-nebulas library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// the go-nebulas library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with the go-nebulas library. If not, see . -// - -'use strict'; - -var Allowed = function (obj) { - this.allowed = {}; - this.parse(obj); -} - -Allowed.prototype = { - toString: function () { - return JSON.stringify(this.allowed); - }, - - parse: function (obj) { - if (typeof obj != "undefined") { - var data = JSON.parse(obj); - for (var key in data) { - this.allowed[key] = new BigNumber(data[key]); - } - } - }, - - get: function (key) { - return this.allowed[key]; - }, - - set: function (key, value) { - this.allowed[key] = new BigNumber(value); - } -} - -var StandardToken = function () { - LocalContractStorage.defineProperties(this, { - _name: null, - _symbol: null, - _allTokens: { - parse: function (value) { - var arr = JSON.parse(value); - var ret = new Array(); - arr.forEach(function(v) { - ret.push(new BigNumber(v)); - }, this); - return ret; - }, - stringify: function (o) { - return JSON.stringify(o); - } - }, - }); - - LocalContractStorage.defineMapProperties(this, { - "tokenOwner": null, - "ownedTokensCount": { - parse: function (value) { - return new BigNumber(value); - }, - stringify: function (o) { - return o.toString(10); - } - }, - "ownedTokens": { - parse: function (value) { - var arr = JSON.parse(value); - var ret = new Array(); - arr.forEach(function(v) { - ret.push(new BigNumber(v)); - }, this); - return ret; - }, - stringify: function (o) { - return JSON.stringify(o); - } - }, - "ownedTokensIndex": { - parse: function (value) { - return new BigNumber(value); - }, - stringify: function (o) { - return o.toString(10); - } - } - }); -}; - -StandardToken.prototype = { - init: function (name, symbol) { - this._name = name; - this._symbol = symbol; - }, - - // Returns the name of the token - name: function () { - return this._name; - }, - - // Returns the symbol of the token - symbol: function () { - return this._symbol; - }, - - totalSupply: function () { - return this._allTokens.length; - }, - - balanceOf: function (owner) { - var balance = this.balances.get(owner); - - if (balance instanceof BigNumber) { - return balance.toString(10); - } else { - return "0"; - } - }, - - transfer: function (to, value) { - value = new BigNumber(value); - - var from = Blockchain.transaction.from; - var balance = this.balances.get(from) || new BigNumber(0); - - if (balance.lt(value)) { - throw new Error("transfer failed."); - } - - this.balances.set(from, balance.sub(value)); - var toBalance = this.balances.get(to) || new BigNumber(0); - this.balances.set(to, toBalance.add(value)); - - this.transferEvent(true, from, to, value); - }, - - transferFrom: function (from, to, value) { - var txFrom = Blockchain.transaction.from; - var balance = this.balances.get(from) || new BigNumber(0); - - var allowed = this.allowed.get(from) || new Allowed(); - var allowedValue = allowed.get(txFrom) || new BigNumber(0); - - if (balance.gte(value) && allowedValue.gte(value)) { - - this.balances.set(from, balance.sub(value)); - - // update allowed value - allowed.set(txFrom, allowedValue.sub(value)); - this.allowed.set(from, allowed); - - var toBalance = this.balances.get(to) || new BigNumber(0); - this.balances.set(to, toBalance.add(value)); - - this.transferEvent(true, from, to, value); - } else { - throw new Error("transfer failed."); - } - }, - - transferEvent: function (status, from, to, value) { - Event.Trigger(this.name(), { - Status: status, - Transfer: { - from: from, - to: to, - value: value - } - }); - }, - - approve: function (spender, currentValue, value) { - var from = Blockchain.transaction.from; - - var oldValue = this.allowance(from, spender); - if (oldValue != currentValue.toString()) { - throw new Error("current approve value mistake."); - } - - var balance = new BigNumber(this.balanceOf(from)); - if (balance.lt(value)) { - throw new Error("approve value bigger than balance."); - } - - var owned = this.allowed.get(from) || new Allowed(); - owned.set(spender, new BigNumber(value)); - - this.allowed.set(from, owned); - - this.approveEvent(true, from, spender, value); - }, - - approveEvent: function (status, from, spender, value) { - Event.Trigger(this.name(), { - Status: status, - Approve: { - owner: from, - spender: spender, - value: value - } - }); - }, - - allowance: function (owner, spender) { - var owned = this.allowed.get(owner); - - if (owned instanceof Allowed) { - var spender = owned.get(spender); - if (typeof spender != "undefined") { - return spender.toString(10); - } - } - return "0"; - } -}; - -module.exports = StandardToken; From d683c4b9ca8b8632d66bd686a98e9f68bf5162ce Mon Sep 17 00:00:00 2001 From: Larry Wang Date: Sat, 28 Apr 2018 13:49:03 +0800 Subject: [PATCH 32/69] nvm: fix nrc20 params set --- nf/nvm/test/NRC20.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf/nvm/test/NRC20.js b/nf/nvm/test/NRC20.js index 1443867cc..dec13b223 100644 --- a/nf/nvm/test/NRC20.js +++ b/nf/nvm/test/NRC20.js @@ -85,7 +85,7 @@ StandardToken.prototype = { init: function (name, symbol, decimals, totalSupply) { this._name = name; this._symbol = symbol; - this._decimals = decimals | 0; + this._decimals = decimals || 0; this._totalSupply = new BigNumber(totalSupply).mul(new BigNumber(10).pow(decimals)); var from = Blockchain.transaction.from; From 4848144e10a63fa64cf00af4930aa3fa556871f1 Mon Sep 17 00:00:00 2001 From: fengzi Date: Sat, 28 Apr 2018 15:24:14 +0800 Subject: [PATCH 33/69] rpc:api_service.go return execute error in get tx func and add simulate where nonce = acc.noce +1 --- rpc/api_service.go | 45 ++++--- rpc/pb/rpc.pb.go | 292 +++++++++++++++++++++++--------------------- rpc/pb/rpc.pb.gw.go | 108 ++++++++++------ rpc/pb/rpc.proto | 3 + 4 files changed, 255 insertions(+), 193 deletions(-) diff --git a/rpc/api_service.go b/rpc/api_service.go index 291eb3355..6d3b651da 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -202,6 +202,18 @@ func handleTransactionResponse(neb core.Neblet, tx *core.Transaction) (resp *rpc return nil, errors.New("transaction's nonce is invalid, should bigger than the from's nonce") } + // check Balance Simulate + if tx.Nonce() == acc.Nonce()+1 { + result, err := neb.BlockChain().SimulateTransactionExecution(tx) + if err != nil { + return nil, err + } + + if result.Err != nil { + return nil, result.Err + } + } + if tx.Type() == core.TxPayloadDeployType { if !tx.From().Equals(tx.To()) { return nil, core.ErrContractTransactionAddressNotEqual @@ -350,8 +362,9 @@ func (s *APIService) GetTransactionReceipt(ctx context.Context, req *rpcpb.GetTr func (s *APIService) toTransactionResponse(tx *core.Transaction) (*rpcpb.TransactionResponse, error) { var ( - status int32 - gasUsed string + status int32 + gasUsed string + execute_error string ) neb := s.server.Neblet() event, err := neb.BlockChain().TailBlock().FetchExecutionResultEvent(tx.Hash()) @@ -367,24 +380,26 @@ func (s *APIService) toTransactionResponse(tx *core.Transaction) (*rpcpb.Transac } status = int32(txEvent.Status) gasUsed = txEvent.GasUsed + execute_error = txEvent.Error } else { status = core.TxExecutionPendding } resp := &rpcpb.TransactionResponse{ - ChainId: tx.ChainID(), - Hash: tx.Hash().String(), - From: tx.From().String(), - To: tx.To().String(), - Value: tx.Value().String(), - Nonce: tx.Nonce(), - Timestamp: tx.Timestamp(), - Type: tx.Type(), - Data: tx.Data(), - GasPrice: tx.GasPrice().String(), - GasLimit: tx.GasLimit().String(), - Status: status, - GasUsed: gasUsed, + ChainId: tx.ChainID(), + Hash: tx.Hash().String(), + From: tx.From().String(), + To: tx.To().String(), + Value: tx.Value().String(), + Nonce: tx.Nonce(), + Timestamp: tx.Timestamp(), + Type: tx.Type(), + Data: tx.Data(), + GasPrice: tx.GasPrice().String(), + GasLimit: tx.GasLimit().String(), + Status: status, + GasUsed: gasUsed, + ExecuteError: execute_error, } if tx.Type() == core.TxPayloadDeployType { diff --git a/rpc/pb/rpc.pb.go b/rpc/pb/rpc.pb.go index ed29b0d89..17dee1e88 100644 --- a/rpc/pb/rpc.pb.go +++ b/rpc/pb/rpc.pb.go @@ -58,10 +58,8 @@ import _ "google.golang.org/genproto/googleapis/api/annotations" import consensuspb "github.com/nebulasio/go-nebulas/consensus/pb" import nebletpb "github.com/nebulasio/go-nebulas/neblet/pb" -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -851,6 +849,8 @@ type TransactionResponse struct { Status int32 `protobuf:"varint,13,opt,name=status,proto3" json:"status,omitempty"` // transaction gas used GasUsed string `protobuf:"bytes,14,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + // contract excute + ExecuteError string `protobuf:"bytes,15,opt,name=execute_error,json=executeError,proto3" json:"execute_error,omitempty"` } func (m *TransactionResponse) Reset() { *m = TransactionResponse{} } @@ -956,6 +956,13 @@ func (m *TransactionResponse) GetGasUsed() string { return "" } +func (m *TransactionResponse) GetExecuteError() string { + if m != nil { + return m.ExecuteError + } + return "" +} + type NewAccountRequest struct { Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` } @@ -2318,142 +2325,143 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2190 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0x4b, 0x6f, 0x1b, 0xc9, - 0x11, 0x06, 0x49, 0x3d, 0xc8, 0x22, 0x25, 0xd1, 0xad, 0xd7, 0x88, 0x96, 0x64, 0xb9, 0xbd, 0xd8, - 0xd5, 0x1a, 0x59, 0x71, 0xad, 0x05, 0x9c, 0xc0, 0xc1, 0x06, 0xb0, 0x1d, 0xaf, 0xd6, 0x81, 0x61, - 0x38, 0x23, 0x6f, 0xb2, 0x40, 0xe2, 0x10, 0xcd, 0x61, 0x8b, 0xec, 0xec, 0x68, 0x66, 0x32, 0xdd, - 0xb4, 0x2d, 0x5d, 0x02, 0xec, 0x3d, 0xa7, 0x5c, 0x72, 0xc8, 0x3f, 0xc8, 0xaf, 0x09, 0x72, 0xc8, - 0x25, 0xc7, 0x9c, 0x72, 0xcb, 0x3f, 0x08, 0xba, 0xa6, 0x7b, 0x5e, 0x1c, 0x8a, 0x71, 0x0e, 0xb9, - 0x4d, 0x55, 0x77, 0x57, 0x55, 0xd7, 0xe3, 0xab, 0x6a, 0x12, 0x5a, 0x71, 0xe4, 0x9d, 0x44, 0x71, - 0xa8, 0x42, 0xb2, 0x1c, 0x47, 0x5e, 0x34, 0xec, 0xed, 0x8f, 0xc3, 0x70, 0xec, 0xf3, 0x3e, 0x8b, - 0x44, 0x9f, 0x05, 0x41, 0xa8, 0x98, 0x12, 0x61, 0x20, 0x93, 0x4d, 0xbd, 0x1f, 0x8d, 0x85, 0x9a, - 0x4c, 0x87, 0x27, 0x5e, 0x78, 0xd9, 0x0f, 0xf8, 0x70, 0xea, 0x33, 0x29, 0xc2, 0xfe, 0x38, 0xfc, - 0xcc, 0x10, 0x7d, 0x2f, 0x0c, 0x24, 0x0f, 0xe4, 0x54, 0xf6, 0xa3, 0x61, 0x5f, 0x2a, 0xa6, 0xb8, - 0x39, 0xf9, 0x70, 0xd1, 0xc9, 0x80, 0x0f, 0x7d, 0xae, 0xf4, 0x31, 0x2f, 0x0c, 0x2e, 0xc4, 0x38, - 0x39, 0x47, 0xef, 0x43, 0xf7, 0x7c, 0x3a, 0x94, 0x5e, 0x2c, 0x86, 0xdc, 0xe5, 0xbf, 0x9b, 0x72, - 0xa9, 0xc8, 0x0e, 0xac, 0xa8, 0x30, 0x12, 0x9e, 0x74, 0x6a, 0x47, 0x8d, 0xe3, 0x96, 0x6b, 0x28, - 0xfa, 0x25, 0xdc, 0xca, 0xed, 0x95, 0x91, 0xb6, 0x85, 0x6c, 0xc1, 0x32, 0x2e, 0x3b, 0xb5, 0xa3, - 0xda, 0x71, 0xcb, 0x4d, 0x08, 0x42, 0x60, 0x69, 0xc4, 0x14, 0x73, 0xea, 0xc8, 0xc4, 0x6f, 0x4a, - 0xa0, 0xfb, 0x32, 0x0c, 0x5e, 0xb1, 0x98, 0x5d, 0x4a, 0xa3, 0x8a, 0xfe, 0xb9, 0xae, 0x99, 0x23, - 0xfe, 0x3c, 0xb8, 0x08, 0x53, 0x91, 0xeb, 0x50, 0x17, 0x23, 0x23, 0xaf, 0x2e, 0x46, 0x64, 0x0f, - 0x9a, 0xde, 0x84, 0x89, 0x60, 0x20, 0x46, 0x28, 0x70, 0xcd, 0x5d, 0x45, 0xfa, 0xf9, 0x88, 0xf4, - 0xa0, 0xe9, 0x85, 0x22, 0x18, 0x32, 0xc9, 0x9d, 0x06, 0x1e, 0x48, 0x69, 0x72, 0x00, 0x10, 0x71, - 0x1e, 0x0f, 0xbc, 0x70, 0x1a, 0x28, 0x67, 0x09, 0x0f, 0xb6, 0x34, 0xe7, 0xa9, 0x66, 0x10, 0x0a, - 0x1d, 0x79, 0x15, 0x78, 0x93, 0x38, 0x0c, 0xc4, 0x35, 0x1f, 0x39, 0xcb, 0x47, 0xb5, 0xe3, 0xa6, - 0x5b, 0xe0, 0x91, 0x3b, 0xd0, 0x1e, 0x4e, 0xbd, 0xef, 0xb8, 0x1a, 0x48, 0x71, 0xcd, 0x9d, 0x95, - 0xa3, 0xda, 0xf1, 0xb2, 0x0b, 0x09, 0xeb, 0x5c, 0x5c, 0x73, 0xf2, 0x29, 0x74, 0xd1, 0x8f, 0x5e, - 0xe8, 0x0f, 0xde, 0xf2, 0x58, 0x8a, 0x30, 0x70, 0x00, 0xed, 0xd8, 0xb0, 0xfc, 0x5f, 0x24, 0x6c, - 0x72, 0x0a, 0xed, 0x38, 0x9c, 0x2a, 0x3e, 0x50, 0x6c, 0xe8, 0x73, 0xa7, 0x7d, 0xd4, 0x38, 0x6e, - 0x9f, 0xde, 0x3a, 0xc1, 0xb4, 0x38, 0x71, 0xf5, 0xca, 0x6b, 0xbd, 0xe0, 0x42, 0x9c, 0x7e, 0xd3, - 0x87, 0x00, 0xd9, 0xca, 0x8c, 0x5f, 0x1c, 0x58, 0x65, 0xa3, 0x51, 0xcc, 0xa5, 0x74, 0xea, 0x18, - 0x28, 0x4b, 0xd2, 0xbf, 0xd7, 0x60, 0xf3, 0x8c, 0xab, 0x97, 0x7c, 0x78, 0xae, 0x73, 0x24, 0xf5, - 0x6c, 0xde, 0x93, 0xb5, 0xa2, 0x27, 0x09, 0x2c, 0x29, 0x26, 0x7c, 0x1b, 0x31, 0xfd, 0x4d, 0xba, - 0xd0, 0xf0, 0xc5, 0xd0, 0x38, 0x56, 0x7f, 0xea, 0xd4, 0x98, 0x70, 0x31, 0x9e, 0x24, 0xfe, 0x5c, - 0x72, 0x0d, 0x55, 0xe9, 0x87, 0x95, 0x6a, 0x3f, 0x94, 0xfd, 0xbe, 0x5a, 0xe1, 0x77, 0x07, 0x56, - 0xad, 0x94, 0x26, 0x4a, 0xb1, 0x24, 0xfd, 0x1c, 0xba, 0x8f, 0x3d, 0x8c, 0xa8, 0x4c, 0x6f, 0xb5, - 0x0f, 0x2d, 0x73, 0x71, 0x6e, 0x53, 0x36, 0x63, 0xd0, 0x9f, 0xc1, 0xce, 0x19, 0x57, 0xe6, 0x90, - 0x71, 0x47, 0x92, 0xe7, 0x39, 0xff, 0x25, 0x4e, 0xb5, 0x64, 0xee, 0x9a, 0xf5, 0xfc, 0x35, 0xe9, - 0x1b, 0xd8, 0x9d, 0x91, 0x65, 0x8c, 0x70, 0x60, 0x75, 0xc8, 0x7c, 0x16, 0x78, 0xdc, 0x0a, 0x33, - 0xa4, 0xae, 0x90, 0x20, 0xd4, 0xfc, 0x44, 0x56, 0x42, 0xa0, 0xbf, 0xaf, 0xa2, 0x24, 0x6b, 0xd7, - 0x5c, 0xfc, 0xa6, 0xbf, 0x85, 0xce, 0x53, 0xe6, 0xfb, 0xa9, 0xcc, 0x1d, 0x58, 0x89, 0xb9, 0x9c, - 0xfa, 0xca, 0x88, 0x34, 0x94, 0x4e, 0x4b, 0xfe, 0x9e, 0x7b, 0x3a, 0x99, 0x78, 0x1c, 0x9b, 0x90, - 0x81, 0x61, 0x3d, 0x8b, 0x63, 0x72, 0x17, 0x3a, 0x5c, 0x2a, 0x71, 0xc9, 0x14, 0x1f, 0x8c, 0x99, - 0x34, 0x11, 0x6c, 0x5b, 0xde, 0x19, 0x93, 0xf4, 0x04, 0xb6, 0x9e, 0x5c, 0x3d, 0xf1, 0x43, 0xef, - 0xbb, 0xaf, 0xf1, 0x6e, 0xb9, 0xe2, 0x37, 0x57, 0xaf, 0x15, 0xae, 0xfe, 0x03, 0x20, 0x67, 0x5c, - 0xfd, 0xf4, 0x2a, 0x60, 0x52, 0x5d, 0xe5, 0x2d, 0xbc, 0x14, 0x01, 0x8f, 0x53, 0xa8, 0x48, 0x28, - 0xfa, 0xaf, 0x1a, 0x90, 0xd7, 0x31, 0x0b, 0x24, 0xf3, 0x34, 0xbe, 0x59, 0xe1, 0x04, 0x96, 0x2e, - 0xe2, 0xf0, 0xd2, 0x5c, 0x07, 0xbf, 0x75, 0x56, 0xab, 0xd0, 0xdc, 0xa1, 0xae, 0x42, 0xed, 0xae, - 0xb7, 0xcc, 0x9f, 0xda, 0x7a, 0x4e, 0x88, 0xcc, 0x89, 0x4b, 0x79, 0x27, 0xde, 0x86, 0xd6, 0x98, - 0xc9, 0x41, 0x14, 0x0b, 0x8f, 0x63, 0x01, 0xb7, 0xdc, 0xe6, 0x98, 0xc9, 0x57, 0x9a, 0xb6, 0x8b, - 0xbe, 0xb8, 0x14, 0xca, 0x24, 0xa3, 0x5e, 0x7c, 0xa1, 0x69, 0x72, 0xaa, 0x81, 0x23, 0x50, 0x31, - 0xf3, 0x14, 0x66, 0x60, 0xfb, 0x74, 0xc7, 0x94, 0xe2, 0x53, 0xc3, 0x36, 0x36, 0xbb, 0xe9, 0x3e, - 0x7d, 0xd9, 0xa1, 0x08, 0x58, 0x7c, 0x85, 0x25, 0xde, 0x71, 0x0d, 0x45, 0xaf, 0x61, 0xa3, 0x74, - 0x48, 0x6f, 0x95, 0xe1, 0x34, 0x4e, 0x93, 0xc1, 0x50, 0x3a, 0x72, 0xc9, 0xd7, 0x00, 0x83, 0x6f, - 0x22, 0x97, 0xb0, 0x5e, 0x5f, 0x45, 0x5c, 0x03, 0xda, 0xc5, 0x34, 0x40, 0xa7, 0x59, 0x40, 0xb3, - 0xb4, 0xf6, 0x1e, 0x8b, 0xc7, 0x12, 0x5d, 0xd0, 0x72, 0xf1, 0x9b, 0xf6, 0x61, 0xef, 0x9c, 0x07, - 0x23, 0x97, 0xbd, 0xab, 0x76, 0x37, 0xa2, 0x70, 0x0d, 0xcd, 0x4d, 0x50, 0xf8, 0xd7, 0xb0, 0xab, - 0x0f, 0x14, 0x76, 0x67, 0xc1, 0x54, 0xef, 0x27, 0x4c, 0x4e, 0xac, 0xd1, 0x09, 0xa5, 0x8b, 0xdb, - 0xfa, 0x60, 0x90, 0x01, 0x0e, 0x16, 0xb7, 0xe5, 0x3f, 0x36, 0xc0, 0x33, 0x80, 0xed, 0x33, 0xae, - 0x30, 0xad, 0x9e, 0x5c, 0x7d, 0xcd, 0xe4, 0x24, 0x67, 0x4a, 0x4e, 0x32, 0x7e, 0x93, 0x53, 0xd8, - 0xbe, 0x98, 0xfa, 0xfe, 0xe0, 0x42, 0xf8, 0xfe, 0x40, 0x65, 0x06, 0xa1, 0xf0, 0xa6, 0xbb, 0xa9, - 0x17, 0xbf, 0x12, 0xbe, 0x9f, 0xb3, 0x95, 0x72, 0xac, 0x40, 0xab, 0xe0, 0xbf, 0xc9, 0xdc, 0xff, - 0x49, 0xcd, 0x03, 0xb8, 0x7d, 0xc6, 0x55, 0x8e, 0xb3, 0xf0, 0x36, 0xf4, 0x1f, 0x0d, 0x58, 0x43, - 0xbb, 0x52, 0x7f, 0x56, 0xdd, 0xf9, 0x0e, 0xb4, 0x23, 0x16, 0xf3, 0x40, 0x0d, 0x70, 0xc9, 0x24, - 0x40, 0xc2, 0xd2, 0x1a, 0x72, 0xb7, 0x68, 0x14, 0x6e, 0x51, 0x5d, 0x00, 0xf9, 0xfe, 0xb7, 0x5c, - 0xea, 0x7f, 0xfb, 0xd0, 0x52, 0xe2, 0x92, 0x4b, 0xc5, 0x2e, 0x23, 0xcc, 0xff, 0x86, 0x9b, 0x31, - 0x0a, 0xad, 0x60, 0xb5, 0xd8, 0x0a, 0x0e, 0x00, 0x70, 0xb4, 0x18, 0xc4, 0x61, 0xa8, 0x0c, 0x00, - 0xb7, 0x90, 0xe3, 0x86, 0xa1, 0xd2, 0x27, 0xd5, 0x7b, 0x99, 0x2c, 0xb6, 0x12, 0xa8, 0x53, 0xef, - 0x25, 0x2e, 0x69, 0x60, 0x7a, 0xcb, 0x03, 0x65, 0x56, 0xc1, 0x00, 0x13, 0xb2, 0x70, 0xc3, 0x63, - 0x58, 0x4f, 0x47, 0x98, 0x64, 0x4f, 0x1b, 0x8b, 0xaf, 0x77, 0x92, 0xb2, 0x93, 0x12, 0x4c, 0xbe, - 0xf5, 0x19, 0x77, 0xcd, 0xcb, 0x93, 0xda, 0x11, 0x08, 0x32, 0x4e, 0x27, 0xc1, 0x07, 0x24, 0xb4, - 0x66, 0x21, 0x07, 0x17, 0x22, 0x60, 0xbe, 0x50, 0x57, 0xce, 0x1a, 0x86, 0x16, 0x84, 0xfc, 0xca, - 0x70, 0xc8, 0x4f, 0xa0, 0x93, 0x8b, 0xbd, 0x74, 0x46, 0xd8, 0x7f, 0x7b, 0xa6, 0xe8, 0x2b, 0xca, - 0xc1, 0x2d, 0xec, 0xa7, 0xff, 0xae, 0xc3, 0x66, 0x55, 0xd1, 0x54, 0x05, 0xd9, 0x01, 0xeb, 0xcb, - 0xf2, 0xbc, 0x62, 0x01, 0xb0, 0x31, 0x03, 0x80, 0x4b, 0xb3, 0x00, 0xb8, 0x5c, 0x09, 0x80, 0x2b, - 0xf9, 0xf8, 0x17, 0x62, 0xbc, 0x5a, 0x8e, 0xb1, 0xed, 0x31, 0x4d, 0xd3, 0xd3, 0x35, 0xc0, 0x58, - 0x4c, 0x68, 0x65, 0x98, 0x50, 0x84, 0x51, 0xb8, 0x09, 0x46, 0xdb, 0x25, 0x18, 0xad, 0x82, 0x86, - 0x4e, 0x25, 0x34, 0x20, 0x24, 0x2a, 0xa6, 0xa6, 0x12, 0x83, 0xb3, 0xec, 0x1a, 0x4a, 0xa7, 0x93, - 0x96, 0x3f, 0x95, 0x7c, 0xe4, 0xac, 0x27, 0xe9, 0x34, 0x66, 0xf2, 0x1b, 0xc9, 0x47, 0xf4, 0x0b, - 0xb8, 0xf5, 0x92, 0xbf, 0x33, 0xed, 0xd6, 0xd6, 0xde, 0x21, 0x40, 0xc4, 0xa4, 0x8c, 0x26, 0xb1, - 0x4e, 0xfa, 0x9a, 0x2d, 0x20, 0xcb, 0xa1, 0x27, 0x40, 0xf2, 0x87, 0xb2, 0xf6, 0x5c, 0xdd, 0xeb, - 0xa9, 0x0f, 0x5b, 0xdf, 0x04, 0xba, 0x6e, 0x4b, 0x7a, 0xe6, 0x4f, 0x07, 0x45, 0x0b, 0xea, 0x65, - 0x0b, 0x74, 0x51, 0x8e, 0xa6, 0x31, 0x4b, 0x31, 0x7c, 0xc9, 0x4d, 0x69, 0xda, 0x87, 0xed, 0x92, - 0xb6, 0xca, 0x5e, 0xdf, 0xb4, 0xbd, 0x5e, 0x5f, 0xe7, 0xc5, 0x07, 0x18, 0x47, 0x3f, 0x83, 0xcd, - 0x17, 0x1f, 0x20, 0xfe, 0xe7, 0xb0, 0x71, 0x2e, 0xc6, 0x41, 0x1e, 0xdc, 0xe6, 0x5f, 0xdc, 0xe6, - 0x7a, 0x3d, 0xc9, 0x1d, 0xcc, 0xf5, 0x2e, 0x34, 0x98, 0x3f, 0x36, 0x63, 0x8c, 0xfe, 0xa4, 0x1f, - 0x43, 0x37, 0x13, 0x99, 0x55, 0xc9, 0x4c, 0x27, 0xfa, 0x3d, 0x1c, 0xe9, 0x7d, 0xb9, 0xa2, 0x7a, - 0x95, 0xfa, 0xd0, 0xda, 0xf2, 0x63, 0x68, 0xe7, 0x11, 0xbb, 0x86, 0x60, 0xb1, 0x57, 0x55, 0xb4, - 0x49, 0xb3, 0xce, 0xef, 0x5e, 0x14, 0x27, 0xfa, 0x43, 0xb8, 0x7b, 0x83, 0x01, 0x0b, 0x2c, 0x2f, - 0xf6, 0xd0, 0xff, 0xb3, 0xe5, 0x7d, 0xe8, 0x9e, 0x99, 0xfa, 0x4c, 0x0d, 0x2d, 0x14, 0x71, 0xad, - 0x58, 0xc4, 0xf4, 0x2e, 0xb4, 0x17, 0xf5, 0xaf, 0x07, 0xd0, 0x3e, 0x63, 0xd9, 0x50, 0xdd, 0x85, - 0x86, 0x9e, 0x1c, 0x93, 0x1d, 0xfa, 0x53, 0x73, 0xb2, 0x69, 0x53, 0x7f, 0xd2, 0x87, 0xb0, 0xfe, - 0x2c, 0xc1, 0x76, 0x7b, 0xea, 0x23, 0x58, 0x49, 0xd0, 0x1e, 0xe7, 0xc1, 0xf6, 0x69, 0xc7, 0x5c, - 0x18, 0xb7, 0xb9, 0x66, 0x8d, 0x3e, 0x80, 0x65, 0x64, 0x7c, 0xc0, 0xe3, 0xf1, 0x63, 0xe8, 0xbc, - 0x8a, 0xe2, 0xf0, 0x22, 0xd7, 0xec, 0x7d, 0x21, 0x15, 0x0f, 0xec, 0xac, 0x92, 0x50, 0xf4, 0x13, - 0x58, 0x33, 0xfb, 0x16, 0x24, 0xfe, 0x97, 0x70, 0xeb, 0x8c, 0xab, 0xa7, 0xf8, 0x16, 0x4e, 0x37, - 0x1f, 0xc3, 0x4a, 0xf2, 0x3a, 0x36, 0xf1, 0xea, 0x9e, 0x24, 0xcf, 0xe6, 0xa4, 0x27, 0xe9, 0x9d, - 0x66, 0xfd, 0xf4, 0xaf, 0x00, 0xf0, 0x38, 0x12, 0xe7, 0x3c, 0x7e, 0xab, 0x41, 0xf2, 0x0d, 0xb4, - 0x73, 0xef, 0x2d, 0xb2, 0x6b, 0xae, 0x5d, 0x7e, 0xef, 0xf6, 0x6c, 0xbf, 0xa9, 0x78, 0x9c, 0xd1, - 0xbd, 0xef, 0xff, 0xf6, 0xcf, 0x3f, 0xd6, 0x37, 0xc9, 0xad, 0xfe, 0xdb, 0x07, 0xfd, 0xa9, 0xe4, - 0xb1, 0x7e, 0xb3, 0x63, 0xdb, 0x25, 0xbf, 0x81, 0xdd, 0x17, 0x4c, 0x71, 0xa9, 0x9e, 0xc7, 0x31, - 0xc7, 0xa7, 0xd0, 0xd0, 0xe7, 0x38, 0x6c, 0xcc, 0x57, 0xb5, 0x65, 0x16, 0x0a, 0x33, 0x09, 0xdd, - 0x42, 0x25, 0xeb, 0xa4, 0x93, 0x2a, 0xd1, 0xcf, 0xba, 0x18, 0x36, 0x4a, 0xef, 0x1a, 0x72, 0x90, - 0x59, 0x5a, 0xf1, 0x76, 0xea, 0x1d, 0xce, 0x5b, 0x36, 0x7a, 0x8e, 0x50, 0x4f, 0x8f, 0x6e, 0xa7, - 0x7a, 0x98, 0x79, 0xb6, 0xe9, 0x6d, 0x8f, 0x6a, 0xf7, 0xc9, 0x2b, 0x58, 0xd2, 0x8f, 0x1d, 0x32, - 0xbf, 0x26, 0x7a, 0x9b, 0x76, 0x24, 0xcf, 0x3d, 0x8a, 0xa8, 0x83, 0x92, 0x09, 0x5d, 0x4b, 0x25, - 0x7b, 0xcc, 0xf7, 0xb5, 0xc4, 0x6b, 0x20, 0xb3, 0xb3, 0x30, 0x39, 0x32, 0x42, 0xe6, 0x8e, 0xc9, - 0xe9, 0x5d, 0xe6, 0xcc, 0xc5, 0x94, 0xa2, 0xc6, 0x7d, 0xba, 0x9b, 0x6a, 0x8c, 0xd9, 0xbb, 0x5c, - 0xb9, 0x6a, 0xdd, 0x13, 0x58, 0x2f, 0x0e, 0xbe, 0x64, 0x3f, 0xf3, 0xd0, 0xec, 0x3c, 0x3c, 0x27, - 0x3a, 0xb3, 0x9a, 0xc6, 0x85, 0xd3, 0x5a, 0x53, 0x00, 0xdd, 0xf2, 0x04, 0x4c, 0x0e, 0x67, 0x75, - 0xe5, 0x47, 0xe3, 0x39, 0xda, 0x3e, 0x42, 0x6d, 0x87, 0x74, 0xaf, 0x4a, 0x1b, 0x9e, 0xd7, 0xfa, - 0xbe, 0xaf, 0xe1, 0x4c, 0x5f, 0x70, 0x8c, 0xc7, 0x45, 0xa4, 0x08, 0xcd, 0xb4, 0xce, 0x9b, 0x94, - 0x7b, 0x37, 0x0c, 0x58, 0xf4, 0x53, 0xd4, 0x7f, 0x8f, 0x1e, 0xe6, 0xf5, 0xcf, 0xea, 0xd1, 0x46, - 0x0c, 0xa0, 0x95, 0xfe, 0xf4, 0x94, 0xa6, 0x7c, 0xf9, 0x87, 0xab, 0x9e, 0x33, 0xbb, 0x60, 0x54, - 0x1d, 0xa0, 0xaa, 0x5d, 0x4a, 0x52, 0x55, 0xd2, 0xee, 0x79, 0x54, 0xbb, 0xff, 0x79, 0xcd, 0x14, - 0xb0, 0x05, 0xd5, 0xf9, 0x55, 0x65, 0x17, 0xca, 0xf0, 0x4b, 0xf7, 0x51, 0xc3, 0x0e, 0xd9, 0xca, - 0x5f, 0x26, 0x95, 0xf7, 0x06, 0xda, 0xcf, 0xb2, 0xc7, 0xf7, 0x4d, 0x39, 0x4f, 0x32, 0x05, 0xa9, - 0xec, 0x3b, 0x28, 0x7b, 0x8f, 0x66, 0xb2, 0x73, 0x2f, 0x79, 0xed, 0x1e, 0x86, 0xf5, 0x9b, 0x60, - 0xb1, 0x49, 0x3f, 0x2b, 0x27, 0x1f, 0x8c, 0xed, 0x3c, 0x1a, 0x67, 0xe2, 0xef, 0xa1, 0xf8, 0x03, - 0xea, 0xe4, 0x4d, 0xcf, 0x0b, 0x4b, 0x54, 0x40, 0xf6, 0xfe, 0x27, 0xb7, 0x6d, 0x42, 0x55, 0xfc, - 0x84, 0xd0, 0xdb, 0xcb, 0xf2, 0xa2, 0xf4, 0x7b, 0x01, 0xbd, 0x8d, 0xaa, 0xb6, 0x69, 0x37, 0x55, - 0x35, 0x4a, 0x76, 0x3c, 0xaa, 0xdd, 0x3f, 0xfd, 0x4b, 0x0b, 0x3a, 0x8f, 0x47, 0x97, 0x22, 0xb0, - 0xa8, 0xfa, 0x2d, 0x34, 0xed, 0x8f, 0x3d, 0x8b, 0x23, 0x52, 0xfe, 0x59, 0x88, 0xf6, 0x50, 0xd7, - 0x16, 0xc1, 0x98, 0x33, 0x2d, 0x37, 0xc5, 0x20, 0xe2, 0x01, 0x64, 0x43, 0x22, 0xb1, 0x79, 0x33, - 0x33, 0x6c, 0xa6, 0x57, 0x99, 0x9d, 0x28, 0x8b, 0x08, 0x57, 0x10, 0xdf, 0x0f, 0xf8, 0x3b, 0xed, - 0xb2, 0x10, 0xd6, 0x0a, 0xb3, 0x5e, 0xea, 0xb5, 0xaa, 0x79, 0xb3, 0xb7, 0x5f, 0xbd, 0x58, 0x15, - 0xa3, 0xa2, 0xb6, 0x29, 0x1e, 0xd0, 0x0a, 0xc7, 0xd0, 0xce, 0xcd, 0x7e, 0x69, 0x96, 0xcd, 0xce, - 0x8f, 0x69, 0x59, 0x56, 0x8c, 0x8a, 0xf4, 0x2e, 0xaa, 0xba, 0x4d, 0x77, 0x66, 0x55, 0x59, 0x45, - 0x01, 0x6c, 0x94, 0xc0, 0xf2, 0xa6, 0x94, 0x5e, 0x84, 0xaf, 0x15, 0x9e, 0x2c, 0xa1, 0xeb, 0xaf, - 0xa0, 0x69, 0x47, 0x4a, 0x62, 0x7f, 0xa7, 0x29, 0x8d, 0xad, 0x69, 0x1e, 0x94, 0x67, 0x4f, 0x7a, - 0x88, 0xe2, 0x1d, 0xba, 0x99, 0x89, 0x97, 0x62, 0x1c, 0xf4, 0x27, 0x26, 0xb3, 0xff, 0x50, 0x83, - 0x83, 0xd2, 0x1c, 0xf8, 0x4b, 0xa1, 0x26, 0xd9, 0x48, 0x47, 0x3e, 0xc9, 0x89, 0xbe, 0x69, 0xe8, - 0xeb, 0x1d, 0x2f, 0xde, 0x58, 0x6c, 0xf6, 0x74, 0xbd, 0x68, 0x94, 0xb6, 0xe7, 0x4f, 0xda, 0x9e, - 0xa2, 0xab, 0xe6, 0xd9, 0xb3, 0x60, 0x08, 0x5d, 0xe8, 0xf9, 0x13, 0xb4, 0xe2, 0x98, 0xde, 0xab, - 0xf4, 0x7c, 0x51, 0xab, 0x36, 0xed, 0x1c, 0xe0, 0x5c, 0xb1, 0x58, 0xe1, 0x88, 0x45, 0x6c, 0x7b, - 0xce, 0x0f, 0x66, 0x69, 0xab, 0x29, 0x4c, 0x61, 0xb6, 0x16, 0xe9, 0x46, 0xa6, 0x28, 0xd2, 0x1b, - 0x92, 0xe0, 0xb6, 0xd2, 0x49, 0x6c, 0x7e, 0x99, 0x3b, 0x19, 0xa8, 0x14, 0x87, 0x36, 0x8b, 0x29, - 0x24, 0x17, 0xdf, 0x71, 0x2a, 0xef, 0x5b, 0x68, 0xda, 0xff, 0x17, 0x16, 0x43, 0x48, 0xf9, 0x9f, - 0x88, 0x2a, 0x08, 0x09, 0xc2, 0x11, 0x17, 0xc1, 0x45, 0x38, 0x5c, 0xc1, 0x1f, 0xb6, 0xbf, 0xf8, - 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x97, 0x9c, 0x43, 0x6f, 0xe4, 0x19, 0x00, 0x00, + // 2205 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x6f, 0x1b, 0xb9, + 0x15, 0x87, 0x24, 0x7f, 0x48, 0x4f, 0xb2, 0xad, 0xd0, 0x5f, 0x63, 0xc5, 0x76, 0x1c, 0x66, 0xb1, + 0xeb, 0x0d, 0xba, 0xd6, 0xc6, 0x0b, 0xa4, 0x45, 0x8a, 0x2d, 0x90, 0xa4, 0x59, 0x6f, 0x8a, 0x20, + 0x48, 0xc7, 0xd9, 0x76, 0x81, 0x36, 0x15, 0xa8, 0x11, 0x2d, 0xb1, 0x3b, 0x9e, 0x99, 0x0e, 0xa9, + 0x24, 0xf6, 0xa5, 0xc0, 0xde, 0x7b, 0x2a, 0x50, 0xf4, 0xd0, 0xff, 0xa0, 0x7f, 0x4d, 0xd1, 0x43, + 0x2f, 0x3d, 0xf6, 0xd4, 0xbf, 0xa2, 0xe0, 0x1b, 0x72, 0xbe, 0x34, 0xb2, 0x9a, 0x1e, 0x7a, 0xe3, + 0x7b, 0x24, 0xdf, 0x7b, 0x7c, 0x5f, 0xfc, 0x71, 0x06, 0x5a, 0x71, 0xe4, 0x9d, 0x44, 0x71, 0xa8, + 0x42, 0xb2, 0x1c, 0x47, 0x5e, 0x34, 0xec, 0xed, 0x8f, 0xc3, 0x70, 0xec, 0xf3, 0x3e, 0x8b, 0x44, + 0x9f, 0x05, 0x41, 0xa8, 0x98, 0x12, 0x61, 0x20, 0x93, 0x45, 0xbd, 0x1f, 0x8d, 0x85, 0x9a, 0x4c, + 0x87, 0x27, 0x5e, 0x78, 0xd9, 0x0f, 0xf8, 0x70, 0xea, 0x33, 0x29, 0xc2, 0xfe, 0x38, 0xfc, 0xcc, + 0x10, 0x7d, 0x2f, 0x0c, 0x24, 0x0f, 0xe4, 0x54, 0xf6, 0xa3, 0x61, 0x5f, 0x2a, 0xa6, 0xb8, 0xd9, + 0xf9, 0x70, 0xd1, 0xce, 0x80, 0x0f, 0x7d, 0xae, 0xf4, 0x36, 0x2f, 0x0c, 0x2e, 0xc4, 0x38, 0xd9, + 0x47, 0xef, 0x43, 0xf7, 0x7c, 0x3a, 0x94, 0x5e, 0x2c, 0x86, 0xdc, 0xe5, 0xbf, 0x9b, 0x72, 0xa9, + 0xc8, 0x0e, 0xac, 0xa8, 0x30, 0x12, 0x9e, 0x74, 0x6a, 0x47, 0x8d, 0xe3, 0x96, 0x6b, 0x28, 0xfa, + 0x25, 0xdc, 0xca, 0xad, 0x95, 0x91, 0xb6, 0x85, 0x6c, 0xc1, 0x32, 0x4e, 0x3b, 0xb5, 0xa3, 0xda, + 0x71, 0xcb, 0x4d, 0x08, 0x42, 0x60, 0x69, 0xc4, 0x14, 0x73, 0xea, 0xc8, 0xc4, 0x31, 0x25, 0xd0, + 0x7d, 0x19, 0x06, 0xaf, 0x58, 0xcc, 0x2e, 0xa5, 0x51, 0x45, 0xff, 0x52, 0xd7, 0xcc, 0x11, 0x7f, + 0x1e, 0x5c, 0x84, 0xa9, 0xc8, 0x75, 0xa8, 0x8b, 0x91, 0x91, 0x57, 0x17, 0x23, 0xb2, 0x07, 0x4d, + 0x6f, 0xc2, 0x44, 0x30, 0x10, 0x23, 0x14, 0xb8, 0xe6, 0xae, 0x22, 0xfd, 0x7c, 0x44, 0x7a, 0xd0, + 0xf4, 0x42, 0x11, 0x0c, 0x99, 0xe4, 0x4e, 0x03, 0x37, 0xa4, 0x34, 0x39, 0x00, 0x88, 0x38, 0x8f, + 0x07, 0x5e, 0x38, 0x0d, 0x94, 0xb3, 0x84, 0x1b, 0x5b, 0x9a, 0xf3, 0x54, 0x33, 0x08, 0x85, 0x8e, + 0xbc, 0x0a, 0xbc, 0x49, 0x1c, 0x06, 0xe2, 0x9a, 0x8f, 0x9c, 0xe5, 0xa3, 0xda, 0x71, 0xd3, 0x2d, + 0xf0, 0xc8, 0x1d, 0x68, 0x0f, 0xa7, 0xde, 0x77, 0x5c, 0x0d, 0xa4, 0xb8, 0xe6, 0xce, 0xca, 0x51, + 0xed, 0x78, 0xd9, 0x85, 0x84, 0x75, 0x2e, 0xae, 0x39, 0xf9, 0x14, 0xba, 0xe8, 0x47, 0x2f, 0xf4, + 0x07, 0x6f, 0x79, 0x2c, 0x45, 0x18, 0x38, 0x80, 0x76, 0x6c, 0x58, 0xfe, 0x2f, 0x12, 0x36, 0x39, + 0x85, 0x76, 0x1c, 0x4e, 0x15, 0x1f, 0x28, 0x36, 0xf4, 0xb9, 0xd3, 0x3e, 0x6a, 0x1c, 0xb7, 0x4f, + 0x6f, 0x9d, 0x60, 0x5a, 0x9c, 0xb8, 0x7a, 0xe6, 0xb5, 0x9e, 0x70, 0x21, 0x4e, 0xc7, 0xf4, 0x21, + 0x40, 0x36, 0x33, 0xe3, 0x17, 0x07, 0x56, 0xd9, 0x68, 0x14, 0x73, 0x29, 0x9d, 0x3a, 0x06, 0xca, + 0x92, 0xf4, 0x1f, 0x35, 0xd8, 0x3c, 0xe3, 0xea, 0x25, 0x1f, 0x9e, 0xeb, 0x1c, 0x49, 0x3d, 0x9b, + 0xf7, 0x64, 0xad, 0xe8, 0x49, 0x02, 0x4b, 0x8a, 0x09, 0xdf, 0x46, 0x4c, 0x8f, 0x49, 0x17, 0x1a, + 0xbe, 0x18, 0x1a, 0xc7, 0xea, 0xa1, 0x4e, 0x8d, 0x09, 0x17, 0xe3, 0x49, 0xe2, 0xcf, 0x25, 0xd7, + 0x50, 0x95, 0x7e, 0x58, 0xa9, 0xf6, 0x43, 0xd9, 0xef, 0xab, 0x15, 0x7e, 0x77, 0x60, 0xd5, 0x4a, + 0x69, 0xa2, 0x14, 0x4b, 0xd2, 0xcf, 0xa1, 0xfb, 0xd8, 0xc3, 0x88, 0xca, 0xf4, 0x54, 0xfb, 0xd0, + 0x32, 0x07, 0xe7, 0x36, 0x65, 0x33, 0x06, 0xfd, 0x19, 0xec, 0x9c, 0x71, 0x65, 0x36, 0x19, 0x77, + 0x24, 0x79, 0x9e, 0xf3, 0x5f, 0xe2, 0x54, 0x4b, 0xe6, 0x8e, 0x59, 0xcf, 0x1f, 0x93, 0xbe, 0x81, + 0xdd, 0x19, 0x59, 0xc6, 0x08, 0x07, 0x56, 0x87, 0xcc, 0x67, 0x81, 0xc7, 0xad, 0x30, 0x43, 0xea, + 0x0a, 0x09, 0x42, 0xcd, 0x4f, 0x64, 0x25, 0x04, 0xfa, 0xfb, 0x2a, 0x4a, 0xb2, 0x76, 0xcd, 0xc5, + 0x31, 0xfd, 0x2d, 0x74, 0x9e, 0x32, 0xdf, 0x4f, 0x65, 0xee, 0xc0, 0x4a, 0xcc, 0xe5, 0xd4, 0x57, + 0x46, 0xa4, 0xa1, 0x74, 0x5a, 0xf2, 0xf7, 0xdc, 0xd3, 0xc9, 0xc4, 0xe3, 0xd8, 0x84, 0x0c, 0x0c, + 0xeb, 0x59, 0x1c, 0x93, 0xbb, 0xd0, 0xe1, 0x52, 0x89, 0x4b, 0xa6, 0xf8, 0x60, 0xcc, 0xa4, 0x89, + 0x60, 0xdb, 0xf2, 0xce, 0x98, 0xa4, 0x27, 0xb0, 0xf5, 0xe4, 0xea, 0x89, 0x1f, 0x7a, 0xdf, 0x7d, + 0x8d, 0x67, 0xcb, 0x15, 0xbf, 0x39, 0x7a, 0xad, 0x70, 0xf4, 0x1f, 0x00, 0x39, 0xe3, 0xea, 0xa7, + 0x57, 0x01, 0x93, 0xea, 0x2a, 0x6f, 0xe1, 0xa5, 0x08, 0x78, 0x9c, 0xb6, 0x8a, 0x84, 0xa2, 0xff, + 0xae, 0x01, 0x79, 0x1d, 0xb3, 0x40, 0x32, 0x4f, 0xf7, 0x37, 0x2b, 0x9c, 0xc0, 0xd2, 0x45, 0x1c, + 0x5e, 0x9a, 0xe3, 0xe0, 0x58, 0x67, 0xb5, 0x0a, 0xcd, 0x19, 0xea, 0x2a, 0xd4, 0xee, 0x7a, 0xcb, + 0xfc, 0xa9, 0xad, 0xe7, 0x84, 0xc8, 0x9c, 0xb8, 0x94, 0x77, 0xe2, 0x6d, 0x68, 0x8d, 0x99, 0x1c, + 0x44, 0xb1, 0xf0, 0x38, 0x16, 0x70, 0xcb, 0x6d, 0x8e, 0x99, 0x7c, 0xa5, 0x69, 0x3b, 0xe9, 0x8b, + 0x4b, 0xa1, 0x4c, 0x32, 0xea, 0xc9, 0x17, 0x9a, 0x26, 0xa7, 0xba, 0x71, 0x04, 0x2a, 0x66, 0x9e, + 0xc2, 0x0c, 0x6c, 0x9f, 0xee, 0x98, 0x52, 0x7c, 0x6a, 0xd8, 0xc6, 0x66, 0x37, 0x5d, 0xa7, 0x0f, + 0x3b, 0x14, 0x01, 0x8b, 0xaf, 0xb0, 0xc4, 0x3b, 0xae, 0xa1, 0xe8, 0x35, 0x6c, 0x94, 0x36, 0xe9, + 0xa5, 0x32, 0x9c, 0xc6, 0x69, 0x32, 0x18, 0x4a, 0x47, 0x2e, 0x19, 0x0d, 0x30, 0xf8, 0x26, 0x72, + 0x09, 0xeb, 0xf5, 0x55, 0xc4, 0x75, 0x43, 0xbb, 0x98, 0x06, 0xe8, 0x34, 0xdb, 0xd0, 0x2c, 0xad, + 0xbd, 0xc7, 0xe2, 0xb1, 0x44, 0x17, 0xb4, 0x5c, 0x1c, 0xd3, 0x3e, 0xec, 0x9d, 0xf3, 0x60, 0xe4, + 0xb2, 0x77, 0xd5, 0xee, 0xc6, 0x2e, 0x5c, 0x43, 0x73, 0x93, 0x2e, 0xfc, 0x6b, 0xd8, 0xd5, 0x1b, + 0x0a, 0xab, 0xb3, 0x60, 0xaa, 0xf7, 0x13, 0x26, 0x27, 0xd6, 0xe8, 0x84, 0xd2, 0xc5, 0x6d, 0x7d, + 0x30, 0xc8, 0x1a, 0x0e, 0x16, 0xb7, 0xe5, 0x3f, 0x36, 0x8d, 0x67, 0x00, 0xdb, 0x67, 0x5c, 0x61, + 0x5a, 0x3d, 0xb9, 0xfa, 0x9a, 0xc9, 0x49, 0xce, 0x94, 0x9c, 0x64, 0x1c, 0x93, 0x53, 0xd8, 0xbe, + 0x98, 0xfa, 0xfe, 0xe0, 0x42, 0xf8, 0xfe, 0x40, 0x65, 0x06, 0xa1, 0xf0, 0xa6, 0xbb, 0xa9, 0x27, + 0xbf, 0x12, 0xbe, 0x9f, 0xb3, 0x95, 0x72, 0xac, 0x40, 0xab, 0xe0, 0xbf, 0xc9, 0xdc, 0xff, 0x49, + 0xcd, 0x03, 0xb8, 0x7d, 0xc6, 0x55, 0x8e, 0xb3, 0xf0, 0x34, 0xf4, 0x9f, 0x0d, 0x58, 0x43, 0xbb, + 0x52, 0x7f, 0x56, 0x9d, 0xf9, 0x0e, 0xb4, 0x23, 0x16, 0xf3, 0x40, 0x0d, 0x70, 0xca, 0x24, 0x40, + 0xc2, 0xd2, 0x1a, 0x72, 0xa7, 0x68, 0x14, 0x4e, 0x51, 0x5d, 0x00, 0xf9, 0xfb, 0x6f, 0xb9, 0x74, + 0xff, 0xed, 0x43, 0x4b, 0x89, 0x4b, 0x2e, 0x15, 0xbb, 0x8c, 0x30, 0xff, 0x1b, 0x6e, 0xc6, 0x28, + 0x5c, 0x05, 0xab, 0xc5, 0xab, 0xe0, 0x00, 0x00, 0xa1, 0xc5, 0x20, 0x0e, 0x43, 0x65, 0x1a, 0x70, + 0x0b, 0x39, 0x6e, 0x18, 0x2a, 0xbd, 0x53, 0xbd, 0x97, 0xc9, 0x64, 0x2b, 0x69, 0x75, 0xea, 0xbd, + 0xc4, 0x29, 0xdd, 0x98, 0xde, 0xf2, 0x40, 0x99, 0x59, 0x30, 0x8d, 0x09, 0x59, 0xb8, 0xe0, 0x31, + 0xac, 0xa7, 0x10, 0x26, 0x59, 0xd3, 0xc6, 0xe2, 0xeb, 0x9d, 0xa4, 0xec, 0xa4, 0x04, 0x93, 0xb1, + 0xde, 0xe3, 0xae, 0x79, 0x79, 0x52, 0x3b, 0x02, 0x9b, 0x8c, 0xd3, 0x49, 0xfa, 0x03, 0x12, 0x5a, + 0xb3, 0x90, 0x83, 0x0b, 0x11, 0x30, 0x5f, 0xa8, 0x2b, 0x67, 0x0d, 0x43, 0x0b, 0x42, 0x7e, 0x65, + 0x38, 0xe4, 0x27, 0xd0, 0xc9, 0xc5, 0x5e, 0x3a, 0x23, 0xbc, 0x7f, 0x7b, 0xa6, 0xe8, 0x2b, 0xca, + 0xc1, 0x2d, 0xac, 0xa7, 0x7f, 0x6a, 0xc0, 0x66, 0x55, 0xd1, 0x54, 0x05, 0xd9, 0x01, 0xeb, 0xcb, + 0x32, 0x5e, 0xb1, 0x0d, 0xb0, 0x31, 0xd3, 0x00, 0x97, 0x66, 0x1b, 0xe0, 0x72, 0x65, 0x03, 0x5c, + 0xc9, 0xc7, 0xbf, 0x10, 0xe3, 0xd5, 0x72, 0x8c, 0xed, 0x1d, 0xd3, 0x34, 0x77, 0xba, 0x6e, 0x30, + 0xb6, 0x27, 0xb4, 0xb2, 0x9e, 0x50, 0x6c, 0xa3, 0x70, 0x53, 0x1b, 0x6d, 0x97, 0xda, 0x68, 0x55, + 0x6b, 0xe8, 0x54, 0xb6, 0x06, 0x6c, 0x89, 0x8a, 0xa9, 0xa9, 0xc4, 0xe0, 0x2c, 0xbb, 0x86, 0xd2, + 0xe9, 0xa4, 0xe5, 0x4f, 0x25, 0x1f, 0x39, 0xeb, 0x49, 0x3a, 0x8d, 0x99, 0xfc, 0x46, 0xf2, 0x11, + 0xb9, 0x07, 0x6b, 0xb9, 0x7b, 0x2e, 0x8c, 0x9d, 0x0d, 0x9c, 0xef, 0x64, 0x37, 0x5d, 0x18, 0xd3, + 0x2f, 0xe0, 0xd6, 0x4b, 0xfe, 0xce, 0xdc, 0xc9, 0xb6, 0x40, 0x0f, 0x01, 0x22, 0x26, 0x65, 0x34, + 0x89, 0x75, 0x65, 0xd4, 0x6c, 0x95, 0x59, 0x0e, 0x3d, 0x01, 0x92, 0xdf, 0x94, 0xdd, 0xe1, 0xd5, + 0x80, 0x80, 0xfa, 0xb0, 0xf5, 0x4d, 0xa0, 0x8b, 0xbb, 0xa4, 0x67, 0x3e, 0x84, 0x28, 0x5a, 0x50, + 0x2f, 0x5b, 0xa0, 0x2b, 0x77, 0x34, 0x8d, 0x59, 0xda, 0xe8, 0x97, 0xdc, 0x94, 0xa6, 0x7d, 0xd8, + 0x2e, 0x69, 0xab, 0x04, 0x04, 0x4d, 0x0b, 0x08, 0xf4, 0x71, 0x5e, 0x7c, 0x80, 0x71, 0xf4, 0x33, + 0xd8, 0x7c, 0xf1, 0x01, 0xe2, 0x7f, 0x0e, 0x1b, 0xe7, 0x62, 0x1c, 0xe4, 0x3b, 0xe0, 0xfc, 0x83, + 0xdb, 0x82, 0xa8, 0x27, 0x09, 0x86, 0x05, 0xd1, 0x85, 0x06, 0xf3, 0xc7, 0x06, 0xeb, 0xe8, 0x21, + 0xfd, 0x18, 0xba, 0x99, 0xc8, 0xac, 0x94, 0x66, 0xae, 0xab, 0xdf, 0xc3, 0x91, 0x5e, 0x97, 0xab, + 0xbc, 0x57, 0xa9, 0x0f, 0xad, 0x2d, 0x3f, 0x86, 0x76, 0xbe, 0xad, 0xd7, 0xb0, 0xa3, 0xec, 0x55, + 0x55, 0x76, 0x72, 0xa3, 0xe7, 0x57, 0x2f, 0x8a, 0x13, 0xfd, 0x21, 0xdc, 0xbd, 0xc1, 0x80, 0x05, + 0x96, 0x17, 0x2f, 0xda, 0xff, 0xb3, 0xe5, 0x7d, 0xe8, 0x9e, 0x99, 0x22, 0x4e, 0x0d, 0x2d, 0x54, + 0x7a, 0xad, 0x58, 0xe9, 0xf4, 0x2e, 0xb4, 0x17, 0x5d, 0x72, 0x0f, 0xa0, 0x7d, 0xc6, 0x32, 0xe4, + 0xdd, 0x85, 0x86, 0x86, 0x97, 0xc9, 0x0a, 0x3d, 0xd4, 0x9c, 0x0c, 0x92, 0xea, 0x21, 0x7d, 0x08, + 0xeb, 0xcf, 0x92, 0x0b, 0xc0, 0xee, 0xfa, 0x08, 0x56, 0x92, 0x2b, 0x01, 0x41, 0x63, 0xfb, 0xb4, + 0x63, 0x0e, 0x8c, 0xcb, 0x5c, 0x33, 0x47, 0x1f, 0xc0, 0x32, 0x32, 0x3e, 0xe0, 0x85, 0xf9, 0x31, + 0x74, 0x5e, 0x45, 0x71, 0x78, 0x91, 0x43, 0x04, 0xbe, 0x90, 0x8a, 0x07, 0x16, 0xd0, 0x24, 0x14, + 0xfd, 0x04, 0xd6, 0xcc, 0xba, 0x05, 0x89, 0xff, 0x25, 0xdc, 0x3a, 0xe3, 0xea, 0x29, 0x3e, 0x98, + 0xd3, 0xc5, 0xc7, 0xb0, 0x92, 0x3c, 0xa1, 0x4d, 0xbc, 0xba, 0x27, 0xc9, 0xdb, 0x3a, 0xb9, 0xb8, + 0xf4, 0x4a, 0x33, 0x7f, 0xfa, 0x37, 0x00, 0x78, 0x1c, 0x89, 0x73, 0x1e, 0xbf, 0xd5, 0x9d, 0xf4, + 0x0d, 0xb4, 0x73, 0x8f, 0x32, 0xb2, 0x6b, 0x8e, 0x5d, 0x7e, 0x14, 0xf7, 0xec, 0xa5, 0x54, 0xf1, + 0x82, 0xa3, 0x7b, 0xdf, 0xff, 0xfd, 0x5f, 0x7f, 0xac, 0x6f, 0x92, 0x5b, 0xfd, 0xb7, 0x0f, 0xfa, + 0x53, 0xc9, 0x63, 0xfd, 0xb0, 0xc7, 0xbb, 0x99, 0xfc, 0x06, 0x76, 0x5f, 0x30, 0xc5, 0xa5, 0x7a, + 0x1e, 0xc7, 0x1c, 0xdf, 0x4b, 0x43, 0x9f, 0x23, 0x22, 0x99, 0xaf, 0x6a, 0xcb, 0x4c, 0x14, 0x80, + 0x0b, 0xdd, 0x42, 0x25, 0xeb, 0xa4, 0x93, 0x2a, 0xd1, 0x6f, 0xbf, 0x18, 0x36, 0x4a, 0x8f, 0x1f, + 0x72, 0x90, 0x59, 0x5a, 0xf1, 0xc0, 0xea, 0x1d, 0xce, 0x9b, 0x36, 0x7a, 0x8e, 0x50, 0x4f, 0x8f, + 0x6e, 0xa7, 0x7a, 0x98, 0x79, 0xdb, 0xe9, 0x65, 0x8f, 0x6a, 0xf7, 0xc9, 0x2b, 0x58, 0xd2, 0x2f, + 0x22, 0x32, 0xbf, 0x26, 0x7a, 0x9b, 0x16, 0xb7, 0xe7, 0x5e, 0x4e, 0xd4, 0x41, 0xc9, 0x84, 0xae, + 0xa5, 0x92, 0x3d, 0xe6, 0xfb, 0x5a, 0xe2, 0x35, 0x90, 0x59, 0xc0, 0x4c, 0x8e, 0x8c, 0x90, 0xb9, + 0x58, 0x3a, 0x3d, 0xcb, 0x1c, 0xf0, 0x4c, 0x29, 0x6a, 0xdc, 0xa7, 0xbb, 0xa9, 0xc6, 0x98, 0xbd, + 0xcb, 0x95, 0xab, 0xd6, 0x3d, 0x81, 0xf5, 0x22, 0x3a, 0x26, 0xfb, 0x99, 0x87, 0x66, 0x41, 0xf3, + 0x9c, 0xe8, 0xcc, 0x6a, 0x1a, 0x17, 0x76, 0x6b, 0x4d, 0x01, 0x74, 0xcb, 0x30, 0x99, 0x1c, 0xce, + 0xea, 0xca, 0xe3, 0xe7, 0x39, 0xda, 0x3e, 0x42, 0x6d, 0x87, 0x74, 0xaf, 0x4a, 0x1b, 0xee, 0xd7, + 0xfa, 0xbe, 0xaf, 0x21, 0xf0, 0x2f, 0x38, 0xc6, 0xe3, 0x22, 0x52, 0x84, 0x66, 0x5a, 0xe7, 0xc1, + 0xe9, 0xde, 0x0d, 0x28, 0x8c, 0x7e, 0x8a, 0xfa, 0xef, 0xd1, 0xc3, 0xbc, 0xfe, 0x59, 0x3d, 0xda, + 0x88, 0x01, 0xb4, 0xd2, 0xef, 0x53, 0x69, 0xca, 0x97, 0xbf, 0x6e, 0xf5, 0x9c, 0xd9, 0x09, 0xa3, + 0xea, 0x00, 0x55, 0xed, 0x52, 0x92, 0xaa, 0x92, 0x76, 0xcd, 0xa3, 0xda, 0xfd, 0xcf, 0x6b, 0xa6, + 0x80, 0x6d, 0x53, 0x9d, 0x5f, 0x55, 0x76, 0xa2, 0xdc, 0x7e, 0xe9, 0x3e, 0x6a, 0xd8, 0x21, 0x5b, + 0xf9, 0xc3, 0xa4, 0xf2, 0xde, 0x40, 0xfb, 0x59, 0xf6, 0x42, 0xbf, 0x29, 0xe7, 0x49, 0xa6, 0x20, + 0x95, 0x7d, 0x07, 0x65, 0xef, 0xd1, 0x4c, 0x76, 0xee, 0xb9, 0xaf, 0xdd, 0xc3, 0xb0, 0x7e, 0x93, + 0x5e, 0x6c, 0xd2, 0xcf, 0xca, 0xc9, 0x07, 0x63, 0x3b, 0xdf, 0x8d, 0x33, 0xf1, 0xf7, 0x50, 0xfc, + 0x01, 0x75, 0xf2, 0xa6, 0xe7, 0x85, 0x25, 0x2a, 0x20, 0xfb, 0x48, 0x40, 0x6e, 0xdb, 0x84, 0xaa, + 0xf8, 0xce, 0xd0, 0xdb, 0xcb, 0xf2, 0xa2, 0xf4, 0x51, 0x81, 0xde, 0x46, 0x55, 0xdb, 0xb4, 0x9b, + 0xaa, 0x1a, 0x25, 0x2b, 0x1e, 0xd5, 0xee, 0x9f, 0xfe, 0xb5, 0x05, 0x9d, 0xc7, 0xa3, 0x4b, 0x11, + 0xd8, 0xae, 0xfa, 0x2d, 0x34, 0xed, 0x17, 0xa1, 0xc5, 0x11, 0x29, 0x7f, 0x3b, 0xa2, 0x3d, 0xd4, + 0xb5, 0x45, 0x30, 0xe6, 0x4c, 0xcb, 0x4d, 0x7b, 0x10, 0xf1, 0x00, 0x32, 0x90, 0x48, 0x6c, 0xde, + 0xcc, 0x80, 0xcd, 0xf4, 0x28, 0xb3, 0x88, 0xb2, 0xd8, 0xe1, 0x0a, 0xe2, 0xfb, 0x01, 0x7f, 0xa7, + 0x5d, 0x16, 0xc2, 0x5a, 0x01, 0xeb, 0xa5, 0x5e, 0xab, 0xc2, 0x9b, 0xbd, 0xfd, 0xea, 0xc9, 0xaa, + 0x18, 0x15, 0xb5, 0x4d, 0x71, 0x83, 0x56, 0x38, 0x86, 0x76, 0x0e, 0xfb, 0xa5, 0x59, 0x36, 0x8b, + 0x1f, 0xd3, 0xb2, 0xac, 0x80, 0x8a, 0xf4, 0x2e, 0xaa, 0xba, 0x4d, 0x77, 0x66, 0x55, 0x59, 0x45, + 0x01, 0x6c, 0x94, 0x9a, 0xe5, 0x4d, 0x29, 0xbd, 0xa8, 0xbf, 0x56, 0x78, 0xb2, 0xd4, 0x5d, 0x7f, + 0x05, 0x4d, 0x0b, 0x29, 0x89, 0xfd, 0x98, 0x53, 0x82, 0xad, 0x69, 0x1e, 0x94, 0xb1, 0x27, 0x3d, + 0x44, 0xf1, 0x0e, 0xdd, 0xcc, 0xc4, 0x4b, 0x31, 0x0e, 0xfa, 0x13, 0x93, 0xd9, 0x7f, 0xa8, 0xc1, + 0x41, 0x09, 0x07, 0xfe, 0x52, 0xa8, 0x49, 0x06, 0xe9, 0xc8, 0x27, 0x39, 0xd1, 0x37, 0x81, 0xbe, + 0xde, 0xf1, 0xe2, 0x85, 0xc5, 0xcb, 0x9e, 0xae, 0x17, 0x8d, 0xd2, 0xf6, 0xfc, 0x59, 0xdb, 0x53, + 0x74, 0xd5, 0x3c, 0x7b, 0x16, 0x80, 0xd0, 0x85, 0x9e, 0x3f, 0x41, 0x2b, 0x8e, 0xe9, 0xbd, 0x4a, + 0xcf, 0x17, 0xb5, 0x6a, 0xd3, 0xce, 0x01, 0xce, 0x15, 0x8b, 0x15, 0x42, 0x2c, 0x62, 0xaf, 0xe7, + 0x3c, 0x30, 0x4b, 0xaf, 0x9a, 0x02, 0x0a, 0xb3, 0xb5, 0x48, 0x37, 0x32, 0x45, 0x91, 0x5e, 0x90, + 0x04, 0xb7, 0x95, 0x22, 0xb1, 0xf9, 0x65, 0xee, 0x64, 0x4d, 0xa5, 0x08, 0xda, 0x6c, 0x4f, 0x21, + 0xb9, 0xf8, 0x8e, 0x53, 0x79, 0xdf, 0x42, 0xd3, 0xfe, 0x84, 0x58, 0xdc, 0x42, 0xca, 0xbf, 0x2b, + 0xaa, 0x5a, 0x48, 0x10, 0x8e, 0xb8, 0x08, 0x2e, 0xc2, 0xe1, 0x0a, 0x7e, 0xfd, 0xfe, 0xe2, 0x3f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0x3a, 0x99, 0x19, 0x87, 0x09, 0x1a, 0x00, 0x00, } diff --git a/rpc/pb/rpc.pb.gw.go b/rpc/pb/rpc.pb.gw.go index 882c34d70..afe51fc04 100644 --- a/rpc/pb/rpc.pb.gw.go +++ b/rpc/pb/rpc.pb.gw.go @@ -50,8 +50,10 @@ func request_ApiService_GetAccountState_0(ctx context.Context, marshaler runtime var protoReq GetAccountStateRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.GetAccountState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -63,8 +65,10 @@ func request_ApiService_Call_0(ctx context.Context, marshaler runtime.Marshaler, var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.Call(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -76,8 +80,10 @@ func request_ApiService_SendRawTransaction_0(ctx context.Context, marshaler runt var protoReq SendRawTransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.SendRawTransaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -89,8 +95,10 @@ func request_ApiService_GetBlockByHash_0(ctx context.Context, marshaler runtime. var protoReq GetBlockByHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.GetBlockByHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -102,8 +110,10 @@ func request_ApiService_GetBlockByHeight_0(ctx context.Context, marshaler runtim var protoReq GetBlockByHeightRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.GetBlockByHeight(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -115,8 +125,10 @@ func request_ApiService_GetTransactionReceipt_0(ctx context.Context, marshaler r var protoReq GetTransactionByHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.GetTransactionReceipt(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -128,8 +140,10 @@ func request_ApiService_Subscribe_0(ctx context.Context, marshaler runtime.Marsh var protoReq SubscribeRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } stream, err := client.Subscribe(ctx, &protoReq) @@ -158,8 +172,10 @@ func request_ApiService_EstimateGas_0(ctx context.Context, marshaler runtime.Mar var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.EstimateGas(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -171,8 +187,10 @@ func request_ApiService_GetEventsByHash_0(ctx context.Context, marshaler runtime var protoReq HashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.GetEventsByHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -184,8 +202,10 @@ func request_ApiService_GetDynasty_0(ctx context.Context, marshaler runtime.Mars var protoReq ByBlockHeightRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.GetDynasty(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -206,8 +226,10 @@ func request_AdminService_NewAccount_0(ctx context.Context, marshaler runtime.Ma var protoReq NewAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.NewAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -219,8 +241,10 @@ func request_AdminService_UnlockAccount_0(ctx context.Context, marshaler runtime var protoReq UnlockAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.UnlockAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -232,8 +256,10 @@ func request_AdminService_LockAccount_0(ctx context.Context, marshaler runtime.M var protoReq LockAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.LockAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -245,8 +271,10 @@ func request_AdminService_SendTransaction_0(ctx context.Context, marshaler runti var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.SendTransaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -258,8 +286,10 @@ func request_AdminService_SignHash_0(ctx context.Context, marshaler runtime.Mars var protoReq SignHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.SignHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -271,8 +301,10 @@ func request_AdminService_SignTransactionWithPassphrase_0(ctx context.Context, m var protoReq SignTransactionPassphraseRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.SignTransactionWithPassphrase(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -284,8 +316,10 @@ func request_AdminService_SendTransactionWithPassphrase_0(ctx context.Context, m var protoReq SendTransactionPassphraseRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.SendTransactionWithPassphrase(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -297,8 +331,10 @@ func request_AdminService_StartPprof_0(ctx context.Context, marshaler runtime.Ma var protoReq PprofRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } } msg, err := client.StartPprof(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) diff --git a/rpc/pb/rpc.proto b/rpc/pb/rpc.proto index 08d54d7cb..018399ae8 100644 --- a/rpc/pb/rpc.proto +++ b/rpc/pb/rpc.proto @@ -497,6 +497,9 @@ message TransactionResponse { // transaction gas used string gas_used = 14; + + // contract execute error + string execute_error = 15; } message NewAccountRequest { From ec339c34be181da15856fb5997de05f536a14e0a Mon Sep 17 00:00:00 2001 From: fengzi Date: Sat, 28 Apr 2018 16:05:30 +0800 Subject: [PATCH 34/69] rpc:api_service.go update get transaction api --- nf/nvm/test/NRC20.js | 2 +- rpc/api_service.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nf/nvm/test/NRC20.js b/nf/nvm/test/NRC20.js index dec13b223..1443867cc 100644 --- a/nf/nvm/test/NRC20.js +++ b/nf/nvm/test/NRC20.js @@ -85,7 +85,7 @@ StandardToken.prototype = { init: function (name, symbol, decimals, totalSupply) { this._name = name; this._symbol = symbol; - this._decimals = decimals || 0; + this._decimals = decimals | 0; this._totalSupply = new BigNumber(totalSupply).mul(new BigNumber(10).pow(decimals)); var from = Blockchain.transaction.from; diff --git a/rpc/api_service.go b/rpc/api_service.go index 6d3b651da..fd37e6c07 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -203,7 +203,7 @@ func handleTransactionResponse(neb core.Neblet, tx *core.Transaction) (resp *rpc } // check Balance Simulate - if tx.Nonce() == acc.Nonce()+1 { + if tx.Nonce() == (acc.Nonce() + 1) { result, err := neb.BlockChain().SimulateTransactionExecution(tx) if err != nil { return nil, err From 48b82f7363ab8a148b8852745144df9e04040265 Mon Sep 17 00:00:00 2001 From: Leon Date: Sat, 28 Apr 2018 16:45:03 +0800 Subject: [PATCH 35/69] net: bug fix in neb message compression. --- net/neb_message.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/neb_message.go b/net/neb_message.go index c92e29a3d..f566cdf3f 100644 --- a/net/neb_message.go +++ b/net/neb_message.go @@ -194,7 +194,7 @@ func (message *NebMessage) Length() uint64 { // NewNebMessage new neb message func NewNebMessage(chainID uint32, reserved []byte, version byte, messageName string, data []byte) (*NebMessage, error) { // Process message compression - if (reserved[0] & ReservedCompressionEnableFlag) > 0 { + if (reserved[2] != ReservedCompressionClientFlag) && ((reserved[0] & ReservedCompressionEnableFlag) > 0) { data = snappy.Encode(nil, data) } From cc66d638add12de3dcf966055723cadf3255ed36 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 28 Apr 2018 19:27:53 +0800 Subject: [PATCH 36/69] nvm: random --- account/manager.go | 46 ++ consensus/dpos/dpos.go | 95 ++++- core/block.go | 54 ++- core/block_pool.go | 54 +++ core/block_test.go | 3 + core/blockchain.go | 21 + core/compatibility.go | 7 +- core/pb/block.pb.go | 127 ++++-- core/pb/block.proto | 6 + core/types.go | 3 + .../vrf/secp256k1VRF/secp256k1VRF.go | 4 +- .../vrf/secp256k1VRF/secp256k1VRF_test.go | 51 +++ crypto/keystore/secp256k1/vrf/vrf_test.go | 67 +-- .../contract/contract.feature.random.test.js | 392 +++++++++++++++++ nf/nvm/context.go | 16 +- nf/nvm/engine_v8_test.go | 14 +- nf/nvm/test/contract_date_and_random.js | 18 +- nf/nvm/test/test_random_disable.js | 23 + .../{test_random.js => test_random_enable.js} | 4 + nf/nvm/test/test_random_seed.js | 23 + nf/nvm/types.go | 2 + nf/nvm/v8/lib/execution_env.js | 16 +- nf/nvm/v8/lib/random.js | 47 ++- rpc/admin_service.go | 24 ++ rpc/pb/rpc.pb.go | 394 +++++++++++------- rpc/pb/rpc.pb.gw.go | 154 +++---- rpc/pb/rpc.proto | 19 + 27 files changed, 1295 insertions(+), 389 deletions(-) create mode 100644 nebtestkit/cases/contract/contract.feature.random.test.js create mode 100644 nf/nvm/test/test_random_disable.js rename nf/nvm/test/{test_random.js => test_random_enable.js} (92%) create mode 100644 nf/nvm/test/test_random_seed.js diff --git a/account/manager.go b/account/manager.go index f33114b8b..fa8e7fa10 100644 --- a/account/manager.go +++ b/account/manager.go @@ -21,6 +21,8 @@ package account import ( "errors" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" + "github.com/nebulasio/go-nebulas/util/byteutils" "path/filepath" @@ -386,6 +388,50 @@ func (m *Manager) SignBlock(addr *core.Address, block *core.Block) error { return block.Sign(signature) } +// GenerateBlockRand generate rand +func (m *Manager) GenerateBlockRand(addr *core.Address, parentHashes []byteutils.Hash) (vrfHash, vrfProof []byte, err error) { + + if len(parentHashes) != core.VRFInputParentHashNumber { + logging.VLog().WithFields(logrus.Fields{ + "parent_hash_length": len(parentHashes), + }).Error("Parent hashes are not enough.") + return nil, nil, core.ErrInvalidArgument + } + + key, err := m.ks.GetUnlocked(addr.String()) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to get unlocked private key to generate block rand.") + return nil, nil, ErrAccountIsLocked + } + + _, err = crypto.NewSignature(m.signatureAlg) + if err != nil { + return nil, nil, err + } + + seckey, err := key.(keystore.PrivateKey).Encoded() + if err != nil { + return nil, nil, err + } + + signer, err := secp256k1VRF.NewVRFSignerFromRawKey(seckey) + if err != nil { + return nil, nil, err + } + + var data []byte + for _, h := range parentHashes { + data = append(data, []byte(h)...) + } + index, proof := signer.Evaluate(data) + if proof == nil { + return nil, nil, secp256k1VRF.ErrEvaluateFailed + } + return index[:], proof, nil +} + // SignTransactionWithPassphrase sign transaction with the from passphrase func (m *Manager) SignTransactionWithPassphrase(addr *core.Address, tx *core.Transaction, passphrase []byte) error { // check sign addr is tx's from addr diff --git a/consensus/dpos/dpos.go b/consensus/dpos/dpos.go index b65779d84..0decef561 100644 --- a/consensus/dpos/dpos.go +++ b/consensus/dpos/dpos.go @@ -56,6 +56,7 @@ var ( ErrGenerateNextConsensusState = errors.New("Failed to generate next consensus state") ErrDoubleBlockMinted = errors.New("double block minted") ErrAppendNewBlockFailed = errors.New("failed to append new block to real chain") + ErrInvalidArgument = errors.New("invalid argument") ) // Metrics @@ -375,33 +376,73 @@ func (dpos *Dpos) VerifyBlock(block *core.Block) error { if err := verifyBlockSign(miner, block); err != nil { return err } + + // check block rand + if block.Height() >= core.RandomAvailableCompatibleHeight && !block.HasBlockRand() { + logging.VLog().WithFields(logrus.Fields{ + "compatibleHeight": core.RandomAvailableCompatibleHeight, + }).Debug("No rand found in block header.") + return core.ErrInvalidBlockRand + } + dpos.slot.Add(block.Timestamp(), block) return nil } -func (dpos *Dpos) signBlock(block *core.Block) error { +func (dpos *Dpos) generateBlockSand(block *core.Block, adminService rpcpb.AdminServiceClient) error { if dpos.enableRemoteSignServer == true { - conn, err := rpc.Dial(dpos.remoteSignServer) + if adminService == nil { + return ErrInvalidArgument + } + // generate VRF hash,proof + if block.Height() >= core.RandomAvailableCompatibleHeight { + rand, err := adminService.GenerateBlockRand( + context.Background(), + &rpcpb.GenerateBlockRandRequest{ + Address: dpos.miner.String(), + ParentHash: block.ParentHash(), + }) + if err != nil { + return err + } + block.SetBlockRand(rand.VrfHash, rand.VrfProof) + } + return nil + } + + // generate VRF hash,proof + if block.Height() >= core.RandomAvailableCompatibleHeight { + hashes, err := dpos.chain.GetRecentNBlockHashBeforeInclusive(block.ParentHash(), core.VRFInputParentHashNumber) if err != nil { return err } - adminService := rpcpb.NewAdminServiceClient(conn) - alg := keystore.SECP256K1 - resp, err := adminService.SignHash( - context.Background(), - &rpcpb.SignHashRequest{ - Address: dpos.miner.String(), - Hash: block.Hash(), - Alg: uint32(alg), - }) - conn.Close() + vrfHash, vrfProof, err := dpos.am.GenerateBlockRand(dpos.miner, hashes) if err != nil { return err } - block.SetSignature(alg, resp.Data) - return nil + block.SetBlockRand(vrfHash, vrfProof) + } + return nil +} + +func (dpos *Dpos) remoteSignBlock(block *core.Block, adminService rpcpb.AdminServiceClient) error { + if adminService == nil { + return ErrInvalidArgument + } + alg := keystore.SECP256K1 + resp, err := adminService.SignHash( + context.Background(), + &rpcpb.SignHashRequest{ + Address: dpos.miner.String(), + Hash: block.Hash(), + Alg: uint32(alg), + }) + if err != nil { + return err } - return dpos.am.SignBlock(dpos.miner, block) + + block.SetSignature(alg, resp.Data) + return nil } func (dpos *Dpos) unlock(passphrase string) error { @@ -425,6 +466,22 @@ func (dpos *Dpos) newBlock(tail *core.Block, consensusState state.ConsensusState return nil, err } + var adminService rpcpb.AdminServiceClient + if dpos.enableRemoteSignServer == true { + conn, err := rpc.Dial(dpos.remoteSignServer) + defer func() { + if conn != nil { + conn.Close() + } + }() + if err != nil { + return nil, err + } + adminService = rpcpb.NewAdminServiceClient(conn) + } + + dpos.generateBlockSand(block, adminService) + block.WorldState().SetConsensusState(consensusState) block.SetTimestamp(consensusState.TimeStamp()) block.CollectTransactions(deadlineInMs) @@ -436,7 +493,13 @@ func (dpos *Dpos) newBlock(tail *core.Block, consensusState state.ConsensusState go block.ReturnTransactions() return nil, err } - if err = dpos.signBlock(block); err != nil { + + if dpos.enableRemoteSignServer == true { + err = dpos.remoteSignBlock(block, adminService) + } else { + err = dpos.am.SignBlock(dpos.miner, block) + } + if err != nil { logging.CLog().WithFields(logrus.Fields{ "miner": dpos.miner, "block": block, diff --git a/core/block.go b/core/block.go index b5dfcab3a..7555c1b66 100644 --- a/core/block.go +++ b/core/block.go @@ -40,6 +40,11 @@ import ( "golang.org/x/crypto/sha3" ) +// const +const ( + VRFInputParentHashNumber = 7 +) + var ( // BlockHashLength define a const of the length of Hash of Block in byte. BlockHashLength = 32 @@ -74,6 +79,9 @@ type BlockHeader struct { // sign alg keystore.Algorithm sign byteutils.Hash + + // rand + rand *corepb.Rand } // ToProto converts domain BlockHeader to proto BlockHeader @@ -90,6 +98,7 @@ func (b *BlockHeader) ToProto() (proto.Message, error) { ChainId: b.chainID, Alg: uint32(b.alg), Sign: b.sign, + Rand: b.rand, }, nil } @@ -121,6 +130,7 @@ func (b *BlockHeader) FromProto(msg proto.Message) error { b.alg = alg b.sign = msg.Sign + b.rand = msg.Rand return nil } return ErrInvalidProtoToBlockHeader @@ -189,6 +199,12 @@ func (block *Block) FromProto(msg proto.Message) error { if err := block.header.FromProto(msg.Header); err != nil { return err } + if msg.Height >= RandomAvailableCompatibleHeight && !block.HasBlockRand() { + logging.VLog().WithFields(logrus.Fields{ + "compatibleHeight": RandomAvailableCompatibleHeight, + }).Debug("No rand found in block header.") + return ErrInvalidProtoToBlockHeader + } block.transactions = make(Transactions, len(msg.Transactions)) for idx, v := range msg.Transactions { if v != nil { @@ -270,6 +286,19 @@ func (block *Block) Sign(signature keystore.Signature) error { return nil } +// SetBlockRand set block.header.rand +func (block *Block) SetBlockRand(vrfhash, vrfproof []byte) { + block.header.rand = &corepb.Rand{ + VrfHash: vrfhash, + VrfProof: vrfproof, + } +} + +// HasBlockRand check rand if exists +func (block *Block) HasBlockRand() bool { + return block.header.rand != nil && block.header.rand.VrfHash != nil && block.header.rand.VrfProof != nil +} + // ChainID returns block's chainID func (block *Block) ChainID() uint32 { return block.header.chainID @@ -355,6 +384,19 @@ func (block *Block) Transactions() Transactions { return block.transactions } +// RandomSeed block rand seed (VRF) +func (block *Block) RandomSeed() string { + if block.height >= RandomAvailableCompatibleHeight { + return byteutils.Hex(block.header.rand.VrfHash) + } + return "" +} + +// SupportRandom check is random supported +func (block *Block) SupportRandom() bool { + return block.height >= RandomAvailableCompatibleHeight +} + // LinkParentBlock link parent block, return true if hash is the same; false otherwise. func (block *Block) LinkParentBlock(chain *BlockChain, parentBlock *Block) error { if !block.ParentHash().Equals(parentBlock.Hash()) { @@ -750,7 +792,16 @@ func (block *Block) Seal() error { } func (block *Block) String() string { - return fmt.Sprintf(`{"height": %d, "hash": "%s", "parent_hash": "%s", "acc_root": "%s", "timestamp": %d, "tx": %d, "miner": "%s"}`, + rand := "" + if block.height >= RandomAvailableCompatibleHeight && block.header.rand != nil { + if block.header.rand.VrfHash != nil { + rand += "/vrf_hash/" + byteutils.Hex(block.header.rand.VrfHash) + } + if block.header.rand.VrfProof != nil { + rand += "/vrf_proof/" + byteutils.Hex(block.header.rand.VrfProof) + } + } + return fmt.Sprintf(`{"height": %d, "hash": "%s", "parent_hash": "%s", "acc_root": "%s", "timestamp": %d, "tx": %d, "miner": "%s", "rand": "%s"}`, block.height, block.header.hash, block.header.parentHash, @@ -758,6 +809,7 @@ func (block *Block) String() string { block.header.timestamp, len(block.transactions), byteutils.Hash(block.header.consensusRoot.Proposer).Base58(), + rand, ) } diff --git a/core/block_pool.go b/core/block_pool.go index 85737a7eb..e282f0c0f 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -19,12 +19,16 @@ package core import ( + "bytes" "sync" "time" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" + "github.com/gogo/protobuf/proto" lru "github.com/hashicorp/golang-lru" "github.com/nebulasio/go-nebulas/core/pb" + "github.com/nebulasio/go-nebulas/crypto" "github.com/nebulasio/go-nebulas/net" "github.com/nebulasio/go-nebulas/util/byteutils" @@ -499,6 +503,56 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( return nil, nil, err } + // VRF verify + if lb.block.Height() >= RandomAvailableCompatibleHeight { + hashes, err := lb.chain.GetRecentNBlockHashBeforeInclusive(parentBlock.Hash(), VRFInputParentHashNumber) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to get parent block hash for verifying VRF.") + return nil, nil, err + } + signature, err := crypto.NewSignature(lb.block.Alg()) + if err != nil { + return nil, nil, err + } + pub, err := signature.RecoverPublic(lb.block.Hash(), lb.block.Signature()) + if err != nil { + return nil, nil, err + } + pubdata, err := pub.Encoded() + if err != nil { + return nil, nil, err + } + + verifier, err := secp256k1VRF.NewVRFVerifierFromRawKey(pubdata) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to new VRF verifier.") + return nil, nil, err + } + + var data []byte + for _, h := range hashes { + data = append(data, []byte(h)...) + } + index, err := verifier.ProofToHash(data, lb.block.header.rand.VrfProof) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to calculate VRF proof.") + return nil, nil, err + } + + if !bytes.Equal(index[:], lb.block.header.rand.VrfHash) { + logging.VLog().WithFields(logrus.Fields{ + "block": lb.block, + }).Error("VRF proof failed.") + return nil, nil, ErrVRFProofFailed + } + } + logging.VLog().WithFields(logrus.Fields{ "block": lb.block, }).Info("Block Verified.") diff --git a/core/block_test.go b/core/block_test.go index f397ba9bd..fbee602d8 100644 --- a/core/block_test.go +++ b/core/block_test.go @@ -219,6 +219,9 @@ func (m mockManager) Update(*Address, []byte, []byte) error { return nil } func (m mockManager) Load([]byte, []byte) (*Address, error) { return nil, nil } func (m mockManager) Import([]byte, []byte) (*Address, error) { return nil, nil } func (m mockManager) Remove(*Address, []byte) error { return nil } +func (m mockManager) GenerateBlockRand(addr *Address, parentHashes []byteutils.Hash) (vrfHash, vrfProof []byte, err error) { + return nil, nil, nil +} var ( received = []byte{} diff --git a/core/blockchain.go b/core/blockchain.go index a8350ce8b..1d54e1101 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -464,6 +464,27 @@ func (bc *BlockChain) GetBlockOnCanonicalChainByHash(blockHash byteutils.Hash) * return blockByHeight } +// GetRecentNBlockHashBeforeInclusive read hashes of 'N' parent blocks before hash(inclusive) as VRF input. +// hashes order: from back to front +func (bc *BlockChain) GetRecentNBlockHashBeforeInclusive(hash byteutils.Hash, n int) (hashes []byteutils.Hash, err error) { + if n == 0 || hash == nil { + return nil, ErrInvalidArgument + } + for i := 0; i < n; i++ { + block := bc.GetBlockOnCanonicalChainByHash(hash) + if block == nil { + return nil, ErrNotBlockInCanonicalChain + } + hashes = append(hashes, hash) + // if i < n-1 && block.Height() == 1 { + // // if chain height is not enough, return current hashes + // return + // } + hash = block.ParentHash() + } + return +} + // FindCommonAncestorWithTail return the block's common ancestor with current tail func (bc *BlockChain) FindCommonAncestorWithTail(block *Block) (*Block, error) { if block == nil { diff --git a/core/compatibility.go b/core/compatibility.go index e8a55c60a..5abed9c8b 100644 --- a/core/compatibility.go +++ b/core/compatibility.go @@ -22,9 +22,6 @@ const ( // TransferFromContractEventCompatibleHeight record event 'TransferFromContractEvent' since this height TransferFromContractEventCompatibleHeight uint64 = 200000 - // RandomSeedAvailableCompatibleHeight make 'random' available in contract since this height - RandomSeedAvailableCompatibleHeight uint64 = 200000 - - // CheckRandomSeedCompatibleHeight random seed need be check since this height - CheckRandomSeedCompatibleHeight = RandomSeedAvailableCompatibleHeight + 1 + // RandomAvailableCompatibleHeight make 'random' available in contract since this height + RandomAvailableCompatibleHeight uint64 = 200000 ) diff --git a/core/pb/block.pb.go b/core/pb/block.pb.go index 474e66ca1..394045ca5 100644 --- a/core/pb/block.pb.go +++ b/core/pb/block.pb.go @@ -16,6 +16,7 @@ It has these top-level messages: NetBlocks NetBlock DownloadBlock + Rand */ package corepb @@ -224,6 +225,7 @@ type BlockHeader struct { TxsRoot []byte `protobuf:"bytes,10,opt,name=txs_root,json=txsRoot,proto3" json:"txs_root,omitempty"` EventsRoot []byte `protobuf:"bytes,11,opt,name=events_root,json=eventsRoot,proto3" json:"events_root,omitempty"` ConsensusRoot *consensuspb.ConsensusRoot `protobuf:"bytes,12,opt,name=consensus_root,json=consensusRoot" json:"consensus_root,omitempty"` + Rand *Rand `protobuf:"bytes,13,opt,name=rand" json:"rand,omitempty"` } func (m *BlockHeader) Reset() { *m = BlockHeader{} } @@ -308,6 +310,13 @@ func (m *BlockHeader) GetConsensusRoot() *consensuspb.ConsensusRoot { return nil } +func (m *BlockHeader) GetRand() *Rand { + if m != nil { + return m.Rand + } + return nil +} + type Block struct { Header *BlockHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` Transactions []*Transaction `protobuf:"bytes,2,rep,name=transactions" json:"transactions,omitempty"` @@ -436,6 +445,30 @@ func (m *DownloadBlock) GetSign() []byte { return nil } +type Rand struct { + VrfHash []byte `protobuf:"bytes,1,opt,name=vrf_hash,json=vrfHash,proto3" json:"vrf_hash,omitempty"` + VrfProof []byte `protobuf:"bytes,2,opt,name=vrf_proof,json=vrfProof,proto3" json:"vrf_proof,omitempty"` +} + +func (m *Rand) Reset() { *m = Rand{} } +func (m *Rand) String() string { return proto.CompactTextString(m) } +func (*Rand) ProtoMessage() {} +func (*Rand) Descriptor() ([]byte, []int) { return fileDescriptorBlock, []int{8} } + +func (m *Rand) GetVrfHash() []byte { + if m != nil { + return m.VrfHash + } + return nil +} + +func (m *Rand) GetVrfProof() []byte { + if m != nil { + return m.VrfProof + } + return nil +} + func init() { proto.RegisterType((*Account)(nil), "corepb.Account") proto.RegisterType((*Data)(nil), "corepb.Data") @@ -445,54 +478,58 @@ func init() { proto.RegisterType((*NetBlocks)(nil), "corepb.NetBlocks") proto.RegisterType((*NetBlock)(nil), "corepb.NetBlock") proto.RegisterType((*DownloadBlock)(nil), "corepb.DownloadBlock") + proto.RegisterType((*Rand)(nil), "corepb.rand") } func init() { proto.RegisterFile("block.proto", fileDescriptorBlock) } var fileDescriptorBlock = []byte{ - // 698 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x6d, 0x8b, 0xd3, 0x40, - 0x10, 0x26, 0x6d, 0xfa, 0x36, 0x69, 0x8f, 0x63, 0x3d, 0x24, 0x56, 0xe5, 0x4a, 0x44, 0x28, 0x8a, - 0x2d, 0x9c, 0xc2, 0xf9, 0xf5, 0xf4, 0x3e, 0x9c, 0x22, 0x72, 0x04, 0xbf, 0x08, 0x42, 0x99, 0x6c, - 0xd6, 0x24, 0x98, 0xee, 0x86, 0xec, 0xf6, 0xbc, 0xfb, 0x19, 0xfe, 0x0f, 0xbf, 0xf8, 0x93, 0xfc, - 0x27, 0xb2, 0xb3, 0xe9, 0xdb, 0x79, 0x20, 0x7e, 0xea, 0x3e, 0xf3, 0x64, 0xa6, 0xf3, 0x3c, 0x33, - 0xbb, 0x10, 0x24, 0xa5, 0xe2, 0xdf, 0x66, 0x55, 0xad, 0x8c, 0x62, 0x5d, 0xae, 0x6a, 0x51, 0x25, - 0xe3, 0xd3, 0xac, 0x30, 0xf9, 0x2a, 0x99, 0x71, 0xb5, 0x9c, 0x4b, 0x91, 0xac, 0x4a, 0xd4, 0x85, - 0x9a, 0x67, 0xea, 0x45, 0x03, 0xe6, 0x5c, 0x2d, 0x97, 0x4a, 0xce, 0x53, 0xcc, 0xe6, 0x55, 0x62, - 0x7f, 0x5c, 0x81, 0xf1, 0xeb, 0x7f, 0x27, 0x4a, 0x2d, 0xa4, 0x5e, 0x69, 0x9b, 0xa7, 0x0d, 0x1a, - 0xe1, 0x32, 0xa3, 0x1f, 0x1e, 0xf4, 0xce, 0x38, 0x57, 0x2b, 0x69, 0x58, 0x08, 0x3d, 0x4c, 0xd3, - 0x5a, 0x68, 0x1d, 0x7a, 0x13, 0x6f, 0x3a, 0x8c, 0xd7, 0xd0, 0x32, 0x09, 0x96, 0x28, 0xb9, 0x08, - 0x5b, 0x8e, 0x69, 0x20, 0x3b, 0x82, 0x8e, 0x54, 0x36, 0xde, 0x9e, 0x78, 0x53, 0x3f, 0x76, 0x80, - 0x3d, 0x84, 0xc1, 0x15, 0xd6, 0x7a, 0x91, 0xa3, 0xce, 0x43, 0x9f, 0x32, 0xfa, 0x36, 0x70, 0x81, - 0x3a, 0x67, 0xc7, 0x10, 0x24, 0x45, 0x6d, 0xf2, 0x45, 0x55, 0x22, 0x17, 0x61, 0x87, 0x68, 0xa0, - 0xd0, 0xa5, 0x8d, 0x44, 0xaf, 0xc0, 0x3f, 0x47, 0x83, 0x8c, 0x81, 0x6f, 0x6e, 0x2a, 0x41, 0xcd, - 0x0c, 0x62, 0x3a, 0xdb, 0x4e, 0x2a, 0xbc, 0x29, 0x15, 0xa6, 0xeb, 0x4e, 0x1a, 0x18, 0xfd, 0x6c, - 0x41, 0xf0, 0xa9, 0x46, 0xa9, 0x91, 0x9b, 0x42, 0x49, 0x9b, 0x4d, 0x7f, 0xef, 0xa4, 0xd0, 0xd9, - 0xc6, 0xbe, 0xd6, 0x6a, 0xd9, 0xa4, 0xd2, 0x99, 0x1d, 0x40, 0xcb, 0x28, 0x6a, 0x7f, 0x18, 0xb7, - 0x8c, 0xb2, 0x8a, 0xae, 0xb0, 0x5c, 0x89, 0xa6, 0x6f, 0x07, 0xb6, 0x3a, 0x3b, 0xbb, 0x3a, 0x1f, - 0xc1, 0xc0, 0x14, 0x4b, 0xa1, 0x0d, 0x2e, 0xab, 0xb0, 0x3b, 0xf1, 0xa6, 0xed, 0x78, 0x1b, 0x60, - 0x13, 0xf0, 0x53, 0x34, 0x18, 0xf6, 0x26, 0xde, 0x34, 0x38, 0x19, 0xce, 0xdc, 0x94, 0x67, 0x56, - 0x5b, 0x4c, 0x0c, 0x7b, 0x00, 0x7d, 0x9e, 0x63, 0x21, 0x17, 0x45, 0x1a, 0xf6, 0x27, 0xde, 0x74, - 0x14, 0xf7, 0x08, 0xbf, 0x4b, 0xad, 0x85, 0x19, 0xea, 0x45, 0x55, 0x17, 0x5c, 0x84, 0x03, 0x67, - 0x61, 0x86, 0xfa, 0xd2, 0xe2, 0x35, 0x59, 0x16, 0xcb, 0xc2, 0x84, 0xb0, 0x21, 0x3f, 0x58, 0xcc, - 0x0e, 0xa1, 0x8d, 0x65, 0x16, 0x06, 0x54, 0xcf, 0x1e, 0xad, 0x6c, 0x5d, 0x64, 0x32, 0x1c, 0x3a, - 0xd9, 0xf6, 0x1c, 0xfd, 0x6e, 0x41, 0xf0, 0xc6, 0xee, 0xe0, 0x85, 0xc0, 0x54, 0xd4, 0x77, 0xda, - 0x75, 0x0c, 0x41, 0x85, 0xb5, 0x90, 0xc6, 0x0d, 0xd2, 0xb9, 0x06, 0x2e, 0x44, 0xa3, 0x1c, 0x43, - 0x9f, 0xab, 0x42, 0x26, 0xa8, 0xd7, 0x76, 0x6d, 0xf0, 0xbe, 0x37, 0x9d, 0xdb, 0xde, 0xec, 0x2a, - 0xef, 0xee, 0x2b, 0x6f, 0xfa, 0xef, 0xfd, 0xdd, 0x7f, 0x7f, 0xdb, 0x3f, 0x7b, 0x0c, 0x40, 0x7b, - 0xbc, 0xa8, 0x95, 0x32, 0x8d, 0x41, 0x03, 0x8a, 0xc4, 0x4a, 0x19, 0x5b, 0xdf, 0x5c, 0x6b, 0x47, - 0x3a, 0x83, 0x7a, 0xe6, 0x5a, 0x13, 0x75, 0x0c, 0x81, 0xb8, 0x12, 0xd2, 0x34, 0x6c, 0xe0, 0x54, - 0xb9, 0x10, 0x7d, 0x70, 0x06, 0x07, 0x9b, 0xfb, 0xe2, 0xbe, 0x19, 0xd2, 0x04, 0xc7, 0xb3, 0x4d, - 0xb8, 0x4a, 0x66, 0x6f, 0xd7, 0x67, 0x9b, 0x13, 0x8f, 0xf8, 0x2e, 0x7c, 0xef, 0xf7, 0xdb, 0x87, - 0x7e, 0xf4, 0xcb, 0x83, 0x0e, 0x79, 0xcc, 0x9e, 0x43, 0x37, 0x27, 0x9f, 0xc9, 0xdf, 0xe0, 0xe4, - 0xde, 0x7a, 0x19, 0x76, 0x46, 0x10, 0x37, 0x9f, 0xb0, 0x53, 0x18, 0x9a, 0xed, 0x22, 0xeb, 0xb0, - 0x35, 0x69, 0xef, 0xa6, 0xec, 0x2c, 0x79, 0xbc, 0xf7, 0x21, 0x7b, 0x06, 0x90, 0x8a, 0x4a, 0xc8, - 0x54, 0x48, 0x7e, 0x43, 0x2b, 0x1d, 0x9c, 0xc0, 0x2c, 0xc5, 0x8c, 0xb6, 0x2e, 0x8b, 0x77, 0x58, - 0x76, 0xdf, 0x76, 0x54, 0x64, 0xb9, 0xa1, 0xc1, 0xf9, 0x71, 0x83, 0xa2, 0x2f, 0x30, 0xf8, 0x28, - 0x0c, 0xb5, 0xa5, 0x37, 0xf7, 0xa5, 0xb9, 0x81, 0x74, 0x5f, 0x8e, 0xa0, 0x93, 0xa0, 0xe1, 0x6e, - 0x1d, 0xfc, 0xd8, 0x01, 0xf6, 0x14, 0xba, 0xf4, 0xa2, 0xe9, 0xb0, 0x4d, 0xdd, 0x8e, 0xf6, 0x04, - 0xc6, 0x0d, 0x19, 0x7d, 0x86, 0xfe, 0xba, 0xfa, 0x7f, 0x14, 0x7f, 0x02, 0x1d, 0xca, 0x6f, 0x24, - 0xdd, 0xaa, 0xed, 0xb8, 0xe8, 0x14, 0x46, 0xe7, 0xea, 0xbb, 0xb4, 0x6f, 0xc1, 0xa6, 0xfe, 0x5d, - 0x0f, 0x00, 0x6d, 0x52, 0x6b, 0xbb, 0x49, 0x49, 0x97, 0x5e, 0xc2, 0x97, 0x7f, 0x02, 0x00, 0x00, - 0xff, 0xff, 0xa7, 0xc4, 0x6c, 0xca, 0x93, 0x05, 0x00, 0x00, + // 744 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6a, 0xdb, 0x4a, + 0x10, 0x46, 0xb6, 0xfc, 0x37, 0xb2, 0x43, 0xd8, 0x13, 0x0e, 0x3a, 0x3e, 0x2d, 0x31, 0x2a, 0x05, + 0xd3, 0x52, 0x1b, 0xd2, 0x42, 0x7a, 0x55, 0x48, 0x9b, 0x8b, 0xb4, 0x94, 0x12, 0x96, 0xde, 0x14, + 0x0a, 0x66, 0x25, 0xad, 0x25, 0x51, 0x79, 0x57, 0xec, 0xae, 0xdd, 0xe4, 0xba, 0x4f, 0xd0, 0xf7, + 0xe8, 0x4d, 0xdf, 0xb0, 0xec, 0xac, 0x6c, 0xcb, 0x69, 0xa0, 0xf4, 0x4a, 0xfb, 0xcd, 0xb7, 0x33, + 0x9a, 0x99, 0x6f, 0x66, 0x21, 0x88, 0x4b, 0x99, 0x7c, 0x99, 0x55, 0x4a, 0x1a, 0x49, 0xba, 0x89, + 0x54, 0xbc, 0x8a, 0xc7, 0xe7, 0x59, 0x61, 0xf2, 0x75, 0x3c, 0x4b, 0xe4, 0x6a, 0x2e, 0x78, 0xbc, + 0x2e, 0x99, 0x2e, 0xe4, 0x3c, 0x93, 0xcf, 0x6a, 0x30, 0x4f, 0xe4, 0x6a, 0x25, 0xc5, 0x3c, 0x65, + 0xd9, 0xbc, 0x8a, 0xed, 0xc7, 0x05, 0x18, 0xbf, 0xfc, 0xb3, 0xa3, 0xd0, 0x5c, 0xe8, 0xb5, 0xb6, + 0x7e, 0xda, 0x30, 0xc3, 0x9d, 0x67, 0xf4, 0xdd, 0x83, 0xde, 0x45, 0x92, 0xc8, 0xb5, 0x30, 0x24, + 0x84, 0x1e, 0x4b, 0x53, 0xc5, 0xb5, 0x0e, 0xbd, 0x89, 0x37, 0x1d, 0xd2, 0x2d, 0xb4, 0x4c, 0xcc, + 0x4a, 0x26, 0x12, 0x1e, 0xb6, 0x1c, 0x53, 0x43, 0x72, 0x02, 0x1d, 0x21, 0xad, 0xbd, 0x3d, 0xf1, + 0xa6, 0x3e, 0x75, 0x80, 0xfc, 0x0f, 0x83, 0x0d, 0x53, 0x7a, 0x91, 0x33, 0x9d, 0x87, 0x3e, 0x7a, + 0xf4, 0xad, 0xe1, 0x8a, 0xe9, 0x9c, 0x9c, 0x42, 0x10, 0x17, 0xca, 0xe4, 0x8b, 0xaa, 0x64, 0x09, + 0x0f, 0x3b, 0x48, 0x03, 0x9a, 0xae, 0xad, 0x25, 0x7a, 0x01, 0xfe, 0x25, 0x33, 0x8c, 0x10, 0xf0, + 0xcd, 0x6d, 0xc5, 0x31, 0x99, 0x01, 0xc5, 0xb3, 0xcd, 0xa4, 0x62, 0xb7, 0xa5, 0x64, 0xe9, 0x36, + 0x93, 0x1a, 0x46, 0x3f, 0x5a, 0x10, 0x7c, 0x54, 0x4c, 0x68, 0x96, 0x98, 0x42, 0x0a, 0xeb, 0x8d, + 0xbf, 0x77, 0xa5, 0xe0, 0xd9, 0xda, 0x96, 0x4a, 0xae, 0x6a, 0x57, 0x3c, 0x93, 0x23, 0x68, 0x19, + 0x89, 0xe9, 0x0f, 0x69, 0xcb, 0x48, 0x5b, 0xd1, 0x86, 0x95, 0x6b, 0x5e, 0xe7, 0xed, 0xc0, 0xbe, + 0xce, 0x4e, 0xb3, 0xce, 0x07, 0x30, 0x30, 0xc5, 0x8a, 0x6b, 0xc3, 0x56, 0x55, 0xd8, 0x9d, 0x78, + 0xd3, 0x36, 0xdd, 0x1b, 0xc8, 0x04, 0xfc, 0x94, 0x19, 0x16, 0xf6, 0x26, 0xde, 0x34, 0x38, 0x1b, + 0xce, 0x9c, 0xca, 0x33, 0x5b, 0x1b, 0x45, 0x86, 0xfc, 0x07, 0xfd, 0x24, 0x67, 0x85, 0x58, 0x14, + 0x69, 0xd8, 0x9f, 0x78, 0xd3, 0x11, 0xed, 0x21, 0x7e, 0x9b, 0xda, 0x16, 0x66, 0x4c, 0x2f, 0x2a, + 0x55, 0x24, 0x3c, 0x1c, 0xb8, 0x16, 0x66, 0x4c, 0x5f, 0x5b, 0xbc, 0x25, 0xcb, 0x62, 0x55, 0x98, + 0x10, 0x76, 0xe4, 0x7b, 0x8b, 0xc9, 0x31, 0xb4, 0x59, 0x99, 0x85, 0x01, 0xc6, 0xb3, 0x47, 0x5b, + 0xb6, 0x2e, 0x32, 0x11, 0x0e, 0x5d, 0xd9, 0xf6, 0x1c, 0x7d, 0x6b, 0x43, 0xf0, 0xda, 0xce, 0xe0, + 0x15, 0x67, 0x29, 0x57, 0xf7, 0xb6, 0xeb, 0x14, 0x82, 0x8a, 0x29, 0x2e, 0x8c, 0x13, 0xd2, 0x75, + 0x0d, 0x9c, 0x09, 0xa5, 0x1c, 0x43, 0x3f, 0x91, 0x85, 0x88, 0x99, 0xde, 0xb6, 0x6b, 0x87, 0x0f, + 0x7b, 0xd3, 0xb9, 0xdb, 0x9b, 0x66, 0xe5, 0xdd, 0xc3, 0xca, 0xeb, 0xfc, 0x7b, 0xbf, 0xe7, 0xdf, + 0xdf, 0xe7, 0x4f, 0x1e, 0x02, 0xe0, 0x1c, 0x2f, 0x94, 0x94, 0xa6, 0x6e, 0xd0, 0x00, 0x2d, 0x54, + 0x4a, 0x63, 0xe3, 0x9b, 0x1b, 0xed, 0x48, 0xd7, 0xa0, 0x9e, 0xb9, 0xd1, 0x48, 0x9d, 0x42, 0xc0, + 0x37, 0x5c, 0x98, 0x9a, 0x0d, 0x5c, 0x55, 0xce, 0x84, 0x17, 0x2e, 0xe0, 0x68, 0xb7, 0x2f, 0xee, + 0xce, 0x10, 0x15, 0x1c, 0xcf, 0x76, 0xe6, 0x2a, 0x9e, 0xbd, 0xd9, 0x9e, 0xad, 0x0f, 0x1d, 0x25, + 0x4d, 0x68, 0xa5, 0x57, 0x4c, 0xa4, 0xe1, 0xe8, 0x50, 0x7a, 0x6b, 0xa3, 0xc8, 0xbc, 0xf3, 0xfb, + 0xed, 0x63, 0x3f, 0xfa, 0xe9, 0x41, 0x07, 0x55, 0x20, 0x4f, 0xa1, 0x9b, 0xa3, 0x12, 0xa8, 0x40, + 0x70, 0xf6, 0xcf, 0xd6, 0xa7, 0x21, 0x12, 0xad, 0xaf, 0x90, 0x73, 0x18, 0x9a, 0xfd, 0xa8, 0xeb, + 0xb0, 0x35, 0x69, 0x37, 0x5d, 0x1a, 0x6b, 0x40, 0x0f, 0x2e, 0x92, 0x27, 0x00, 0x29, 0xaf, 0xb8, + 0x48, 0xb9, 0x48, 0x6e, 0x71, 0xe8, 0x83, 0x33, 0x98, 0xa5, 0x2c, 0xc3, 0xb9, 0xcc, 0x68, 0x83, + 0x25, 0xff, 0xda, 0x8c, 0x8a, 0x2c, 0x37, 0x28, 0xad, 0x4f, 0x6b, 0x14, 0x7d, 0x86, 0xc1, 0x07, + 0x6e, 0x30, 0x2d, 0xbd, 0xdb, 0xa8, 0x7a, 0x47, 0x71, 0xa3, 0x4e, 0xa0, 0x13, 0x33, 0x93, 0xb8, + 0x81, 0xf1, 0xa9, 0x03, 0xe4, 0x31, 0x74, 0xf1, 0xcd, 0xd3, 0x61, 0x1b, 0xb3, 0x1d, 0x1d, 0x14, + 0x48, 0x6b, 0x32, 0xfa, 0x04, 0xfd, 0x6d, 0xf4, 0xbf, 0x08, 0xfe, 0x08, 0x3a, 0xe8, 0x5f, 0x97, + 0x74, 0x27, 0xb6, 0xe3, 0xa2, 0x73, 0x18, 0x5d, 0xca, 0xaf, 0xc2, 0xbe, 0x16, 0xbb, 0xf8, 0xf7, + 0x3d, 0x11, 0x38, 0x6b, 0xad, 0xc6, 0xae, 0xbc, 0x72, 0x6a, 0xda, 0xa1, 0xda, 0xa8, 0xe5, 0xa2, + 0xe1, 0xd3, 0xdb, 0xa8, 0x25, 0x6e, 0x82, 0x7d, 0xf1, 0xd4, 0x72, 0x51, 0x29, 0x29, 0x97, 0xb5, + 0xaf, 0xbd, 0x7b, 0x6d, 0x71, 0xdc, 0xc5, 0xb7, 0xf6, 0xf9, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x7c, 0xd8, 0x7b, 0x5f, 0xf5, 0x05, 0x00, 0x00, } diff --git a/core/pb/block.proto b/core/pb/block.proto index 24e67e288..9c3bc29e2 100644 --- a/core/pb/block.proto +++ b/core/pb/block.proto @@ -64,6 +64,7 @@ message BlockHeader { bytes txs_root = 10; bytes events_root = 11; consensuspb.ConsensusRoot consensus_root = 12; + rand rand = 13; } message Block { @@ -90,3 +91,8 @@ message DownloadBlock { bytes hash = 1; bytes sign = 2; } + +message rand { + bytes vrf_hash = 1; + bytes vrf_proof = 2; +} \ No newline at end of file diff --git a/core/types.go b/core/types.go index 196e16317..d0d843229 100644 --- a/core/types.go +++ b/core/types.go @@ -95,6 +95,8 @@ var ( ErrDoubleSealBlock = errors.New("cannot seal a block twice") ErrDuplicatedBlock = errors.New("duplicated block") ErrDoubleBlockMinted = errors.New("double block minted") + ErrVRFProofFailed = errors.New("VRF proof failed") + ErrInvalidBlockRand = errors.New("invalid block rand") ErrInvalidChainID = errors.New("invalid transaction chainID") ErrInvalidTransactionSigner = errors.New("invalid transaction signer") @@ -237,6 +239,7 @@ type AccountManager interface { SignHash(*Address, byteutils.Hash, keystore.Algorithm) ([]byte, error) SignBlock(*Address, *Block) error + GenerateBlockRand(*Address, []byteutils.Hash) ([]byte, []byte, error) SignTransaction(*Address, *Transaction) error SignTransactionWithPassphrase(*Address, *Transaction, []byte) error diff --git a/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go index 864870d9b..7f53c37eb 100644 --- a/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go +++ b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF.go @@ -37,7 +37,7 @@ import ( "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1" "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/bitelliptic" - "github.com/google/keytransparency/core/crypto/vrf" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf" ) var ( @@ -52,6 +52,8 @@ var ( ErrNoPEMFound = errors.New("no PEM block found") // ErrInvalidVRF occurs when the VRF does not validate. ErrInvalidVRF = errors.New("invalid VRF proof") + // ErrEvaluateFailed fail + ErrEvaluateFailed = errors.New("failed to evaluate VRF") ) // PublicKey holds a public VRF key. diff --git a/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go index 43b1af1e1..5d87a51e5 100644 --- a/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go +++ b/crypto/keystore/secp256k1/vrf/secp256k1VRF/secp256k1VRF_test.go @@ -23,6 +23,7 @@ import ( "testing" "time" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1" "github.com/nebulasio/go-nebulas/util/byteutils" // _ "github.com/google/trillian/crypto/keys/der/proto" ) @@ -309,3 +310,53 @@ func h2b(h string) []byte { } return b } + +func Test256VRF(t *testing.T) { + + seckey, err := byteutils.FromHex(privKey) + if err != nil { + t.Errorf("load priv err: %v", err) + } + ecdsaPriv, err := secp256k1.ToECDSAPrivateKey(seckey) + if err != nil { + t.Errorf("ecdsa err: %v", err) + } + + signer, err := NewVRFSigner(ecdsaPriv) + if err != nil { + t.Errorf("new signer err: %v", err) + } + + data := []byte("b10c1203d5ae6d4d069d5f520eb060f2f5fb74e942f391e7cadbc2b5148dfbcb") + sIndex, proof := signer.Evaluate(data) + + seckeyPub, err := byteutils.FromHex(pubKey) + + priv := new(secp256k1.PrivateKey) + err = priv.Decode(seckey) + if err != nil { + t.Errorf("decode priv err: %v", err) + } + + epub, err := priv.PublicKey().Encoded() + if err != nil { + t.Errorf("encode pub err: %v", err) + } + if !bytes.Equal(seckeyPub, epub) { + t.Errorf("mismatched priv/pub err: %v", err) + } + + verifier, err := NewVRFVerifierFromRawKey(seckeyPub) + if err != nil { + t.Errorf("new verifier err: %v", err) + } + + vIndex, err := verifier.ProofToHash(data, proof) + if err != nil { + t.Errorf("exec proof err: %v", err) + } + + if !bytes.Equal(sIndex[0:], vIndex[0:]) { + t.Errorf("verification failed") + } +} diff --git a/crypto/keystore/secp256k1/vrf/vrf_test.go b/crypto/keystore/secp256k1/vrf/vrf_test.go index ac1ebd53d..5a5fcfe8d 100644 --- a/crypto/keystore/secp256k1/vrf/vrf_test.go +++ b/crypto/keystore/secp256k1/vrf/vrf_test.go @@ -20,13 +20,12 @@ package vrf import ( - "bytes" + "fmt" "testing" + "github.com/nebulasio/go-nebulas/crypto" + "github.com/nebulasio/go-nebulas/crypto/keystore" "github.com/nebulasio/go-nebulas/util/byteutils" - - "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1" - "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" ) const ( @@ -37,62 +36,16 @@ const ( ) func TestVRF(t *testing.T) { - // priv, _ := crypto.NewPrivateKey(keystore.SECP256K1, nil) - // seckey, err := priv.Encoded() - // if err != nil { - // t.Errorf("new priv err: %v", err) - // } - // seckeypub, err := priv.PublicKey().Encoded() - // if err != nil { - // t.Errorf("pub of new priv err: %v", err) - // } - // fmt.Println("1:", byteutils.Hex(seckey)) - // fmt.Println("2:", byteutils.Hex(seckeypub)) - - seckey, err := byteutils.FromHex(privKey) - if err != nil { - t.Errorf("load priv err: %v", err) - } - ecdsaPriv, err := secp256k1.ToECDSAPrivateKey(seckey) + priv, _ := crypto.NewPrivateKey(keystore.SECP256K1, nil) + seckey, err := priv.Encoded() if err != nil { - t.Errorf("ecdsa err: %v", err) + t.Errorf("new priv err: %v", err) } - - signer, err := secp256k1VRF.NewVRFSigner(ecdsaPriv) + seckeypub, err := priv.PublicKey().Encoded() if err != nil { - t.Errorf("new signer err: %v", err) + t.Errorf("pub of new priv err: %v", err) } + fmt.Println("1:", byteutils.Hex(seckey)) + fmt.Println("2:", byteutils.Hex(seckeypub)) - data := []byte("b10c1203d5ae6d4d069d5f520eb060f2f5fb74e942f391e7cadbc2b5148dfbcb") - sIndex, proof := signer.Evaluate(data) - - seckeyPub, err := byteutils.FromHex(pubKey) - - priv := new(secp256k1.PrivateKey) - err = priv.Decode(seckey) - if err != nil { - t.Errorf("decode priv err: %v", err) - } - - epub, err := priv.PublicKey().Encoded() - if err != nil { - t.Errorf("encode pub err: %v", err) - } - if !bytes.Equal(seckeyPub, epub) { - t.Errorf("mismatched priv/pub err: %v", err) - } - - verifier, err := secp256k1VRF.NewVRFVerifierFromRawKey(seckeyPub) - if err != nil { - t.Errorf("new verifier err: %v", err) - } - - vIndex, err := verifier.ProofToHash(data, proof) - if err != nil { - t.Errorf("exec proof err: %v", err) - } - - if !bytes.Equal(sIndex[0:], vIndex[0:]) { - t.Errorf("verification failed") - } } diff --git a/nebtestkit/cases/contract/contract.feature.random.test.js b/nebtestkit/cases/contract/contract.feature.random.test.js new file mode 100644 index 000000000..93881dd22 --- /dev/null +++ b/nebtestkit/cases/contract/contract.feature.random.test.js @@ -0,0 +1,392 @@ +'use strict'; + +var sleep = require('system-sleep'); +var FS = require('fs'); +var expect = require('chai').expect; +var BigNumber = require('bignumber.js'); +var HttpRequest = require('../../node-request'); +var TestnetConfig = require('../testnet_config'); +var Wallet = require('nebulas'); + +var Account = Wallet.Account; +var Transaction = Wallet.Transaction; +var env = process.argv.splice(2)[1]; +var testnetConfig = new TestnetConfig(env); +var originSource = testnetConfig.sourceAccount; +var ChainID = testnetConfig.ChainId; +var coinbase = testnetConfig.coinbase; +var neb = new Wallet.Neb(); +neb.setRequest(new HttpRequest(testnetConfig.apiEndPoint)); + + +var deploy, from, contractAddr, source, fromState, coinState; +var caseIndex = 0, lastnonce = 0; + +function prepareSource(done) { + console.log("originSource address: " + originSource.getAddressString()); + neb.api.getAccountState(originSource.getAddressString()).then(function (resp) { + console.log("prepare source account state:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + + source = Account.NewAccount(); + + var tx = new Transaction(ChainID, originSource, source, neb.nasToBasic(1000), nonce + 1, "1000000", "200000"); + tx.signTransaction(); + + console.log("cliam source tx:", tx.toString()); + + return neb.api.sendRawTransaction(tx.toProtoString()); + }).then(function (resp) { + console.log("send Raw Tx:" + JSON.stringify(resp)); + expect(resp).to.be.have.property('txhash'); + checkTransaction(resp.txhash, 0, function (receipt) { + console.log("tx receipt : " + JSON.stringify(receipt)); + expect(receipt).to.be.have.property('status').equal(1); + + done(); + }); + }).catch(function (err) { + done(err); + }); +} + +function cliamTokens(accounts, values, done) { + for (var i = 0; i < accounts.length; i++) { + console.log("acc:"+accounts[i].getAddressString()+" value:"+values[i]); + sendTransaction(source, accounts[i], values[i], ++lastnonce); + sleep(30); + } + checkCliamTokens(done); +} + + +function sendTransaction(from, address, value, nonce) { + var transaction = new Transaction(ChainID, from, address, value, nonce, "1000000", "200000"); + transaction.signTransaction(); + var rawTx = transaction.toProtoString(); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("send raw transaction resp:" + JSON.stringify(resp)); + }); +} + +function checkCliamTokens(done) { + var intervalAccount = setInterval(function () { + neb.api.getAccountState(source.getAddressString()).then(function (resp) { + // console.log("master accountState resp:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + console.log("check cliam tokens nonce:", lastnonce); + + if (lastnonce <= nonce){ + console.log("cliam tokens success"); + clearInterval(intervalAccount); + done(); + } + }); + }, 2000); +} + +function checkTransaction(txhash, retry, done){ + + var maxRetry = 45; + + // contract status and get contract_address + var interval = setTimeout(function () { + neb.api.getTransactionReceipt(txhash).then(function (resp) { + retry++; + + console.log("check transaction status:" + resp.status); + if(resp.status && resp.status === 1) { + // clearInterval(interval); + + if (resp.contract_address) { + console.log("deploy private key:" + deploy.getPrivateKeyString()); + console.log("deploy address:" + deploy.getAddressString()); + console.log("deploy contract address:" + resp.contract_address); + + contractAddr = resp.contract_address; + } + + done(resp); + } else if (resp.status && resp.status === 2) { + if (retry > maxRetry) { + console.log("check transaction time out"); + // clearInterval(interval); + done(resp); + } else { + checkTransaction(txhash, retry++, done); + } + } else { + // clearInterval(interval); + console.log("transaction execution failed"); + done(resp); + } + }).catch(function (err) { + retry++; + console.log("check transaction not found retry " + retry); + if (retry > maxRetry) { + console.log(JSON.stringify(err.error)); + // clearInterval(interval); + done(err); + } else { + checkTransaction(txhash, retry++, done); + } + }); + + }, 2000); +} + + +function deployContract(done, caseGroup) { + console.log("start deploying contract: " + caseGroup.groupname); + + neb.api.getAccountState(source.getAddressString()).then(function (resp) { + console.log("source account state:" + JSON.stringify(resp)); + + var accounts = new Array(); + var values = new Array(); + deploy = Account.NewAccount(); + accounts.push(deploy); + values.push(neb.nasToBasic(1)); + + from = Account.NewAccount(); + accounts.push(from); + var fromBalance = (typeof caseGroup.fromBalance === "undefined") ? neb.nasToBasic(1) : caseGroup.fromBalance; + values.push(fromBalance); + + cliamTokens(accounts, values, () => { + try { + var source = FS.readFileSync("../../../nf/nvm/test/" + caseGroup.filename, "utf-8"); + var contract = { + "source": source, + "sourceType": caseGroup.type, + "args": "" + }; + + var tx = new Transaction(testnetConfig.ChainId, deploy, deploy, "0", 1, "10000000", "2000000", contract); + tx.signTransaction(); + var rawTx = tx.toProtoString(); + + // console.log("contract:" + rawTx); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("deploy contract " + caseGroup.groupname + " return: " + JSON.stringify(resp)); + + checkTransaction(resp.txhash, 0, (ret) => { + if (ret.status && ret.status === 1) { + done(); + } else { + done(ret); + } + }); + }); + } catch (err) { + done(err); + }; + }); + + }).catch (err => done(err)); +} + +function runTest(testInput, testExpect, done) { + var fromAcc = (typeof testInput.from === "undefined") ? from : testInput.from; + var to = (typeof testInput.to === "undefined") ? Account.fromAddress(contractAddr) : testInput.to; + + var fromBalanceBefore, toBalanceBefore; + + neb.api.getAccountState(to.getAddressString()).then(function (resp) { + console.log("contractAddr state before: " + JSON.stringify(resp)); + toBalanceBefore = resp.balance; + return neb.api.getAccountState(from.getAddressString()); + }).then(resp => { + fromState = resp; + fromBalanceBefore = resp.balanece; + console.log("from state before: ", JSON.stringify(resp)); + return neb.api.getAccountState(coinbase); + }).then(function (resp) { + console.log("coin state before: ", JSON.stringify(resp)); + coinState = resp; + + var tx = new Transaction(ChainID, fromAcc, to, testInput.value, parseInt(fromState.nonce) + testInput.nonce, testInput.gasPrice, testInput.gasLimit, testInput.contract); + tx.from.address = fromAcc.address; + tx.to.address = to.address; + tx.gasPrice = new BigNumber(testInput.gasPrice); + tx.gasLimit = new BigNumber(testInput.gasLimit); + tx.signTransaction(); + console.log("binary tx raw before send: ", tx.toString()); + return neb.api.sendRawTransaction(tx.toProtoString()); + }).then(function (rawResp) { + console.log("send Raw Tx return:" + JSON.stringify(rawResp)); + expect(rawResp).to.be.have.property('txhash'); + + checkTransaction(rawResp.txhash, 0, function (receipt) { + console.log("tx receipt : " + JSON.stringify(receipt)); + try { + expect(receipt).to.not.be.a('undefined'); + if (true === testExpect.canExcuteTx) { + expect(receipt).to.be.have.property('status').equal(1); + } else { + expect(receipt).to.be.have.property('status').equal(0); + } + + neb.api.getAccountState(receipt.from).then(function (state) { + + console.log("from state after: " + JSON.stringify(state)); + // expect(state.balance).to.equal(testExpect.fromBalanceAfterTx); + return neb.api.getAccountState(contractAddr); + }).then(function (state) { + + console.log("contractAddr state after: " + JSON.stringify(state)); + var change = new BigNumber(state.balance).minus(new BigNumber(toBalanceBefore)); + // expect(change.toString()).to.equal(testExpect.toBalanceChange); + return neb.api.getAccountState(coinbase); + }).then(function (state) { + + console.log("get coinbase account state before tx:" + JSON.stringify(coinState)); + console.log("get coinbase account state after tx:" + JSON.stringify(state)); + var reward = new BigNumber(state.balance).sub(coinState.balance); + reward = reward.mod(new BigNumber(1.42694).mul(new BigNumber(10).pow(18))); + // The transaction should be only + // expect(reward.toString()).to.equal(testExpect.transferReward); + console.log("coinbase reward: " + reward.toString()); + if (receipt.gasUsed) { + var txCost = new BigNumber(receipt.gasUsed).mul(receipt.gasPrice).toString(10); + // expect(txCost).to.equal(testExpect.transferReward); + console.log("tx cost gas: " + txCost.toString()); + } + + return neb.api.getEventsByHash(receipt.hash); + }).then(function (events) { + for (var i = 0; i < events.events.length; i++) { + var event = events.events[i]; + //console.log("tx event:", JSON.stringify(event,null,'\t')); + console.log("tx event:", event.data); + if (event.topic === "chain.transactionResult") { + var result = JSON.parse(event.data); + expect(result.status).to.equal(testExpect.status); + + if (testExpect.hasOwnProperty("eventErr")){ + console.log("Event error checked."); + expect(result.error).to.equal(testExpect.eventErr); + } + } + if (event.topic === "chain.contract.random") { + var result = JSON.parse(event.data); + expect(result.defaultSeedRandom1 == result.userSeedRandom).to.equal(testExpect.equalr1r2); + console.log("check equalr1r2 success"); + } + } + done(); + }).catch(function (err) { + console.log("exe tx err:", err); + done(err); + }); + } catch (err) { + console.log("submit tx err:", err.message); + done(err); + } + }); + }).catch(function (err) { + console.log("send tx err"); + done(err); + }); +} + +var testCaseGroups = []; +var caseGroup = { + "filename": "contract_date_and_random.js", + "type": "js", + "groupname": "case group 0: Math.random", + "groupIndex": 0, + + cases: [ + { + "name": "0-1. test 'not define user seed'", + "testInput": { + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000, + contract: { + function: "testRandom", + args: "" + } + }, + "testExpect": { + canExcuteTx: false, + toBalanceChange: "0", + status: 0, + equalBlockTime: true + } + }, + { + "name": "0-2. test 'empty user seed('') == reset random seed'", + "testInput": { + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000, + contract: { + function: "testRandom", + args: "[\"\"]" + } + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "0", + status: 1, + equalr1r2: true + } + }, + { + "name": "0-3. test 'set user seed('abc')'", + "testInput": { + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000, + contract: { + function: "testRandom", + args: "[\"abc\"]" + } + }, + "testExpect": { + canExcuteTx: true, + toBalanceChange: "0", + status: 1, + equalr1r2: false + } + } + ] +}; +testCaseGroups.push(caseGroup); + +describe('Contract Math.random test', () => { + + before(done => prepareSource(done)); + + for (var i = 0; i < testCaseGroups.length; i++) { + + // if (i != 3) {continue;} // selectively run tests + + let caseGroup = testCaseGroups[i]; + describe(caseGroup.groupname, () => { + before(done => { + deployContract(done, caseGroup); + caseIndex = 0; + }); + + + for (var j = 0; j < caseGroup.cases.length; j++) { + let testCase = caseGroup.cases[j]; + it(testCase.name, done => { + console.log("===> running case: " + JSON.stringify(testCase)); + runTest(testCase.testInput, testCase.testExpect, done); + }); + } + + afterEach(() => { + caseIndex++; + console.log("case group: " + caseGroup.groupIndex + ", index: " + caseIndex); + }); + }); + } +}); \ No newline at end of file diff --git a/nf/nvm/context.go b/nf/nvm/context.go index a6e6c35f5..3101455d9 100644 --- a/nf/nvm/context.go +++ b/nf/nvm/context.go @@ -32,9 +32,11 @@ type SerializableAccount struct { // SerializableBlock serializable block type SerializableBlock struct { - Timestamp int64 `json:"timestamp"` - Hash string `json:"hash"` - Height uint64 `json:"height"` + Timestamp int64 `json:"timestamp"` + Hash string `json:"hash"` + Height uint64 `json:"height"` + SupportRandom bool `json:"supportRandom"` + Seed string `json:"seed"` } // SerializableTransaction serializable transaction @@ -81,9 +83,11 @@ func toSerializableAccount(acc Account) *SerializableAccount { func toSerializableBlock(block Block) *SerializableBlock { sBlock := &SerializableBlock{ - Timestamp: block.Timestamp(), - Hash: block.Hash().String(), - Height: block.Height(), + Timestamp: block.Timestamp(), + Hash: block.Hash().String(), + Height: block.Height(), + SupportRandom: block.SupportRandom(), + Seed: block.RandomSeed(), } return sBlock } diff --git a/nf/nvm/engine_v8_test.go b/nf/nvm/engine_v8_test.go index 9b4d56a7f..780c18f6e 100644 --- a/nf/nvm/engine_v8_test.go +++ b/nf/nvm/engine_v8_test.go @@ -76,6 +76,16 @@ func (block *testBlock) Height() uint64 { return 1 } +// RandomSeed mock +func (block *testBlock) RandomSeed() string { + return "59fc526072b09af8a8ca9732dae17132c4e9127e43cf2232" +} + +// SupportRandom mock +func (block *testBlock) SupportRandom() bool { + return true +} + // GetTransaction mock func (block *testBlock) GetTransaction(hash byteutils.Hash) (*core.Transaction, error) { return nil, nil @@ -132,7 +142,9 @@ func TestRunScriptSource(t *testing.T) { {"test/test_eval.js", core.ErrExecutionFailed, "EvalError: Code generation from strings disallowed for this context"}, {"test/test_date.js", nil, "\"\""}, {"test/test_bignumber_random.js", core.ErrExecutionFailed, "Error: BigNumber.random is not allowed in nvm."}, - {"test/test_random.js", core.ErrExecutionFailed, "Error: Math.random func is not allowed in nvm."}, + {"test/test_random_enable.js", nil, "\"\""}, + {"test/test_random_disable.js", core.ErrExecutionFailed, "Error: Math.random func is not allowed in nvm."}, + {"test/test_random_seed.js", core.ErrExecutionFailed, "Error: random seed must be a string"}, } for _, tt := range tests { diff --git a/nf/nvm/test/contract_date_and_random.js b/nf/nvm/test/contract_date_and_random.js index 50688924c..9528b9d61 100644 --- a/nf/nvm/test/contract_date_and_random.js +++ b/nf/nvm/test/contract_date_and_random.js @@ -43,8 +43,22 @@ Contract.prototype = { return data; }, - testRandom: function() { - // TODO + testRandom: function(userseed) { + var r1 = Math.random(); + var r12 = Math.random(); + var r13 = Math.random(); + // equivalent to reset seed + Math.random.seed(userseed); + var r2 = Math.random(); + + Event.Trigger("random", { + "supportRandom": Blockchain.block.supportRandom, + "seed": Blockchain.block.seed, + "defaultSeedRandom1": r1, + "defaultSeedRandom2": r12, + "defaultSeedRandom3": r13, + "userSeedRandom": r2 + }); } }; diff --git a/nf/nvm/test/test_random_disable.js b/nf/nvm/test/test_random_disable.js new file mode 100644 index 000000000..dd0cc17c4 --- /dev/null +++ b/nf/nvm/test/test_random_disable.js @@ -0,0 +1,23 @@ +// Copyright (C) 2018 go-nebulas +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + +Blockchain.block = { + supportRandom: false, + seed: "test seed" +} +console.log(Math.random()); \ No newline at end of file diff --git a/nf/nvm/test/test_random.js b/nf/nvm/test/test_random_enable.js similarity index 92% rename from nf/nvm/test/test_random.js rename to nf/nvm/test/test_random_enable.js index 75895f922..8dd0bec79 100644 --- a/nf/nvm/test/test_random.js +++ b/nf/nvm/test/test_random_enable.js @@ -16,4 +16,8 @@ // along with the go-nebulas library. If not, see . // +Blockchain.block = { + supportRandom: true, + seed: "seed" +} console.log(Math.random()); diff --git a/nf/nvm/test/test_random_seed.js b/nf/nvm/test/test_random_seed.js new file mode 100644 index 000000000..d4cd34be5 --- /dev/null +++ b/nf/nvm/test/test_random_seed.js @@ -0,0 +1,23 @@ +// Copyright (C) 2018 go-nebulas +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + +Blockchain.block = { + supportRandom: true, + seed: "null" +} +console.log(Math.random.seed()); \ No newline at end of file diff --git a/nf/nvm/types.go b/nf/nvm/types.go index 6de4944a2..d6a5349e0 100644 --- a/nf/nvm/types.go +++ b/nf/nvm/types.go @@ -56,6 +56,8 @@ type Block interface { Hash() byteutils.Hash Height() uint64 // ToAdd: timestamp interface Timestamp() int64 + RandomSeed() string + SupportRandom() bool } // Transaction interface breaks cycle import dependency and hides unused services. diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index bbf4573ff..a6e3a3676 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -17,10 +17,6 @@ // -Math.random = function () { - throw new Error("Math.random func is not allowed in nvm."); -}; - const require = (function (global) { var PathRegexForNotLibFile = /^\.{0,2}\//; var modules = new Map(); @@ -149,14 +145,4 @@ var Date = (function(Date) { return NebDate; })(Date); -// Blockchain.block = { -// // seed: 20000000 -// } - -// Math.random = require('random.js'); - -// var arr = []; -// for (var i = 0; i<10; ++i) { -// arr.push(Math.random()); -// } -// throw new Error(arr); \ No newline at end of file +Math.random = require('random.js'); \ No newline at end of file diff --git a/nf/nvm/v8/lib/random.js b/nf/nvm/v8/lib/random.js index e66bd7665..3bffdb7ee 100644 --- a/nf/nvm/v8/lib/random.js +++ b/nf/nvm/v8/lib/random.js @@ -97,26 +97,39 @@ function Mash() { module.exports = (function(){ - if (!Blockchain) { - throw new Error("'Blockchain' is not defined."); - } - if (!Blockchain.block) { - throw new Error("'Blockchain.block' is not defined."); - } + var arng = null; - if (!Blockchain.block.seed) { - throw new Error("random seed not found."); + function checkCtx() { + if (!Blockchain) { + throw new Error("'Blockchain' is undefined."); + } + if (!Blockchain.block) { + throw new Error("'Blockchain.block' is undefined."); + } + + if (!Blockchain.block.supportRandom) { + throw new Error("Math.random func is not allowed in nvm."); + } + + if (!Blockchain.block.seed) { + throw new Error("random seed is undefined."); + } } - var arng = new impl(Blockchain.block.seed); - return function() { - // Get a 32 bit (signed) integer. - // arng.int32() - - // Gets 56 bits of randomness. - // arng.double() - - // By default provides 32 bits of randomness in a float. + function rand() { + if (arng == null) { + checkCtx(); + arng = new impl(Blockchain.block.seed); + } return arng(); } + rand.seed = function(userseed) { + if (typeof(userseed) !== 'string') { + throw new Error("random seed must be a string") + } + checkCtx(); + arng = new impl(Blockchain.block.seed + userseed); + } + + return rand; })(); \ No newline at end of file diff --git a/rpc/admin_service.go b/rpc/admin_service.go index e97f13154..73c4f929a 100644 --- a/rpc/admin_service.go +++ b/rpc/admin_service.go @@ -136,6 +136,30 @@ func (s *AdminService) SignHash(ctx context.Context, req *rpcpb.SignHashRequest) return &rpcpb.SignHashResponse{Data: data}, nil } +// GenerateBlockRand generate block's rand info +func (s *AdminService) GenerateBlockRand(ctx context.Context, req *rpcpb.GenerateBlockRandRequest) (*rpcpb.GenerateBlockRandResponse, error) { + neb := s.server.Neblet() + hashes, err := neb.BlockChain().GetRecentNBlockHashBeforeInclusive(req.ParentHash, core.VRFInputParentHashNumber) + if err != nil { + return nil, err + } + + addr, err := core.AddressParse(req.Address) + if err != nil { + return nil, err + } + + vrfHash, vrfProof, err := neb.AccountManager().GenerateBlockRand(addr, hashes) + if err != nil { + return nil, err + } + + return &rpcpb.GenerateBlockRandResponse{ + VrfHash: vrfHash, + VrfProof: vrfProof, + }, nil +} + // SignTransactionWithPassphrase sign transaction with the from addr passphrase func (s *AdminService) SignTransactionWithPassphrase(ctx context.Context, req *rpcpb.SignTransactionPassphraseRequest) (*rpcpb.SignTransactionPassphraseResponse, error) { diff --git a/rpc/pb/rpc.pb.go b/rpc/pb/rpc.pb.go index 17dee1e88..8946c5c49 100644 --- a/rpc/pb/rpc.pb.go +++ b/rpc/pb/rpc.pb.go @@ -37,6 +37,8 @@ It has these top-level messages: LockAccountResponse SignHashRequest SignHashResponse + GenerateBlockRandRequest + GenerateBlockRandResponse SignTransactionPassphraseRequest SignTransactionPassphraseResponse SendTransactionPassphraseRequest @@ -849,7 +851,7 @@ type TransactionResponse struct { Status int32 `protobuf:"varint,13,opt,name=status,proto3" json:"status,omitempty"` // transaction gas used GasUsed string `protobuf:"bytes,14,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` - // contract excute + // contract execute error ExecuteError string `protobuf:"bytes,15,opt,name=execute_error,json=executeError,proto3" json:"execute_error,omitempty"` } @@ -1126,6 +1128,56 @@ func (m *SignHashResponse) GetData() []byte { return nil } +type GenerateBlockRandRequest struct { + // miner address + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // parent hash of new block + ParentHash []byte `protobuf:"bytes,2,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` +} + +func (m *GenerateBlockRandRequest) Reset() { *m = GenerateBlockRandRequest{} } +func (m *GenerateBlockRandRequest) String() string { return proto.CompactTextString(m) } +func (*GenerateBlockRandRequest) ProtoMessage() {} +func (*GenerateBlockRandRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } + +func (m *GenerateBlockRandRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *GenerateBlockRandRequest) GetParentHash() []byte { + if m != nil { + return m.ParentHash + } + return nil +} + +type GenerateBlockRandResponse struct { + VrfHash []byte `protobuf:"bytes,1,opt,name=vrf_hash,json=vrfHash,proto3" json:"vrf_hash,omitempty"` + VrfProof []byte `protobuf:"bytes,2,opt,name=vrf_proof,json=vrfProof,proto3" json:"vrf_proof,omitempty"` +} + +func (m *GenerateBlockRandResponse) Reset() { *m = GenerateBlockRandResponse{} } +func (m *GenerateBlockRandResponse) String() string { return proto.CompactTextString(m) } +func (*GenerateBlockRandResponse) ProtoMessage() {} +func (*GenerateBlockRandResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } + +func (m *GenerateBlockRandResponse) GetVrfHash() []byte { + if m != nil { + return m.VrfHash + } + return nil +} + +func (m *GenerateBlockRandResponse) GetVrfProof() []byte { + if m != nil { + return m.VrfProof + } + return nil +} + type SignTransactionPassphraseRequest struct { // transaction struct Transaction *TransactionRequest `protobuf:"bytes,1,opt,name=transaction" json:"transaction,omitempty"` @@ -1137,7 +1189,7 @@ func (m *SignTransactionPassphraseRequest) Reset() { *m = SignTransactio func (m *SignTransactionPassphraseRequest) String() string { return proto.CompactTextString(m) } func (*SignTransactionPassphraseRequest) ProtoMessage() {} func (*SignTransactionPassphraseRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{29} + return fileDescriptorRpc, []int{31} } func (m *SignTransactionPassphraseRequest) GetTransaction() *TransactionRequest { @@ -1162,7 +1214,7 @@ func (m *SignTransactionPassphraseResponse) Reset() { *m = SignTransacti func (m *SignTransactionPassphraseResponse) String() string { return proto.CompactTextString(m) } func (*SignTransactionPassphraseResponse) ProtoMessage() {} func (*SignTransactionPassphraseResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{30} + return fileDescriptorRpc, []int{32} } func (m *SignTransactionPassphraseResponse) GetData() []byte { @@ -1183,7 +1235,7 @@ func (m *SendTransactionPassphraseRequest) Reset() { *m = SendTransactio func (m *SendTransactionPassphraseRequest) String() string { return proto.CompactTextString(m) } func (*SendTransactionPassphraseRequest) ProtoMessage() {} func (*SendTransactionPassphraseRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{31} + return fileDescriptorRpc, []int{33} } func (m *SendTransactionPassphraseRequest) GetTransaction() *TransactionRequest { @@ -1207,7 +1259,7 @@ type GasPriceResponse struct { func (m *GasPriceResponse) Reset() { *m = GasPriceResponse{} } func (m *GasPriceResponse) String() string { return proto.CompactTextString(m) } func (*GasPriceResponse) ProtoMessage() {} -func (*GasPriceResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{32} } +func (*GasPriceResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} } func (m *GasPriceResponse) GetGasPrice() string { if m != nil { @@ -1225,7 +1277,7 @@ type HashRequest struct { func (m *HashRequest) Reset() { *m = HashRequest{} } func (m *HashRequest) String() string { return proto.CompactTextString(m) } func (*HashRequest) ProtoMessage() {} -func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{33} } +func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} } func (m *HashRequest) GetHash() string { if m != nil { @@ -1242,7 +1294,7 @@ type GasResponse struct { func (m *GasResponse) Reset() { *m = GasResponse{} } func (m *GasResponse) String() string { return proto.CompactTextString(m) } func (*GasResponse) ProtoMessage() {} -func (*GasResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} } +func (*GasResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} } func (m *GasResponse) GetGas() string { if m != nil { @@ -1265,7 +1317,7 @@ type EventsResponse struct { func (m *EventsResponse) Reset() { *m = EventsResponse{} } func (m *EventsResponse) String() string { return proto.CompactTextString(m) } func (*EventsResponse) ProtoMessage() {} -func (*EventsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} } +func (*EventsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} } func (m *EventsResponse) GetEvents() []*Event { if m != nil { @@ -1282,7 +1334,7 @@ type Event struct { func (m *Event) Reset() { *m = Event{} } func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} -func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} } +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} } func (m *Event) GetTopic() string { if m != nil { @@ -1305,7 +1357,7 @@ type PprofRequest struct { func (m *PprofRequest) Reset() { *m = PprofRequest{} } func (m *PprofRequest) String() string { return proto.CompactTextString(m) } func (*PprofRequest) ProtoMessage() {} -func (*PprofRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} } +func (*PprofRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} } func (m *PprofRequest) GetListen() string { if m != nil { @@ -1321,7 +1373,7 @@ type PprofResponse struct { func (m *PprofResponse) Reset() { *m = PprofResponse{} } func (m *PprofResponse) String() string { return proto.CompactTextString(m) } func (*PprofResponse) ProtoMessage() {} -func (*PprofResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} } +func (*PprofResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{40} } func (m *PprofResponse) GetResult() bool { if m != nil { @@ -1338,7 +1390,7 @@ type GetConfigResponse struct { func (m *GetConfigResponse) Reset() { *m = GetConfigResponse{} } func (m *GetConfigResponse) String() string { return proto.CompactTextString(m) } func (*GetConfigResponse) ProtoMessage() {} -func (*GetConfigResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} } +func (*GetConfigResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{41} } func (m *GetConfigResponse) GetConfig() *nebletpb.Config { if m != nil { @@ -1377,6 +1429,8 @@ func init() { proto.RegisterType((*LockAccountResponse)(nil), "rpcpb.LockAccountResponse") proto.RegisterType((*SignHashRequest)(nil), "rpcpb.SignHashRequest") proto.RegisterType((*SignHashResponse)(nil), "rpcpb.SignHashResponse") + proto.RegisterType((*GenerateBlockRandRequest)(nil), "rpcpb.GenerateBlockRandRequest") + proto.RegisterType((*GenerateBlockRandResponse)(nil), "rpcpb.GenerateBlockRandResponse") proto.RegisterType((*SignTransactionPassphraseRequest)(nil), "rpcpb.SignTransactionPassphraseRequest") proto.RegisterType((*SignTransactionPassphraseResponse)(nil), "rpcpb.SignTransactionPassphraseResponse") proto.RegisterType((*SendTransactionPassphraseRequest)(nil), "rpcpb.SendTransactionPassphraseRequest") @@ -1923,6 +1977,7 @@ type AdminServiceClient interface { SendTransaction(ctx context.Context, in *TransactionRequest, opts ...grpc.CallOption) (*SendTransactionResponse, error) // Sign sign msg SignHash(ctx context.Context, in *SignHashRequest, opts ...grpc.CallOption) (*SignHashResponse, error) + GenerateBlockRand(ctx context.Context, in *GenerateBlockRandRequest, opts ...grpc.CallOption) (*GenerateBlockRandResponse, error) // Sign sign transaction SignTransactionWithPassphrase(ctx context.Context, in *SignTransactionPassphraseRequest, opts ...grpc.CallOption) (*SignTransactionPassphraseResponse, error) // SendTransactionWithPassphrase send transaction with passphrase @@ -1996,6 +2051,15 @@ func (c *adminServiceClient) SignHash(ctx context.Context, in *SignHashRequest, return out, nil } +func (c *adminServiceClient) GenerateBlockRand(ctx context.Context, in *GenerateBlockRandRequest, opts ...grpc.CallOption) (*GenerateBlockRandResponse, error) { + out := new(GenerateBlockRandResponse) + err := grpc.Invoke(ctx, "/rpcpb.AdminService/GenerateBlockRand", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *adminServiceClient) SignTransactionWithPassphrase(ctx context.Context, in *SignTransactionPassphraseRequest, opts ...grpc.CallOption) (*SignTransactionPassphraseResponse, error) { out := new(SignTransactionPassphraseResponse) err := grpc.Invoke(ctx, "/rpcpb.AdminService/SignTransactionWithPassphrase", in, out, c.cc, opts...) @@ -2056,6 +2120,7 @@ type AdminServiceServer interface { SendTransaction(context.Context, *TransactionRequest) (*SendTransactionResponse, error) // Sign sign msg SignHash(context.Context, *SignHashRequest) (*SignHashResponse, error) + GenerateBlockRand(context.Context, *GenerateBlockRandRequest) (*GenerateBlockRandResponse, error) // Sign sign transaction SignTransactionWithPassphrase(context.Context, *SignTransactionPassphraseRequest) (*SignTransactionPassphraseResponse, error) // SendTransactionWithPassphrase send transaction with passphrase @@ -2179,6 +2244,24 @@ func _AdminService_SignHash_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _AdminService_GenerateBlockRand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateBlockRandRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServiceServer).GenerateBlockRand(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpcpb.AdminService/GenerateBlockRand", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServiceServer).GenerateBlockRand(ctx, req.(*GenerateBlockRandRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AdminService_SignTransactionWithPassphrase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SignTransactionPassphraseRequest) if err := dec(in); err != nil { @@ -2297,6 +2380,10 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ MethodName: "SignHash", Handler: _AdminService_SignHash_Handler, }, + { + MethodName: "GenerateBlockRand", + Handler: _AdminService_GenerateBlockRand_Handler, + }, { MethodName: "SignTransactionWithPassphrase", Handler: _AdminService_SignTransactionWithPassphrase_Handler, @@ -2325,143 +2412,148 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2205 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x6f, 0x1b, 0xb9, - 0x15, 0x87, 0x24, 0x7f, 0x48, 0x4f, 0xb2, 0xad, 0xd0, 0x5f, 0x63, 0xc5, 0x76, 0x1c, 0x66, 0xb1, - 0xeb, 0x0d, 0xba, 0xd6, 0xc6, 0x0b, 0xa4, 0x45, 0x8a, 0x2d, 0x90, 0xa4, 0x59, 0x6f, 0x8a, 0x20, - 0x48, 0xc7, 0xd9, 0x76, 0x81, 0x36, 0x15, 0xa8, 0x11, 0x2d, 0xb1, 0x3b, 0x9e, 0x99, 0x0e, 0xa9, - 0x24, 0xf6, 0xa5, 0xc0, 0xde, 0x7b, 0x2a, 0x50, 0xf4, 0xd0, 0xff, 0xa0, 0x7f, 0x4d, 0xd1, 0x43, - 0x2f, 0x3d, 0xf6, 0xd4, 0xbf, 0xa2, 0xe0, 0x1b, 0x72, 0xbe, 0x34, 0xb2, 0x9a, 0x1e, 0x7a, 0xe3, - 0x7b, 0x24, 0xdf, 0x7b, 0x7c, 0x5f, 0xfc, 0x71, 0x06, 0x5a, 0x71, 0xe4, 0x9d, 0x44, 0x71, 0xa8, - 0x42, 0xb2, 0x1c, 0x47, 0x5e, 0x34, 0xec, 0xed, 0x8f, 0xc3, 0x70, 0xec, 0xf3, 0x3e, 0x8b, 0x44, - 0x9f, 0x05, 0x41, 0xa8, 0x98, 0x12, 0x61, 0x20, 0x93, 0x45, 0xbd, 0x1f, 0x8d, 0x85, 0x9a, 0x4c, - 0x87, 0x27, 0x5e, 0x78, 0xd9, 0x0f, 0xf8, 0x70, 0xea, 0x33, 0x29, 0xc2, 0xfe, 0x38, 0xfc, 0xcc, - 0x10, 0x7d, 0x2f, 0x0c, 0x24, 0x0f, 0xe4, 0x54, 0xf6, 0xa3, 0x61, 0x5f, 0x2a, 0xa6, 0xb8, 0xd9, - 0xf9, 0x70, 0xd1, 0xce, 0x80, 0x0f, 0x7d, 0xae, 0xf4, 0x36, 0x2f, 0x0c, 0x2e, 0xc4, 0x38, 0xd9, - 0x47, 0xef, 0x43, 0xf7, 0x7c, 0x3a, 0x94, 0x5e, 0x2c, 0x86, 0xdc, 0xe5, 0xbf, 0x9b, 0x72, 0xa9, - 0xc8, 0x0e, 0xac, 0xa8, 0x30, 0x12, 0x9e, 0x74, 0x6a, 0x47, 0x8d, 0xe3, 0x96, 0x6b, 0x28, 0xfa, - 0x25, 0xdc, 0xca, 0xad, 0x95, 0x91, 0xb6, 0x85, 0x6c, 0xc1, 0x32, 0x4e, 0x3b, 0xb5, 0xa3, 0xda, - 0x71, 0xcb, 0x4d, 0x08, 0x42, 0x60, 0x69, 0xc4, 0x14, 0x73, 0xea, 0xc8, 0xc4, 0x31, 0x25, 0xd0, - 0x7d, 0x19, 0x06, 0xaf, 0x58, 0xcc, 0x2e, 0xa5, 0x51, 0x45, 0xff, 0x52, 0xd7, 0xcc, 0x11, 0x7f, - 0x1e, 0x5c, 0x84, 0xa9, 0xc8, 0x75, 0xa8, 0x8b, 0x91, 0x91, 0x57, 0x17, 0x23, 0xb2, 0x07, 0x4d, - 0x6f, 0xc2, 0x44, 0x30, 0x10, 0x23, 0x14, 0xb8, 0xe6, 0xae, 0x22, 0xfd, 0x7c, 0x44, 0x7a, 0xd0, - 0xf4, 0x42, 0x11, 0x0c, 0x99, 0xe4, 0x4e, 0x03, 0x37, 0xa4, 0x34, 0x39, 0x00, 0x88, 0x38, 0x8f, - 0x07, 0x5e, 0x38, 0x0d, 0x94, 0xb3, 0x84, 0x1b, 0x5b, 0x9a, 0xf3, 0x54, 0x33, 0x08, 0x85, 0x8e, - 0xbc, 0x0a, 0xbc, 0x49, 0x1c, 0x06, 0xe2, 0x9a, 0x8f, 0x9c, 0xe5, 0xa3, 0xda, 0x71, 0xd3, 0x2d, - 0xf0, 0xc8, 0x1d, 0x68, 0x0f, 0xa7, 0xde, 0x77, 0x5c, 0x0d, 0xa4, 0xb8, 0xe6, 0xce, 0xca, 0x51, - 0xed, 0x78, 0xd9, 0x85, 0x84, 0x75, 0x2e, 0xae, 0x39, 0xf9, 0x14, 0xba, 0xe8, 0x47, 0x2f, 0xf4, - 0x07, 0x6f, 0x79, 0x2c, 0x45, 0x18, 0x38, 0x80, 0x76, 0x6c, 0x58, 0xfe, 0x2f, 0x12, 0x36, 0x39, - 0x85, 0x76, 0x1c, 0x4e, 0x15, 0x1f, 0x28, 0x36, 0xf4, 0xb9, 0xd3, 0x3e, 0x6a, 0x1c, 0xb7, 0x4f, - 0x6f, 0x9d, 0x60, 0x5a, 0x9c, 0xb8, 0x7a, 0xe6, 0xb5, 0x9e, 0x70, 0x21, 0x4e, 0xc7, 0xf4, 0x21, - 0x40, 0x36, 0x33, 0xe3, 0x17, 0x07, 0x56, 0xd9, 0x68, 0x14, 0x73, 0x29, 0x9d, 0x3a, 0x06, 0xca, - 0x92, 0xf4, 0x1f, 0x35, 0xd8, 0x3c, 0xe3, 0xea, 0x25, 0x1f, 0x9e, 0xeb, 0x1c, 0x49, 0x3d, 0x9b, - 0xf7, 0x64, 0xad, 0xe8, 0x49, 0x02, 0x4b, 0x8a, 0x09, 0xdf, 0x46, 0x4c, 0x8f, 0x49, 0x17, 0x1a, - 0xbe, 0x18, 0x1a, 0xc7, 0xea, 0xa1, 0x4e, 0x8d, 0x09, 0x17, 0xe3, 0x49, 0xe2, 0xcf, 0x25, 0xd7, - 0x50, 0x95, 0x7e, 0x58, 0xa9, 0xf6, 0x43, 0xd9, 0xef, 0xab, 0x15, 0x7e, 0x77, 0x60, 0xd5, 0x4a, - 0x69, 0xa2, 0x14, 0x4b, 0xd2, 0xcf, 0xa1, 0xfb, 0xd8, 0xc3, 0x88, 0xca, 0xf4, 0x54, 0xfb, 0xd0, - 0x32, 0x07, 0xe7, 0x36, 0x65, 0x33, 0x06, 0xfd, 0x19, 0xec, 0x9c, 0x71, 0x65, 0x36, 0x19, 0x77, - 0x24, 0x79, 0x9e, 0xf3, 0x5f, 0xe2, 0x54, 0x4b, 0xe6, 0x8e, 0x59, 0xcf, 0x1f, 0x93, 0xbe, 0x81, - 0xdd, 0x19, 0x59, 0xc6, 0x08, 0x07, 0x56, 0x87, 0xcc, 0x67, 0x81, 0xc7, 0xad, 0x30, 0x43, 0xea, - 0x0a, 0x09, 0x42, 0xcd, 0x4f, 0x64, 0x25, 0x04, 0xfa, 0xfb, 0x2a, 0x4a, 0xb2, 0x76, 0xcd, 0xc5, - 0x31, 0xfd, 0x2d, 0x74, 0x9e, 0x32, 0xdf, 0x4f, 0x65, 0xee, 0xc0, 0x4a, 0xcc, 0xe5, 0xd4, 0x57, - 0x46, 0xa4, 0xa1, 0x74, 0x5a, 0xf2, 0xf7, 0xdc, 0xd3, 0xc9, 0xc4, 0xe3, 0xd8, 0x84, 0x0c, 0x0c, - 0xeb, 0x59, 0x1c, 0x93, 0xbb, 0xd0, 0xe1, 0x52, 0x89, 0x4b, 0xa6, 0xf8, 0x60, 0xcc, 0xa4, 0x89, - 0x60, 0xdb, 0xf2, 0xce, 0x98, 0xa4, 0x27, 0xb0, 0xf5, 0xe4, 0xea, 0x89, 0x1f, 0x7a, 0xdf, 0x7d, - 0x8d, 0x67, 0xcb, 0x15, 0xbf, 0x39, 0x7a, 0xad, 0x70, 0xf4, 0x1f, 0x00, 0x39, 0xe3, 0xea, 0xa7, - 0x57, 0x01, 0x93, 0xea, 0x2a, 0x6f, 0xe1, 0xa5, 0x08, 0x78, 0x9c, 0xb6, 0x8a, 0x84, 0xa2, 0xff, - 0xae, 0x01, 0x79, 0x1d, 0xb3, 0x40, 0x32, 0x4f, 0xf7, 0x37, 0x2b, 0x9c, 0xc0, 0xd2, 0x45, 0x1c, - 0x5e, 0x9a, 0xe3, 0xe0, 0x58, 0x67, 0xb5, 0x0a, 0xcd, 0x19, 0xea, 0x2a, 0xd4, 0xee, 0x7a, 0xcb, - 0xfc, 0xa9, 0xad, 0xe7, 0x84, 0xc8, 0x9c, 0xb8, 0x94, 0x77, 0xe2, 0x6d, 0x68, 0x8d, 0x99, 0x1c, - 0x44, 0xb1, 0xf0, 0x38, 0x16, 0x70, 0xcb, 0x6d, 0x8e, 0x99, 0x7c, 0xa5, 0x69, 0x3b, 0xe9, 0x8b, - 0x4b, 0xa1, 0x4c, 0x32, 0xea, 0xc9, 0x17, 0x9a, 0x26, 0xa7, 0xba, 0x71, 0x04, 0x2a, 0x66, 0x9e, - 0xc2, 0x0c, 0x6c, 0x9f, 0xee, 0x98, 0x52, 0x7c, 0x6a, 0xd8, 0xc6, 0x66, 0x37, 0x5d, 0xa7, 0x0f, - 0x3b, 0x14, 0x01, 0x8b, 0xaf, 0xb0, 0xc4, 0x3b, 0xae, 0xa1, 0xe8, 0x35, 0x6c, 0x94, 0x36, 0xe9, - 0xa5, 0x32, 0x9c, 0xc6, 0x69, 0x32, 0x18, 0x4a, 0x47, 0x2e, 0x19, 0x0d, 0x30, 0xf8, 0x26, 0x72, - 0x09, 0xeb, 0xf5, 0x55, 0xc4, 0x75, 0x43, 0xbb, 0x98, 0x06, 0xe8, 0x34, 0xdb, 0xd0, 0x2c, 0xad, - 0xbd, 0xc7, 0xe2, 0xb1, 0x44, 0x17, 0xb4, 0x5c, 0x1c, 0xd3, 0x3e, 0xec, 0x9d, 0xf3, 0x60, 0xe4, - 0xb2, 0x77, 0xd5, 0xee, 0xc6, 0x2e, 0x5c, 0x43, 0x73, 0x93, 0x2e, 0xfc, 0x6b, 0xd8, 0xd5, 0x1b, - 0x0a, 0xab, 0xb3, 0x60, 0xaa, 0xf7, 0x13, 0x26, 0x27, 0xd6, 0xe8, 0x84, 0xd2, 0xc5, 0x6d, 0x7d, - 0x30, 0xc8, 0x1a, 0x0e, 0x16, 0xb7, 0xe5, 0x3f, 0x36, 0x8d, 0x67, 0x00, 0xdb, 0x67, 0x5c, 0x61, - 0x5a, 0x3d, 0xb9, 0xfa, 0x9a, 0xc9, 0x49, 0xce, 0x94, 0x9c, 0x64, 0x1c, 0x93, 0x53, 0xd8, 0xbe, - 0x98, 0xfa, 0xfe, 0xe0, 0x42, 0xf8, 0xfe, 0x40, 0x65, 0x06, 0xa1, 0xf0, 0xa6, 0xbb, 0xa9, 0x27, - 0xbf, 0x12, 0xbe, 0x9f, 0xb3, 0x95, 0x72, 0xac, 0x40, 0xab, 0xe0, 0xbf, 0xc9, 0xdc, 0xff, 0x49, - 0xcd, 0x03, 0xb8, 0x7d, 0xc6, 0x55, 0x8e, 0xb3, 0xf0, 0x34, 0xf4, 0x9f, 0x0d, 0x58, 0x43, 0xbb, - 0x52, 0x7f, 0x56, 0x9d, 0xf9, 0x0e, 0xb4, 0x23, 0x16, 0xf3, 0x40, 0x0d, 0x70, 0xca, 0x24, 0x40, - 0xc2, 0xd2, 0x1a, 0x72, 0xa7, 0x68, 0x14, 0x4e, 0x51, 0x5d, 0x00, 0xf9, 0xfb, 0x6f, 0xb9, 0x74, - 0xff, 0xed, 0x43, 0x4b, 0x89, 0x4b, 0x2e, 0x15, 0xbb, 0x8c, 0x30, 0xff, 0x1b, 0x6e, 0xc6, 0x28, - 0x5c, 0x05, 0xab, 0xc5, 0xab, 0xe0, 0x00, 0x00, 0xa1, 0xc5, 0x20, 0x0e, 0x43, 0x65, 0x1a, 0x70, - 0x0b, 0x39, 0x6e, 0x18, 0x2a, 0xbd, 0x53, 0xbd, 0x97, 0xc9, 0x64, 0x2b, 0x69, 0x75, 0xea, 0xbd, - 0xc4, 0x29, 0xdd, 0x98, 0xde, 0xf2, 0x40, 0x99, 0x59, 0x30, 0x8d, 0x09, 0x59, 0xb8, 0xe0, 0x31, - 0xac, 0xa7, 0x10, 0x26, 0x59, 0xd3, 0xc6, 0xe2, 0xeb, 0x9d, 0xa4, 0xec, 0xa4, 0x04, 0x93, 0xb1, - 0xde, 0xe3, 0xae, 0x79, 0x79, 0x52, 0x3b, 0x02, 0x9b, 0x8c, 0xd3, 0x49, 0xfa, 0x03, 0x12, 0x5a, - 0xb3, 0x90, 0x83, 0x0b, 0x11, 0x30, 0x5f, 0xa8, 0x2b, 0x67, 0x0d, 0x43, 0x0b, 0x42, 0x7e, 0x65, - 0x38, 0xe4, 0x27, 0xd0, 0xc9, 0xc5, 0x5e, 0x3a, 0x23, 0xbc, 0x7f, 0x7b, 0xa6, 0xe8, 0x2b, 0xca, - 0xc1, 0x2d, 0xac, 0xa7, 0x7f, 0x6a, 0xc0, 0x66, 0x55, 0xd1, 0x54, 0x05, 0xd9, 0x01, 0xeb, 0xcb, - 0x32, 0x5e, 0xb1, 0x0d, 0xb0, 0x31, 0xd3, 0x00, 0x97, 0x66, 0x1b, 0xe0, 0x72, 0x65, 0x03, 0x5c, - 0xc9, 0xc7, 0xbf, 0x10, 0xe3, 0xd5, 0x72, 0x8c, 0xed, 0x1d, 0xd3, 0x34, 0x77, 0xba, 0x6e, 0x30, - 0xb6, 0x27, 0xb4, 0xb2, 0x9e, 0x50, 0x6c, 0xa3, 0x70, 0x53, 0x1b, 0x6d, 0x97, 0xda, 0x68, 0x55, - 0x6b, 0xe8, 0x54, 0xb6, 0x06, 0x6c, 0x89, 0x8a, 0xa9, 0xa9, 0xc4, 0xe0, 0x2c, 0xbb, 0x86, 0xd2, - 0xe9, 0xa4, 0xe5, 0x4f, 0x25, 0x1f, 0x39, 0xeb, 0x49, 0x3a, 0x8d, 0x99, 0xfc, 0x46, 0xf2, 0x11, - 0xb9, 0x07, 0x6b, 0xb9, 0x7b, 0x2e, 0x8c, 0x9d, 0x0d, 0x9c, 0xef, 0x64, 0x37, 0x5d, 0x18, 0xd3, - 0x2f, 0xe0, 0xd6, 0x4b, 0xfe, 0xce, 0xdc, 0xc9, 0xb6, 0x40, 0x0f, 0x01, 0x22, 0x26, 0x65, 0x34, - 0x89, 0x75, 0x65, 0xd4, 0x6c, 0x95, 0x59, 0x0e, 0x3d, 0x01, 0x92, 0xdf, 0x94, 0xdd, 0xe1, 0xd5, - 0x80, 0x80, 0xfa, 0xb0, 0xf5, 0x4d, 0xa0, 0x8b, 0xbb, 0xa4, 0x67, 0x3e, 0x84, 0x28, 0x5a, 0x50, - 0x2f, 0x5b, 0xa0, 0x2b, 0x77, 0x34, 0x8d, 0x59, 0xda, 0xe8, 0x97, 0xdc, 0x94, 0xa6, 0x7d, 0xd8, - 0x2e, 0x69, 0xab, 0x04, 0x04, 0x4d, 0x0b, 0x08, 0xf4, 0x71, 0x5e, 0x7c, 0x80, 0x71, 0xf4, 0x33, - 0xd8, 0x7c, 0xf1, 0x01, 0xe2, 0x7f, 0x0e, 0x1b, 0xe7, 0x62, 0x1c, 0xe4, 0x3b, 0xe0, 0xfc, 0x83, - 0xdb, 0x82, 0xa8, 0x27, 0x09, 0x86, 0x05, 0xd1, 0x85, 0x06, 0xf3, 0xc7, 0x06, 0xeb, 0xe8, 0x21, - 0xfd, 0x18, 0xba, 0x99, 0xc8, 0xac, 0x94, 0x66, 0xae, 0xab, 0xdf, 0xc3, 0x91, 0x5e, 0x97, 0xab, - 0xbc, 0x57, 0xa9, 0x0f, 0xad, 0x2d, 0x3f, 0x86, 0x76, 0xbe, 0xad, 0xd7, 0xb0, 0xa3, 0xec, 0x55, - 0x55, 0x76, 0x72, 0xa3, 0xe7, 0x57, 0x2f, 0x8a, 0x13, 0xfd, 0x21, 0xdc, 0xbd, 0xc1, 0x80, 0x05, - 0x96, 0x17, 0x2f, 0xda, 0xff, 0xb3, 0xe5, 0x7d, 0xe8, 0x9e, 0x99, 0x22, 0x4e, 0x0d, 0x2d, 0x54, - 0x7a, 0xad, 0x58, 0xe9, 0xf4, 0x2e, 0xb4, 0x17, 0x5d, 0x72, 0x0f, 0xa0, 0x7d, 0xc6, 0x32, 0xe4, - 0xdd, 0x85, 0x86, 0x86, 0x97, 0xc9, 0x0a, 0x3d, 0xd4, 0x9c, 0x0c, 0x92, 0xea, 0x21, 0x7d, 0x08, - 0xeb, 0xcf, 0x92, 0x0b, 0xc0, 0xee, 0xfa, 0x08, 0x56, 0x92, 0x2b, 0x01, 0x41, 0x63, 0xfb, 0xb4, - 0x63, 0x0e, 0x8c, 0xcb, 0x5c, 0x33, 0x47, 0x1f, 0xc0, 0x32, 0x32, 0x3e, 0xe0, 0x85, 0xf9, 0x31, - 0x74, 0x5e, 0x45, 0x71, 0x78, 0x91, 0x43, 0x04, 0xbe, 0x90, 0x8a, 0x07, 0x16, 0xd0, 0x24, 0x14, - 0xfd, 0x04, 0xd6, 0xcc, 0xba, 0x05, 0x89, 0xff, 0x25, 0xdc, 0x3a, 0xe3, 0xea, 0x29, 0x3e, 0x98, - 0xd3, 0xc5, 0xc7, 0xb0, 0x92, 0x3c, 0xa1, 0x4d, 0xbc, 0xba, 0x27, 0xc9, 0xdb, 0x3a, 0xb9, 0xb8, - 0xf4, 0x4a, 0x33, 0x7f, 0xfa, 0x37, 0x00, 0x78, 0x1c, 0x89, 0x73, 0x1e, 0xbf, 0xd5, 0x9d, 0xf4, - 0x0d, 0xb4, 0x73, 0x8f, 0x32, 0xb2, 0x6b, 0x8e, 0x5d, 0x7e, 0x14, 0xf7, 0xec, 0xa5, 0x54, 0xf1, - 0x82, 0xa3, 0x7b, 0xdf, 0xff, 0xfd, 0x5f, 0x7f, 0xac, 0x6f, 0x92, 0x5b, 0xfd, 0xb7, 0x0f, 0xfa, - 0x53, 0xc9, 0x63, 0xfd, 0xb0, 0xc7, 0xbb, 0x99, 0xfc, 0x06, 0x76, 0x5f, 0x30, 0xc5, 0xa5, 0x7a, - 0x1e, 0xc7, 0x1c, 0xdf, 0x4b, 0x43, 0x9f, 0x23, 0x22, 0x99, 0xaf, 0x6a, 0xcb, 0x4c, 0x14, 0x80, - 0x0b, 0xdd, 0x42, 0x25, 0xeb, 0xa4, 0x93, 0x2a, 0xd1, 0x6f, 0xbf, 0x18, 0x36, 0x4a, 0x8f, 0x1f, - 0x72, 0x90, 0x59, 0x5a, 0xf1, 0xc0, 0xea, 0x1d, 0xce, 0x9b, 0x36, 0x7a, 0x8e, 0x50, 0x4f, 0x8f, - 0x6e, 0xa7, 0x7a, 0x98, 0x79, 0xdb, 0xe9, 0x65, 0x8f, 0x6a, 0xf7, 0xc9, 0x2b, 0x58, 0xd2, 0x2f, - 0x22, 0x32, 0xbf, 0x26, 0x7a, 0x9b, 0x16, 0xb7, 0xe7, 0x5e, 0x4e, 0xd4, 0x41, 0xc9, 0x84, 0xae, - 0xa5, 0x92, 0x3d, 0xe6, 0xfb, 0x5a, 0xe2, 0x35, 0x90, 0x59, 0xc0, 0x4c, 0x8e, 0x8c, 0x90, 0xb9, - 0x58, 0x3a, 0x3d, 0xcb, 0x1c, 0xf0, 0x4c, 0x29, 0x6a, 0xdc, 0xa7, 0xbb, 0xa9, 0xc6, 0x98, 0xbd, - 0xcb, 0x95, 0xab, 0xd6, 0x3d, 0x81, 0xf5, 0x22, 0x3a, 0x26, 0xfb, 0x99, 0x87, 0x66, 0x41, 0xf3, - 0x9c, 0xe8, 0xcc, 0x6a, 0x1a, 0x17, 0x76, 0x6b, 0x4d, 0x01, 0x74, 0xcb, 0x30, 0x99, 0x1c, 0xce, - 0xea, 0xca, 0xe3, 0xe7, 0x39, 0xda, 0x3e, 0x42, 0x6d, 0x87, 0x74, 0xaf, 0x4a, 0x1b, 0xee, 0xd7, - 0xfa, 0xbe, 0xaf, 0x21, 0xf0, 0x2f, 0x38, 0xc6, 0xe3, 0x22, 0x52, 0x84, 0x66, 0x5a, 0xe7, 0xc1, - 0xe9, 0xde, 0x0d, 0x28, 0x8c, 0x7e, 0x8a, 0xfa, 0xef, 0xd1, 0xc3, 0xbc, 0xfe, 0x59, 0x3d, 0xda, - 0x88, 0x01, 0xb4, 0xd2, 0xef, 0x53, 0x69, 0xca, 0x97, 0xbf, 0x6e, 0xf5, 0x9c, 0xd9, 0x09, 0xa3, - 0xea, 0x00, 0x55, 0xed, 0x52, 0x92, 0xaa, 0x92, 0x76, 0xcd, 0xa3, 0xda, 0xfd, 0xcf, 0x6b, 0xa6, - 0x80, 0x6d, 0x53, 0x9d, 0x5f, 0x55, 0x76, 0xa2, 0xdc, 0x7e, 0xe9, 0x3e, 0x6a, 0xd8, 0x21, 0x5b, - 0xf9, 0xc3, 0xa4, 0xf2, 0xde, 0x40, 0xfb, 0x59, 0xf6, 0x42, 0xbf, 0x29, 0xe7, 0x49, 0xa6, 0x20, - 0x95, 0x7d, 0x07, 0x65, 0xef, 0xd1, 0x4c, 0x76, 0xee, 0xb9, 0xaf, 0xdd, 0xc3, 0xb0, 0x7e, 0x93, - 0x5e, 0x6c, 0xd2, 0xcf, 0xca, 0xc9, 0x07, 0x63, 0x3b, 0xdf, 0x8d, 0x33, 0xf1, 0xf7, 0x50, 0xfc, - 0x01, 0x75, 0xf2, 0xa6, 0xe7, 0x85, 0x25, 0x2a, 0x20, 0xfb, 0x48, 0x40, 0x6e, 0xdb, 0x84, 0xaa, - 0xf8, 0xce, 0xd0, 0xdb, 0xcb, 0xf2, 0xa2, 0xf4, 0x51, 0x81, 0xde, 0x46, 0x55, 0xdb, 0xb4, 0x9b, - 0xaa, 0x1a, 0x25, 0x2b, 0x1e, 0xd5, 0xee, 0x9f, 0xfe, 0xb5, 0x05, 0x9d, 0xc7, 0xa3, 0x4b, 0x11, - 0xd8, 0xae, 0xfa, 0x2d, 0x34, 0xed, 0x17, 0xa1, 0xc5, 0x11, 0x29, 0x7f, 0x3b, 0xa2, 0x3d, 0xd4, - 0xb5, 0x45, 0x30, 0xe6, 0x4c, 0xcb, 0x4d, 0x7b, 0x10, 0xf1, 0x00, 0x32, 0x90, 0x48, 0x6c, 0xde, - 0xcc, 0x80, 0xcd, 0xf4, 0x28, 0xb3, 0x88, 0xb2, 0xd8, 0xe1, 0x0a, 0xe2, 0xfb, 0x01, 0x7f, 0xa7, - 0x5d, 0x16, 0xc2, 0x5a, 0x01, 0xeb, 0xa5, 0x5e, 0xab, 0xc2, 0x9b, 0xbd, 0xfd, 0xea, 0xc9, 0xaa, - 0x18, 0x15, 0xb5, 0x4d, 0x71, 0x83, 0x56, 0x38, 0x86, 0x76, 0x0e, 0xfb, 0xa5, 0x59, 0x36, 0x8b, - 0x1f, 0xd3, 0xb2, 0xac, 0x80, 0x8a, 0xf4, 0x2e, 0xaa, 0xba, 0x4d, 0x77, 0x66, 0x55, 0x59, 0x45, - 0x01, 0x6c, 0x94, 0x9a, 0xe5, 0x4d, 0x29, 0xbd, 0xa8, 0xbf, 0x56, 0x78, 0xb2, 0xd4, 0x5d, 0x7f, - 0x05, 0x4d, 0x0b, 0x29, 0x89, 0xfd, 0x98, 0x53, 0x82, 0xad, 0x69, 0x1e, 0x94, 0xb1, 0x27, 0x3d, - 0x44, 0xf1, 0x0e, 0xdd, 0xcc, 0xc4, 0x4b, 0x31, 0x0e, 0xfa, 0x13, 0x93, 0xd9, 0x7f, 0xa8, 0xc1, - 0x41, 0x09, 0x07, 0xfe, 0x52, 0xa8, 0x49, 0x06, 0xe9, 0xc8, 0x27, 0x39, 0xd1, 0x37, 0x81, 0xbe, - 0xde, 0xf1, 0xe2, 0x85, 0xc5, 0xcb, 0x9e, 0xae, 0x17, 0x8d, 0xd2, 0xf6, 0xfc, 0x59, 0xdb, 0x53, - 0x74, 0xd5, 0x3c, 0x7b, 0x16, 0x80, 0xd0, 0x85, 0x9e, 0x3f, 0x41, 0x2b, 0x8e, 0xe9, 0xbd, 0x4a, - 0xcf, 0x17, 0xb5, 0x6a, 0xd3, 0xce, 0x01, 0xce, 0x15, 0x8b, 0x15, 0x42, 0x2c, 0x62, 0xaf, 0xe7, - 0x3c, 0x30, 0x4b, 0xaf, 0x9a, 0x02, 0x0a, 0xb3, 0xb5, 0x48, 0x37, 0x32, 0x45, 0x91, 0x5e, 0x90, - 0x04, 0xb7, 0x95, 0x22, 0xb1, 0xf9, 0x65, 0xee, 0x64, 0x4d, 0xa5, 0x08, 0xda, 0x6c, 0x4f, 0x21, - 0xb9, 0xf8, 0x8e, 0x53, 0x79, 0xdf, 0x42, 0xd3, 0xfe, 0x84, 0x58, 0xdc, 0x42, 0xca, 0xbf, 0x2b, - 0xaa, 0x5a, 0x48, 0x10, 0x8e, 0xb8, 0x08, 0x2e, 0xc2, 0xe1, 0x0a, 0x7e, 0xfd, 0xfe, 0xe2, 0x3f, - 0x01, 0x00, 0x00, 0xff, 0xff, 0x3a, 0x99, 0x19, 0x87, 0x09, 0x1a, 0x00, 0x00, + // 2288 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcb, 0x6f, 0x1b, 0xb9, + 0x19, 0x87, 0x24, 0x3f, 0xa4, 0x4f, 0xb2, 0xad, 0xd0, 0xaf, 0xb1, 0xfc, 0x88, 0xc3, 0x2c, 0x76, + 0xbd, 0x41, 0xd7, 0xda, 0x78, 0x81, 0x6d, 0x91, 0x62, 0x0b, 0x38, 0x69, 0x56, 0x9b, 0x22, 0x08, + 0xdc, 0x71, 0xd2, 0x2e, 0xd0, 0xa6, 0x02, 0x35, 0xa2, 0xa4, 0xe9, 0x8e, 0x39, 0x53, 0x92, 0x72, + 0x62, 0x5f, 0x0a, 0xec, 0xbd, 0xa7, 0x02, 0x45, 0x0f, 0xbd, 0xf5, 0x2f, 0x2a, 0x7a, 0xe8, 0xa5, + 0xc7, 0x9e, 0xfa, 0x57, 0x14, 0xe4, 0x90, 0xf3, 0xd2, 0xc8, 0x6a, 0x7a, 0xe8, 0x8d, 0xcf, 0xef, + 0xfb, 0xf8, 0x3d, 0x7e, 0xfc, 0x71, 0x06, 0x1a, 0x3c, 0xf2, 0x4e, 0x23, 0x1e, 0xca, 0x10, 0x2d, + 0xf3, 0xc8, 0x8b, 0x06, 0x9d, 0x83, 0x71, 0x18, 0x8e, 0x03, 0xda, 0x25, 0x91, 0xdf, 0x25, 0x8c, + 0x85, 0x92, 0x48, 0x3f, 0x64, 0x22, 0x5e, 0xd4, 0xf9, 0xd1, 0xd8, 0x97, 0x93, 0xe9, 0xe0, 0xd4, + 0x0b, 0xaf, 0xba, 0x8c, 0x0e, 0xa6, 0x01, 0x11, 0x7e, 0xd8, 0x1d, 0x87, 0x9f, 0x99, 0x4e, 0xd7, + 0x0b, 0x99, 0xa0, 0x4c, 0x4c, 0x45, 0x37, 0x1a, 0x74, 0x85, 0x24, 0x92, 0x9a, 0x9d, 0x5f, 0x2e, + 0xda, 0xc9, 0xe8, 0x20, 0xa0, 0x52, 0x6d, 0xf3, 0x42, 0x36, 0xf2, 0xc7, 0xf1, 0x3e, 0xfc, 0x08, + 0xda, 0x97, 0xd3, 0x81, 0xf0, 0xb8, 0x3f, 0xa0, 0x2e, 0xfd, 0xdd, 0x94, 0x0a, 0x89, 0x76, 0x60, + 0x45, 0x86, 0x91, 0xef, 0x09, 0xa7, 0x72, 0x5c, 0x3b, 0x69, 0xb8, 0xa6, 0x87, 0xbf, 0x82, 0x7b, + 0x99, 0xb5, 0x22, 0x52, 0xb6, 0xa0, 0x2d, 0x58, 0xd6, 0xd3, 0x4e, 0xe5, 0xb8, 0x72, 0xd2, 0x70, + 0xe3, 0x0e, 0x42, 0xb0, 0x34, 0x24, 0x92, 0x38, 0x55, 0x3d, 0xa8, 0xdb, 0x18, 0x41, 0xfb, 0x55, + 0xc8, 0x2e, 0x08, 0x27, 0x57, 0xc2, 0xa8, 0xc2, 0x7f, 0xa9, 0xaa, 0xc1, 0x21, 0x7d, 0xc1, 0x46, + 0x61, 0x22, 0x72, 0x1d, 0xaa, 0xfe, 0xd0, 0xc8, 0xab, 0xfa, 0x43, 0xb4, 0x07, 0x75, 0x6f, 0x42, + 0x7c, 0xd6, 0xf7, 0x87, 0x5a, 0xe0, 0x9a, 0xbb, 0xaa, 0xfb, 0x2f, 0x86, 0xa8, 0x03, 0x75, 0x2f, + 0xf4, 0xd9, 0x80, 0x08, 0xea, 0xd4, 0xf4, 0x86, 0xa4, 0x8f, 0x0e, 0x01, 0x22, 0x4a, 0x79, 0xdf, + 0x0b, 0xa7, 0x4c, 0x3a, 0x4b, 0x7a, 0x63, 0x43, 0x8d, 0x3c, 0x53, 0x03, 0x08, 0x43, 0x4b, 0xdc, + 0x30, 0x6f, 0xc2, 0x43, 0xe6, 0xdf, 0xd2, 0xa1, 0xb3, 0x7c, 0x5c, 0x39, 0xa9, 0xbb, 0xb9, 0x31, + 0x74, 0x1f, 0x9a, 0x83, 0xa9, 0xf7, 0x1d, 0x95, 0x7d, 0xe1, 0xdf, 0x52, 0x67, 0xe5, 0xb8, 0x72, + 0xb2, 0xec, 0x42, 0x3c, 0x74, 0xe9, 0xdf, 0x52, 0xf4, 0x29, 0xb4, 0xb5, 0x1f, 0xbd, 0x30, 0xe8, + 0x5f, 0x53, 0x2e, 0xfc, 0x90, 0x39, 0xa0, 0xed, 0xd8, 0xb0, 0xe3, 0xbf, 0x88, 0x87, 0xd1, 0x19, + 0x34, 0x79, 0x38, 0x95, 0xb4, 0x2f, 0xc9, 0x20, 0xa0, 0x4e, 0xf3, 0xb8, 0x76, 0xd2, 0x3c, 0xbb, + 0x77, 0xaa, 0xd3, 0xe2, 0xd4, 0x55, 0x33, 0xaf, 0xd5, 0x84, 0x0b, 0x3c, 0x69, 0xe3, 0x2f, 0x01, + 0xd2, 0x99, 0x19, 0xbf, 0x38, 0xb0, 0x4a, 0x86, 0x43, 0x4e, 0x85, 0x70, 0xaa, 0x3a, 0x50, 0xb6, + 0x8b, 0xff, 0x51, 0x81, 0xcd, 0x1e, 0x95, 0xaf, 0xe8, 0xe0, 0x52, 0xe5, 0x48, 0xe2, 0xd9, 0xac, + 0x27, 0x2b, 0x79, 0x4f, 0x22, 0x58, 0x92, 0xc4, 0x0f, 0x6c, 0xc4, 0x54, 0x1b, 0xb5, 0xa1, 0x16, + 0xf8, 0x03, 0xe3, 0x58, 0xd5, 0x54, 0xa9, 0x31, 0xa1, 0xfe, 0x78, 0x12, 0xfb, 0x73, 0xc9, 0x35, + 0xbd, 0x52, 0x3f, 0xac, 0x94, 0xfb, 0xa1, 0xe8, 0xf7, 0xd5, 0x12, 0xbf, 0x3b, 0xb0, 0x6a, 0xa5, + 0xd4, 0xb5, 0x14, 0xdb, 0xc5, 0x9f, 0x43, 0xfb, 0xdc, 0xd3, 0x11, 0x15, 0xc9, 0xa9, 0x0e, 0xa0, + 0x61, 0x0e, 0x4e, 0x6d, 0xca, 0xa6, 0x03, 0xf8, 0x67, 0xb0, 0xd3, 0xa3, 0xd2, 0x6c, 0x32, 0xee, + 0x88, 0xf3, 0x3c, 0xe3, 0xbf, 0xd8, 0xa9, 0xb6, 0x9b, 0x39, 0x66, 0x35, 0x7b, 0x4c, 0xfc, 0x16, + 0x76, 0x67, 0x64, 0x19, 0x23, 0x1c, 0x58, 0x1d, 0x90, 0x80, 0x30, 0x8f, 0x5a, 0x61, 0xa6, 0xab, + 0x2a, 0x84, 0x85, 0x6a, 0x3c, 0x96, 0x15, 0x77, 0xb4, 0xbf, 0x6f, 0xa2, 0x38, 0x6b, 0xd7, 0x5c, + 0xdd, 0xc6, 0xbf, 0x85, 0xd6, 0x33, 0x12, 0x04, 0x89, 0xcc, 0x1d, 0x58, 0xe1, 0x54, 0x4c, 0x03, + 0x69, 0x44, 0x9a, 0x9e, 0x4a, 0x4b, 0xfa, 0x9e, 0x7a, 0x2a, 0x99, 0x28, 0xe7, 0x26, 0x64, 0x60, + 0x86, 0x9e, 0x73, 0x8e, 0x1e, 0x40, 0x8b, 0x0a, 0xe9, 0x5f, 0x11, 0x49, 0xfb, 0x63, 0x22, 0x4c, + 0x04, 0x9b, 0x76, 0xac, 0x47, 0x04, 0x3e, 0x85, 0xad, 0xa7, 0x37, 0x4f, 0x83, 0xd0, 0xfb, 0xee, + 0x1b, 0x7d, 0xb6, 0x4c, 0xf1, 0x9b, 0xa3, 0x57, 0x72, 0x47, 0xff, 0x01, 0xa0, 0x1e, 0x95, 0x3f, + 0xbd, 0x61, 0x44, 0xc8, 0x9b, 0xac, 0x85, 0x57, 0x3e, 0xa3, 0x3c, 0x81, 0x8a, 0xb8, 0x87, 0xff, + 0x5d, 0x01, 0xf4, 0x9a, 0x13, 0x26, 0x88, 0xa7, 0xf0, 0xcd, 0x0a, 0x47, 0xb0, 0x34, 0xe2, 0xe1, + 0x95, 0x39, 0x8e, 0x6e, 0xab, 0xac, 0x96, 0xa1, 0x39, 0x43, 0x55, 0x86, 0xca, 0x5d, 0xd7, 0x24, + 0x98, 0xda, 0x7a, 0x8e, 0x3b, 0xa9, 0x13, 0x97, 0xb2, 0x4e, 0xdc, 0x87, 0xc6, 0x98, 0x88, 0x7e, + 0xc4, 0x7d, 0x8f, 0xea, 0x02, 0x6e, 0xb8, 0xf5, 0x31, 0x11, 0x17, 0xaa, 0x6f, 0x27, 0x03, 0xff, + 0xca, 0x97, 0x26, 0x19, 0xd5, 0xe4, 0x4b, 0xd5, 0x47, 0x67, 0x0a, 0x38, 0x98, 0xe4, 0xc4, 0x93, + 0x3a, 0x03, 0x9b, 0x67, 0x3b, 0xa6, 0x14, 0x9f, 0x99, 0x61, 0x63, 0xb3, 0x9b, 0xac, 0x53, 0x87, + 0x1d, 0xf8, 0x8c, 0xf0, 0x1b, 0x5d, 0xe2, 0x2d, 0xd7, 0xf4, 0xf0, 0x2d, 0x6c, 0x14, 0x36, 0xa9, + 0xa5, 0x22, 0x9c, 0xf2, 0x24, 0x19, 0x4c, 0x4f, 0x45, 0x2e, 0x6e, 0xf5, 0x75, 0xf0, 0x4d, 0xe4, + 0xe2, 0xa1, 0xd7, 0x37, 0x11, 0x55, 0x80, 0x36, 0x9a, 0x32, 0xed, 0x34, 0x0b, 0x68, 0xb6, 0xaf, + 0xbc, 0x47, 0xf8, 0x58, 0x68, 0x17, 0x34, 0x5c, 0xdd, 0xc6, 0x5d, 0xd8, 0xbb, 0xa4, 0x6c, 0xe8, + 0x92, 0x77, 0xe5, 0xee, 0xd6, 0x28, 0x5c, 0xd1, 0xe6, 0xc6, 0x28, 0xfc, 0x6b, 0xd8, 0x55, 0x1b, + 0x72, 0xab, 0xd3, 0x60, 0xca, 0xf7, 0x13, 0x22, 0x26, 0xd6, 0xe8, 0xb8, 0xa7, 0x8a, 0xdb, 0xfa, + 0xa0, 0x9f, 0x02, 0x8e, 0x2e, 0x6e, 0x3b, 0x7e, 0x6e, 0x80, 0xa7, 0x0f, 0xdb, 0x3d, 0x2a, 0x75, + 0x5a, 0x3d, 0xbd, 0xf9, 0x86, 0x88, 0x49, 0xc6, 0x94, 0x8c, 0x64, 0xdd, 0x46, 0x67, 0xb0, 0x3d, + 0x9a, 0x06, 0x41, 0x7f, 0xe4, 0x07, 0x41, 0x5f, 0xa6, 0x06, 0x69, 0xe1, 0x75, 0x77, 0x53, 0x4d, + 0x7e, 0xed, 0x07, 0x41, 0xc6, 0x56, 0x4c, 0x75, 0x05, 0x5a, 0x05, 0xff, 0x4d, 0xe6, 0xfe, 0x4f, + 0x6a, 0x1e, 0xc3, 0x7e, 0x8f, 0xca, 0xcc, 0xc8, 0xc2, 0xd3, 0xe0, 0x7f, 0xd6, 0x60, 0x4d, 0xdb, + 0x95, 0xf8, 0xb3, 0xec, 0xcc, 0xf7, 0xa1, 0x19, 0x11, 0x4e, 0x99, 0xec, 0xeb, 0x29, 0x93, 0x00, + 0xf1, 0x90, 0xd2, 0x90, 0x39, 0x45, 0x2d, 0x77, 0x8a, 0xf2, 0x02, 0xc8, 0xde, 0x7f, 0xcb, 0x85, + 0xfb, 0xef, 0x00, 0x1a, 0xd2, 0xbf, 0xa2, 0x42, 0x92, 0xab, 0x48, 0xe7, 0x7f, 0xcd, 0x4d, 0x07, + 0x72, 0x57, 0xc1, 0x6a, 0xfe, 0x2a, 0x38, 0x04, 0xd0, 0xd4, 0xa2, 0xcf, 0xc3, 0x50, 0x1a, 0x00, + 0x6e, 0xe8, 0x11, 0x37, 0x0c, 0xa5, 0xda, 0x29, 0xdf, 0x8b, 0x78, 0xb2, 0x11, 0x43, 0x9d, 0x7c, + 0x2f, 0xf4, 0x94, 0x02, 0xa6, 0x6b, 0xca, 0xa4, 0x99, 0x05, 0x03, 0x4c, 0x7a, 0x48, 0x2f, 0x38, + 0x87, 0xf5, 0x84, 0xc2, 0xc4, 0x6b, 0x9a, 0xba, 0xf8, 0x3a, 0xa7, 0xc9, 0x70, 0x5c, 0x82, 0x71, + 0x5b, 0xed, 0x71, 0xd7, 0xbc, 0x6c, 0x57, 0x39, 0x42, 0x83, 0x8c, 0xd3, 0x8a, 0xf1, 0x41, 0x77, + 0x94, 0x66, 0x5f, 0xf4, 0x47, 0x3e, 0x23, 0x81, 0x2f, 0x6f, 0x9c, 0x35, 0x1d, 0x5a, 0xf0, 0xc5, + 0xd7, 0x66, 0x04, 0xfd, 0x04, 0x5a, 0x99, 0xd8, 0x0b, 0x67, 0xa8, 0xef, 0xdf, 0x8e, 0x29, 0xfa, + 0x92, 0x72, 0x70, 0x73, 0xeb, 0xf1, 0x9f, 0x6a, 0xb0, 0x59, 0x56, 0x34, 0x65, 0x41, 0x76, 0xc0, + 0xfa, 0xb2, 0xc8, 0x57, 0x2c, 0x00, 0xd6, 0x66, 0x00, 0x70, 0x69, 0x16, 0x00, 0x97, 0x4b, 0x01, + 0x70, 0x25, 0x1b, 0xff, 0x5c, 0x8c, 0x57, 0x8b, 0x31, 0xb6, 0x77, 0x4c, 0xdd, 0xdc, 0xe9, 0x0a, + 0x60, 0x2c, 0x26, 0x34, 0x52, 0x4c, 0xc8, 0xc3, 0x28, 0xdc, 0x05, 0xa3, 0xcd, 0x02, 0x8c, 0x96, + 0x41, 0x43, 0xab, 0x14, 0x1a, 0x34, 0x24, 0x4a, 0x22, 0xa7, 0x42, 0x07, 0x67, 0xd9, 0x35, 0x3d, + 0x95, 0x4e, 0x4a, 0xfe, 0x54, 0xd0, 0xa1, 0xb3, 0x1e, 0xa7, 0xd3, 0x98, 0x88, 0x37, 0x82, 0x0e, + 0xd1, 0x43, 0x58, 0xcb, 0xdc, 0x73, 0x21, 0x77, 0x36, 0xf4, 0x7c, 0x2b, 0xbd, 0xe9, 0x42, 0x8e, + 0xbf, 0x80, 0x7b, 0xaf, 0xe8, 0x3b, 0x73, 0x27, 0xdb, 0x02, 0x3d, 0x02, 0x88, 0x88, 0x10, 0xd1, + 0x84, 0xab, 0xca, 0xa8, 0xd8, 0x2a, 0xb3, 0x23, 0xf8, 0x14, 0x50, 0x76, 0x53, 0x7a, 0x87, 0x97, + 0x13, 0x02, 0x1c, 0xc0, 0xd6, 0x1b, 0xa6, 0x8a, 0xbb, 0xa0, 0x67, 0x3e, 0x85, 0xc8, 0x5b, 0x50, + 0x2d, 0x5a, 0xa0, 0x2a, 0x77, 0x38, 0xe5, 0x24, 0x01, 0xfa, 0x25, 0x37, 0xe9, 0xe3, 0x2e, 0x6c, + 0x17, 0xb4, 0x95, 0x12, 0x82, 0xba, 0x25, 0x04, 0xea, 0x38, 0x2f, 0x3f, 0xc0, 0x38, 0xfc, 0x19, + 0x6c, 0xbe, 0xfc, 0x00, 0xf1, 0x3f, 0x87, 0x8d, 0x4b, 0x7f, 0xcc, 0xb2, 0x08, 0x38, 0xff, 0xe0, + 0xb6, 0x20, 0xaa, 0x71, 0x82, 0xe9, 0x82, 0x68, 0x43, 0x8d, 0x04, 0x63, 0xc3, 0x75, 0x54, 0x13, + 0x7f, 0x0c, 0xed, 0x54, 0x64, 0x5a, 0x4a, 0x33, 0xd7, 0xd5, 0x1b, 0x70, 0x7a, 0x94, 0x51, 0x4e, + 0x24, 0x8d, 0xc1, 0x95, 0xb0, 0xe1, 0x62, 0x1b, 0x4a, 0x50, 0xb6, 0x95, 0x45, 0x59, 0x7c, 0x09, + 0x7b, 0x25, 0x62, 0x53, 0x96, 0x7c, 0xcd, 0x47, 0xfd, 0xa4, 0xac, 0x5b, 0xee, 0xea, 0x35, 0x1f, + 0x69, 0x74, 0xde, 0x87, 0x86, 0x9a, 0x8a, 0x78, 0x18, 0x8e, 0x8c, 0x58, 0xb5, 0xf6, 0x42, 0xf5, + 0xf1, 0xef, 0xe1, 0x58, 0x9d, 0x29, 0x83, 0x12, 0x17, 0x49, 0xbc, 0xad, 0xcd, 0x3f, 0x86, 0x66, + 0xf6, 0x0a, 0xaa, 0x68, 0xf4, 0xdb, 0x2b, 0x43, 0xa1, 0x98, 0x7d, 0x64, 0x57, 0x2f, 0xca, 0x29, + 0xfc, 0x43, 0x78, 0x70, 0x87, 0x01, 0x77, 0x78, 0x59, 0x59, 0x9e, 0x27, 0x05, 0xff, 0x67, 0xcb, + 0xbb, 0xd0, 0xee, 0x19, 0xc0, 0x49, 0x0c, 0xcd, 0xa1, 0x52, 0x25, 0x8f, 0x4a, 0xf8, 0x01, 0x34, + 0x17, 0x5d, 0xc8, 0x8f, 0xa1, 0xd9, 0x23, 0xe9, 0x2b, 0xa1, 0x0d, 0x35, 0x45, 0x85, 0xe3, 0x15, + 0xaa, 0xa9, 0x46, 0x52, 0xfa, 0xac, 0x9a, 0xf8, 0x4b, 0x58, 0x7f, 0x1e, 0x5f, 0x56, 0x76, 0xd7, + 0x47, 0xb0, 0x12, 0x5f, 0x5f, 0x9a, 0xe0, 0x36, 0xcf, 0x5a, 0xe6, 0xc0, 0x7a, 0x99, 0x6b, 0xe6, + 0xf0, 0x63, 0x58, 0xd6, 0x03, 0x1f, 0xf0, 0x1a, 0xfe, 0x18, 0x5a, 0x17, 0x11, 0x0f, 0x47, 0x19, + 0xf6, 0x12, 0xf8, 0x42, 0x52, 0x66, 0xc9, 0x57, 0xdc, 0xc3, 0x9f, 0xc0, 0x9a, 0x59, 0xb7, 0xa0, + 0x48, 0xbf, 0x82, 0x7b, 0x3d, 0x2a, 0x9f, 0xe9, 0xc7, 0x7d, 0xb2, 0xf8, 0x04, 0x56, 0xe2, 0xe7, + 0xbe, 0x89, 0x57, 0xfb, 0x34, 0xfe, 0x0e, 0x10, 0x5f, 0xb2, 0x6a, 0xa5, 0x99, 0x3f, 0xfb, 0x1b, + 0x00, 0x9c, 0x47, 0xfe, 0x25, 0xe5, 0xd7, 0x0a, 0xf5, 0xdf, 0x42, 0x33, 0xf3, 0x80, 0x44, 0xbb, + 0xe6, 0xd8, 0xc5, 0x07, 0x7c, 0xc7, 0x5e, 0xa0, 0x25, 0xaf, 0x4d, 0xbc, 0xf7, 0xfd, 0xdf, 0xff, + 0xf5, 0xc7, 0xea, 0x26, 0xba, 0xd7, 0xbd, 0x7e, 0xdc, 0x9d, 0x0a, 0xca, 0xbb, 0x8c, 0x0e, 0x34, + 0x8f, 0x40, 0xbf, 0x81, 0xdd, 0x97, 0x44, 0x52, 0x21, 0x5f, 0x70, 0x4e, 0xf5, 0xdb, 0x6e, 0x10, + 0xc4, 0x95, 0x38, 0x5f, 0xd5, 0x96, 0x99, 0xc8, 0x91, 0x2c, 0xbc, 0xa5, 0x95, 0xac, 0xa3, 0x56, + 0xa2, 0x44, 0xbd, 0x53, 0x39, 0x6c, 0x14, 0x1e, 0x6a, 0xe8, 0x30, 0xb5, 0xb4, 0xe4, 0x31, 0xd8, + 0x39, 0x9a, 0x37, 0x6d, 0xf4, 0x1c, 0x6b, 0x3d, 0x1d, 0xbc, 0x9d, 0xe8, 0x21, 0xe6, 0x1d, 0xaa, + 0x96, 0x3d, 0xa9, 0x3c, 0x42, 0x17, 0xb0, 0xa4, 0x5e, 0x6f, 0x68, 0x7e, 0x4d, 0x74, 0x36, 0xed, + 0x1b, 0x23, 0xf3, 0xca, 0xc3, 0x8e, 0x96, 0x8c, 0xf0, 0x5a, 0x22, 0xd9, 0x23, 0x41, 0xa0, 0x24, + 0xde, 0x02, 0x9a, 0x25, 0xf7, 0xe8, 0xd8, 0x08, 0x99, 0xcb, 0xfb, 0x93, 0xb3, 0xcc, 0x21, 0xfa, + 0x18, 0x6b, 0x8d, 0x07, 0x78, 0x37, 0xd1, 0xc8, 0xc9, 0xbb, 0x4c, 0xb9, 0x2a, 0xdd, 0x13, 0x58, + 0xcf, 0x33, 0x79, 0x74, 0x90, 0x7a, 0x68, 0x96, 0xe0, 0xcf, 0x89, 0xce, 0xac, 0xa6, 0x71, 0x6e, + 0xb7, 0xd2, 0xc4, 0xa0, 0x5d, 0xa4, 0xf4, 0xe8, 0x68, 0x56, 0x57, 0x96, 0xeb, 0xcf, 0xd1, 0xf6, + 0x91, 0xd6, 0x76, 0x84, 0xf7, 0xca, 0xb4, 0xe9, 0xfd, 0x4a, 0xdf, 0xf7, 0x15, 0xfd, 0x48, 0xc9, + 0x39, 0xc6, 0xa3, 0x7e, 0x24, 0x11, 0x4e, 0xb5, 0xce, 0xa3, 0xfe, 0x9d, 0x3b, 0x18, 0x23, 0xfe, + 0x54, 0xeb, 0x7f, 0x88, 0x8f, 0xb2, 0xfa, 0x67, 0xf5, 0x28, 0x23, 0xfa, 0xd0, 0x48, 0xbe, 0xa5, + 0x25, 0x29, 0x5f, 0xfc, 0x12, 0xd7, 0x71, 0x66, 0x27, 0x8c, 0xaa, 0x43, 0xad, 0x6a, 0x17, 0xa3, + 0x44, 0x95, 0xb0, 0x6b, 0x9e, 0x54, 0x1e, 0x7d, 0x5e, 0x31, 0x05, 0x6c, 0x41, 0x75, 0x7e, 0x55, + 0xd9, 0x89, 0x22, 0xfc, 0xe2, 0x03, 0xad, 0x61, 0x07, 0x6d, 0x65, 0x0f, 0x93, 0xc8, 0x7b, 0x0b, + 0xcd, 0xe7, 0xe9, 0xd7, 0x84, 0xbb, 0x72, 0x1e, 0xa5, 0x0a, 0x12, 0xd9, 0xf7, 0xb5, 0xec, 0x3d, + 0x9c, 0xca, 0xce, 0x7c, 0x9a, 0x50, 0xee, 0x21, 0xba, 0x7e, 0x63, 0x2c, 0x36, 0xe9, 0x67, 0xe5, + 0x64, 0x83, 0xb1, 0x9d, 0x45, 0xe3, 0x54, 0xfc, 0x43, 0x2d, 0xfe, 0x10, 0x3b, 0x59, 0xd3, 0xb3, + 0xc2, 0x62, 0x15, 0x90, 0x7e, 0xd0, 0x40, 0xfb, 0x36, 0xa1, 0x4a, 0xbe, 0x89, 0x74, 0xf6, 0xd2, + 0xbc, 0x28, 0x7c, 0x00, 0xc1, 0xfb, 0x5a, 0xd5, 0x36, 0x6e, 0x27, 0xaa, 0x86, 0xf1, 0x8a, 0x27, + 0x95, 0x47, 0x67, 0x7f, 0x05, 0x68, 0x9d, 0x0f, 0xaf, 0x7c, 0x66, 0x51, 0xf5, 0x5b, 0xa8, 0xdb, + 0xaf, 0x57, 0x8b, 0x23, 0x52, 0xfc, 0xce, 0x85, 0x3b, 0x5a, 0xd7, 0x16, 0xd2, 0x31, 0x27, 0x4a, + 0x6e, 0x82, 0x41, 0xc8, 0x03, 0x48, 0x09, 0x2d, 0xb2, 0x79, 0x33, 0x43, 0x8c, 0x93, 0xa3, 0xcc, + 0xb2, 0xdf, 0x3c, 0xc2, 0xe5, 0xc4, 0x77, 0x19, 0x7d, 0xa7, 0x5c, 0x16, 0xc2, 0x5a, 0x8e, 0x97, + 0x26, 0x5e, 0x2b, 0xe3, 0xc6, 0x9d, 0x83, 0xf2, 0xc9, 0xb2, 0x18, 0xe5, 0xb5, 0x4d, 0xf5, 0x06, + 0xa5, 0x70, 0x0c, 0xcd, 0x0c, 0x4f, 0x4d, 0xb2, 0x6c, 0x96, 0xeb, 0x26, 0x65, 0x59, 0x42, 0x6b, + 0xf1, 0x03, 0xad, 0x6a, 0x1f, 0xef, 0xcc, 0xaa, 0xb2, 0x8a, 0x18, 0x6c, 0x14, 0xc0, 0xf2, 0xae, + 0x94, 0x5e, 0x84, 0xaf, 0x25, 0x9e, 0x2c, 0xa0, 0xeb, 0xaf, 0xa0, 0x6e, 0xe9, 0x2f, 0xb2, 0x1f, + 0x9e, 0x0a, 0x14, 0x3b, 0xc9, 0x83, 0x22, 0x4f, 0xc6, 0x47, 0x5a, 0xbc, 0x83, 0x37, 0x53, 0xf1, + 0xc2, 0x1f, 0xb3, 0xee, 0xc4, 0x64, 0xf6, 0xb5, 0x62, 0x02, 0x05, 0x72, 0x8b, 0xee, 0x27, 0x39, + 0x5c, 0xce, 0xa6, 0x3b, 0xc7, 0xf3, 0x17, 0xcc, 0xd7, 0x3b, 0x50, 0x8b, 0x38, 0x61, 0x43, 0xa5, + 0xf7, 0x0f, 0x15, 0x38, 0x2c, 0xf0, 0xcf, 0x5f, 0xfa, 0x72, 0x92, 0x52, 0x49, 0xf4, 0x49, 0xe6, + 0x48, 0x77, 0x91, 0xcd, 0xce, 0xc9, 0xe2, 0x85, 0x79, 0x92, 0x81, 0xd7, 0xf3, 0xce, 0x50, 0xf6, + 0xfc, 0x59, 0xd9, 0x93, 0x0f, 0xd1, 0x3c, 0x7b, 0x16, 0x90, 0xdf, 0x85, 0x11, 0x3f, 0xd5, 0x56, + 0x9c, 0xe0, 0x87, 0xa5, 0x11, 0xcf, 0x6b, 0x55, 0xa6, 0x5d, 0x02, 0x5c, 0x4a, 0xc2, 0xa5, 0xa6, + 0x76, 0xc8, 0xd2, 0x82, 0x2c, 0x21, 0x4c, 0xae, 0xb8, 0x1c, 0xfb, 0xb3, 0x18, 0x80, 0x37, 0x52, + 0x45, 0x91, 0x5a, 0x10, 0x27, 0x55, 0x23, 0x61, 0x80, 0xf3, 0xe1, 0xc5, 0x49, 0xc1, 0x2c, 0x4f, + 0x16, 0x2d, 0x96, 0xa1, 0x4c, 0x7c, 0xc7, 0x89, 0xbc, 0x6f, 0xa1, 0x6e, 0x7f, 0xd4, 0x2c, 0x86, + 0xae, 0xe2, 0x2f, 0x9d, 0x32, 0xe8, 0x62, 0xe1, 0x90, 0xfa, 0x6c, 0x14, 0x0e, 0x56, 0xf4, 0x1f, + 0x82, 0x2f, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x75, 0xf5, 0x4d, 0x17, 0x2d, 0x1b, 0x00, 0x00, } diff --git a/rpc/pb/rpc.pb.gw.go b/rpc/pb/rpc.pb.gw.go index afe51fc04..261c1ca80 100644 --- a/rpc/pb/rpc.pb.gw.go +++ b/rpc/pb/rpc.pb.gw.go @@ -50,10 +50,8 @@ func request_ApiService_GetAccountState_0(ctx context.Context, marshaler runtime var protoReq GetAccountStateRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.GetAccountState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -65,10 +63,8 @@ func request_ApiService_Call_0(ctx context.Context, marshaler runtime.Marshaler, var protoReq TransactionRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.Call(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -80,10 +76,8 @@ func request_ApiService_SendRawTransaction_0(ctx context.Context, marshaler runt var protoReq SendRawTransactionRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.SendRawTransaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -95,10 +89,8 @@ func request_ApiService_GetBlockByHash_0(ctx context.Context, marshaler runtime. var protoReq GetBlockByHashRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.GetBlockByHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -110,10 +102,8 @@ func request_ApiService_GetBlockByHeight_0(ctx context.Context, marshaler runtim var protoReq GetBlockByHeightRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.GetBlockByHeight(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -125,10 +115,8 @@ func request_ApiService_GetTransactionReceipt_0(ctx context.Context, marshaler r var protoReq GetTransactionByHashRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.GetTransactionReceipt(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -140,10 +128,8 @@ func request_ApiService_Subscribe_0(ctx context.Context, marshaler runtime.Marsh var protoReq SubscribeRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } stream, err := client.Subscribe(ctx, &protoReq) @@ -172,10 +158,8 @@ func request_ApiService_EstimateGas_0(ctx context.Context, marshaler runtime.Mar var protoReq TransactionRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.EstimateGas(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -187,10 +171,8 @@ func request_ApiService_GetEventsByHash_0(ctx context.Context, marshaler runtime var protoReq HashRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.GetEventsByHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -202,10 +184,8 @@ func request_ApiService_GetDynasty_0(ctx context.Context, marshaler runtime.Mars var protoReq ByBlockHeightRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.GetDynasty(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -226,10 +206,8 @@ func request_AdminService_NewAccount_0(ctx context.Context, marshaler runtime.Ma var protoReq NewAccountRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.NewAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -241,10 +219,8 @@ func request_AdminService_UnlockAccount_0(ctx context.Context, marshaler runtime var protoReq UnlockAccountRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.UnlockAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -256,10 +232,8 @@ func request_AdminService_LockAccount_0(ctx context.Context, marshaler runtime.M var protoReq LockAccountRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.LockAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -271,10 +245,8 @@ func request_AdminService_SendTransaction_0(ctx context.Context, marshaler runti var protoReq TransactionRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.SendTransaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -286,10 +258,8 @@ func request_AdminService_SignHash_0(ctx context.Context, marshaler runtime.Mars var protoReq SignHashRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.SignHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -297,14 +267,25 @@ func request_AdminService_SignHash_0(ctx context.Context, marshaler runtime.Mars } +func request_AdminService_GenerateBlockRand_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateBlockRandRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GenerateBlockRand(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + func request_AdminService_SignTransactionWithPassphrase_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq SignTransactionPassphraseRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.SignTransactionWithPassphrase(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -316,10 +297,8 @@ func request_AdminService_SendTransactionWithPassphrase_0(ctx context.Context, m var protoReq SendTransactionPassphraseRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.SendTransactionWithPassphrase(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -331,10 +310,8 @@ func request_AdminService_StartPprof_0(ctx context.Context, marshaler runtime.Ma var protoReq PprofRequest var metadata runtime.ServerMetadata - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } msg, err := client.StartPprof(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -1046,6 +1023,35 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("POST", pattern_AdminService_GenerateBlockRand_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AdminService_GenerateBlockRand_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_GenerateBlockRand_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_AdminService_SignTransactionWithPassphrase_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1207,6 +1213,8 @@ var ( pattern_AdminService_SignHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "admin", "sign", "hash"}, "")) + pattern_AdminService_GenerateBlockRand_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "blockrand"}, "")) + pattern_AdminService_SignTransactionWithPassphrase_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "sign"}, "")) pattern_AdminService_SendTransactionWithPassphrase_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "transactionWithPassphrase"}, "")) @@ -1231,6 +1239,8 @@ var ( forward_AdminService_SignHash_0 = runtime.ForwardResponseMessage + forward_AdminService_GenerateBlockRand_0 = runtime.ForwardResponseMessage + forward_AdminService_SignTransactionWithPassphrase_0 = runtime.ForwardResponseMessage forward_AdminService_SendTransactionWithPassphrase_0 = runtime.ForwardResponseMessage diff --git a/rpc/pb/rpc.proto b/rpc/pb/rpc.proto index 018399ae8..ed4ef5075 100644 --- a/rpc/pb/rpc.proto +++ b/rpc/pb/rpc.proto @@ -174,6 +174,13 @@ service AdminService { }; } + rpc GenerateBlockRand(GenerateBlockRandRequest) returns (GenerateBlockRandResponse) { + option (google.api.http) = { + post: "/v1/admin/blockrand" + body: "*" + }; + } + // Sign sign transaction rpc SignTransactionWithPassphrase(SignTransactionPassphraseRequest) returns (SignTransactionPassphraseResponse) { option (google.api.http) = { @@ -544,6 +551,18 @@ message SignHashResponse { bytes data = 1; } +message GenerateBlockRandRequest { + // miner address + string address = 1; + // parent hash of new block + bytes parent_hash = 2; +} + +message GenerateBlockRandResponse { + bytes vrf_hash = 1; + bytes vrf_proof = 2; +} + message SignTransactionPassphraseRequest { // transaction struct TransactionRequest transaction = 1; From c664c0bb840deb6ded371148680af7e4e893a440 Mon Sep 17 00:00:00 2001 From: fengzi Date: Sat, 28 Apr 2018 22:02:12 +0800 Subject: [PATCH 37/69] core:account_state.go update get contract account error --- core/state/account_state.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/state/account_state.go b/core/state/account_state.go index 3ae8ccc8e..fed37295b 100644 --- a/core/state/account_state.go +++ b/core/state/account_state.go @@ -32,8 +32,9 @@ import ( // Errors var ( - ErrBalanceInsufficient = errors.New("cannot subtract a value which is bigger than current balance") - ErrAccountNotFound = errors.New("cannot found account in storage") + ErrBalanceInsufficient = errors.New("cannot subtract a value which is bigger than current balance") + ErrAccountNotFound = errors.New("cannot found account in storage") + ErrContractAccountNotFound = errors.New("cannot found contract account in storage please check contract address is valid or deploy is success") ) // account info in state Trie @@ -301,6 +302,10 @@ func (as *accountState) GetOrCreateUserAccount(addr byteutils.Hash) (Account, er // GetContractAccount from current AccountState func (as *accountState) GetContractAccount(addr byteutils.Hash) (Account, error) { acc, err := as.getAccount(addr) + + if err == ErrAccountNotFound { + err = ErrContractAccountNotFound + } if err != nil { return nil, err } From d8b8b9c6909d64af37f9f38e549ffe6c53b5f9a0 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 28 Apr 2018 22:06:03 +0800 Subject: [PATCH 38/69] nvm: simulate execution bugfix --- core/block.go | 1 + core/blockchain.go | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/core/block.go b/core/block.go index 7555c1b66..131b1a5d6 100644 --- a/core/block.go +++ b/core/block.go @@ -243,6 +243,7 @@ func NewBlock(chainID uint32, coinbase *Address, parent *Block) (*Block, error) coinbase: coinbase, timestamp: time.Now().Unix(), consensusRoot: &consensuspb.ConsensusRoot{}, + rand: &corepb.Rand{}, }, transactions: make(Transactions, 0), dependency: dag.NewDag(), diff --git a/core/blockchain.go b/core/blockchain.go index 1d54e1101..a81c40a0b 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -19,6 +19,8 @@ package core import ( + "crypto/rand" + "io" "strings" "time" @@ -698,6 +700,13 @@ func (bc *BlockChain) SimulateTransactionExecution(tx *Transaction) (*SimulateRe if err != nil { return nil, err } + + sVrfHash, sVrfProof := make([]byte, 32), make([]byte, 129) + _, _ = io.ReadFull(rand.Reader, sVrfHash) + _, _ = io.ReadFull(rand.Reader, sVrfProof) + block.header.rand.VrfHash = sVrfHash + block.header.rand.VrfProof = sVrfProof + defer block.RollBack() // simulate execution. From ccacf20599e056beebb681b566019ff0f91d2ef9 Mon Sep 17 00:00:00 2001 From: fengzi Date: Sat, 28 Apr 2018 22:42:32 +0800 Subject: [PATCH 39/69] storage:rocks_storage.go update metrics --- storage/rocks_storage.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/rocks_storage.go b/storage/rocks_storage.go index 538c7335a..63d459926 100644 --- a/storage/rocks_storage.go +++ b/storage/rocks_storage.go @@ -1,6 +1,7 @@ package storage import ( + "strconv" "sync" "time" @@ -175,18 +176,17 @@ func RecordMetrics(storage *RocksStorage) { cacheSize := storage.cache.GetUsage() pinnedSize := storage.cache.GetPinnedUsage() - readersMemByte, err := byteutils.FromHex(readersMemStr) + readersMem, err := strconv.Atoi(readersMemStr) if err != nil { break } - - allMemTablesByte, err := byteutils.FromHex(allMemTablesStr) + allMemTables, err := strconv.Atoi(allMemTablesStr) if err != nil { break } - metricsBlocksdbAllMemTables.Update(byteutils.Int64(allMemTablesByte)) - metricsBlocksdbTableReaderMem.Update(byteutils.Int64(readersMemByte)) + metricsBlocksdbAllMemTables.Update(int64(allMemTables)) + metricsBlocksdbTableReaderMem.Update(int64(readersMem)) metricsBlocksdbCacheSize.Update(int64(cacheSize)) metricsBlocksdbCachePinnedSize.Update(int64(pinnedSize)) } From 13f741700ba489ecf97d257ab9f057f8908ad495 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 28 Apr 2018 22:48:43 +0800 Subject: [PATCH 40/69] nvm: rename block random --- consensus/dpos/dpos.go | 10 +- core/block.go | 38 +++--- core/block_pool.go | 4 +- core/blockchain.go | 4 +- core/pb/block.pb.go | 120 +++++++++--------- core/pb/block.proto | 4 +- core/types.go | 2 +- .../contract/contract.feature.random.test.js | 12 +- 8 files changed, 101 insertions(+), 93 deletions(-) diff --git a/consensus/dpos/dpos.go b/consensus/dpos/dpos.go index 0decef561..f821ce689 100644 --- a/consensus/dpos/dpos.go +++ b/consensus/dpos/dpos.go @@ -377,12 +377,12 @@ func (dpos *Dpos) VerifyBlock(block *core.Block) error { return err } - // check block rand + // check block random if block.Height() >= core.RandomAvailableCompatibleHeight && !block.HasBlockRand() { logging.VLog().WithFields(logrus.Fields{ "compatibleHeight": core.RandomAvailableCompatibleHeight, - }).Debug("No rand found in block header.") - return core.ErrInvalidBlockRand + }).Debug("No random found in block header.") + return core.ErrInvalidBlockRandom } dpos.slot.Add(block.Timestamp(), block) @@ -396,7 +396,7 @@ func (dpos *Dpos) generateBlockSand(block *core.Block, adminService rpcpb.AdminS } // generate VRF hash,proof if block.Height() >= core.RandomAvailableCompatibleHeight { - rand, err := adminService.GenerateBlockRand( + random, err := adminService.GenerateBlockRand( context.Background(), &rpcpb.GenerateBlockRandRequest{ Address: dpos.miner.String(), @@ -405,7 +405,7 @@ func (dpos *Dpos) generateBlockSand(block *core.Block, adminService rpcpb.AdminS if err != nil { return err } - block.SetBlockRand(rand.VrfHash, rand.VrfProof) + block.SetBlockRand(random.VrfHash, random.VrfProof) } return nil } diff --git a/core/block.go b/core/block.go index 131b1a5d6..cef74804d 100644 --- a/core/block.go +++ b/core/block.go @@ -81,7 +81,7 @@ type BlockHeader struct { sign byteutils.Hash // rand - rand *corepb.Rand + random *corepb.Random } // ToProto converts domain BlockHeader to proto BlockHeader @@ -98,7 +98,7 @@ func (b *BlockHeader) ToProto() (proto.Message, error) { ChainId: b.chainID, Alg: uint32(b.alg), Sign: b.sign, - Rand: b.rand, + Random: b.random, }, nil } @@ -130,7 +130,7 @@ func (b *BlockHeader) FromProto(msg proto.Message) error { b.alg = alg b.sign = msg.Sign - b.rand = msg.Rand + b.random = msg.Random return nil } return ErrInvalidProtoToBlockHeader @@ -202,7 +202,7 @@ func (block *Block) FromProto(msg proto.Message) error { if msg.Height >= RandomAvailableCompatibleHeight && !block.HasBlockRand() { logging.VLog().WithFields(logrus.Fields{ "compatibleHeight": RandomAvailableCompatibleHeight, - }).Debug("No rand found in block header.") + }).Debug("No random found in block header.") return ErrInvalidProtoToBlockHeader } block.transactions = make(Transactions, len(msg.Transactions)) @@ -243,7 +243,7 @@ func NewBlock(chainID uint32, coinbase *Address, parent *Block) (*Block, error) coinbase: coinbase, timestamp: time.Now().Unix(), consensusRoot: &consensuspb.ConsensusRoot{}, - rand: &corepb.Rand{}, + random: &corepb.Random{}, }, transactions: make(Transactions, 0), dependency: dag.NewDag(), @@ -287,17 +287,17 @@ func (block *Block) Sign(signature keystore.Signature) error { return nil } -// SetBlockRand set block.header.rand +// SetBlockRand set block.header.random func (block *Block) SetBlockRand(vrfhash, vrfproof []byte) { - block.header.rand = &corepb.Rand{ + block.header.random = &corepb.Random{ VrfHash: vrfhash, VrfProof: vrfproof, } } -// HasBlockRand check rand if exists +// HasBlockRand check random if exists func (block *Block) HasBlockRand() bool { - return block.header.rand != nil && block.header.rand.VrfHash != nil && block.header.rand.VrfProof != nil + return block.header.random != nil && block.header.random.VrfHash != nil && block.header.random.VrfProof != nil } // ChainID returns block's chainID @@ -385,10 +385,10 @@ func (block *Block) Transactions() Transactions { return block.transactions } -// RandomSeed block rand seed (VRF) +// RandomSeed block random seed (VRF) func (block *Block) RandomSeed() string { if block.height >= RandomAvailableCompatibleHeight { - return byteutils.Hex(block.header.rand.VrfHash) + return byteutils.Hex(block.header.random.VrfHash) } return "" } @@ -793,16 +793,16 @@ func (block *Block) Seal() error { } func (block *Block) String() string { - rand := "" - if block.height >= RandomAvailableCompatibleHeight && block.header.rand != nil { - if block.header.rand.VrfHash != nil { - rand += "/vrf_hash/" + byteutils.Hex(block.header.rand.VrfHash) + random := "" + if block.height >= RandomAvailableCompatibleHeight && block.header.random != nil { + if block.header.random.VrfHash != nil { + random += "/vrf_hash/" + byteutils.Hex(block.header.random.VrfHash) } - if block.header.rand.VrfProof != nil { - rand += "/vrf_proof/" + byteutils.Hex(block.header.rand.VrfProof) + if block.header.random.VrfProof != nil { + random += "/vrf_proof/" + byteutils.Hex(block.header.random.VrfProof) } } - return fmt.Sprintf(`{"height": %d, "hash": "%s", "parent_hash": "%s", "acc_root": "%s", "timestamp": %d, "tx": %d, "miner": "%s", "rand": "%s"}`, + return fmt.Sprintf(`{"height": %d, "hash": "%s", "parent_hash": "%s", "acc_root": "%s", "timestamp": %d, "tx": %d, "miner": "%s", "random": "%s"}`, block.height, block.header.hash, block.header.parentHash, @@ -810,7 +810,7 @@ func (block *Block) String() string { block.header.timestamp, len(block.transactions), byteutils.Hash(block.header.consensusRoot.Proposer).Base58(), - rand, + random, ) } diff --git a/core/block_pool.go b/core/block_pool.go index e282f0c0f..f34f9cb21 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -537,7 +537,7 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( for _, h := range hashes { data = append(data, []byte(h)...) } - index, err := verifier.ProofToHash(data, lb.block.header.rand.VrfProof) + index, err := verifier.ProofToHash(data, lb.block.header.random.VrfProof) if err != nil { logging.VLog().WithFields(logrus.Fields{ "err": err, @@ -545,7 +545,7 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( return nil, nil, err } - if !bytes.Equal(index[:], lb.block.header.rand.VrfHash) { + if !bytes.Equal(index[:], lb.block.header.random.VrfHash) { logging.VLog().WithFields(logrus.Fields{ "block": lb.block, }).Error("VRF proof failed.") diff --git a/core/blockchain.go b/core/blockchain.go index a81c40a0b..252855357 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -704,8 +704,8 @@ func (bc *BlockChain) SimulateTransactionExecution(tx *Transaction) (*SimulateRe sVrfHash, sVrfProof := make([]byte, 32), make([]byte, 129) _, _ = io.ReadFull(rand.Reader, sVrfHash) _, _ = io.ReadFull(rand.Reader, sVrfProof) - block.header.rand.VrfHash = sVrfHash - block.header.rand.VrfProof = sVrfProof + block.header.random.VrfHash = sVrfHash + block.header.random.VrfProof = sVrfProof defer block.RollBack() diff --git a/core/pb/block.pb.go b/core/pb/block.pb.go index 394045ca5..5911b588c 100644 --- a/core/pb/block.pb.go +++ b/core/pb/block.pb.go @@ -16,7 +16,7 @@ It has these top-level messages: NetBlocks NetBlock DownloadBlock - Rand + Random */ package corepb @@ -225,7 +225,7 @@ type BlockHeader struct { TxsRoot []byte `protobuf:"bytes,10,opt,name=txs_root,json=txsRoot,proto3" json:"txs_root,omitempty"` EventsRoot []byte `protobuf:"bytes,11,opt,name=events_root,json=eventsRoot,proto3" json:"events_root,omitempty"` ConsensusRoot *consensuspb.ConsensusRoot `protobuf:"bytes,12,opt,name=consensus_root,json=consensusRoot" json:"consensus_root,omitempty"` - Rand *Rand `protobuf:"bytes,13,opt,name=rand" json:"rand,omitempty"` + Random *Random `protobuf:"bytes,13,opt,name=random" json:"random,omitempty"` } func (m *BlockHeader) Reset() { *m = BlockHeader{} } @@ -310,9 +310,9 @@ func (m *BlockHeader) GetConsensusRoot() *consensuspb.ConsensusRoot { return nil } -func (m *BlockHeader) GetRand() *Rand { +func (m *BlockHeader) GetRandom() *Random { if m != nil { - return m.Rand + return m.Random } return nil } @@ -445,24 +445,24 @@ func (m *DownloadBlock) GetSign() []byte { return nil } -type Rand struct { +type Random struct { VrfHash []byte `protobuf:"bytes,1,opt,name=vrf_hash,json=vrfHash,proto3" json:"vrf_hash,omitempty"` VrfProof []byte `protobuf:"bytes,2,opt,name=vrf_proof,json=vrfProof,proto3" json:"vrf_proof,omitempty"` } -func (m *Rand) Reset() { *m = Rand{} } -func (m *Rand) String() string { return proto.CompactTextString(m) } -func (*Rand) ProtoMessage() {} -func (*Rand) Descriptor() ([]byte, []int) { return fileDescriptorBlock, []int{8} } +func (m *Random) Reset() { *m = Random{} } +func (m *Random) String() string { return proto.CompactTextString(m) } +func (*Random) ProtoMessage() {} +func (*Random) Descriptor() ([]byte, []int) { return fileDescriptorBlock, []int{8} } -func (m *Rand) GetVrfHash() []byte { +func (m *Random) GetVrfHash() []byte { if m != nil { return m.VrfHash } return nil } -func (m *Rand) GetVrfProof() []byte { +func (m *Random) GetVrfProof() []byte { if m != nil { return m.VrfProof } @@ -478,58 +478,58 @@ func init() { proto.RegisterType((*NetBlocks)(nil), "corepb.NetBlocks") proto.RegisterType((*NetBlock)(nil), "corepb.NetBlock") proto.RegisterType((*DownloadBlock)(nil), "corepb.DownloadBlock") - proto.RegisterType((*Rand)(nil), "corepb.rand") + proto.RegisterType((*Random)(nil), "corepb.Random") } func init() { proto.RegisterFile("block.proto", fileDescriptorBlock) } var fileDescriptorBlock = []byte{ - // 744 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6a, 0xdb, 0x4a, - 0x10, 0x46, 0xb6, 0xfc, 0x37, 0xb2, 0x43, 0xd8, 0x13, 0x0e, 0x3a, 0x3e, 0x2d, 0x31, 0x2a, 0x05, - 0xd3, 0x52, 0x1b, 0xd2, 0x42, 0x7a, 0x55, 0x48, 0x9b, 0x8b, 0xb4, 0x94, 0x12, 0x96, 0xde, 0x14, - 0x0a, 0x66, 0x25, 0xad, 0x25, 0x51, 0x79, 0x57, 0xec, 0xae, 0xdd, 0xe4, 0xba, 0x4f, 0xd0, 0xf7, - 0xe8, 0x4d, 0xdf, 0xb0, 0xec, 0xac, 0x6c, 0xcb, 0x69, 0xa0, 0xf4, 0x4a, 0xfb, 0xcd, 0xb7, 0x33, - 0x9a, 0x99, 0x6f, 0x66, 0x21, 0x88, 0x4b, 0x99, 0x7c, 0x99, 0x55, 0x4a, 0x1a, 0x49, 0xba, 0x89, - 0x54, 0xbc, 0x8a, 0xc7, 0xe7, 0x59, 0x61, 0xf2, 0x75, 0x3c, 0x4b, 0xe4, 0x6a, 0x2e, 0x78, 0xbc, - 0x2e, 0x99, 0x2e, 0xe4, 0x3c, 0x93, 0xcf, 0x6a, 0x30, 0x4f, 0xe4, 0x6a, 0x25, 0xc5, 0x3c, 0x65, - 0xd9, 0xbc, 0x8a, 0xed, 0xc7, 0x05, 0x18, 0xbf, 0xfc, 0xb3, 0xa3, 0xd0, 0x5c, 0xe8, 0xb5, 0xb6, - 0x7e, 0xda, 0x30, 0xc3, 0x9d, 0x67, 0xf4, 0xdd, 0x83, 0xde, 0x45, 0x92, 0xc8, 0xb5, 0x30, 0x24, - 0x84, 0x1e, 0x4b, 0x53, 0xc5, 0xb5, 0x0e, 0xbd, 0x89, 0x37, 0x1d, 0xd2, 0x2d, 0xb4, 0x4c, 0xcc, - 0x4a, 0x26, 0x12, 0x1e, 0xb6, 0x1c, 0x53, 0x43, 0x72, 0x02, 0x1d, 0x21, 0xad, 0xbd, 0x3d, 0xf1, - 0xa6, 0x3e, 0x75, 0x80, 0xfc, 0x0f, 0x83, 0x0d, 0x53, 0x7a, 0x91, 0x33, 0x9d, 0x87, 0x3e, 0x7a, - 0xf4, 0xad, 0xe1, 0x8a, 0xe9, 0x9c, 0x9c, 0x42, 0x10, 0x17, 0xca, 0xe4, 0x8b, 0xaa, 0x64, 0x09, - 0x0f, 0x3b, 0x48, 0x03, 0x9a, 0xae, 0xad, 0x25, 0x7a, 0x01, 0xfe, 0x25, 0x33, 0x8c, 0x10, 0xf0, - 0xcd, 0x6d, 0xc5, 0x31, 0x99, 0x01, 0xc5, 0xb3, 0xcd, 0xa4, 0x62, 0xb7, 0xa5, 0x64, 0xe9, 0x36, - 0x93, 0x1a, 0x46, 0x3f, 0x5a, 0x10, 0x7c, 0x54, 0x4c, 0x68, 0x96, 0x98, 0x42, 0x0a, 0xeb, 0x8d, - 0xbf, 0x77, 0xa5, 0xe0, 0xd9, 0xda, 0x96, 0x4a, 0xae, 0x6a, 0x57, 0x3c, 0x93, 0x23, 0x68, 0x19, - 0x89, 0xe9, 0x0f, 0x69, 0xcb, 0x48, 0x5b, 0xd1, 0x86, 0x95, 0x6b, 0x5e, 0xe7, 0xed, 0xc0, 0xbe, - 0xce, 0x4e, 0xb3, 0xce, 0x07, 0x30, 0x30, 0xc5, 0x8a, 0x6b, 0xc3, 0x56, 0x55, 0xd8, 0x9d, 0x78, - 0xd3, 0x36, 0xdd, 0x1b, 0xc8, 0x04, 0xfc, 0x94, 0x19, 0x16, 0xf6, 0x26, 0xde, 0x34, 0x38, 0x1b, - 0xce, 0x9c, 0xca, 0x33, 0x5b, 0x1b, 0x45, 0x86, 0xfc, 0x07, 0xfd, 0x24, 0x67, 0x85, 0x58, 0x14, - 0x69, 0xd8, 0x9f, 0x78, 0xd3, 0x11, 0xed, 0x21, 0x7e, 0x9b, 0xda, 0x16, 0x66, 0x4c, 0x2f, 0x2a, - 0x55, 0x24, 0x3c, 0x1c, 0xb8, 0x16, 0x66, 0x4c, 0x5f, 0x5b, 0xbc, 0x25, 0xcb, 0x62, 0x55, 0x98, - 0x10, 0x76, 0xe4, 0x7b, 0x8b, 0xc9, 0x31, 0xb4, 0x59, 0x99, 0x85, 0x01, 0xc6, 0xb3, 0x47, 0x5b, - 0xb6, 0x2e, 0x32, 0x11, 0x0e, 0x5d, 0xd9, 0xf6, 0x1c, 0x7d, 0x6b, 0x43, 0xf0, 0xda, 0xce, 0xe0, - 0x15, 0x67, 0x29, 0x57, 0xf7, 0xb6, 0xeb, 0x14, 0x82, 0x8a, 0x29, 0x2e, 0x8c, 0x13, 0xd2, 0x75, - 0x0d, 0x9c, 0x09, 0xa5, 0x1c, 0x43, 0x3f, 0x91, 0x85, 0x88, 0x99, 0xde, 0xb6, 0x6b, 0x87, 0x0f, - 0x7b, 0xd3, 0xb9, 0xdb, 0x9b, 0x66, 0xe5, 0xdd, 0xc3, 0xca, 0xeb, 0xfc, 0x7b, 0xbf, 0xe7, 0xdf, - 0xdf, 0xe7, 0x4f, 0x1e, 0x02, 0xe0, 0x1c, 0x2f, 0x94, 0x94, 0xa6, 0x6e, 0xd0, 0x00, 0x2d, 0x54, - 0x4a, 0x63, 0xe3, 0x9b, 0x1b, 0xed, 0x48, 0xd7, 0xa0, 0x9e, 0xb9, 0xd1, 0x48, 0x9d, 0x42, 0xc0, - 0x37, 0x5c, 0x98, 0x9a, 0x0d, 0x5c, 0x55, 0xce, 0x84, 0x17, 0x2e, 0xe0, 0x68, 0xb7, 0x2f, 0xee, - 0xce, 0x10, 0x15, 0x1c, 0xcf, 0x76, 0xe6, 0x2a, 0x9e, 0xbd, 0xd9, 0x9e, 0xad, 0x0f, 0x1d, 0x25, - 0x4d, 0x68, 0xa5, 0x57, 0x4c, 0xa4, 0xe1, 0xe8, 0x50, 0x7a, 0x6b, 0xa3, 0xc8, 0xbc, 0xf3, 0xfb, - 0xed, 0x63, 0x3f, 0xfa, 0xe9, 0x41, 0x07, 0x55, 0x20, 0x4f, 0xa1, 0x9b, 0xa3, 0x12, 0xa8, 0x40, - 0x70, 0xf6, 0xcf, 0xd6, 0xa7, 0x21, 0x12, 0xad, 0xaf, 0x90, 0x73, 0x18, 0x9a, 0xfd, 0xa8, 0xeb, - 0xb0, 0x35, 0x69, 0x37, 0x5d, 0x1a, 0x6b, 0x40, 0x0f, 0x2e, 0x92, 0x27, 0x00, 0x29, 0xaf, 0xb8, - 0x48, 0xb9, 0x48, 0x6e, 0x71, 0xe8, 0x83, 0x33, 0x98, 0xa5, 0x2c, 0xc3, 0xb9, 0xcc, 0x68, 0x83, - 0x25, 0xff, 0xda, 0x8c, 0x8a, 0x2c, 0x37, 0x28, 0xad, 0x4f, 0x6b, 0x14, 0x7d, 0x86, 0xc1, 0x07, - 0x6e, 0x30, 0x2d, 0xbd, 0xdb, 0xa8, 0x7a, 0x47, 0x71, 0xa3, 0x4e, 0xa0, 0x13, 0x33, 0x93, 0xb8, - 0x81, 0xf1, 0xa9, 0x03, 0xe4, 0x31, 0x74, 0xf1, 0xcd, 0xd3, 0x61, 0x1b, 0xb3, 0x1d, 0x1d, 0x14, - 0x48, 0x6b, 0x32, 0xfa, 0x04, 0xfd, 0x6d, 0xf4, 0xbf, 0x08, 0xfe, 0x08, 0x3a, 0xe8, 0x5f, 0x97, - 0x74, 0x27, 0xb6, 0xe3, 0xa2, 0x73, 0x18, 0x5d, 0xca, 0xaf, 0xc2, 0xbe, 0x16, 0xbb, 0xf8, 0xf7, - 0x3d, 0x11, 0x38, 0x6b, 0xad, 0xc6, 0xae, 0xbc, 0x72, 0x6a, 0xda, 0xa1, 0xda, 0xa8, 0xe5, 0xa2, - 0xe1, 0xd3, 0xdb, 0xa8, 0x25, 0x6e, 0x82, 0x7d, 0xf1, 0xd4, 0x72, 0x51, 0x29, 0x29, 0x97, 0xb5, - 0xaf, 0xbd, 0x7b, 0x6d, 0x71, 0xdc, 0xc5, 0xb7, 0xf6, 0xf9, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x7c, 0xd8, 0x7b, 0x5f, 0xf5, 0x05, 0x00, 0x00, + // 749 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x5f, 0x8b, 0xeb, 0x44, + 0x14, 0x27, 0x6d, 0x9a, 0xb6, 0x27, 0xed, 0xb2, 0x8c, 0x8b, 0xc4, 0xaa, 0x6c, 0x89, 0x28, 0x45, + 0xb1, 0x85, 0x55, 0x58, 0x1f, 0x5d, 0xdd, 0x87, 0x55, 0x44, 0x96, 0xc1, 0x17, 0x41, 0x28, 0x93, + 0x64, 0x9a, 0x04, 0x93, 0x99, 0x30, 0x33, 0xad, 0xbb, 0x1f, 0xc1, 0x47, 0xbf, 0x87, 0x2f, 0xf7, + 0x1b, 0x5e, 0xe6, 0x4c, 0xd2, 0xa6, 0x7b, 0x17, 0x2e, 0xf7, 0x29, 0xf3, 0x3b, 0xbf, 0xf9, 0x9d, + 0x9c, 0xbf, 0x03, 0x61, 0x52, 0xc9, 0xf4, 0xef, 0x75, 0xa3, 0xa4, 0x91, 0x24, 0x48, 0xa5, 0xe2, + 0x4d, 0xb2, 0xb8, 0xcd, 0x4b, 0x53, 0xec, 0x93, 0x75, 0x2a, 0xeb, 0x8d, 0xe0, 0xc9, 0xbe, 0x62, + 0xba, 0x94, 0x9b, 0x5c, 0x7e, 0xdb, 0x82, 0x4d, 0x2a, 0xeb, 0x5a, 0x8a, 0x4d, 0xc6, 0xf2, 0x4d, + 0x93, 0xd8, 0x8f, 0x73, 0xb0, 0xf8, 0xe1, 0xfd, 0x42, 0xa1, 0xb9, 0xd0, 0x7b, 0x6d, 0x75, 0xda, + 0x30, 0xc3, 0x9d, 0x32, 0xfe, 0xcf, 0x83, 0xf1, 0x5d, 0x9a, 0xca, 0xbd, 0x30, 0x24, 0x82, 0x31, + 0xcb, 0x32, 0xc5, 0xb5, 0x8e, 0xbc, 0xa5, 0xb7, 0x9a, 0xd1, 0x0e, 0x5a, 0x26, 0x61, 0x15, 0x13, + 0x29, 0x8f, 0x06, 0x8e, 0x69, 0x21, 0xb9, 0x82, 0x91, 0x90, 0xd6, 0x3e, 0x5c, 0x7a, 0x2b, 0x9f, + 0x3a, 0x40, 0x3e, 0x85, 0xe9, 0x81, 0x29, 0xbd, 0x2d, 0x98, 0x2e, 0x22, 0x1f, 0x15, 0x13, 0x6b, + 0x78, 0x60, 0xba, 0x20, 0xd7, 0x10, 0x26, 0xa5, 0x32, 0xc5, 0xb6, 0xa9, 0x58, 0xca, 0xa3, 0x11, + 0xd2, 0x80, 0xa6, 0x47, 0x6b, 0x89, 0xbf, 0x07, 0xff, 0x9e, 0x19, 0x46, 0x08, 0xf8, 0xe6, 0xb9, + 0xe1, 0x18, 0xcc, 0x94, 0xe2, 0xd9, 0x46, 0xd2, 0xb0, 0xe7, 0x4a, 0xb2, 0xac, 0x8b, 0xa4, 0x85, + 0xf1, 0xff, 0x03, 0x08, 0xff, 0x50, 0x4c, 0x68, 0x96, 0x9a, 0x52, 0x0a, 0xab, 0xc6, 0xdf, 0xbb, + 0x54, 0xf0, 0x6c, 0x6d, 0x3b, 0x25, 0xeb, 0x56, 0x8a, 0x67, 0x72, 0x01, 0x03, 0x23, 0x31, 0xfc, + 0x19, 0x1d, 0x18, 0x69, 0x33, 0x3a, 0xb0, 0x6a, 0xcf, 0xdb, 0xb8, 0x1d, 0x38, 0xe5, 0x39, 0xea, + 0xe7, 0xf9, 0x19, 0x4c, 0x4d, 0x59, 0x73, 0x6d, 0x58, 0xdd, 0x44, 0xc1, 0xd2, 0x5b, 0x0d, 0xe9, + 0xc9, 0x40, 0x96, 0xe0, 0x67, 0xcc, 0xb0, 0x68, 0xbc, 0xf4, 0x56, 0xe1, 0xcd, 0x6c, 0xed, 0xba, + 0xbc, 0xb6, 0xb9, 0x51, 0x64, 0xc8, 0x27, 0x30, 0x49, 0x0b, 0x56, 0x8a, 0x6d, 0x99, 0x45, 0x93, + 0xa5, 0xb7, 0x9a, 0xd3, 0x31, 0xe2, 0x5f, 0x32, 0x5b, 0xc2, 0x9c, 0xe9, 0x6d, 0xa3, 0xca, 0x94, + 0x47, 0x53, 0x57, 0xc2, 0x9c, 0xe9, 0x47, 0x8b, 0x3b, 0xb2, 0x2a, 0xeb, 0xd2, 0x44, 0x70, 0x24, + 0x7f, 0xb3, 0x98, 0x5c, 0xc2, 0x90, 0x55, 0x79, 0x14, 0xa2, 0x3f, 0x7b, 0xb4, 0x69, 0xeb, 0x32, + 0x17, 0xd1, 0xcc, 0xa5, 0x6d, 0xcf, 0xf1, 0xbf, 0x43, 0x08, 0x7f, 0xb2, 0x33, 0xf8, 0xc0, 0x59, + 0xc6, 0xd5, 0xab, 0xe5, 0xba, 0x86, 0xb0, 0x61, 0x8a, 0x0b, 0xe3, 0x1a, 0xe9, 0xaa, 0x06, 0xce, + 0x84, 0xad, 0x5c, 0xc0, 0x24, 0x95, 0xa5, 0x48, 0x98, 0xee, 0xca, 0x75, 0xc4, 0xe7, 0xb5, 0x19, + 0xbd, 0xac, 0x4d, 0x3f, 0xf3, 0xe0, 0x3c, 0xf3, 0x36, 0xfe, 0xf1, 0xbb, 0xf1, 0x4f, 0x4e, 0xf1, + 0x93, 0xcf, 0x01, 0x70, 0x8e, 0xb7, 0x4a, 0x4a, 0xd3, 0x16, 0x68, 0x8a, 0x16, 0x2a, 0xa5, 0xb1, + 0xfe, 0xcd, 0x93, 0x76, 0xa4, 0x2b, 0xd0, 0xd8, 0x3c, 0x69, 0xa4, 0xae, 0x21, 0xe4, 0x07, 0x2e, + 0x4c, 0xcb, 0x86, 0x2e, 0x2b, 0x67, 0xc2, 0x0b, 0x77, 0x70, 0x71, 0xdc, 0x17, 0x77, 0x67, 0x86, + 0x1d, 0x5c, 0xac, 0x8f, 0xe6, 0x26, 0x59, 0xff, 0xdc, 0x9d, 0xad, 0x86, 0xce, 0xd3, 0x3e, 0x24, + 0x5f, 0x41, 0xa0, 0x98, 0xc8, 0x64, 0x1d, 0xcd, 0x51, 0x7a, 0xd1, 0x35, 0x9f, 0xa2, 0x95, 0xb6, + 0xec, 0xaf, 0xfe, 0x64, 0x78, 0xe9, 0xc7, 0x6f, 0x3c, 0x18, 0x61, 0x2f, 0xc8, 0x37, 0x10, 0x14, + 0xd8, 0x0f, 0xec, 0x43, 0x78, 0xf3, 0x51, 0xa7, 0xeb, 0xb5, 0x8a, 0xb6, 0x57, 0xc8, 0x2d, 0xcc, + 0xcc, 0x69, 0xe0, 0x75, 0x34, 0x58, 0x0e, 0xfb, 0x92, 0xde, 0x32, 0xd0, 0xb3, 0x8b, 0xe4, 0x6b, + 0x80, 0x8c, 0x37, 0x5c, 0x64, 0x5c, 0xa4, 0xcf, 0x38, 0xfa, 0xe1, 0x0d, 0xac, 0x33, 0x96, 0xe3, + 0x74, 0xe6, 0xb4, 0xc7, 0x92, 0x8f, 0x6d, 0x44, 0x65, 0x5e, 0x18, 0x6c, 0xb0, 0x4f, 0x5b, 0x14, + 0xff, 0x05, 0xd3, 0xdf, 0xb9, 0xc1, 0xb0, 0xf4, 0x71, 0xaf, 0xda, 0x4d, 0xc5, 0xbd, 0xba, 0x82, + 0x51, 0xc2, 0x4c, 0xea, 0xc6, 0xc6, 0xa7, 0x0e, 0x90, 0x2f, 0x21, 0xc0, 0x97, 0x4f, 0x47, 0x43, + 0x8c, 0x76, 0x7e, 0x96, 0x20, 0x6d, 0xc9, 0xf8, 0x4f, 0x98, 0x74, 0xde, 0x3f, 0xc0, 0xf9, 0x17, + 0x30, 0x42, 0x7d, 0x9b, 0xd2, 0x0b, 0xdf, 0x8e, 0x8b, 0x6f, 0x61, 0x7e, 0x2f, 0xff, 0x11, 0xf6, + 0xcd, 0x38, 0xfa, 0x7f, 0xed, 0xa1, 0xc0, 0x89, 0x1b, 0xf4, 0x36, 0xe6, 0x47, 0x08, 0x5c, 0xf7, + 0xec, 0x70, 0x1d, 0xd4, 0x6e, 0xdb, 0x53, 0x8d, 0x0f, 0x6a, 0x87, 0x1b, 0x61, 0x5f, 0x3e, 0xb5, + 0xdb, 0x36, 0x4a, 0xca, 0x5d, 0xab, 0xb6, 0x77, 0x1f, 0x2d, 0x4e, 0x02, 0x7c, 0x73, 0xbf, 0x7b, + 0x1b, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xa5, 0xbd, 0xd2, 0xfd, 0x05, 0x00, 0x00, } diff --git a/core/pb/block.proto b/core/pb/block.proto index 9c3bc29e2..d7b5b00fd 100644 --- a/core/pb/block.proto +++ b/core/pb/block.proto @@ -64,7 +64,7 @@ message BlockHeader { bytes txs_root = 10; bytes events_root = 11; consensuspb.ConsensusRoot consensus_root = 12; - rand rand = 13; + Random random = 13; } message Block { @@ -92,7 +92,7 @@ message DownloadBlock { bytes sign = 2; } -message rand { +message Random { bytes vrf_hash = 1; bytes vrf_proof = 2; } \ No newline at end of file diff --git a/core/types.go b/core/types.go index d0d843229..32689c06b 100644 --- a/core/types.go +++ b/core/types.go @@ -96,7 +96,7 @@ var ( ErrDuplicatedBlock = errors.New("duplicated block") ErrDoubleBlockMinted = errors.New("double block minted") ErrVRFProofFailed = errors.New("VRF proof failed") - ErrInvalidBlockRand = errors.New("invalid block rand") + ErrInvalidBlockRandom = errors.New("invalid block random") ErrInvalidChainID = errors.New("invalid transaction chainID") ErrInvalidTransactionSigner = errors.New("invalid transaction signer") diff --git a/nebtestkit/cases/contract/contract.feature.random.test.js b/nebtestkit/cases/contract/contract.feature.random.test.js index 93881dd22..dad9c35eb 100644 --- a/nebtestkit/cases/contract/contract.feature.random.test.js +++ b/nebtestkit/cases/contract/contract.feature.random.test.js @@ -285,7 +285,15 @@ function runTest(testInput, testExpect, done) { } }); }).catch(function (err) { - console.log("send tx err"); + if (err.error && err.error.error && testExpect.eventErr) { + try { + expect(err.error.error).to.equal(testExpect.eventErr) + done(); + } catch (err) { + done(err); + } + return; + } done(err); }); } @@ -314,7 +322,7 @@ var caseGroup = { canExcuteTx: false, toBalanceChange: "0", status: 0, - equalBlockTime: true + eventErr: "Call: Error: random seed must be a string" } }, { From a697250f926c631cc6dfb5ac85e21f1fdbf1602f Mon Sep 17 00:00:00 2001 From: Leon Date: Sun, 29 Apr 2018 03:00:35 +0800 Subject: [PATCH 41/69] net: fix bug by array deep copy. --- net/stream.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/stream.go b/net/stream.go index 99dd2fd45..3ac4d5050 100644 --- a/net/stream.go +++ b/net/stream.go @@ -279,11 +279,14 @@ func (s *Stream) WriteProtoMessage(messageName string, pb proto.Message, reserve // WriteMessage write raw msg in the stream func (s *Stream) WriteMessage(messageName string, data []byte, reservedClientFlag byte) error { // hello and ok messages come with the client flag bit. + var reserved = make([]byte, len(s.reservedFlag)) + copy(reserved, s.reservedFlag) + if reservedClientFlag == ReservedCompressionClientFlag { - s.reservedFlag[2] = s.reservedFlag[2] | reservedClientFlag + reserved[2] = s.reservedFlag[2] | reservedClientFlag } - message, err := NewNebMessage(s.node.config.ChainID, s.reservedFlag, CurrentVersion, messageName, data) + message, err := NewNebMessage(s.node.config.ChainID, reserved, CurrentVersion, messageName, data) if err != nil { return err } @@ -470,6 +473,10 @@ func (s *Stream) handleMessage(message *NebMessage) error { default: data, err := s.getData(message) if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + "messageName": message.MessageName(), + }).Error("get data occurs error.") return err } s.node.netService.PutMessage(NewBaseMessage(message.MessageName(), s.pid.Pretty(), data)) From 7bdcc9c44aecfe7dfbe6a3bf912c6f22e6b42eea Mon Sep 17 00:00:00 2001 From: Leon Date: Sun, 29 Apr 2018 03:04:41 +0800 Subject: [PATCH 42/69] net: adjust log level in stream.go --- net/stream.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/stream.go b/net/stream.go index 3ac4d5050..83b35420e 100644 --- a/net/stream.go +++ b/net/stream.go @@ -476,7 +476,7 @@ func (s *Stream) handleMessage(message *NebMessage) error { logging.VLog().WithFields(logrus.Fields{ "err": err, "messageName": message.MessageName(), - }).Error("get data occurs error.") + }).Info("Handle message data occurs error.") return err } s.node.netService.PutMessage(NewBaseMessage(message.MessageName(), s.pid.Pretty(), data)) From 13d9358f00b16a7e8512f06e847393ecc8821b36 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 00:20:42 +0800 Subject: [PATCH 43/69] add log info --- consensus/dpos/dpos.go | 1 + core/block.go | 1 + 2 files changed, 2 insertions(+) diff --git a/consensus/dpos/dpos.go b/consensus/dpos/dpos.go index f821ce689..c08305f63 100644 --- a/consensus/dpos/dpos.go +++ b/consensus/dpos/dpos.go @@ -380,6 +380,7 @@ func (dpos *Dpos) VerifyBlock(block *core.Block) error { // check block random if block.Height() >= core.RandomAvailableCompatibleHeight && !block.HasBlockRand() { logging.VLog().WithFields(logrus.Fields{ + "blockHeight": block.Height(), "compatibleHeight": core.RandomAvailableCompatibleHeight, }).Debug("No random found in block header.") return core.ErrInvalidBlockRandom diff --git a/core/block.go b/core/block.go index cef74804d..76b82e5d3 100644 --- a/core/block.go +++ b/core/block.go @@ -201,6 +201,7 @@ func (block *Block) FromProto(msg proto.Message) error { } if msg.Height >= RandomAvailableCompatibleHeight && !block.HasBlockRand() { logging.VLog().WithFields(logrus.Fields{ + "blockHeight": msg.Height, "compatibleHeight": RandomAvailableCompatibleHeight, }).Debug("No random found in block header.") return ErrInvalidProtoToBlockHeader From 455419b5c4bc5796a2322ec6b4a1d012373702a2 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 07:14:19 +0800 Subject: [PATCH 44/69] random: bugfix --- core/block_pool.go | 178 ++++++++++++++++++++++++++++++++------------- core/blockchain.go | 6 +- core/types.go | 1 + 3 files changed, 128 insertions(+), 57 deletions(-) diff --git a/core/block_pool.go b/core/block_pool.go index f34f9cb21..0a44a5053 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -23,12 +23,11 @@ import ( "sync" "time" - "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" - "github.com/gogo/protobuf/proto" lru "github.com/hashicorp/golang-lru" "github.com/nebulasio/go-nebulas/core/pb" "github.com/nebulasio/go-nebulas/crypto" + "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" "github.com/nebulasio/go-nebulas/net" "github.com/nebulasio/go-nebulas/util/byteutils" @@ -451,6 +450,13 @@ func (pool *BlockPool) push(sender string, block *Block) error { return err } + // VRF verify + allBlocks, tailBlocks = pool.verifyVrfOfTails(parentBlock, allBlocks, tailBlocks) + if len(tailBlocks) == 0 { + cache.Remove(lb.hash.Hex()) + return nil + } + if err := bc.putVerifiedNewBlocks(parentBlock, allBlocks, tailBlocks); err != nil { cache.Remove(lb.hash.Hex()) return err @@ -465,6 +471,124 @@ func (pool *BlockPool) push(sender string, block *Block) error { return pool.bc.ConsensusHandler().ForkChoice() } +func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []*Block) (newAll, newTails []*Block) { + + allBlocksMap := make(map[string]*Block) + for _, b := range allBlocks { + allBlocksMap[b.Hash().String()] = b + } + + for _, tail := range tailBlocks { + + subAll, valid := pool.isValidSubChain(parent, tail, allBlocksMap) + if !valid { + logging.VLog().WithFields(logrus.Fields{ + "parent": parent.String(), + "tail": tail.String(), + }).Error("Discard an invalid sub chain.") + continue + } + newAll = append(newAll, subAll...) + newTails = append(newTails, tail) + } + return +} + +func (pool *BlockPool) isValidSubChain(parentOnChain, tail *Block, allBlocksMap map[string]*Block) (allBlocks []*Block, valid bool) { + + for parentOnChain.Height() < tail.Height() { + + tph := tail.ParentHash() + allBlocks = append(allBlocks, tail) + + if tail.Height() < RandomAvailableCompatibleHeight { + var ok bool + tail, ok = allBlocksMap[tph.String()] + if !ok { + tail = pool.bc.GetBlock(tph) + } + continue + } + + hashes := make([]byteutils.Hash, 0) + + for i := 0; i < VRFInputParentHashNumber; i++ { + + b, ok := allBlocksMap[tph.String()] + if !ok { + b = pool.bc.GetBlock(tph) + } + if b == nil { + break + } + hashes = append(hashes, tph) + tph = b.ParentHash() + } + if len(hashes) != VRFInputParentHashNumber { + logging.VLog().WithFields(logrus.Fields{ + "tail": tail.String(), + }).Error("Failed to get enough parent block hash for VRF.") + return nil, false + } + + if err := pool.vrfProof(tail, hashes); err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to VRF proof.") + return nil, false + } + var ok bool + tail, ok = allBlocksMap[tph.String()] + if !ok { + tail = pool.bc.GetBlock(tph) + } + } + return allBlocks, true +} + +func (pool *BlockPool) vrfProof(block *Block, pHashes []byteutils.Hash) error { + signature, err := crypto.NewSignature(block.Alg()) + if err != nil { + return err + } + pub, err := signature.RecoverPublic(block.Hash(), block.Signature()) + if err != nil { + return err + } + pubdata, err := pub.Encoded() + if err != nil { + return err + } + + verifier, err := secp256k1VRF.NewVRFVerifierFromRawKey(pubdata) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to new VRF verifier.") + return err + } + + var data []byte + for _, h := range pHashes { + data = append(data, []byte(h)...) + } + index, err := verifier.ProofToHash(data, block.header.random.VrfProof) + if err != nil { + logging.VLog().WithFields(logrus.Fields{ + "err": err, + }).Error("Failed to calculate VRF proof.") + return err + } + + if !bytes.Equal(index[:], block.header.random.VrfHash) { + logging.VLog().WithFields(logrus.Fields{ + "block": block, + }).Error("VRF proof failed.") + return ErrVRFProofFailed + } + return nil +} + func (pool *BlockPool) setBlockChain(bc *BlockChain) { pool.bc = bc } @@ -503,56 +627,6 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( return nil, nil, err } - // VRF verify - if lb.block.Height() >= RandomAvailableCompatibleHeight { - hashes, err := lb.chain.GetRecentNBlockHashBeforeInclusive(parentBlock.Hash(), VRFInputParentHashNumber) - if err != nil { - logging.VLog().WithFields(logrus.Fields{ - "err": err, - }).Error("Failed to get parent block hash for verifying VRF.") - return nil, nil, err - } - signature, err := crypto.NewSignature(lb.block.Alg()) - if err != nil { - return nil, nil, err - } - pub, err := signature.RecoverPublic(lb.block.Hash(), lb.block.Signature()) - if err != nil { - return nil, nil, err - } - pubdata, err := pub.Encoded() - if err != nil { - return nil, nil, err - } - - verifier, err := secp256k1VRF.NewVRFVerifierFromRawKey(pubdata) - if err != nil { - logging.VLog().WithFields(logrus.Fields{ - "err": err, - }).Error("Failed to new VRF verifier.") - return nil, nil, err - } - - var data []byte - for _, h := range hashes { - data = append(data, []byte(h)...) - } - index, err := verifier.ProofToHash(data, lb.block.header.random.VrfProof) - if err != nil { - logging.VLog().WithFields(logrus.Fields{ - "err": err, - }).Error("Failed to calculate VRF proof.") - return nil, nil, err - } - - if !bytes.Equal(index[:], lb.block.header.random.VrfHash) { - logging.VLog().WithFields(logrus.Fields{ - "block": lb.block, - }).Error("VRF proof failed.") - return nil, nil, ErrVRFProofFailed - } - } - logging.VLog().WithFields(logrus.Fields{ "block": lb.block, }).Info("Block Verified.") diff --git a/core/blockchain.go b/core/blockchain.go index 252855357..50ed0be74 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -466,7 +466,7 @@ func (bc *BlockChain) GetBlockOnCanonicalChainByHash(blockHash byteutils.Hash) * return blockByHeight } -// GetRecentNBlockHashBeforeInclusive read hashes of 'N' parent blocks before hash(inclusive) as VRF input. +// GetRecentNBlockHashBeforeInclusive read hashes of 'N' on-chain parent blocks before hash(inclusive) as VRF input. // hashes order: from back to front func (bc *BlockChain) GetRecentNBlockHashBeforeInclusive(hash byteutils.Hash, n int) (hashes []byteutils.Hash, err error) { if n == 0 || hash == nil { @@ -478,10 +478,6 @@ func (bc *BlockChain) GetRecentNBlockHashBeforeInclusive(hash byteutils.Hash, n return nil, ErrNotBlockInCanonicalChain } hashes = append(hashes, hash) - // if i < n-1 && block.Height() == 1 { - // // if chain height is not enough, return current hashes - // return - // } hash = block.ParentHash() } return diff --git a/core/types.go b/core/types.go index 32689c06b..c5c64e338 100644 --- a/core/types.go +++ b/core/types.go @@ -80,6 +80,7 @@ var ( ErrCannotFindBlockAtGivenHeight = errors.New("cannot find a block at given height which is less than tail block's height") ErrInvalidBlockCannotFindParentInLocalAndTryDownload = errors.New("invalid block received, download its parent from others") ErrInvalidBlockCannotFindParentInLocalAndTrySync = errors.New("invalid block received, sync its parent from others") + ErrBlockNotFound = errors.New("block not found in blockchain cache nor chain") ErrInvalidConfigChainID = errors.New("invalid chainID, genesis chainID not equal to chainID in config") ErrCannotLoadGenesisConf = errors.New("cannot load genesis conf") From b703461a5e3f96a6bb564d27b6775a3715b3ecf7 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 16:08:48 +0800 Subject: [PATCH 45/69] random: add log --- core/block_pool.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/core/block_pool.go b/core/block_pool.go index 0a44a5053..43f720e72 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -451,13 +451,13 @@ func (pool *BlockPool) push(sender string, block *Block) error { } // VRF verify - allBlocks, tailBlocks = pool.verifyVrfOfTails(parentBlock, allBlocks, tailBlocks) - if len(tailBlocks) == 0 { + newAllBlocks, newTailBlocks := pool.verifyVrfOfTails(parentBlock, allBlocks, tailBlocks) + if len(newTailBlocks) == 0 { cache.Remove(lb.hash.Hex()) return nil } - if err := bc.putVerifiedNewBlocks(parentBlock, allBlocks, tailBlocks); err != nil { + if err := bc.putVerifiedNewBlocks(parentBlock, newAllBlocks, newTailBlocks); err != nil { cache.Remove(lb.hash.Hex()) return err } @@ -488,6 +488,13 @@ func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []* }).Error("Discard an invalid sub chain.") continue } + logging.VLog().WithFields(logrus.Fields{ + "newAll": newAll, + "newTails": newTails, + "subAll": subAll, + "valid": valid, + "tail": tail, + }).Error("check tail===========.") newAll = append(newAll, subAll...) newTails = append(newTails, tail) } From 9d6611cfcce8c380ea8cf50a3942c1e2b98bc2bc Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 16:20:12 +0800 Subject: [PATCH 46/69] random: add log --- core/block_pool.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/block_pool.go b/core/block_pool.go index 43f720e72..ba89d3709 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -457,11 +457,18 @@ func (pool *BlockPool) push(sender string, block *Block) error { return nil } + logging.VLog().WithFields(logrus.Fields{ + "newAllBlocks": newAllBlocks, + "newTailBlocks": newTailBlocks, + }).Error("new tail===========.") + if err := bc.putVerifiedNewBlocks(parentBlock, newAllBlocks, newTailBlocks); err != nil { cache.Remove(lb.hash.Hex()) return err } - + logging.VLog().WithFields(logrus.Fields{ + "parentBlock": parentBlock, + }).Error("parentBlock===========.") // remove allBlocks from cache. for _, v := range allBlocks { cache.Remove(v.Hash().Hex()) @@ -480,6 +487,10 @@ func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []* for _, tail := range tailBlocks { + logging.VLog().WithFields(logrus.Fields{ + "tail": tail, + }).Error("current tail===========.") + subAll, valid := pool.isValidSubChain(parent, tail, allBlocksMap) if !valid { logging.VLog().WithFields(logrus.Fields{ From 687de8b62016bc4405777de8747e86e8b21d9df8 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 19:06:55 +0800 Subject: [PATCH 47/69] random: add log --- core/block_pool.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/core/block_pool.go b/core/block_pool.go index ba89d3709..00ca2820d 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -460,7 +460,7 @@ func (pool *BlockPool) push(sender string, block *Block) error { logging.VLog().WithFields(logrus.Fields{ "newAllBlocks": newAllBlocks, "newTailBlocks": newTailBlocks, - }).Error("new tail===========.") + }).Error("new tail===========.5") if err := bc.putVerifiedNewBlocks(parentBlock, newAllBlocks, newTailBlocks); err != nil { cache.Remove(lb.hash.Hex()) @@ -468,7 +468,7 @@ func (pool *BlockPool) push(sender string, block *Block) error { } logging.VLog().WithFields(logrus.Fields{ "parentBlock": parentBlock, - }).Error("parentBlock===========.") + }).Error("parentBlock===========.4") // remove allBlocks from cache. for _, v := range allBlocks { cache.Remove(v.Hash().Hex()) @@ -479,7 +479,11 @@ func (pool *BlockPool) push(sender string, block *Block) error { } func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []*Block) (newAll, newTails []*Block) { - + defer func() { + if r := recover(); r != nil { + logging.VLog().WithFields(logrus.Fields{}).Error("current tail===========recover.", r) + } + }() allBlocksMap := make(map[string]*Block) for _, b := range allBlocks { allBlocksMap[b.Hash().String()] = b @@ -488,15 +492,17 @@ func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []* for _, tail := range tailBlocks { logging.VLog().WithFields(logrus.Fields{ - "tail": tail, - }).Error("current tail===========.") + "tail": tail, + "parent": parent, + "allBlocksMap": allBlocksMap, + }).Error("current tail===========1.") subAll, valid := pool.isValidSubChain(parent, tail, allBlocksMap) if !valid { logging.VLog().WithFields(logrus.Fields{ - "parent": parent.String(), - "tail": tail.String(), - }).Error("Discard an invalid sub chain.") + "parent": parent, + "tail": tail, + }).Error("Discard an invalid sub chain.3") continue } logging.VLog().WithFields(logrus.Fields{ @@ -505,7 +511,7 @@ func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []* "subAll": subAll, "valid": valid, "tail": tail, - }).Error("check tail===========.") + }).Error("check tail===========2.") newAll = append(newAll, subAll...) newTails = append(newTails, tail) } From ea9082c8642579f3fc4ac18de9675d4f4f3b9dd1 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 20:09:24 +0800 Subject: [PATCH 48/69] random: add log --- core/block_pool.go | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/core/block_pool.go b/core/block_pool.go index 00ca2820d..6b9998fae 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -518,9 +518,9 @@ func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []* return } -func (pool *BlockPool) isValidSubChain(parentOnChain, tail *Block, allBlocksMap map[string]*Block) (allBlocks []*Block, valid bool) { +func (pool *BlockPool) isValidSubChain(stop, tail *Block, allBlocksMap map[string]*Block) (allBlocks []*Block, valid bool) { - for parentOnChain.Height() < tail.Height() { + for stop.Height() < tail.Height() { tph := tail.ParentHash() allBlocks = append(allBlocks, tail) @@ -531,30 +531,44 @@ func (pool *BlockPool) isValidSubChain(parentOnChain, tail *Block, allBlocksMap if !ok { tail = pool.bc.GetBlock(tph) } + logging.VLog().WithFields(logrus.Fields{ + "ok": ok, + "tail": tail, + "stop": stop, + "allBlocks": allBlocks, + }).Error("check ===========10.") continue } hashes := make([]byteutils.Hash, 0) - + p := tph for i := 0; i < VRFInputParentHashNumber; i++ { - b, ok := allBlocksMap[tph.String()] + b, ok := allBlocksMap[p.String()] if !ok { - b = pool.bc.GetBlock(tph) + b = pool.bc.GetBlock(p) } if b == nil { break } - hashes = append(hashes, tph) - tph = b.ParentHash() + hashes = append(hashes, p) + p = b.ParentHash() } if len(hashes) != VRFInputParentHashNumber { logging.VLog().WithFields(logrus.Fields{ - "tail": tail.String(), + "tail": tail, + "stop": stop, + "hashes": hashes, }).Error("Failed to get enough parent block hash for VRF.") return nil, false } + logging.VLog().WithFields(logrus.Fields{ + "tail": tail, + "stop": stop, + "hashes": hashes, + }).Error("================12") + if err := pool.vrfProof(tail, hashes); err != nil { logging.VLog().WithFields(logrus.Fields{ "err": err, @@ -566,6 +580,11 @@ func (pool *BlockPool) isValidSubChain(parentOnChain, tail *Block, allBlocksMap if !ok { tail = pool.bc.GetBlock(tph) } + logging.VLog().WithFields(logrus.Fields{ + "tail": tail, + "stop": stop, + "ok": ok, + }).Error("================13") } return allBlocks, true } From 5a247664101d53f3548be9268944f73123213e32 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 22:02:58 +0800 Subject: [PATCH 49/69] random: add log --- core/block_pool.go | 81 ++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/core/block_pool.go b/core/block_pool.go index 6b9998fae..343941497 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -451,24 +451,16 @@ func (pool *BlockPool) push(sender string, block *Block) error { } // VRF verify - newAllBlocks, newTailBlocks := pool.verifyVrfOfTails(parentBlock, allBlocks, tailBlocks) + newAllBlocks, newTailBlocks := pool.verifyVRFOfForks(parentBlock, allBlocks, tailBlocks) if len(newTailBlocks) == 0 { cache.Remove(lb.hash.Hex()) return nil } - logging.VLog().WithFields(logrus.Fields{ - "newAllBlocks": newAllBlocks, - "newTailBlocks": newTailBlocks, - }).Error("new tail===========.5") - if err := bc.putVerifiedNewBlocks(parentBlock, newAllBlocks, newTailBlocks); err != nil { cache.Remove(lb.hash.Hex()) return err } - logging.VLog().WithFields(logrus.Fields{ - "parentBlock": parentBlock, - }).Error("parentBlock===========.4") // remove allBlocks from cache. for _, v := range allBlocks { cache.Remove(v.Hash().Hex()) @@ -478,12 +470,8 @@ func (pool *BlockPool) push(sender string, block *Block) error { return pool.bc.ConsensusHandler().ForkChoice() } -func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []*Block) (newAll, newTails []*Block) { - defer func() { - if r := recover(); r != nil { - logging.VLog().WithFields(logrus.Fields{}).Error("current tail===========recover.", r) - } - }() +func (pool *BlockPool) verifyVRFOfForks(parent *Block, allBlocks, tailBlocks []*Block) (newAll, newTails []*Block) { + allBlocksMap := make(map[string]*Block) for _, b := range allBlocks { allBlocksMap[b.Hash().String()] = b @@ -491,34 +479,21 @@ func (pool *BlockPool) verifyVrfOfTails(parent *Block, allBlocks, tailBlocks []* for _, tail := range tailBlocks { - logging.VLog().WithFields(logrus.Fields{ - "tail": tail, - "parent": parent, - "allBlocksMap": allBlocksMap, - }).Error("current tail===========1.") - - subAll, valid := pool.isValidSubChain(parent, tail, allBlocksMap) + forkAll, valid := pool.verifyVRFOfFork(parent, tail, allBlocksMap) if !valid { logging.VLog().WithFields(logrus.Fields{ "parent": parent, "tail": tail, - }).Error("Discard an invalid sub chain.3") + }).Error("Discard an invalid fork for VRF verification failure.") continue } - logging.VLog().WithFields(logrus.Fields{ - "newAll": newAll, - "newTails": newTails, - "subAll": subAll, - "valid": valid, - "tail": tail, - }).Error("check tail===========2.") - newAll = append(newAll, subAll...) + newAll = append(newAll, forkAll...) newTails = append(newTails, tail) } return } -func (pool *BlockPool) isValidSubChain(stop, tail *Block, allBlocksMap map[string]*Block) (allBlocks []*Block, valid bool) { +func (pool *BlockPool) verifyVRFOfFork(stop, tail *Block, allBlocksMap map[string]*Block) (allBlocks []*Block, valid bool) { for stop.Height() < tail.Height() { @@ -531,12 +506,14 @@ func (pool *BlockPool) isValidSubChain(stop, tail *Block, allBlocksMap map[strin if !ok { tail = pool.bc.GetBlock(tph) } - logging.VLog().WithFields(logrus.Fields{ - "ok": ok, - "tail": tail, - "stop": stop, - "allBlocks": allBlocks, - }).Error("check ===========10.") + if tail == nil { + // Normally, should not be here + logging.VLog().WithFields(logrus.Fields{ + "blockHash": tph, + "traverseStop": stop, + }).Error("Parent block not found for VRF input") + return nil, false + } continue } @@ -556,35 +533,33 @@ func (pool *BlockPool) isValidSubChain(stop, tail *Block, allBlocksMap map[strin } if len(hashes) != VRFInputParentHashNumber { logging.VLog().WithFields(logrus.Fields{ - "tail": tail, - "stop": stop, - "hashes": hashes, + "tail": tail, + "traverseStop": stop, + "hashes": hashes, }).Error("Failed to get enough parent block hash for VRF.") return nil, false } - logging.VLog().WithFields(logrus.Fields{ - "tail": tail, - "stop": stop, - "hashes": hashes, - }).Error("================12") - if err := pool.vrfProof(tail, hashes); err != nil { logging.VLog().WithFields(logrus.Fields{ "err": err, - }).Error("Failed to VRF proof.") + }).Error("VRF proof failed.") return nil, false } + var ok bool tail, ok = allBlocksMap[tph.String()] if !ok { tail = pool.bc.GetBlock(tph) } - logging.VLog().WithFields(logrus.Fields{ - "tail": tail, - "stop": stop, - "ok": ok, - }).Error("================13") + if tail == nil { + // Normally, should not be here + logging.VLog().WithFields(logrus.Fields{ + "blockHash": tph, + "traverseStop": stop, + }).Error("Parent block not found for VRF input") + return nil, false + } } return allBlocks, true } From 39ceb89410f5365d9b7862221c27e1a42561f359 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 23:08:25 +0800 Subject: [PATCH 50/69] nebtestkit: perfect testcase --- nf/nvm/test/contract_date_and_random.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nf/nvm/test/contract_date_and_random.js b/nf/nvm/test/contract_date_and_random.js index 9528b9d61..7283a3bfc 100644 --- a/nf/nvm/test/contract_date_and_random.js +++ b/nf/nvm/test/contract_date_and_random.js @@ -15,8 +15,16 @@ Contract.prototype = { }); var date = arguments.length == 0 ? new Date() : new Date(arguments[0]); + var date2 = new Date(); + date2.setFullYear(1988); var data = { + UTC: Date.UTC(), now: Date.now(), + parse: Date.parse('04 Dec 1995 00:12:00 GMT'), + getUTCDate: date.getUTCDate(), + timeZone: date.getTimezoneOffset(), + toJSON: date.toJSON(), + setFullYear: date2.toString(), height: Blockchain.block.height, timestamp: Blockchain.block.timestamp, valueOf: date.valueOf(), From e2e937b0c18c5ca3e6eb1d38e98661acb602acbf Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Mon, 30 Apr 2018 23:31:50 +0800 Subject: [PATCH 51/69] nebtestkit: perfect testcase --- .../cases/contract/contract.feature.accept.test.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nebtestkit/cases/contract/contract.feature.accept.test.js b/nebtestkit/cases/contract/contract.feature.accept.test.js index 5c8fd9e47..48988d096 100644 --- a/nebtestkit/cases/contract/contract.feature.accept.test.js +++ b/nebtestkit/cases/contract/contract.feature.accept.test.js @@ -280,7 +280,16 @@ function testBinary(testInput, testExpect, done) { } }); }).catch(function (err) { - console.log("send tx err"); + console.log("send tx err", err); + if (err.error && err.error.error && testExpect.eventErr) { + try { + expect(err.error.error).to.equal(testExpect.eventErr) + done(); + } catch (err) { + done(err); + } + return; + } done(err); }); } @@ -419,7 +428,7 @@ describe('accept func test', () => { for (var i = 0; i < testCaseGroups.length; i++) { - // if (i != 3) {continue;} // selectively run tests + // if (i != 2) {continue;} // selectively run tests let caseGroup = testCaseGroups[i]; describe(caseGroup.groupname, () => { From e7839b2ac38a19e3aaabce06bd0c797cb1e7eb3b Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Tue, 1 May 2018 00:22:35 +0800 Subject: [PATCH 52/69] nebtestkit: stress test case for contract new feature --- .../stress/contract.date.and.random.test.js | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 nebtestkit/cases/stress/contract.date.and.random.test.js diff --git a/nebtestkit/cases/stress/contract.date.and.random.test.js b/nebtestkit/cases/stress/contract.date.and.random.test.js new file mode 100644 index 000000000..5462f40f2 --- /dev/null +++ b/nebtestkit/cases/stress/contract.date.and.random.test.js @@ -0,0 +1,277 @@ +'use strict'; + +var Wallet = require('nebulas'); +var sleep = require("system-sleep"); +var HttpRequest = require("../../node-request"); + +var args = process.argv.splice(2); + +if (args.length != 3) { + console.log("please input args 0:env(local,testneb1,testneb2,testneb3) 1:address number(concurrency) 2:sendtimes"); + return; +} + +var env = args[0]; // local testneb1 testneb2 + +const AddressNumber = parseInt(args[1]); +const SendTimes = parseInt(args[2]); + +if (AddressNumber <= 0 || SendTimes <= 0) { + + console.log("please input correct AddressNumber and SendTimes"); + return; +} + +var Neb = Wallet.Neb; +var neb = new Neb(); + +var ChainID; +var from; + +//local +if (env == 'local') { + neb.setRequest(new HttpRequest("http://127.0.0.1:8685")); //https://testnet.nebulas.io + ChainID = 100; + from = new Wallet.Account("a6e5eb290e1438fce79f5cb8774a72621637c2c9654c8b2525ed1d7e4e73653f"); +} else if (env == 'testneb1') { + neb.setRequest(new HttpRequest("http://35.182.48.19:8685")); + ChainID = 1001; + from = new Wallet.Account("43181d58178263837a9a6b08f06379a348a5b362bfab3631ac78d2ac771c5df3"); +} else if (env == "testneb2") { + neb.setRequest(new HttpRequest("http://34.205.26.12:8685")); + ChainID = 1002; + from = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); +} else if (env == "testneb3") { + neb.setRequest(new HttpRequest("http://35.177.214.138:8685")); + ChainID = 1003; + from = new Wallet.Account("43181d58178263837a9a6b08f06379a348a5b362bfab3631ac78d2ac771c5df3"); +} else { + console.log("please input correct env local testneb1 testneb2 testneb3"); + return; +} + +var FS = require("fs"); + +var lastnonce = 0; + +// new account to get address +var accountArray = new Array(); +for (var i = 0; i < AddressNumber; i++) { + var account = Wallet.Account.NewAccount(); + //var hash = account.getAddressString(); + accountArray.push(account); +} + +neb.api.getAccountState(from.getAddressString()).then(function (resp) { + console.log("master accountState resp:", JSON.stringify(resp), ", env: ", env); + lastnonce = parseInt(resp.nonce); + console.log("lastnonce:", lastnonce); +}); + +sleep(2000); + +cliamTokens(); + +var ContractHash; +var ContractAddress; + +var intervalAccount = setInterval(function () { + neb.api.getAccountState(from.getAddressString()).then(function (resp) { + console.log("master accountState resp:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + console.log("lastnonce:", lastnonce, "resp_nonce:", nonce); + + if (lastnonce <= nonce) { + clearInterval(intervalAccount); + deployContract(); + } + }); +}, 2000); + +function cliamTokens() { + var nonce = lastnonce + 1; + for (var j = 0; j < AddressNumber; j++) { + sendTransaction(nonce, accountArray[j]); + ++nonce; + sleep(30); + } + + lastnonce = nonce - 1; +} + +function deployContract() { + + var nonce = lastnonce; + console.log("nonce:" + nonce); + // create contract + var dateAndRand = FS.readFileSync("../../../nf/nvm/test/contract_date_and_random.js", "utf-8"); + var contract = { + "source": dateAndRand, + "sourceType": "js", + "args": "" + }; + + var transaction = new Wallet.Transaction(ChainID, from, from, "0", ++nonce, "1000000", "20000000000", contract); + transaction.signTransaction(); + var rawTx = transaction.toProtoString(); + + // console.log("contract:" + rawTx); + + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("send raw contract transaction resp:" + JSON.stringify(resp)); + if (resp.balance === "0") { + throw new Error("balance is 0"); + } + ContractHash = resp.txhash; + ContractAddress = resp.contract_address; + + checkContractDeployed(); + }); + + ++lastnonce; +} + +function checkContractDeployed() { + + var retry = 0; + + // contract status and get contract_address + var interval = setInterval(function () { + console.log("getTransactionReceipt hash:" + ContractHash); + neb.api.getTransactionReceipt(ContractHash).then(function (resp) { + + console.log("tx receipt:" + resp.status); + + if (resp.status && resp.status === 1) { + clearInterval(interval); + sendMutilContractTransaction(ContractAddress) + } + }).catch(function (err) { + retry++; + console.log("error!", JSON.stringify(err.error)); + if (retry > 10) { + console.log(JSON.stringify(err.error)); + clearInterval(interval); + } + }); + + }, 2000); +} + + +function sendTransaction(nonce, address) { + var transaction = new Wallet.Transaction(ChainID, from, address, neb.nasToBasic(1), nonce); + transaction.signTransaction(); + var rawTx = transaction.toProtoString(); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("send raw transaction resp:" + JSON.stringify(resp)); + }); +} + + + +// get current height +var BeginHeight; +// +function sendMutilContractTransaction(address) { + + neb.api.getNebState().then(function (resp) { + BeginHeight = resp.height; + console.log("get NebState resp:" + JSON.stringify(resp)); + }); + + sleep(1000); + var nonce = lastnonce; + var t1 = new Date().getTime(); + for (var j = 0; j < AddressNumber; j++) { + nonce = 0; + sendContractTransaction(0, nonce, accountArray[j], address); + //nonce = nonce + SendTimes; + } + + lastnonce = SendTimes; + sleep(1000 * SendTimes) + getTransactionNumberByHeight(); +} + + + +function sendContractTransaction(sendtimes, nonce, from_address, contract_address) { + if (sendtimes < SendTimes) { + + var X = Math.floor(Math.random() * Math.floor(6)); + + var call = { + "function": X % 2 == 0 ? "testDate" : "testRandom", + "args": "" + } + + console.log("send contract nonce:", nonce, ", call:", JSON.stringify(call)); + var transaction = new Wallet.Transaction(ChainID, from_address, contract_address, "0", ++nonce, "1000000", "2000000000", call); + transaction.signTransaction(); + var rawTx = transaction.toProtoString(); + neb.api.sendRawTransaction(rawTx).then(function (resp) { + console.log("send raw contract transaction resp:" + JSON.stringify(resp)); + sendtimes++; + if (resp.txhash) { + sendContractTransaction(sendtimes, nonce, from_address, contract_address); + } + }); + } +} + +function getTransactionNumberByHeight() { + + var intervalHeight = setInterval(function () { + neb.api.getAccountState(accountArray[0].getAddressString()).then(function (resp) { + console.log("master accountState resp:" + JSON.stringify(resp)); + var nonce = parseInt(resp.nonce); + console.log("lastnonce:", lastnonce, "resp_nonce:", nonce); + + if (lastnonce <= nonce) { + clearInterval(intervalHeight) + sleep(2000) + neb.api.getNebState().then(function (resp) { + var EndHeight = resp.height + console.log("BeginHeight:" + BeginHeight + " EndHeight:" + EndHeight); + var sum = 0; + var max = 0; + var height = BeginHeight + var h = EndHeight - BeginHeight + for (; height <= EndHeight; height++) { + neb.api.getBlockByHeight(height, false).then(function (resp) { + if (resp.transactions) { + //console.log("master accountState resp:" + JSON.stringify(resp)); + console.log(resp.height, resp.transactions.length) + sum += resp.transactions.length + max = resp.transactions.length > max ? resp.transactions.length : max + } else { + console.log(resp.height, 0) + } + --h; + }); + sleep(10) + } + + sleep(1000) + var intervalH = setInterval(function () { + if (h < 0) { + clearInterval(intervalH); + console.log("====================") + console.log("env is ", env) + console.log("concurrency number is ", AddressNumber) + console.log("total number is ", AddressNumber * SendTimes) + console.log("height from ", BeginHeight, " to ", EndHeight) + console.log("max of block is ", max) + console.log("avg of block is ", sum / (EndHeight - BeginHeight)) + console.log("max of tps is ", max / 5) + console.log("avg of tps is ", sum / (5 * (EndHeight - BeginHeight))) + console.log("====================") + } + }, 2000); + + }); + } + }) + }, 1000); +} \ No newline at end of file From c862d72fb6d4f4c5db895b4584ca026268c81840 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Wed, 2 May 2018 16:18:52 +0800 Subject: [PATCH 53/69] nvm: export date.js module --- nf/nvm/lib/date.js | 1 + nf/nvm/v8/lib/date.js | 55 ++++++++++++++++++++++++++++++++++ nf/nvm/v8/lib/execution_env.js | 36 +--------------------- 3 files changed, 57 insertions(+), 35 deletions(-) create mode 120000 nf/nvm/lib/date.js create mode 100644 nf/nvm/v8/lib/date.js diff --git a/nf/nvm/lib/date.js b/nf/nvm/lib/date.js new file mode 120000 index 000000000..b2d62a9aa --- /dev/null +++ b/nf/nvm/lib/date.js @@ -0,0 +1 @@ +../v8/lib/date.js \ No newline at end of file diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js new file mode 100644 index 000000000..9d1055e69 --- /dev/null +++ b/nf/nvm/v8/lib/date.js @@ -0,0 +1,55 @@ +// Copyright (C) 2018 go-nebulas authors +// +// This file is part of the go-nebulas library. +// +// the go-nebulas library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// the go-nebulas library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the go-nebulas library. If not, see . +// + + +var NebDate = (function(Date) { + function NebDate() { + if (!Blockchain) { + throw new Error("'Blockchain' is not defined."); + } + if (!Blockchain.block) { + throw new Error("'Blockchain.block' is not defined."); + } + + var date = new(Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))))(); + if (arguments.length == 0) { + // unit of timestamp is second + date.setTime(Blockchain.block.timestamp * 1000); + } + Object.setPrototypeOf(date, NebDate.prototype); + return date; + } + NebDate.now = function() { + return new NebDate().getTime(); + } + NebDate.UTC = function() { + return Date.UTC.apply(null, arguments); + } + NebDate.parse = function(dateString) { + return Date.parse(dateString); + } + NebDate.prototype = new Proxy(NebDate.prototype, { + getPrototypeOf: function(target) { + throw new Error("Unsupported method!"); + }, + }); + Object.setPrototypeOf(NebDate.prototype, Date.prototype); + return NebDate; +})(Date); + +module.exports = NebDate; \ No newline at end of file diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index a6e3a3676..85893735c 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -110,39 +110,5 @@ const BigNumber = require('bignumber.js'); const Blockchain = require('blockchain.js'); const Event = require('event.js'); -var Date = (function(Date) { - function NebDate() { - if (!Blockchain) { - throw new Error("'Blockchain' is not defined."); - } - if (!Blockchain.block) { - throw new Error("'Blockchain.block' is not defined."); - } - - var date = new(Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))))(); - if (arguments.length == 0) { - // unit of timestamp is second - date.setTime(Blockchain.block.timestamp * 1000); - } - Object.setPrototypeOf(date, NebDate.prototype); - return date; - } - NebDate.now = function() { - return new NebDate().getTime(); - } - NebDate.UTC = function() { - return Date.UTC.apply(null, arguments); - } - NebDate.parse = function(dateString) { - return Date.parse(dateString); - } - NebDate.prototype = new Proxy(NebDate.prototype, { - getPrototypeOf: function(target) { - throw new Error("Unsupported method!"); - }, - }); - Object.setPrototypeOf(NebDate.prototype, Date.prototype); - return NebDate; -})(Date); - +var Date = require('date.js') Math.random = require('random.js'); \ No newline at end of file From 31746abb60374e5e14e55f9eefb1f7b4342db603 Mon Sep 17 00:00:00 2001 From: ChengOrangeJu Date: Thu, 3 May 2018 12:24:48 +0800 Subject: [PATCH 54/69] net: remove test case --- net/testing/test/main.go | 47 ---------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 net/testing/test/main.go diff --git a/net/testing/test/main.go b/net/testing/test/main.go deleted file mode 100644 index f53cbf100..000000000 --- a/net/testing/test/main.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strings" -) - -func main() { - resp, err := http.Get("https://api.github.com/repos/btcsuite/btcd/commits?client_id=80386779008eea5dab41&client_secret=f2086aebf790729026fb209b803010029821d8a3") - - if err != nil { - // handle error - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - - if err != nil { - // handle error - } - var f interface{} - json.Unmarshal(body, &f) - - for _, n := range f.([]interface{}) { - for k, v := range n.(map[string]interface{}) { - if k == "commit" { - value := v.(map[string]interface{})["message"].(string) - fmt.Println(value) - if strings.Contains(value, "gx publish ") { - url := v.(map[string]interface{})["url"].(string) - fmt.Println(v.(map[string]interface{})["message"]) - temps := strings.Split(url, "/") - fmt.Println(temps[len(temps)-1]) - - str := "github.com/agl/ed25519" - temps = strings.Split(str, "ghub.com") - fmt.Println(len(temps)) - fmt.Println(temps) - return - } - } - } - } - -} From 566e8ebb92014f1a8abacd27f4dcaee6f588595d Mon Sep 17 00:00:00 2001 From: Larry Wang Date: Thu, 3 May 2018 14:33:19 +0800 Subject: [PATCH 55/69] rpc: add transaction type and test --- ...dmin.SignTransactionWithPassphrase.test.js | 181 ++++++++++- nebtestkit/cases/rpc/rpc_client/rpc.proto | 3 + rpc/api_service.go | 110 +++++-- rpc/pb/rpc.pb.go | 302 +++++++++--------- rpc/pb/rpc.pb.gw.go | 88 ++--- rpc/pb/rpc.proto | 3 + 6 files changed, 464 insertions(+), 223 deletions(-) diff --git a/nebtestkit/cases/rpc/admin.SignTransactionWithPassphrase.test.js b/nebtestkit/cases/rpc/admin.SignTransactionWithPassphrase.test.js index fa84d4e05..cbb600564 100644 --- a/nebtestkit/cases/rpc/admin.SignTransactionWithPassphrase.test.js +++ b/nebtestkit/cases/rpc/admin.SignTransactionWithPassphrase.test.js @@ -10,7 +10,7 @@ var coinbase, server_address; var env = process.env.NET || 'local'; -var env = 'maintest'; +var env = 'local'; if (env === 'testneb1') { chain_id = 1001; sourceAccount = new Wallet.Account("25a3a441a34658e7a595a0eda222fa43ac51bd223017d17b420674fb6d0a4d52"); @@ -450,11 +450,186 @@ describe("rpc: SignTransaction with passphrase", () => { } var testExpect = { - hasError: false, - errorMsg: "", + hasError: true, + errorMsg: "invalid contract", } testSignTransaction(testInput, testExpect, done) }); + +it('17. `invalid type`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + contract: { + "function": "save", + }, + type: "invalid" + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: true, + errorMsg: "invalid transaction data payload type", + + } + + testSignTransaction(testInput, testExpect, done) +}); + +it('18. `binary type`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + type: "binary" + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: false, + errorMsg: "", + + } + + testSignTransaction(testInput, testExpect, done) +}); + +it('19. `deploy type`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + type: "deploy", + contract: { + "source": "var a = {}", + "source_type": "ts" + } + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: false, + errorMsg: "", + + } + + testSignTransaction(testInput, testExpect, done) +}); + +it('20. `deploy type parse err`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + type: "deploy", + contract: { + "source": "var a = {}" + } + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: true, + errorMsg: "invalid source type of deploy payload", + + } + + testSignTransaction(testInput, testExpect, done) +}); + +it('21. `call type`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + type: "call", + contract: { + "function": "save" + } + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: false, + errorMsg: "", + + } + + testSignTransaction(testInput, testExpect, done) +}); +it('22. `call type function err`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + type: "call", + contract: { + "function": "_save" + } + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: true, + errorMsg: "invalid function of call payload", + + } + + testSignTransaction(testInput, testExpect, done) +}); +it('23. `call type no function`', done => { + var testInput = { + transaction: { + from: address, + to: coinbase, + value: "123", + nonce: "10000", + gas_price: "1000000", + gas_limit: "1000000", + type: "call" + }, + passphrase: 'passphrase' + } + + var testExpect = { + hasError: true, + errorMsg: "invalid function of call payload", + + } + + testSignTransaction(testInput, testExpect, done) +}); }); \ No newline at end of file diff --git a/nebtestkit/cases/rpc/rpc_client/rpc.proto b/nebtestkit/cases/rpc/rpc_client/rpc.proto index 52764eb0f..85bd138d3 100644 --- a/nebtestkit/cases/rpc/rpc_client/rpc.proto +++ b/nebtestkit/cases/rpc/rpc_client/rpc.proto @@ -342,6 +342,9 @@ message TransactionRequest { // binary data for transaction bytes binary = 10; + + // transaction payload type, enum:binary, deploy, call + string type = 20; } message ContractRequest { diff --git a/rpc/api_service.go b/rpc/api_service.go index fd37e6c07..73c5527e9 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -141,46 +141,94 @@ func parseTransaction(neb core.Neblet, reqTx *rpcpb.TransactionRequest) (*core.T if err != nil { return nil, errors.New("invalid gasLimit") } - var ( - payloadType string - payload []byte - ) - if reqTx.Contract != nil { - if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 && fromAddr.Equals(toAddr) { - payloadType = core.TxPayloadDeployType - payloadObj, err := core.NewDeployPayload(reqTx.Contract.Source, reqTx.Contract.SourceType, reqTx.Contract.Args) - if err != nil { - return nil, err + payloadType, payload, err := parseTransactionPayload(reqTx) + if err != nil { + return nil, err + } + + tx, err := core.NewTransaction(neb.BlockChain().ChainID(), fromAddr, toAddr, value, reqTx.Nonce, payloadType, payload, gasPrice, gasLimit) + if err != nil { + return nil, err + } + return tx, nil +} + +func parseTransactionPayload(reqTx *rpcpb.TransactionRequest) (payloadType string, payload []byte, err error) { + if len(reqTx.Type) > 0 { + switch reqTx.Type { + case core.TxPayloadBinaryType: + { + if payload, err = core.NewBinaryPayload(reqTx.Binary).ToBytes(); err != nil { + return "", nil, err + } } - if payload, err = payloadObj.ToBytes(); err != nil { - return nil, err + case core.TxPayloadDeployType: + { + if reqTx.Contract == nil { + return "", nil, core.ErrInvalidDeploySource + } + deployPayload, err := core.NewDeployPayload(reqTx.Contract.Source, reqTx.Contract.SourceType, reqTx.Contract.Args) + if err != nil { + return "", nil, err + } + if payload, err = deployPayload.ToBytes(); err != nil { + return "", nil, err + } } - } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 && toAddr.Type() == core.ContractAddress { - payloadType = core.TxPayloadCallType - callpayload, err := core.NewCallPayload(reqTx.Contract.Function, reqTx.Contract.Args) + case core.TxPayloadCallType: + { + if reqTx.Contract == nil { + return "", nil, core.ErrInvalidCallFunction + } + callpayload, err := core.NewCallPayload(reqTx.Contract.Function, reqTx.Contract.Args) + if err != nil { + return "", nil, err + } + + if payload, err = callpayload.ToBytes(); err != nil { + return "", nil, err + } + } + default: + return "", nil, core.ErrInvalidTxPayloadType + } + } else { + if reqTx.Contract != nil { + toAddr, err := core.AddressParse(reqTx.To) if err != nil { - return nil, err + return "", nil, err } - - if payload, err = callpayload.ToBytes(); err != nil { - return nil, err + if len(reqTx.Contract.Source) > 0 && len(reqTx.Contract.Function) == 0 && reqTx.From == reqTx.To { + payloadType = core.TxPayloadDeployType + payloadObj, err := core.NewDeployPayload(reqTx.Contract.Source, reqTx.Contract.SourceType, reqTx.Contract.Args) + if err != nil { + return "", nil, err + } + if payload, err = payloadObj.ToBytes(); err != nil { + return "", nil, err + } + } else if len(reqTx.Contract.Source) == 0 && len(reqTx.Contract.Function) > 0 && toAddr.Type() == core.ContractAddress { + payloadType = core.TxPayloadCallType + callpayload, err := core.NewCallPayload(reqTx.Contract.Function, reqTx.Contract.Args) + if err != nil { + return "", nil, err + } + + if payload, err = callpayload.ToBytes(); err != nil { + return "", nil, err + } + } else { + return "", nil, errors.New("invalid contract") } } else { - return nil, errors.New("invalid contract") - } - } else { - payloadType = core.TxPayloadBinaryType - if payload, err = core.NewBinaryPayload(reqTx.Binary).ToBytes(); err != nil { - return nil, err + payloadType = core.TxPayloadBinaryType + if payload, err = core.NewBinaryPayload(reqTx.Binary).ToBytes(); err != nil { + return "", nil, err + } } } - - tx, err := core.NewTransaction(neb.BlockChain().ChainID(), fromAddr, toAddr, value, reqTx.Nonce, payloadType, payload, gasPrice, gasLimit) - if err != nil { - return nil, err - } - return tx, nil + return payloadType, payload, nil } func handleTransactionResponse(neb core.Neblet, tx *core.Transaction) (resp *rpcpb.SendTransactionResponse, err error) { diff --git a/rpc/pb/rpc.pb.go b/rpc/pb/rpc.pb.go index 8946c5c49..c05513ebe 100644 --- a/rpc/pb/rpc.pb.go +++ b/rpc/pb/rpc.pb.go @@ -60,8 +60,10 @@ import _ "google.golang.org/genproto/googleapis/api/annotations" import consensuspb "github.com/nebulasio/go-nebulas/consensus/pb" import nebletpb "github.com/nebulasio/go-nebulas/neblet/pb" -import context "golang.org/x/net/context" -import grpc "google.golang.org/grpc" +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -470,6 +472,8 @@ type TransactionRequest struct { Contract *ContractRequest `protobuf:"bytes,7,opt,name=contract" json:"contract,omitempty"` // binary data for transaction Binary []byte `protobuf:"bytes,10,opt,name=binary,proto3" json:"binary,omitempty"` + // transaction payload type, enum:binary, deploy, call + Type string `protobuf:"bytes,20,opt,name=type,proto3" json:"type,omitempty"` } func (m *TransactionRequest) Reset() { *m = TransactionRequest{} } @@ -533,6 +537,13 @@ func (m *TransactionRequest) GetBinary() []byte { return nil } +func (m *TransactionRequest) GetType() string { + if m != nil { + return m.Type + } + return "" +} + type ContractRequest struct { // contract source code. Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` @@ -2412,148 +2423,149 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2288 bytes of a gzipped FileDescriptorProto + // 2292 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcb, 0x6f, 0x1b, 0xb9, - 0x19, 0x87, 0x24, 0x3f, 0xa4, 0x4f, 0xb2, 0xad, 0xd0, 0xaf, 0xb1, 0xfc, 0x88, 0xc3, 0x2c, 0x76, - 0xbd, 0x41, 0xd7, 0xda, 0x78, 0x81, 0x6d, 0x91, 0x62, 0x0b, 0x38, 0x69, 0x56, 0x9b, 0x22, 0x08, - 0xdc, 0x71, 0xd2, 0x2e, 0xd0, 0xa6, 0x02, 0x35, 0xa2, 0xa4, 0xe9, 0x8e, 0x39, 0x53, 0x92, 0x72, - 0x62, 0x5f, 0x0a, 0xec, 0xbd, 0xa7, 0x02, 0x45, 0x0f, 0xbd, 0xf5, 0x2f, 0x2a, 0x7a, 0xe8, 0xa5, - 0xc7, 0x9e, 0xfa, 0x57, 0x14, 0xe4, 0x90, 0xf3, 0xd2, 0xc8, 0x6a, 0x7a, 0xe8, 0x8d, 0xcf, 0xef, - 0xfb, 0xf8, 0x3d, 0x7e, 0xfc, 0x71, 0x06, 0x1a, 0x3c, 0xf2, 0x4e, 0x23, 0x1e, 0xca, 0x10, 0x2d, - 0xf3, 0xc8, 0x8b, 0x06, 0x9d, 0x83, 0x71, 0x18, 0x8e, 0x03, 0xda, 0x25, 0x91, 0xdf, 0x25, 0x8c, - 0x85, 0x92, 0x48, 0x3f, 0x64, 0x22, 0x5e, 0xd4, 0xf9, 0xd1, 0xd8, 0x97, 0x93, 0xe9, 0xe0, 0xd4, - 0x0b, 0xaf, 0xba, 0x8c, 0x0e, 0xa6, 0x01, 0x11, 0x7e, 0xd8, 0x1d, 0x87, 0x9f, 0x99, 0x4e, 0xd7, - 0x0b, 0x99, 0xa0, 0x4c, 0x4c, 0x45, 0x37, 0x1a, 0x74, 0x85, 0x24, 0x92, 0x9a, 0x9d, 0x5f, 0x2e, - 0xda, 0xc9, 0xe8, 0x20, 0xa0, 0x52, 0x6d, 0xf3, 0x42, 0x36, 0xf2, 0xc7, 0xf1, 0x3e, 0xfc, 0x08, - 0xda, 0x97, 0xd3, 0x81, 0xf0, 0xb8, 0x3f, 0xa0, 0x2e, 0xfd, 0xdd, 0x94, 0x0a, 0x89, 0x76, 0x60, - 0x45, 0x86, 0x91, 0xef, 0x09, 0xa7, 0x72, 0x5c, 0x3b, 0x69, 0xb8, 0xa6, 0x87, 0xbf, 0x82, 0x7b, - 0x99, 0xb5, 0x22, 0x52, 0xb6, 0xa0, 0x2d, 0x58, 0xd6, 0xd3, 0x4e, 0xe5, 0xb8, 0x72, 0xd2, 0x70, - 0xe3, 0x0e, 0x42, 0xb0, 0x34, 0x24, 0x92, 0x38, 0x55, 0x3d, 0xa8, 0xdb, 0x18, 0x41, 0xfb, 0x55, - 0xc8, 0x2e, 0x08, 0x27, 0x57, 0xc2, 0xa8, 0xc2, 0x7f, 0xa9, 0xaa, 0xc1, 0x21, 0x7d, 0xc1, 0x46, - 0x61, 0x22, 0x72, 0x1d, 0xaa, 0xfe, 0xd0, 0xc8, 0xab, 0xfa, 0x43, 0xb4, 0x07, 0x75, 0x6f, 0x42, - 0x7c, 0xd6, 0xf7, 0x87, 0x5a, 0xe0, 0x9a, 0xbb, 0xaa, 0xfb, 0x2f, 0x86, 0xa8, 0x03, 0x75, 0x2f, - 0xf4, 0xd9, 0x80, 0x08, 0xea, 0xd4, 0xf4, 0x86, 0xa4, 0x8f, 0x0e, 0x01, 0x22, 0x4a, 0x79, 0xdf, - 0x0b, 0xa7, 0x4c, 0x3a, 0x4b, 0x7a, 0x63, 0x43, 0x8d, 0x3c, 0x53, 0x03, 0x08, 0x43, 0x4b, 0xdc, - 0x30, 0x6f, 0xc2, 0x43, 0xe6, 0xdf, 0xd2, 0xa1, 0xb3, 0x7c, 0x5c, 0x39, 0xa9, 0xbb, 0xb9, 0x31, - 0x74, 0x1f, 0x9a, 0x83, 0xa9, 0xf7, 0x1d, 0x95, 0x7d, 0xe1, 0xdf, 0x52, 0x67, 0xe5, 0xb8, 0x72, - 0xb2, 0xec, 0x42, 0x3c, 0x74, 0xe9, 0xdf, 0x52, 0xf4, 0x29, 0xb4, 0xb5, 0x1f, 0xbd, 0x30, 0xe8, - 0x5f, 0x53, 0x2e, 0xfc, 0x90, 0x39, 0xa0, 0xed, 0xd8, 0xb0, 0xe3, 0xbf, 0x88, 0x87, 0xd1, 0x19, - 0x34, 0x79, 0x38, 0x95, 0xb4, 0x2f, 0xc9, 0x20, 0xa0, 0x4e, 0xf3, 0xb8, 0x76, 0xd2, 0x3c, 0xbb, - 0x77, 0xaa, 0xd3, 0xe2, 0xd4, 0x55, 0x33, 0xaf, 0xd5, 0x84, 0x0b, 0x3c, 0x69, 0xe3, 0x2f, 0x01, - 0xd2, 0x99, 0x19, 0xbf, 0x38, 0xb0, 0x4a, 0x86, 0x43, 0x4e, 0x85, 0x70, 0xaa, 0x3a, 0x50, 0xb6, - 0x8b, 0xff, 0x51, 0x81, 0xcd, 0x1e, 0x95, 0xaf, 0xe8, 0xe0, 0x52, 0xe5, 0x48, 0xe2, 0xd9, 0xac, - 0x27, 0x2b, 0x79, 0x4f, 0x22, 0x58, 0x92, 0xc4, 0x0f, 0x6c, 0xc4, 0x54, 0x1b, 0xb5, 0xa1, 0x16, - 0xf8, 0x03, 0xe3, 0x58, 0xd5, 0x54, 0xa9, 0x31, 0xa1, 0xfe, 0x78, 0x12, 0xfb, 0x73, 0xc9, 0x35, - 0xbd, 0x52, 0x3f, 0xac, 0x94, 0xfb, 0xa1, 0xe8, 0xf7, 0xd5, 0x12, 0xbf, 0x3b, 0xb0, 0x6a, 0xa5, - 0xd4, 0xb5, 0x14, 0xdb, 0xc5, 0x9f, 0x43, 0xfb, 0xdc, 0xd3, 0x11, 0x15, 0xc9, 0xa9, 0x0e, 0xa0, - 0x61, 0x0e, 0x4e, 0x6d, 0xca, 0xa6, 0x03, 0xf8, 0x67, 0xb0, 0xd3, 0xa3, 0xd2, 0x6c, 0x32, 0xee, - 0x88, 0xf3, 0x3c, 0xe3, 0xbf, 0xd8, 0xa9, 0xb6, 0x9b, 0x39, 0x66, 0x35, 0x7b, 0x4c, 0xfc, 0x16, - 0x76, 0x67, 0x64, 0x19, 0x23, 0x1c, 0x58, 0x1d, 0x90, 0x80, 0x30, 0x8f, 0x5a, 0x61, 0xa6, 0xab, - 0x2a, 0x84, 0x85, 0x6a, 0x3c, 0x96, 0x15, 0x77, 0xb4, 0xbf, 0x6f, 0xa2, 0x38, 0x6b, 0xd7, 0x5c, - 0xdd, 0xc6, 0xbf, 0x85, 0xd6, 0x33, 0x12, 0x04, 0x89, 0xcc, 0x1d, 0x58, 0xe1, 0x54, 0x4c, 0x03, - 0x69, 0x44, 0x9a, 0x9e, 0x4a, 0x4b, 0xfa, 0x9e, 0x7a, 0x2a, 0x99, 0x28, 0xe7, 0x26, 0x64, 0x60, - 0x86, 0x9e, 0x73, 0x8e, 0x1e, 0x40, 0x8b, 0x0a, 0xe9, 0x5f, 0x11, 0x49, 0xfb, 0x63, 0x22, 0x4c, - 0x04, 0x9b, 0x76, 0xac, 0x47, 0x04, 0x3e, 0x85, 0xad, 0xa7, 0x37, 0x4f, 0x83, 0xd0, 0xfb, 0xee, - 0x1b, 0x7d, 0xb6, 0x4c, 0xf1, 0x9b, 0xa3, 0x57, 0x72, 0x47, 0xff, 0x01, 0xa0, 0x1e, 0x95, 0x3f, - 0xbd, 0x61, 0x44, 0xc8, 0x9b, 0xac, 0x85, 0x57, 0x3e, 0xa3, 0x3c, 0x81, 0x8a, 0xb8, 0x87, 0xff, - 0x5d, 0x01, 0xf4, 0x9a, 0x13, 0x26, 0x88, 0xa7, 0xf0, 0xcd, 0x0a, 0x47, 0xb0, 0x34, 0xe2, 0xe1, - 0x95, 0x39, 0x8e, 0x6e, 0xab, 0xac, 0x96, 0xa1, 0x39, 0x43, 0x55, 0x86, 0xca, 0x5d, 0xd7, 0x24, - 0x98, 0xda, 0x7a, 0x8e, 0x3b, 0xa9, 0x13, 0x97, 0xb2, 0x4e, 0xdc, 0x87, 0xc6, 0x98, 0x88, 0x7e, - 0xc4, 0x7d, 0x8f, 0xea, 0x02, 0x6e, 0xb8, 0xf5, 0x31, 0x11, 0x17, 0xaa, 0x6f, 0x27, 0x03, 0xff, - 0xca, 0x97, 0x26, 0x19, 0xd5, 0xe4, 0x4b, 0xd5, 0x47, 0x67, 0x0a, 0x38, 0x98, 0xe4, 0xc4, 0x93, - 0x3a, 0x03, 0x9b, 0x67, 0x3b, 0xa6, 0x14, 0x9f, 0x99, 0x61, 0x63, 0xb3, 0x9b, 0xac, 0x53, 0x87, - 0x1d, 0xf8, 0x8c, 0xf0, 0x1b, 0x5d, 0xe2, 0x2d, 0xd7, 0xf4, 0xf0, 0x2d, 0x6c, 0x14, 0x36, 0xa9, - 0xa5, 0x22, 0x9c, 0xf2, 0x24, 0x19, 0x4c, 0x4f, 0x45, 0x2e, 0x6e, 0xf5, 0x75, 0xf0, 0x4d, 0xe4, - 0xe2, 0xa1, 0xd7, 0x37, 0x11, 0x55, 0x80, 0x36, 0x9a, 0x32, 0xed, 0x34, 0x0b, 0x68, 0xb6, 0xaf, - 0xbc, 0x47, 0xf8, 0x58, 0x68, 0x17, 0x34, 0x5c, 0xdd, 0xc6, 0x5d, 0xd8, 0xbb, 0xa4, 0x6c, 0xe8, - 0x92, 0x77, 0xe5, 0xee, 0xd6, 0x28, 0x5c, 0xd1, 0xe6, 0xc6, 0x28, 0xfc, 0x6b, 0xd8, 0x55, 0x1b, - 0x72, 0xab, 0xd3, 0x60, 0xca, 0xf7, 0x13, 0x22, 0x26, 0xd6, 0xe8, 0xb8, 0xa7, 0x8a, 0xdb, 0xfa, - 0xa0, 0x9f, 0x02, 0x8e, 0x2e, 0x6e, 0x3b, 0x7e, 0x6e, 0x80, 0xa7, 0x0f, 0xdb, 0x3d, 0x2a, 0x75, - 0x5a, 0x3d, 0xbd, 0xf9, 0x86, 0x88, 0x49, 0xc6, 0x94, 0x8c, 0x64, 0xdd, 0x46, 0x67, 0xb0, 0x3d, - 0x9a, 0x06, 0x41, 0x7f, 0xe4, 0x07, 0x41, 0x5f, 0xa6, 0x06, 0x69, 0xe1, 0x75, 0x77, 0x53, 0x4d, - 0x7e, 0xed, 0x07, 0x41, 0xc6, 0x56, 0x4c, 0x75, 0x05, 0x5a, 0x05, 0xff, 0x4d, 0xe6, 0xfe, 0x4f, - 0x6a, 0x1e, 0xc3, 0x7e, 0x8f, 0xca, 0xcc, 0xc8, 0xc2, 0xd3, 0xe0, 0x7f, 0xd6, 0x60, 0x4d, 0xdb, - 0x95, 0xf8, 0xb3, 0xec, 0xcc, 0xf7, 0xa1, 0x19, 0x11, 0x4e, 0x99, 0xec, 0xeb, 0x29, 0x93, 0x00, - 0xf1, 0x90, 0xd2, 0x90, 0x39, 0x45, 0x2d, 0x77, 0x8a, 0xf2, 0x02, 0xc8, 0xde, 0x7f, 0xcb, 0x85, - 0xfb, 0xef, 0x00, 0x1a, 0xd2, 0xbf, 0xa2, 0x42, 0x92, 0xab, 0x48, 0xe7, 0x7f, 0xcd, 0x4d, 0x07, - 0x72, 0x57, 0xc1, 0x6a, 0xfe, 0x2a, 0x38, 0x04, 0xd0, 0xd4, 0xa2, 0xcf, 0xc3, 0x50, 0x1a, 0x00, - 0x6e, 0xe8, 0x11, 0x37, 0x0c, 0xa5, 0xda, 0x29, 0xdf, 0x8b, 0x78, 0xb2, 0x11, 0x43, 0x9d, 0x7c, - 0x2f, 0xf4, 0x94, 0x02, 0xa6, 0x6b, 0xca, 0xa4, 0x99, 0x05, 0x03, 0x4c, 0x7a, 0x48, 0x2f, 0x38, - 0x87, 0xf5, 0x84, 0xc2, 0xc4, 0x6b, 0x9a, 0xba, 0xf8, 0x3a, 0xa7, 0xc9, 0x70, 0x5c, 0x82, 0x71, - 0x5b, 0xed, 0x71, 0xd7, 0xbc, 0x6c, 0x57, 0x39, 0x42, 0x83, 0x8c, 0xd3, 0x8a, 0xf1, 0x41, 0x77, - 0x94, 0x66, 0x5f, 0xf4, 0x47, 0x3e, 0x23, 0x81, 0x2f, 0x6f, 0x9c, 0x35, 0x1d, 0x5a, 0xf0, 0xc5, - 0xd7, 0x66, 0x04, 0xfd, 0x04, 0x5a, 0x99, 0xd8, 0x0b, 0x67, 0xa8, 0xef, 0xdf, 0x8e, 0x29, 0xfa, - 0x92, 0x72, 0x70, 0x73, 0xeb, 0xf1, 0x9f, 0x6a, 0xb0, 0x59, 0x56, 0x34, 0x65, 0x41, 0x76, 0xc0, - 0xfa, 0xb2, 0xc8, 0x57, 0x2c, 0x00, 0xd6, 0x66, 0x00, 0x70, 0x69, 0x16, 0x00, 0x97, 0x4b, 0x01, - 0x70, 0x25, 0x1b, 0xff, 0x5c, 0x8c, 0x57, 0x8b, 0x31, 0xb6, 0x77, 0x4c, 0xdd, 0xdc, 0xe9, 0x0a, - 0x60, 0x2c, 0x26, 0x34, 0x52, 0x4c, 0xc8, 0xc3, 0x28, 0xdc, 0x05, 0xa3, 0xcd, 0x02, 0x8c, 0x96, - 0x41, 0x43, 0xab, 0x14, 0x1a, 0x34, 0x24, 0x4a, 0x22, 0xa7, 0x42, 0x07, 0x67, 0xd9, 0x35, 0x3d, - 0x95, 0x4e, 0x4a, 0xfe, 0x54, 0xd0, 0xa1, 0xb3, 0x1e, 0xa7, 0xd3, 0x98, 0x88, 0x37, 0x82, 0x0e, - 0xd1, 0x43, 0x58, 0xcb, 0xdc, 0x73, 0x21, 0x77, 0x36, 0xf4, 0x7c, 0x2b, 0xbd, 0xe9, 0x42, 0x8e, - 0xbf, 0x80, 0x7b, 0xaf, 0xe8, 0x3b, 0x73, 0x27, 0xdb, 0x02, 0x3d, 0x02, 0x88, 0x88, 0x10, 0xd1, - 0x84, 0xab, 0xca, 0xa8, 0xd8, 0x2a, 0xb3, 0x23, 0xf8, 0x14, 0x50, 0x76, 0x53, 0x7a, 0x87, 0x97, - 0x13, 0x02, 0x1c, 0xc0, 0xd6, 0x1b, 0xa6, 0x8a, 0xbb, 0xa0, 0x67, 0x3e, 0x85, 0xc8, 0x5b, 0x50, - 0x2d, 0x5a, 0xa0, 0x2a, 0x77, 0x38, 0xe5, 0x24, 0x01, 0xfa, 0x25, 0x37, 0xe9, 0xe3, 0x2e, 0x6c, - 0x17, 0xb4, 0x95, 0x12, 0x82, 0xba, 0x25, 0x04, 0xea, 0x38, 0x2f, 0x3f, 0xc0, 0x38, 0xfc, 0x19, - 0x6c, 0xbe, 0xfc, 0x00, 0xf1, 0x3f, 0x87, 0x8d, 0x4b, 0x7f, 0xcc, 0xb2, 0x08, 0x38, 0xff, 0xe0, - 0xb6, 0x20, 0xaa, 0x71, 0x82, 0xe9, 0x82, 0x68, 0x43, 0x8d, 0x04, 0x63, 0xc3, 0x75, 0x54, 0x13, - 0x7f, 0x0c, 0xed, 0x54, 0x64, 0x5a, 0x4a, 0x33, 0xd7, 0xd5, 0x1b, 0x70, 0x7a, 0x94, 0x51, 0x4e, - 0x24, 0x8d, 0xc1, 0x95, 0xb0, 0xe1, 0x62, 0x1b, 0x4a, 0x50, 0xb6, 0x95, 0x45, 0x59, 0x7c, 0x09, - 0x7b, 0x25, 0x62, 0x53, 0x96, 0x7c, 0xcd, 0x47, 0xfd, 0xa4, 0xac, 0x5b, 0xee, 0xea, 0x35, 0x1f, - 0x69, 0x74, 0xde, 0x87, 0x86, 0x9a, 0x8a, 0x78, 0x18, 0x8e, 0x8c, 0x58, 0xb5, 0xf6, 0x42, 0xf5, - 0xf1, 0xef, 0xe1, 0x58, 0x9d, 0x29, 0x83, 0x12, 0x17, 0x49, 0xbc, 0xad, 0xcd, 0x3f, 0x86, 0x66, - 0xf6, 0x0a, 0xaa, 0x68, 0xf4, 0xdb, 0x2b, 0x43, 0xa1, 0x98, 0x7d, 0x64, 0x57, 0x2f, 0xca, 0x29, - 0xfc, 0x43, 0x78, 0x70, 0x87, 0x01, 0x77, 0x78, 0x59, 0x59, 0x9e, 0x27, 0x05, 0xff, 0x67, 0xcb, - 0xbb, 0xd0, 0xee, 0x19, 0xc0, 0x49, 0x0c, 0xcd, 0xa1, 0x52, 0x25, 0x8f, 0x4a, 0xf8, 0x01, 0x34, - 0x17, 0x5d, 0xc8, 0x8f, 0xa1, 0xd9, 0x23, 0xe9, 0x2b, 0xa1, 0x0d, 0x35, 0x45, 0x85, 0xe3, 0x15, - 0xaa, 0xa9, 0x46, 0x52, 0xfa, 0xac, 0x9a, 0xf8, 0x4b, 0x58, 0x7f, 0x1e, 0x5f, 0x56, 0x76, 0xd7, - 0x47, 0xb0, 0x12, 0x5f, 0x5f, 0x9a, 0xe0, 0x36, 0xcf, 0x5a, 0xe6, 0xc0, 0x7a, 0x99, 0x6b, 0xe6, - 0xf0, 0x63, 0x58, 0xd6, 0x03, 0x1f, 0xf0, 0x1a, 0xfe, 0x18, 0x5a, 0x17, 0x11, 0x0f, 0x47, 0x19, - 0xf6, 0x12, 0xf8, 0x42, 0x52, 0x66, 0xc9, 0x57, 0xdc, 0xc3, 0x9f, 0xc0, 0x9a, 0x59, 0xb7, 0xa0, - 0x48, 0xbf, 0x82, 0x7b, 0x3d, 0x2a, 0x9f, 0xe9, 0xc7, 0x7d, 0xb2, 0xf8, 0x04, 0x56, 0xe2, 0xe7, - 0xbe, 0x89, 0x57, 0xfb, 0x34, 0xfe, 0x0e, 0x10, 0x5f, 0xb2, 0x6a, 0xa5, 0x99, 0x3f, 0xfb, 0x1b, - 0x00, 0x9c, 0x47, 0xfe, 0x25, 0xe5, 0xd7, 0x0a, 0xf5, 0xdf, 0x42, 0x33, 0xf3, 0x80, 0x44, 0xbb, - 0xe6, 0xd8, 0xc5, 0x07, 0x7c, 0xc7, 0x5e, 0xa0, 0x25, 0xaf, 0x4d, 0xbc, 0xf7, 0xfd, 0xdf, 0xff, - 0xf5, 0xc7, 0xea, 0x26, 0xba, 0xd7, 0xbd, 0x7e, 0xdc, 0x9d, 0x0a, 0xca, 0xbb, 0x8c, 0x0e, 0x34, - 0x8f, 0x40, 0xbf, 0x81, 0xdd, 0x97, 0x44, 0x52, 0x21, 0x5f, 0x70, 0x4e, 0xf5, 0xdb, 0x6e, 0x10, - 0xc4, 0x95, 0x38, 0x5f, 0xd5, 0x96, 0x99, 0xc8, 0x91, 0x2c, 0xbc, 0xa5, 0x95, 0xac, 0xa3, 0x56, - 0xa2, 0x44, 0xbd, 0x53, 0x39, 0x6c, 0x14, 0x1e, 0x6a, 0xe8, 0x30, 0xb5, 0xb4, 0xe4, 0x31, 0xd8, - 0x39, 0x9a, 0x37, 0x6d, 0xf4, 0x1c, 0x6b, 0x3d, 0x1d, 0xbc, 0x9d, 0xe8, 0x21, 0xe6, 0x1d, 0xaa, - 0x96, 0x3d, 0xa9, 0x3c, 0x42, 0x17, 0xb0, 0xa4, 0x5e, 0x6f, 0x68, 0x7e, 0x4d, 0x74, 0x36, 0xed, - 0x1b, 0x23, 0xf3, 0xca, 0xc3, 0x8e, 0x96, 0x8c, 0xf0, 0x5a, 0x22, 0xd9, 0x23, 0x41, 0xa0, 0x24, - 0xde, 0x02, 0x9a, 0x25, 0xf7, 0xe8, 0xd8, 0x08, 0x99, 0xcb, 0xfb, 0x93, 0xb3, 0xcc, 0x21, 0xfa, - 0x18, 0x6b, 0x8d, 0x07, 0x78, 0x37, 0xd1, 0xc8, 0xc9, 0xbb, 0x4c, 0xb9, 0x2a, 0xdd, 0x13, 0x58, - 0xcf, 0x33, 0x79, 0x74, 0x90, 0x7a, 0x68, 0x96, 0xe0, 0xcf, 0x89, 0xce, 0xac, 0xa6, 0x71, 0x6e, - 0xb7, 0xd2, 0xc4, 0xa0, 0x5d, 0xa4, 0xf4, 0xe8, 0x68, 0x56, 0x57, 0x96, 0xeb, 0xcf, 0xd1, 0xf6, - 0x91, 0xd6, 0x76, 0x84, 0xf7, 0xca, 0xb4, 0xe9, 0xfd, 0x4a, 0xdf, 0xf7, 0x15, 0xfd, 0x48, 0xc9, - 0x39, 0xc6, 0xa3, 0x7e, 0x24, 0x11, 0x4e, 0xb5, 0xce, 0xa3, 0xfe, 0x9d, 0x3b, 0x18, 0x23, 0xfe, - 0x54, 0xeb, 0x7f, 0x88, 0x8f, 0xb2, 0xfa, 0x67, 0xf5, 0x28, 0x23, 0xfa, 0xd0, 0x48, 0xbe, 0xa5, - 0x25, 0x29, 0x5f, 0xfc, 0x12, 0xd7, 0x71, 0x66, 0x27, 0x8c, 0xaa, 0x43, 0xad, 0x6a, 0x17, 0xa3, - 0x44, 0x95, 0xb0, 0x6b, 0x9e, 0x54, 0x1e, 0x7d, 0x5e, 0x31, 0x05, 0x6c, 0x41, 0x75, 0x7e, 0x55, - 0xd9, 0x89, 0x22, 0xfc, 0xe2, 0x03, 0xad, 0x61, 0x07, 0x6d, 0x65, 0x0f, 0x93, 0xc8, 0x7b, 0x0b, - 0xcd, 0xe7, 0xe9, 0xd7, 0x84, 0xbb, 0x72, 0x1e, 0xa5, 0x0a, 0x12, 0xd9, 0xf7, 0xb5, 0xec, 0x3d, - 0x9c, 0xca, 0xce, 0x7c, 0x9a, 0x50, 0xee, 0x21, 0xba, 0x7e, 0x63, 0x2c, 0x36, 0xe9, 0x67, 0xe5, - 0x64, 0x83, 0xb1, 0x9d, 0x45, 0xe3, 0x54, 0xfc, 0x43, 0x2d, 0xfe, 0x10, 0x3b, 0x59, 0xd3, 0xb3, - 0xc2, 0x62, 0x15, 0x90, 0x7e, 0xd0, 0x40, 0xfb, 0x36, 0xa1, 0x4a, 0xbe, 0x89, 0x74, 0xf6, 0xd2, - 0xbc, 0x28, 0x7c, 0x00, 0xc1, 0xfb, 0x5a, 0xd5, 0x36, 0x6e, 0x27, 0xaa, 0x86, 0xf1, 0x8a, 0x27, - 0x95, 0x47, 0x67, 0x7f, 0x05, 0x68, 0x9d, 0x0f, 0xaf, 0x7c, 0x66, 0x51, 0xf5, 0x5b, 0xa8, 0xdb, - 0xaf, 0x57, 0x8b, 0x23, 0x52, 0xfc, 0xce, 0x85, 0x3b, 0x5a, 0xd7, 0x16, 0xd2, 0x31, 0x27, 0x4a, - 0x6e, 0x82, 0x41, 0xc8, 0x03, 0x48, 0x09, 0x2d, 0xb2, 0x79, 0x33, 0x43, 0x8c, 0x93, 0xa3, 0xcc, - 0xb2, 0xdf, 0x3c, 0xc2, 0xe5, 0xc4, 0x77, 0x19, 0x7d, 0xa7, 0x5c, 0x16, 0xc2, 0x5a, 0x8e, 0x97, - 0x26, 0x5e, 0x2b, 0xe3, 0xc6, 0x9d, 0x83, 0xf2, 0xc9, 0xb2, 0x18, 0xe5, 0xb5, 0x4d, 0xf5, 0x06, - 0xa5, 0x70, 0x0c, 0xcd, 0x0c, 0x4f, 0x4d, 0xb2, 0x6c, 0x96, 0xeb, 0x26, 0x65, 0x59, 0x42, 0x6b, - 0xf1, 0x03, 0xad, 0x6a, 0x1f, 0xef, 0xcc, 0xaa, 0xb2, 0x8a, 0x18, 0x6c, 0x14, 0xc0, 0xf2, 0xae, - 0x94, 0x5e, 0x84, 0xaf, 0x25, 0x9e, 0x2c, 0xa0, 0xeb, 0xaf, 0xa0, 0x6e, 0xe9, 0x2f, 0xb2, 0x1f, - 0x9e, 0x0a, 0x14, 0x3b, 0xc9, 0x83, 0x22, 0x4f, 0xc6, 0x47, 0x5a, 0xbc, 0x83, 0x37, 0x53, 0xf1, - 0xc2, 0x1f, 0xb3, 0xee, 0xc4, 0x64, 0xf6, 0xb5, 0x62, 0x02, 0x05, 0x72, 0x8b, 0xee, 0x27, 0x39, - 0x5c, 0xce, 0xa6, 0x3b, 0xc7, 0xf3, 0x17, 0xcc, 0xd7, 0x3b, 0x50, 0x8b, 0x38, 0x61, 0x43, 0xa5, - 0xf7, 0x0f, 0x15, 0x38, 0x2c, 0xf0, 0xcf, 0x5f, 0xfa, 0x72, 0x92, 0x52, 0x49, 0xf4, 0x49, 0xe6, - 0x48, 0x77, 0x91, 0xcd, 0xce, 0xc9, 0xe2, 0x85, 0x79, 0x92, 0x81, 0xd7, 0xf3, 0xce, 0x50, 0xf6, - 0xfc, 0x59, 0xd9, 0x93, 0x0f, 0xd1, 0x3c, 0x7b, 0x16, 0x90, 0xdf, 0x85, 0x11, 0x3f, 0xd5, 0x56, - 0x9c, 0xe0, 0x87, 0xa5, 0x11, 0xcf, 0x6b, 0x55, 0xa6, 0x5d, 0x02, 0x5c, 0x4a, 0xc2, 0xa5, 0xa6, - 0x76, 0xc8, 0xd2, 0x82, 0x2c, 0x21, 0x4c, 0xae, 0xb8, 0x1c, 0xfb, 0xb3, 0x18, 0x80, 0x37, 0x52, - 0x45, 0x91, 0x5a, 0x10, 0x27, 0x55, 0x23, 0x61, 0x80, 0xf3, 0xe1, 0xc5, 0x49, 0xc1, 0x2c, 0x4f, - 0x16, 0x2d, 0x96, 0xa1, 0x4c, 0x7c, 0xc7, 0x89, 0xbc, 0x6f, 0xa1, 0x6e, 0x7f, 0xd4, 0x2c, 0x86, - 0xae, 0xe2, 0x2f, 0x9d, 0x32, 0xe8, 0x62, 0xe1, 0x90, 0xfa, 0x6c, 0x14, 0x0e, 0x56, 0xf4, 0x1f, - 0x82, 0x2f, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x75, 0xf5, 0x4d, 0x17, 0x2d, 0x1b, 0x00, 0x00, + 0x19, 0x87, 0xfc, 0x94, 0x3e, 0xc9, 0xb6, 0x42, 0xbf, 0xc6, 0xf2, 0x23, 0x0e, 0xb3, 0xd8, 0xf5, + 0x06, 0x5d, 0x6b, 0xe3, 0x05, 0xb6, 0x45, 0x8a, 0x2d, 0x90, 0xa4, 0x59, 0x6f, 0x8a, 0x20, 0x70, + 0xc7, 0x49, 0xbb, 0x40, 0x9b, 0x0a, 0xd4, 0x88, 0x92, 0xa6, 0x3b, 0xe6, 0x4c, 0x49, 0xca, 0x89, + 0x73, 0x29, 0xb0, 0xf7, 0x9e, 0x0a, 0x14, 0x3d, 0xf4, 0xd6, 0xbf, 0xa8, 0xe8, 0xa1, 0x97, 0x1e, + 0xfb, 0x77, 0x14, 0x05, 0x39, 0x24, 0xe7, 0xa1, 0x91, 0xd5, 0xf4, 0xd0, 0x1b, 0x9f, 0xdf, 0xf7, + 0xf1, 0x7b, 0xfc, 0xf8, 0xe3, 0x0c, 0x34, 0x78, 0x12, 0x9c, 0x26, 0x3c, 0x96, 0x31, 0x5a, 0xe6, + 0x49, 0x90, 0xf4, 0x3b, 0x07, 0xa3, 0x38, 0x1e, 0x45, 0xb4, 0x4b, 0x92, 0xb0, 0x4b, 0x18, 0x8b, + 0x25, 0x91, 0x61, 0xcc, 0x44, 0xba, 0xa8, 0xf3, 0xa3, 0x51, 0x28, 0xc7, 0x93, 0xfe, 0x69, 0x10, + 0x5f, 0x75, 0x19, 0xed, 0x4f, 0x22, 0x22, 0xc2, 0xb8, 0x3b, 0x8a, 0x3f, 0x33, 0x9d, 0x6e, 0x10, + 0x33, 0x41, 0x99, 0x98, 0x88, 0x6e, 0xd2, 0xef, 0x0a, 0x49, 0x24, 0x35, 0x3b, 0xbf, 0x9c, 0xb7, + 0x93, 0xd1, 0x7e, 0x44, 0xa5, 0xda, 0x16, 0xc4, 0x6c, 0x18, 0x8e, 0xd2, 0x7d, 0xf8, 0x01, 0xb4, + 0x2f, 0x27, 0x7d, 0x11, 0xf0, 0xb0, 0x4f, 0x7d, 0xfa, 0xbb, 0x09, 0x15, 0x12, 0xed, 0xc0, 0x8a, + 0x8c, 0x93, 0x30, 0x10, 0x5e, 0xed, 0x78, 0xf1, 0xa4, 0xe1, 0x9b, 0x1e, 0xfe, 0x0a, 0xee, 0xe4, + 0xd6, 0x8a, 0x44, 0xd9, 0x82, 0xb6, 0x60, 0x59, 0x4f, 0x7b, 0xb5, 0xe3, 0xda, 0x49, 0xc3, 0x4f, + 0x3b, 0x08, 0xc1, 0xd2, 0x80, 0x48, 0xe2, 0x2d, 0xe8, 0x41, 0xdd, 0xc6, 0x08, 0xda, 0x2f, 0x63, + 0x76, 0x41, 0x38, 0xb9, 0x12, 0x46, 0x15, 0xfe, 0xcb, 0x82, 0x1a, 0x1c, 0xd0, 0xe7, 0x6c, 0x18, + 0x3b, 0x91, 0xeb, 0xb0, 0x10, 0x0e, 0x8c, 0xbc, 0x85, 0x70, 0x80, 0xf6, 0xa0, 0x1e, 0x8c, 0x49, + 0xc8, 0x7a, 0xe1, 0x40, 0x0b, 0x5c, 0xf3, 0x57, 0x75, 0xff, 0xf9, 0x00, 0x75, 0xa0, 0x1e, 0xc4, + 0x21, 0xeb, 0x13, 0x41, 0xbd, 0x45, 0xbd, 0xc1, 0xf5, 0xd1, 0x21, 0x40, 0x42, 0x29, 0xef, 0x05, + 0xf1, 0x84, 0x49, 0x6f, 0x49, 0x6f, 0x6c, 0xa8, 0x91, 0xa7, 0x6a, 0x00, 0x61, 0x68, 0x89, 0x1b, + 0x16, 0x8c, 0x79, 0xcc, 0xc2, 0xf7, 0x74, 0xe0, 0x2d, 0x1f, 0xd7, 0x4e, 0xea, 0x7e, 0x61, 0x0c, + 0xdd, 0x85, 0x66, 0x7f, 0x12, 0x7c, 0x47, 0x65, 0x4f, 0x84, 0xef, 0xa9, 0xb7, 0x72, 0x5c, 0x3b, + 0x59, 0xf6, 0x21, 0x1d, 0xba, 0x0c, 0xdf, 0x53, 0xf4, 0x29, 0xb4, 0xb5, 0x1f, 0x83, 0x38, 0xea, + 0x5d, 0x53, 0x2e, 0xc2, 0x98, 0x79, 0xa0, 0xed, 0xd8, 0xb0, 0xe3, 0xbf, 0x48, 0x87, 0xd1, 0x19, + 0x34, 0x79, 0x3c, 0x91, 0xb4, 0x27, 0x49, 0x3f, 0xa2, 0x5e, 0xf3, 0x78, 0xf1, 0xa4, 0x79, 0x76, + 0xe7, 0x54, 0xa7, 0xc5, 0xa9, 0xaf, 0x66, 0x5e, 0xa9, 0x09, 0x1f, 0xb8, 0x6b, 0xe3, 0x2f, 0x01, + 0xb2, 0x99, 0x29, 0xbf, 0x78, 0xb0, 0x4a, 0x06, 0x03, 0x4e, 0x85, 0xf0, 0x16, 0x74, 0xa0, 0x6c, + 0x17, 0xff, 0xa3, 0x06, 0x9b, 0xe7, 0x54, 0xbe, 0xa4, 0xfd, 0x4b, 0x95, 0x23, 0xce, 0xb3, 0x79, + 0x4f, 0xd6, 0x8a, 0x9e, 0x44, 0xb0, 0x24, 0x49, 0x18, 0xd9, 0x88, 0xa9, 0x36, 0x6a, 0xc3, 0x62, + 0x14, 0xf6, 0x8d, 0x63, 0x55, 0x53, 0xa5, 0xc6, 0x98, 0x86, 0xa3, 0x71, 0xea, 0xcf, 0x25, 0xdf, + 0xf4, 0x2a, 0xfd, 0xb0, 0x52, 0xed, 0x87, 0xb2, 0xdf, 0x57, 0x2b, 0xfc, 0xee, 0xc1, 0xaa, 0x95, + 0x52, 0xd7, 0x52, 0x6c, 0x17, 0x7f, 0x0e, 0xed, 0xc7, 0x81, 0x8e, 0xa8, 0x70, 0xa7, 0x3a, 0x80, + 0x86, 0x39, 0x38, 0xb5, 0x29, 0x9b, 0x0d, 0xe0, 0x9f, 0xc1, 0xce, 0x39, 0x95, 0x66, 0x93, 0x71, + 0x47, 0x9a, 0xe7, 0x39, 0xff, 0xa5, 0x4e, 0xb5, 0xdd, 0xdc, 0x31, 0x17, 0xf2, 0xc7, 0xc4, 0x6f, + 0x60, 0x77, 0x4a, 0x96, 0x31, 0xc2, 0x83, 0xd5, 0x3e, 0x89, 0x08, 0x0b, 0xa8, 0x15, 0x66, 0xba, + 0xaa, 0x42, 0x58, 0xac, 0xc6, 0x53, 0x59, 0x69, 0x47, 0xfb, 0xfb, 0x26, 0x49, 0xb3, 0x76, 0xcd, + 0xd7, 0x6d, 0xfc, 0x5b, 0x68, 0x3d, 0x25, 0x51, 0xe4, 0x64, 0xee, 0xc0, 0x0a, 0xa7, 0x62, 0x12, + 0x49, 0x23, 0xd2, 0xf4, 0x54, 0x5a, 0xd2, 0x77, 0x34, 0x50, 0xc9, 0x44, 0x39, 0x37, 0x21, 0x03, + 0x33, 0xf4, 0x8c, 0x73, 0x74, 0x0f, 0x5a, 0x54, 0xc8, 0xf0, 0x8a, 0x48, 0xda, 0x1b, 0x11, 0x61, + 0x22, 0xd8, 0xb4, 0x63, 0xe7, 0x44, 0xe0, 0x53, 0xd8, 0x7a, 0x72, 0xf3, 0x24, 0x8a, 0x83, 0xef, + 0xbe, 0xd1, 0x67, 0xcb, 0x15, 0xbf, 0x39, 0x7a, 0xad, 0x70, 0xf4, 0x1f, 0x00, 0x3a, 0xa7, 0xf2, + 0xa7, 0x37, 0x8c, 0x08, 0x79, 0x93, 0xb7, 0xf0, 0x2a, 0x64, 0x94, 0x3b, 0xa8, 0x48, 0x7b, 0xf8, + 0xdf, 0x35, 0x40, 0xaf, 0x38, 0x61, 0x82, 0x04, 0x0a, 0xdf, 0xac, 0x70, 0x04, 0x4b, 0x43, 0x1e, + 0x5f, 0x99, 0xe3, 0xe8, 0xb6, 0xca, 0x6a, 0x19, 0x9b, 0x33, 0x2c, 0xc8, 0x58, 0xb9, 0xeb, 0x9a, + 0x44, 0x13, 0x5b, 0xcf, 0x69, 0x27, 0x73, 0xe2, 0x52, 0xde, 0x89, 0xfb, 0xd0, 0x18, 0x11, 0xd1, + 0x4b, 0x78, 0x18, 0x50, 0x5d, 0xc0, 0x0d, 0xbf, 0x3e, 0x22, 0xe2, 0x42, 0xf5, 0xed, 0x64, 0x14, + 0x5e, 0x85, 0xd2, 0x24, 0xa3, 0x9a, 0x7c, 0xa1, 0xfa, 0xe8, 0x4c, 0x01, 0x07, 0x93, 0x9c, 0x04, + 0x52, 0x67, 0x60, 0xf3, 0x6c, 0xc7, 0x94, 0xe2, 0x53, 0x33, 0x6c, 0x6c, 0xf6, 0xdd, 0x3a, 0x75, + 0xd8, 0x7e, 0xc8, 0x08, 0xbf, 0xd1, 0x25, 0xde, 0xf2, 0x4d, 0xcf, 0x85, 0x72, 0xcb, 0x94, 0x8e, + 0x0a, 0xe5, 0x7b, 0xd8, 0x28, 0x09, 0x52, 0xdb, 0x45, 0x3c, 0xe1, 0x2e, 0x41, 0x4c, 0x4f, 0x45, + 0x33, 0x6d, 0xf5, 0xb4, 0x14, 0x13, 0xcd, 0x74, 0xe8, 0xd5, 0x4d, 0x42, 0x15, 0xc8, 0x0d, 0x27, + 0x4c, 0x3b, 0xd2, 0x82, 0x9c, 0xed, 0x2b, 0xdd, 0x84, 0x8f, 0x84, 0x76, 0x4b, 0xc3, 0xd7, 0x6d, + 0xdc, 0x85, 0xbd, 0x4b, 0xca, 0x06, 0x3e, 0x79, 0x5b, 0x1d, 0x02, 0x8d, 0xcc, 0x35, 0x7d, 0x84, + 0x14, 0x99, 0x7f, 0x0d, 0xbb, 0x6a, 0x43, 0x61, 0x75, 0x16, 0x60, 0xf9, 0x6e, 0x4c, 0xc4, 0xd8, + 0x1a, 0x9d, 0xf6, 0x54, 0xc1, 0x5b, 0xbf, 0xf4, 0x32, 0x10, 0xd2, 0x05, 0x6f, 0xc7, 0x1f, 0x1b, + 0x30, 0xea, 0xc1, 0xf6, 0x39, 0x95, 0x3a, 0xd5, 0x9e, 0xdc, 0x7c, 0x43, 0xc4, 0x38, 0x67, 0x4a, + 0x4e, 0xb2, 0x6e, 0xa3, 0x33, 0xd8, 0x1e, 0x4e, 0xa2, 0xa8, 0x37, 0x0c, 0xa3, 0xa8, 0x27, 0x33, + 0x83, 0xb4, 0xf0, 0xba, 0xbf, 0xa9, 0x26, 0xbf, 0x0e, 0xa3, 0x28, 0x67, 0x2b, 0xa6, 0xba, 0x2a, + 0xad, 0x82, 0xff, 0x26, 0x9b, 0xff, 0x27, 0x35, 0x0f, 0x61, 0xff, 0x9c, 0xca, 0xdc, 0xc8, 0xdc, + 0xd3, 0xe0, 0x7f, 0x2e, 0xc2, 0x9a, 0xb6, 0xcb, 0xf9, 0xb3, 0xea, 0xcc, 0x77, 0xa1, 0x99, 0x10, + 0x4e, 0x99, 0xec, 0xe9, 0x29, 0x93, 0x00, 0xe9, 0x90, 0xd2, 0x90, 0x3b, 0xc5, 0x62, 0xe1, 0x14, + 0xd5, 0x45, 0x91, 0xbf, 0x13, 0x97, 0x4b, 0x77, 0xe2, 0x01, 0x34, 0x64, 0x78, 0x45, 0x85, 0x24, + 0x57, 0x89, 0xae, 0x89, 0x45, 0x3f, 0x1b, 0x28, 0x5c, 0x0f, 0xab, 0xc5, 0xeb, 0xe1, 0x10, 0x40, + 0xd3, 0x8d, 0x1e, 0x8f, 0x63, 0x69, 0x40, 0xb9, 0xa1, 0x47, 0xfc, 0x38, 0x96, 0x6a, 0xa7, 0x7c, + 0x27, 0xd2, 0xc9, 0x46, 0x0a, 0x7f, 0xf2, 0x9d, 0xd0, 0x53, 0x0a, 0xac, 0xae, 0x29, 0x93, 0x66, + 0x16, 0x0c, 0x58, 0xe9, 0x21, 0xbd, 0xe0, 0x31, 0xac, 0x3b, 0x5a, 0x93, 0xae, 0x69, 0xea, 0x82, + 0xec, 0x9c, 0xba, 0xe1, 0xb4, 0x2c, 0xd3, 0xb6, 0xda, 0xe3, 0xaf, 0x05, 0xf9, 0xae, 0x72, 0x84, + 0x06, 0x1e, 0xaf, 0x95, 0x62, 0x86, 0xee, 0x28, 0xcd, 0xa1, 0xe8, 0x0d, 0x43, 0x46, 0xa2, 0x50, + 0xde, 0x78, 0x6b, 0x3a, 0xb4, 0x10, 0x8a, 0xaf, 0xcd, 0x08, 0xfa, 0x09, 0xb4, 0x72, 0xb1, 0x17, + 0xde, 0x40, 0xdf, 0xc9, 0x1d, 0x03, 0x04, 0x15, 0xe5, 0xe0, 0x17, 0xd6, 0xe3, 0x3f, 0x2d, 0xc2, + 0x66, 0x55, 0xd1, 0x54, 0x05, 0xd9, 0x03, 0xeb, 0xcb, 0x32, 0x87, 0xb1, 0xa0, 0xb8, 0x38, 0x05, + 0x8a, 0x4b, 0xd3, 0xa0, 0xb8, 0x5c, 0x09, 0x8a, 0x2b, 0xf9, 0xf8, 0x17, 0x62, 0xbc, 0x5a, 0x8e, + 0xb1, 0x05, 0xab, 0x7a, 0x06, 0x56, 0x0e, 0x13, 0x1a, 0x19, 0x26, 0x14, 0xa1, 0x15, 0x6e, 0x83, + 0xd6, 0x66, 0x09, 0x5a, 0xab, 0xa0, 0xa1, 0x55, 0x09, 0x0d, 0x1a, 0x12, 0x25, 0x91, 0x13, 0xa1, + 0x83, 0xb3, 0xec, 0x9b, 0x9e, 0x4a, 0x27, 0x25, 0x7f, 0x22, 0xe8, 0xc0, 0x5b, 0x4f, 0xd3, 0x69, + 0x44, 0xc4, 0x6b, 0x41, 0x07, 0xe8, 0x3e, 0xac, 0xe5, 0xee, 0xbe, 0x98, 0x7b, 0x1b, 0x7a, 0xbe, + 0x95, 0xdd, 0x7e, 0x31, 0xc7, 0x5f, 0xc0, 0x9d, 0x97, 0xf4, 0xad, 0xb9, 0xa7, 0x6d, 0x81, 0x1e, + 0x01, 0x24, 0x44, 0x88, 0x64, 0xcc, 0x55, 0x65, 0xd4, 0x6c, 0x95, 0xd9, 0x11, 0x7c, 0x0a, 0x28, + 0xbf, 0x29, 0xbb, 0xd7, 0xab, 0x49, 0x02, 0x8e, 0x60, 0xeb, 0x35, 0x53, 0xc5, 0x5d, 0xd2, 0x33, + 0x9b, 0x56, 0x14, 0x2d, 0x58, 0x28, 0x5b, 0xa0, 0x2a, 0x77, 0x30, 0xe1, 0xc4, 0x01, 0xfd, 0x92, + 0xef, 0xfa, 0xb8, 0x0b, 0xdb, 0x25, 0x6d, 0x95, 0x24, 0xa1, 0x6e, 0x49, 0x82, 0x3a, 0xce, 0x8b, + 0x0f, 0x30, 0x0e, 0x7f, 0x06, 0x9b, 0x2f, 0x3e, 0x40, 0xfc, 0xcf, 0x61, 0xe3, 0x32, 0x1c, 0xb1, + 0x3c, 0x02, 0xce, 0x3e, 0xb8, 0x2d, 0x88, 0x85, 0x34, 0xc1, 0x74, 0x41, 0xb4, 0x61, 0x91, 0x44, + 0x23, 0xc3, 0x7f, 0x54, 0x13, 0x7f, 0x0c, 0xed, 0x4c, 0x64, 0x56, 0x4a, 0x53, 0xd7, 0xd5, 0x6b, + 0xf0, 0xce, 0x29, 0xa3, 0x9c, 0x48, 0x9a, 0x82, 0x2b, 0x61, 0x83, 0xf9, 0x36, 0x54, 0xa0, 0x6c, + 0x2b, 0x8f, 0xb2, 0xf8, 0x12, 0xf6, 0x2a, 0xc4, 0x66, 0xcc, 0xf9, 0x9a, 0x0f, 0x7b, 0xae, 0xac, + 0x5b, 0xfe, 0xea, 0x35, 0x1f, 0x6a, 0x74, 0xde, 0x87, 0x86, 0x9a, 0x4a, 0x78, 0x1c, 0x0f, 0x8d, + 0x58, 0xb5, 0xf6, 0x42, 0xf5, 0xf1, 0xef, 0xe1, 0x58, 0x9d, 0x29, 0x87, 0x12, 0x17, 0x2e, 0xde, + 0xd6, 0xe6, 0x1f, 0x43, 0x33, 0x7f, 0x05, 0xd5, 0x34, 0xfa, 0xed, 0x55, 0xa1, 0x50, 0xca, 0x48, + 0xf2, 0xab, 0xe7, 0xe5, 0x14, 0xfe, 0x21, 0xdc, 0xbb, 0xc5, 0x80, 0x5b, 0xbc, 0xac, 0x2c, 0x2f, + 0x92, 0x82, 0xff, 0xb3, 0xe5, 0x5d, 0x68, 0x9f, 0x1b, 0xc0, 0x71, 0x86, 0x16, 0x50, 0xa9, 0x56, + 0x44, 0x25, 0x7c, 0x0f, 0x9a, 0xf3, 0x2e, 0xe4, 0x87, 0xd0, 0x3c, 0x27, 0xd9, 0xcb, 0xa1, 0x0d, + 0x8b, 0x8a, 0x1e, 0xa7, 0x2b, 0x54, 0x53, 0x8d, 0x64, 0x94, 0x5a, 0x35, 0xf1, 0x97, 0xb0, 0xfe, + 0x2c, 0xbd, 0xac, 0xec, 0xae, 0x8f, 0x60, 0x25, 0xbd, 0xbe, 0x34, 0xe9, 0x6d, 0x9e, 0xb5, 0xcc, + 0x81, 0xf5, 0x32, 0xdf, 0xcc, 0xe1, 0x87, 0xb0, 0xac, 0x07, 0x3e, 0xe0, 0x85, 0xfc, 0x31, 0xb4, + 0x2e, 0x12, 0x1e, 0x0f, 0x73, 0xec, 0x25, 0x0a, 0x85, 0xa4, 0xcc, 0x92, 0xaf, 0xb4, 0x87, 0x3f, + 0x81, 0x35, 0xb3, 0x6e, 0x4e, 0x91, 0x7e, 0x05, 0x77, 0xce, 0xa9, 0x7c, 0xaa, 0x1f, 0xfc, 0x6e, + 0xf1, 0x09, 0xac, 0xa4, 0x9f, 0x00, 0x4c, 0xbc, 0xda, 0xa7, 0xe9, 0xb7, 0x81, 0xf4, 0x92, 0x55, + 0x2b, 0xcd, 0xfc, 0xd9, 0xdf, 0x00, 0xe0, 0x71, 0x12, 0x5e, 0x52, 0x7e, 0xad, 0x50, 0xff, 0x0d, + 0x34, 0x73, 0x8f, 0x4a, 0xb4, 0x6b, 0x8e, 0x5d, 0x7e, 0xd4, 0x77, 0xec, 0x05, 0x5a, 0xf1, 0x02, + 0xc5, 0x7b, 0xdf, 0xff, 0xfd, 0x5f, 0x7f, 0x5c, 0xd8, 0x44, 0x77, 0xba, 0xd7, 0x0f, 0xbb, 0x13, + 0x41, 0x79, 0x97, 0xd1, 0xbe, 0xe6, 0x11, 0xe8, 0x37, 0xb0, 0xfb, 0x82, 0x48, 0x2a, 0xe4, 0x73, + 0xce, 0xa9, 0x7e, 0xef, 0xf5, 0xa3, 0xb4, 0x12, 0x67, 0xab, 0xda, 0x32, 0x13, 0x05, 0x92, 0x85, + 0xb7, 0xb4, 0x92, 0x75, 0xd4, 0x72, 0x4a, 0xd4, 0xdb, 0x95, 0xc3, 0x46, 0xe9, 0xf1, 0x86, 0x0e, + 0x33, 0x4b, 0x2b, 0x1e, 0x88, 0x9d, 0xa3, 0x59, 0xd3, 0x46, 0xcf, 0xb1, 0xd6, 0xd3, 0xc1, 0xdb, + 0x4e, 0x0f, 0x31, 0x6f, 0x53, 0xb5, 0xec, 0x51, 0xed, 0x01, 0xba, 0x80, 0x25, 0xf5, 0xa2, 0x43, + 0xb3, 0x6b, 0xa2, 0xb3, 0x69, 0xdf, 0x1d, 0xb9, 0x97, 0x1f, 0xf6, 0xb4, 0x64, 0x84, 0xd7, 0x9c, + 0xe4, 0x80, 0x44, 0x91, 0x92, 0xf8, 0x1e, 0xd0, 0x34, 0xb9, 0x47, 0xc7, 0x46, 0xc8, 0x4c, 0xde, + 0xef, 0xce, 0x32, 0x83, 0xe8, 0x63, 0xac, 0x35, 0x1e, 0xe0, 0x5d, 0xa7, 0x91, 0x93, 0xb7, 0xb9, + 0x72, 0x55, 0xba, 0xc7, 0xb0, 0x5e, 0x64, 0xf2, 0xe8, 0x20, 0xf3, 0xd0, 0x34, 0xc1, 0x9f, 0x11, + 0x9d, 0x69, 0x4d, 0xa3, 0xc2, 0x6e, 0xa5, 0x89, 0x41, 0xbb, 0x4c, 0xe9, 0xd1, 0xd1, 0xb4, 0xae, + 0x3c, 0xd7, 0x9f, 0xa1, 0xed, 0x23, 0xad, 0xed, 0x08, 0xef, 0x55, 0x69, 0xd3, 0xfb, 0x95, 0xbe, + 0xef, 0x6b, 0xfa, 0x91, 0x52, 0x70, 0x4c, 0x40, 0xc3, 0x44, 0x22, 0x9c, 0x69, 0x9d, 0x45, 0xfd, + 0x3b, 0xb7, 0x30, 0x46, 0xfc, 0xa9, 0xd6, 0x7f, 0x1f, 0x1f, 0xe5, 0xf5, 0x4f, 0xeb, 0x51, 0x46, + 0xf4, 0xa0, 0xe1, 0xbe, 0xaf, 0xb9, 0x94, 0x2f, 0x7f, 0x9d, 0xeb, 0x78, 0xd3, 0x13, 0x46, 0xd5, + 0xa1, 0x56, 0xb5, 0x8b, 0x91, 0x53, 0x25, 0xec, 0x9a, 0x47, 0xb5, 0x07, 0x9f, 0xd7, 0x4c, 0x01, + 0x5b, 0x50, 0x9d, 0x5d, 0x55, 0x76, 0xa2, 0x0c, 0xbf, 0xf8, 0x40, 0x6b, 0xd8, 0x41, 0x5b, 0xf9, + 0xc3, 0x38, 0x79, 0x6f, 0xa0, 0xf9, 0x2c, 0xfb, 0xc2, 0x70, 0x5b, 0xce, 0xa3, 0x4c, 0x81, 0x93, + 0x7d, 0x57, 0xcb, 0xde, 0xc3, 0x99, 0xec, 0xdc, 0xe7, 0x0a, 0xe5, 0x1e, 0xa2, 0xeb, 0x37, 0xc5, + 0x62, 0x93, 0x7e, 0x56, 0x4e, 0x3e, 0x18, 0xdb, 0x79, 0x34, 0xce, 0xc4, 0xdf, 0xd7, 0xe2, 0x0f, + 0xb1, 0x97, 0x37, 0x3d, 0x2f, 0x2c, 0x55, 0x01, 0xd9, 0x47, 0x0e, 0xb4, 0x6f, 0x13, 0xaa, 0xe2, + 0x3b, 0x49, 0x67, 0x2f, 0xcb, 0x8b, 0xd2, 0x47, 0x11, 0xbc, 0xaf, 0x55, 0x6d, 0xe3, 0xb6, 0x53, + 0x35, 0x48, 0x57, 0x3c, 0xaa, 0x3d, 0x38, 0xfb, 0x2b, 0x40, 0xeb, 0xf1, 0xe0, 0x2a, 0x64, 0x16, + 0x55, 0xbf, 0x85, 0xba, 0xfd, 0xa2, 0x35, 0x3f, 0x22, 0xe5, 0x6f, 0x5f, 0xb8, 0xa3, 0x75, 0x6d, + 0x21, 0x1d, 0x73, 0xa2, 0xe4, 0x3a, 0x0c, 0x42, 0x01, 0x40, 0x46, 0x68, 0x91, 0xcd, 0x9b, 0x29, + 0x62, 0xec, 0x8e, 0x32, 0xcd, 0x7e, 0x8b, 0x08, 0x57, 0x10, 0xdf, 0x65, 0xf4, 0xad, 0x72, 0x59, + 0x0c, 0x6b, 0x05, 0x5e, 0xea, 0xbc, 0x56, 0xc5, 0x8d, 0x3b, 0x07, 0xd5, 0x93, 0x55, 0x31, 0x2a, + 0x6a, 0x9b, 0xe8, 0x0d, 0x4a, 0xe1, 0x08, 0x9a, 0x39, 0x9e, 0xea, 0xb2, 0x6c, 0x9a, 0xeb, 0xba, + 0xb2, 0xac, 0xa0, 0xb5, 0xf8, 0x9e, 0x56, 0xb5, 0x8f, 0x77, 0xa6, 0x55, 0x59, 0x45, 0x0c, 0x36, + 0x4a, 0x60, 0x79, 0x5b, 0x4a, 0xcf, 0xc3, 0xd7, 0x0a, 0x4f, 0x96, 0xd0, 0xf5, 0x57, 0x50, 0xb7, + 0xf4, 0x17, 0xd9, 0x8f, 0x51, 0x25, 0x8a, 0xed, 0xf2, 0xa0, 0xcc, 0x93, 0xf1, 0x91, 0x16, 0xef, + 0xe1, 0xcd, 0x4c, 0xbc, 0x08, 0x47, 0xac, 0x3b, 0x36, 0x99, 0x7d, 0xad, 0x98, 0x40, 0x89, 0xdc, + 0xa2, 0xbb, 0x2e, 0x87, 0xab, 0xd9, 0x74, 0xe7, 0x78, 0xf6, 0x82, 0xd9, 0x7a, 0xfb, 0x6a, 0x11, + 0x27, 0x6c, 0xa0, 0xf4, 0xfe, 0xa1, 0x06, 0x87, 0x25, 0xfe, 0xf9, 0xcb, 0x50, 0x8e, 0x33, 0x2a, + 0x89, 0x3e, 0xc9, 0x1d, 0xe9, 0x36, 0xb2, 0xd9, 0x39, 0x99, 0xbf, 0xb0, 0x48, 0x32, 0xf0, 0x7a, + 0xd1, 0x19, 0xca, 0x9e, 0x3f, 0x2b, 0x7b, 0x8a, 0x21, 0x9a, 0x65, 0xcf, 0x1c, 0xf2, 0x3b, 0x37, + 0xe2, 0xa7, 0xda, 0x8a, 0x13, 0x7c, 0xbf, 0x32, 0xe2, 0x45, 0xad, 0xca, 0xb4, 0x4b, 0x80, 0x4b, + 0x49, 0xb8, 0xd4, 0xd4, 0x0e, 0x59, 0x5a, 0x90, 0x27, 0x84, 0xee, 0x8a, 0x2b, 0xb0, 0x3f, 0x8b, + 0x01, 0x78, 0x23, 0x53, 0x94, 0xa8, 0x05, 0x69, 0x52, 0x35, 0x1c, 0x03, 0x9c, 0x0d, 0x2f, 0x5e, + 0x06, 0x66, 0x45, 0xb2, 0x68, 0xb1, 0x0c, 0xe5, 0xe2, 0x3b, 0x72, 0xf2, 0xbe, 0x85, 0xba, 0xfd, + 0x79, 0x33, 0x1f, 0xba, 0xca, 0xbf, 0x79, 0xaa, 0xa0, 0x8b, 0xc5, 0x03, 0x1a, 0xb2, 0x61, 0xdc, + 0x5f, 0xd1, 0x7f, 0x0d, 0xbe, 0xf8, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xe8, 0xf0, 0x86, + 0x41, 0x1b, 0x00, 0x00, } diff --git a/rpc/pb/rpc.pb.gw.go b/rpc/pb/rpc.pb.gw.go index 261c1ca80..797f1b102 100644 --- a/rpc/pb/rpc.pb.gw.go +++ b/rpc/pb/rpc.pb.gw.go @@ -50,7 +50,7 @@ func request_ApiService_GetAccountState_0(ctx context.Context, marshaler runtime var protoReq GetAccountStateRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -63,7 +63,7 @@ func request_ApiService_Call_0(ctx context.Context, marshaler runtime.Marshaler, var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -76,7 +76,7 @@ func request_ApiService_SendRawTransaction_0(ctx context.Context, marshaler runt var protoReq SendRawTransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -89,7 +89,7 @@ func request_ApiService_GetBlockByHash_0(ctx context.Context, marshaler runtime. var protoReq GetBlockByHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -102,7 +102,7 @@ func request_ApiService_GetBlockByHeight_0(ctx context.Context, marshaler runtim var protoReq GetBlockByHeightRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -115,7 +115,7 @@ func request_ApiService_GetTransactionReceipt_0(ctx context.Context, marshaler r var protoReq GetTransactionByHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -128,7 +128,7 @@ func request_ApiService_Subscribe_0(ctx context.Context, marshaler runtime.Marsh var protoReq SubscribeRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -158,7 +158,7 @@ func request_ApiService_EstimateGas_0(ctx context.Context, marshaler runtime.Mar var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -171,7 +171,7 @@ func request_ApiService_GetEventsByHash_0(ctx context.Context, marshaler runtime var protoReq HashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -184,7 +184,7 @@ func request_ApiService_GetDynasty_0(ctx context.Context, marshaler runtime.Mars var protoReq ByBlockHeightRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -206,7 +206,7 @@ func request_AdminService_NewAccount_0(ctx context.Context, marshaler runtime.Ma var protoReq NewAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -219,7 +219,7 @@ func request_AdminService_UnlockAccount_0(ctx context.Context, marshaler runtime var protoReq UnlockAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -232,7 +232,7 @@ func request_AdminService_LockAccount_0(ctx context.Context, marshaler runtime.M var protoReq LockAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -245,7 +245,7 @@ func request_AdminService_SendTransaction_0(ctx context.Context, marshaler runti var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -258,7 +258,7 @@ func request_AdminService_SignHash_0(ctx context.Context, marshaler runtime.Mars var protoReq SignHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -271,7 +271,7 @@ func request_AdminService_GenerateBlockRand_0(ctx context.Context, marshaler run var protoReq GenerateBlockRandRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -284,7 +284,7 @@ func request_AdminService_SignTransactionWithPassphrase_0(ctx context.Context, m var protoReq SignTransactionPassphraseRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -297,7 +297,7 @@ func request_AdminService_SendTransactionWithPassphrase_0(ctx context.Context, m var protoReq SendTransactionPassphraseRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -310,7 +310,7 @@ func request_AdminService_StartPprof_0(ctx context.Context, marshaler runtime.Ma var protoReq PprofRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -376,7 +376,7 @@ func RegisterApiServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ApiServiceClient) error { mux.Handle("GET", pattern_ApiService_GetNebState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -405,7 +405,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("GET", pattern_ApiService_LatestIrreversibleBlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -434,7 +434,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetAccountState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -463,7 +463,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_Call_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -492,7 +492,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_SendRawTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -521,7 +521,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetBlockByHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -550,7 +550,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetBlockByHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -579,7 +579,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetTransactionReceipt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -608,7 +608,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_Subscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -637,7 +637,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("GET", pattern_ApiService_GetGasPrice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -666,7 +666,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_EstimateGas_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -695,7 +695,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetEventsByHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -724,7 +724,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetDynasty_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -850,7 +850,7 @@ func RegisterAdminServiceHandler(ctx context.Context, mux *runtime.ServeMux, con func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AdminServiceClient) error { mux.Handle("GET", pattern_AdminService_Accounts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -879,7 +879,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_NewAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -908,7 +908,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_UnlockAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -937,7 +937,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_LockAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -966,7 +966,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SendTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -995,7 +995,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SignHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1024,7 +1024,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_GenerateBlockRand_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1053,7 +1053,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SignTransactionWithPassphrase_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1082,7 +1082,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SendTransactionWithPassphrase_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1111,7 +1111,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_StartPprof_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1140,7 +1140,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("GET", pattern_AdminService_GetConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1169,7 +1169,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("GET", pattern_AdminService_NodeInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) + ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { diff --git a/rpc/pb/rpc.proto b/rpc/pb/rpc.proto index ed4ef5075..a4fefbbc2 100644 --- a/rpc/pb/rpc.proto +++ b/rpc/pb/rpc.proto @@ -366,6 +366,9 @@ message TransactionRequest { // binary data for transaction bytes binary = 10; + + // transaction payload type, enum:binary, deploy, call + string type = 20; } message ContractRequest { From 6fb9bf5887f9920b2864f070c5e0c420217d2828 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Thu, 3 May 2018 15:49:38 +0800 Subject: [PATCH 56/69] random: change vrf seed --- account/manager.go | 22 +-- consensus/dpos/dpos.go | 53 +++--- core/block.go | 25 ++- core/block_pool.go | 167 +++++++------------ core/block_test.go | 5 +- core/blockchain.go | 48 ++++-- core/pb/block.pb.go | 103 ++++++------ core/pb/block.proto | 2 +- core/types.go | 4 +- nf/nvm/v8/lib/date.js | 1 + rpc/admin_service.go | 12 +- rpc/pb/rpc.pb.go | 369 +++++++++++++++++++++-------------------- rpc/pb/rpc.pb.gw.go | 104 ++++++------ rpc/pb/rpc.proto | 12 +- 14 files changed, 455 insertions(+), 472 deletions(-) diff --git a/account/manager.go b/account/manager.go index fa8e7fa10..d61d8daa5 100644 --- a/account/manager.go +++ b/account/manager.go @@ -21,6 +21,7 @@ package account import ( "errors" + "github.com/nebulasio/go-nebulas/crypto/hash" "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" "github.com/nebulasio/go-nebulas/util/byteutils" @@ -388,15 +389,8 @@ func (m *Manager) SignBlock(addr *core.Address, block *core.Block) error { return block.Sign(signature) } -// GenerateBlockRand generate rand -func (m *Manager) GenerateBlockRand(addr *core.Address, parentHashes []byteutils.Hash) (vrfHash, vrfProof []byte, err error) { - - if len(parentHashes) != core.VRFInputParentHashNumber { - logging.VLog().WithFields(logrus.Fields{ - "parent_hash_length": len(parentHashes), - }).Error("Parent hashes are not enough.") - return nil, nil, core.ErrInvalidArgument - } +// GenerateRandomSeed generate rand +func (m *Manager) GenerateRandomSeed(addr *core.Address, args ...[]byte) (vrfSeed, vrfProof []byte, err error) { key, err := m.ks.GetUnlocked(addr.String()) if err != nil { @@ -421,15 +415,13 @@ func (m *Manager) GenerateBlockRand(addr *core.Address, parentHashes []byteutils return nil, nil, err } - var data []byte - for _, h := range parentHashes { - data = append(data, []byte(h)...) - } - index, proof := signer.Evaluate(data) + data := hash.Sha3256(args...) + + seed, proof := signer.Evaluate(data) if proof == nil { return nil, nil, secp256k1VRF.ErrEvaluateFailed } - return index[:], proof, nil + return seed[:], proof, nil } // SignTransactionWithPassphrase sign transaction with the from passphrase diff --git a/consensus/dpos/dpos.go b/consensus/dpos/dpos.go index c08305f63..9b971bceb 100644 --- a/consensus/dpos/dpos.go +++ b/consensus/dpos/dpos.go @@ -378,7 +378,7 @@ func (dpos *Dpos) VerifyBlock(block *core.Block) error { } // check block random - if block.Height() >= core.RandomAvailableCompatibleHeight && !block.HasBlockRand() { + if block.Height() >= core.RandomAvailableCompatibleHeight && !block.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "blockHeight": block.Height(), "compatibleHeight": core.RandomAvailableCompatibleHeight, @@ -390,39 +390,37 @@ func (dpos *Dpos) VerifyBlock(block *core.Block) error { return nil } -func (dpos *Dpos) generateBlockSand(block *core.Block, adminService rpcpb.AdminServiceClient) error { +func (dpos *Dpos) generateRandomSeed(block *core.Block, adminService rpcpb.AdminServiceClient) error { if dpos.enableRemoteSignServer == true { if adminService == nil { return ErrInvalidArgument } // generate VRF hash,proof - if block.Height() >= core.RandomAvailableCompatibleHeight { - random, err := adminService.GenerateBlockRand( - context.Background(), - &rpcpb.GenerateBlockRandRequest{ - Address: dpos.miner.String(), - ParentHash: block.ParentHash(), - }) - if err != nil { - return err - } - block.SetBlockRand(random.VrfHash, random.VrfProof) + random, err := adminService.GenerateRandomSeed( + context.Background(), + &rpcpb.GenerateRandomSeedRequest{ + Address: dpos.miner.String(), + ParentHash: block.ParentHash(), + Height: block.Height(), + }) + if err != nil { + return err } + block.SetRandomSeed(random.VrfSeed, random.VrfProof) return nil } // generate VRF hash,proof - if block.Height() >= core.RandomAvailableCompatibleHeight { - hashes, err := dpos.chain.GetRecentNBlockHashBeforeInclusive(block.ParentHash(), core.VRFInputParentHashNumber) - if err != nil { - return err - } - vrfHash, vrfProof, err := dpos.am.GenerateBlockRand(dpos.miner, hashes) - if err != nil { - return err - } - block.SetBlockRand(vrfHash, vrfProof) + inputs, err := dpos.chain.GetInputForVRFSigner(block.ParentHash(), block.Height()) + if err != nil { + return err + } + vrfSeed, vrfProof, err := dpos.am.GenerateRandomSeed(dpos.miner, inputs...) + if err != nil { + return err } + block.SetRandomSeed(vrfSeed, vrfProof) + return nil } @@ -481,7 +479,9 @@ func (dpos *Dpos) newBlock(tail *core.Block, consensusState state.ConsensusState adminService = rpcpb.NewAdminServiceClient(conn) } - dpos.generateBlockSand(block, adminService) + if block.Height() >= core.RandomAvailableCompatibleHeight { + dpos.generateRandomSeed(block, adminService) + } block.WorldState().SetConsensusState(consensusState) block.SetTimestamp(consensusState.TimeStamp()) @@ -712,3 +712,8 @@ func (dpos *Dpos) findProposer(now int64) (proposer byteutils.Hash, err error) { } return proposer, nil } + +// NumberOfBlocksInDynasty number of blocks in one dynasty +func (dpos *Dpos) NumberOfBlocksInDynasty() uint64 { + return uint64(DynastyIntervalInMs) / uint64(BlockIntervalInMs) +} diff --git a/core/block.go b/core/block.go index 76b82e5d3..4a5283fe1 100644 --- a/core/block.go +++ b/core/block.go @@ -40,11 +40,6 @@ import ( "golang.org/x/crypto/sha3" ) -// const -const ( - VRFInputParentHashNumber = 7 -) - var ( // BlockHashLength define a const of the length of Hash of Block in byte. BlockHashLength = 32 @@ -199,7 +194,7 @@ func (block *Block) FromProto(msg proto.Message) error { if err := block.header.FromProto(msg.Header); err != nil { return err } - if msg.Height >= RandomAvailableCompatibleHeight && !block.HasBlockRand() { + if msg.Height >= RandomAvailableCompatibleHeight && !block.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "blockHeight": msg.Height, "compatibleHeight": RandomAvailableCompatibleHeight, @@ -288,17 +283,17 @@ func (block *Block) Sign(signature keystore.Signature) error { return nil } -// SetBlockRand set block.header.random -func (block *Block) SetBlockRand(vrfhash, vrfproof []byte) { +// SetRandomSeed set block.header.random +func (block *Block) SetRandomSeed(vrfseed, vrfproof []byte) { block.header.random = &corepb.Random{ - VrfHash: vrfhash, + VrfSeed: vrfseed, VrfProof: vrfproof, } } -// HasBlockRand check random if exists -func (block *Block) HasBlockRand() bool { - return block.header.random != nil && block.header.random.VrfHash != nil && block.header.random.VrfProof != nil +// HasRandomSeed check random if exists +func (block *Block) HasRandomSeed() bool { + return block.header.random != nil && block.header.random.VrfSeed != nil && block.header.random.VrfProof != nil } // ChainID returns block's chainID @@ -389,7 +384,7 @@ func (block *Block) Transactions() Transactions { // RandomSeed block random seed (VRF) func (block *Block) RandomSeed() string { if block.height >= RandomAvailableCompatibleHeight { - return byteutils.Hex(block.header.random.VrfHash) + return byteutils.Hex(block.header.random.VrfSeed) } return "" } @@ -796,8 +791,8 @@ func (block *Block) Seal() error { func (block *Block) String() string { random := "" if block.height >= RandomAvailableCompatibleHeight && block.header.random != nil { - if block.header.random.VrfHash != nil { - random += "/vrf_hash/" + byteutils.Hex(block.header.random.VrfHash) + if block.header.random.VrfSeed != nil { + random += "/vrf_seed/" + byteutils.Hex(block.header.random.VrfSeed) } if block.header.random.VrfProof != nil { random += "/vrf_proof/" + byteutils.Hex(block.header.random.VrfProof) diff --git a/core/block_pool.go b/core/block_pool.go index 343941497..69d83d600 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -27,6 +27,7 @@ import ( lru "github.com/hashicorp/golang-lru" "github.com/nebulasio/go-nebulas/core/pb" "github.com/nebulasio/go-nebulas/crypto" + "github.com/nebulasio/go-nebulas/crypto/hash" "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/vrf/secp256k1VRF" "github.com/nebulasio/go-nebulas/net" @@ -450,14 +451,7 @@ func (pool *BlockPool) push(sender string, block *Block) error { return err } - // VRF verify - newAllBlocks, newTailBlocks := pool.verifyVRFOfForks(parentBlock, allBlocks, tailBlocks) - if len(newTailBlocks) == 0 { - cache.Remove(lb.hash.Hex()) - return nil - } - - if err := bc.putVerifiedNewBlocks(parentBlock, newAllBlocks, newTailBlocks); err != nil { + if err := bc.putVerifiedNewBlocks(parentBlock, allBlocks, tailBlocks); err != nil { cache.Remove(lb.hash.Hex()) return err } @@ -470,101 +464,7 @@ func (pool *BlockPool) push(sender string, block *Block) error { return pool.bc.ConsensusHandler().ForkChoice() } -func (pool *BlockPool) verifyVRFOfForks(parent *Block, allBlocks, tailBlocks []*Block) (newAll, newTails []*Block) { - - allBlocksMap := make(map[string]*Block) - for _, b := range allBlocks { - allBlocksMap[b.Hash().String()] = b - } - - for _, tail := range tailBlocks { - - forkAll, valid := pool.verifyVRFOfFork(parent, tail, allBlocksMap) - if !valid { - logging.VLog().WithFields(logrus.Fields{ - "parent": parent, - "tail": tail, - }).Error("Discard an invalid fork for VRF verification failure.") - continue - } - newAll = append(newAll, forkAll...) - newTails = append(newTails, tail) - } - return -} - -func (pool *BlockPool) verifyVRFOfFork(stop, tail *Block, allBlocksMap map[string]*Block) (allBlocks []*Block, valid bool) { - - for stop.Height() < tail.Height() { - - tph := tail.ParentHash() - allBlocks = append(allBlocks, tail) - - if tail.Height() < RandomAvailableCompatibleHeight { - var ok bool - tail, ok = allBlocksMap[tph.String()] - if !ok { - tail = pool.bc.GetBlock(tph) - } - if tail == nil { - // Normally, should not be here - logging.VLog().WithFields(logrus.Fields{ - "blockHash": tph, - "traverseStop": stop, - }).Error("Parent block not found for VRF input") - return nil, false - } - continue - } - - hashes := make([]byteutils.Hash, 0) - p := tph - for i := 0; i < VRFInputParentHashNumber; i++ { - - b, ok := allBlocksMap[p.String()] - if !ok { - b = pool.bc.GetBlock(p) - } - if b == nil { - break - } - hashes = append(hashes, p) - p = b.ParentHash() - } - if len(hashes) != VRFInputParentHashNumber { - logging.VLog().WithFields(logrus.Fields{ - "tail": tail, - "traverseStop": stop, - "hashes": hashes, - }).Error("Failed to get enough parent block hash for VRF.") - return nil, false - } - - if err := pool.vrfProof(tail, hashes); err != nil { - logging.VLog().WithFields(logrus.Fields{ - "err": err, - }).Error("VRF proof failed.") - return nil, false - } - - var ok bool - tail, ok = allBlocksMap[tph.String()] - if !ok { - tail = pool.bc.GetBlock(tph) - } - if tail == nil { - // Normally, should not be here - logging.VLog().WithFields(logrus.Fields{ - "blockHash": tph, - "traverseStop": stop, - }).Error("Parent block not found for VRF input") - return nil, false - } - } - return allBlocks, true -} - -func (pool *BlockPool) vrfProof(block *Block, pHashes []byteutils.Hash) error { +func vrfProof(block *Block, args [][]byte) error { signature, err := crypto.NewSignature(block.Alg()) if err != nil { return err @@ -586,10 +486,7 @@ func (pool *BlockPool) vrfProof(block *Block, pHashes []byteutils.Hash) error { return err } - var data []byte - for _, h := range pHashes { - data = append(data, []byte(h)...) - } + data := hash.Sha3256(args...) index, err := verifier.ProofToHash(data, block.header.random.VrfProof) if err != nil { logging.VLog().WithFields(logrus.Fields{ @@ -598,7 +495,7 @@ func (pool *BlockPool) vrfProof(block *Block, pHashes []byteutils.Hash) error { return err } - if !bytes.Equal(index[:], block.header.random.VrfHash) { + if !bytes.Equal(index[:], block.header.random.VrfSeed) { logging.VLog().WithFields(logrus.Fields{ "block": block, }).Error("VRF proof failed.") @@ -637,6 +534,60 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( return nil, nil, err } + // verify vrf + if lb.block.height >= RandomAvailableCompatibleHeight { + // prepare vrf inputs + inputs := make([][]byte, 0) + + nob := lb.chain.ConsensusHandler().NumberOfBlocksInDynasty() + i := uint64(0) + tmp := lb + for i < nob*2 && tmp != nil { + i++ + tmp = tmp.parentBlock + } + if tmp == nil { + if lb.block.height > nob*2 { + b := lb.chain.GetBlockOnCanonicalChainByHeight(lb.block.height - nob*2) + if b == nil { + logging.VLog().WithFields(logrus.Fields{ + "blockHeight": lb.block.height, + "targetHeight": lb.block.height - nob, + "numOfBlocksInDynasty": nob, + }).Error("Block not found.") + metricsUnexpectedBehavior.Update(1) + return nil, nil, ErrNotBlockInCanonicalChain + } + inputs = append(inputs, b.Hash()) + } else { + inputs = append(inputs, lb.chain.GenesisBlock().Hash()) + } + } else { + inputs = append(inputs, tmp.block.Hash()) + } + + if parentBlock.height >= RandomAvailableCompatibleHeight { + if !parentBlock.HasRandomSeed() { + logging.VLog().WithFields(logrus.Fields{ + "parent": parentBlock, + }).Error("Parent block has no random seed.") + metricsUnexpectedBehavior.Update(1) + return nil, nil, ErrInvalidBlockRandom + } + inputs = append(inputs, parentBlock.header.random.VrfSeed) + } else { + inputs = append(inputs, lb.chain.GenesisBlock().Hash()) + } + + if err := vrfProof(lb.block, inputs); err != nil { + logging.CLog().WithFields(logrus.Fields{ + "err": err, + "lb.block": lb.block, + }).Error("VRF proof failed.") + return nil, nil, ErrVRFProofFailed + } + } + if err := lb.block.VerifyExecution(); err != nil { logging.VLog().WithFields(logrus.Fields{ "block": lb.block, diff --git a/core/block_test.go b/core/block_test.go index fbee602d8..0c822d61f 100644 --- a/core/block_test.go +++ b/core/block_test.go @@ -199,6 +199,9 @@ func (c *mockConsensus) NewState(root *consensuspb.ConsensusRoot, stor storage.S func (c *mockConsensus) GenesisConsensusState(*BlockChain, *corepb.Genesis) (state.ConsensusState, error) { return newMockConsensusState(0) } +func (c *mockConsensus) NumberOfBlocksInDynasty() uint64 { + return 210 +} type mockManager struct{} @@ -219,7 +222,7 @@ func (m mockManager) Update(*Address, []byte, []byte) error { return nil } func (m mockManager) Load([]byte, []byte) (*Address, error) { return nil, nil } func (m mockManager) Import([]byte, []byte) (*Address, error) { return nil, nil } func (m mockManager) Remove(*Address, []byte) error { return nil } -func (m mockManager) GenerateBlockRand(addr *Address, parentHashes []byteutils.Hash) (vrfHash, vrfProof []byte, err error) { +func (m mockManager) GenerateRandomSeed(addr *Address, args ...[]byte) (vrfSeed, vrfProof []byte, err error) { return nil, nil, nil } diff --git a/core/blockchain.go b/core/blockchain.go index 50ed0be74..7d1585550 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -466,19 +466,43 @@ func (bc *BlockChain) GetBlockOnCanonicalChainByHash(blockHash byteutils.Hash) * return blockByHeight } -// GetRecentNBlockHashBeforeInclusive read hashes of 'N' on-chain parent blocks before hash(inclusive) as VRF input. -// hashes order: from back to front -func (bc *BlockChain) GetRecentNBlockHashBeforeInclusive(hash byteutils.Hash, n int) (hashes []byteutils.Hash, err error) { - if n == 0 || hash == nil { +// GetInputForVRFSigner returns [ getBlock(block.height - 2 * dynasty.size).hash, block.parent.seed ] +func (bc *BlockChain) GetInputForVRFSigner(parentHash byteutils.Hash, height uint64) (out [][]byte, err error) { + if parentHash == nil || height < RandomAvailableCompatibleHeight { return nil, ErrInvalidArgument } - for i := 0; i < n; i++ { - block := bc.GetBlockOnCanonicalChainByHash(hash) - if block == nil { + + nob := bc.consensusHandler.NumberOfBlocksInDynasty() + if height > nob*2 { + b := bc.GetBlockOnCanonicalChainByHeight(height - nob*2) + if b == nil { + logging.VLog().WithFields(logrus.Fields{ + "blockHeight": height, + "targetHeight": height - nob, + "numOfBlocksInDynasty": nob, + }).Error("Block not found.") return nil, ErrNotBlockInCanonicalChain } - hashes = append(hashes, hash) - hash = block.ParentHash() + out = append(out, b.Hash()) + } else { + out = append(out, bc.GenesisBlock().Hash()) + } + + parent := bc.GetBlockOnCanonicalChainByHash(parentHash) + if parent == nil { + return nil, ErrNotBlockInCanonicalChain + } + + if parent.height >= RandomAvailableCompatibleHeight { + if !parent.HasRandomSeed() { + logging.VLog().WithFields(logrus.Fields{ + "parent": parent, + }).Info("Parent block has no random seed.") + return nil, ErrInvalidBlockRandom + } + out = append(out, parent.header.random.VrfSeed) + } else { + out = append(out, bc.GenesisBlock().Hash()) } return } @@ -697,10 +721,10 @@ func (bc *BlockChain) SimulateTransactionExecution(tx *Transaction) (*SimulateRe return nil, err } - sVrfHash, sVrfProof := make([]byte, 32), make([]byte, 129) - _, _ = io.ReadFull(rand.Reader, sVrfHash) + sVrfSeed, sVrfProof := make([]byte, 32), make([]byte, 129) + _, _ = io.ReadFull(rand.Reader, sVrfSeed) _, _ = io.ReadFull(rand.Reader, sVrfProof) - block.header.random.VrfHash = sVrfHash + block.header.random.VrfSeed = sVrfSeed block.header.random.VrfProof = sVrfProof defer block.RollBack() diff --git a/core/pb/block.pb.go b/core/pb/block.pb.go index 5911b588c..f6d575257 100644 --- a/core/pb/block.pb.go +++ b/core/pb/block.pb.go @@ -446,7 +446,7 @@ func (m *DownloadBlock) GetSign() []byte { } type Random struct { - VrfHash []byte `protobuf:"bytes,1,opt,name=vrf_hash,json=vrfHash,proto3" json:"vrf_hash,omitempty"` + VrfSeed []byte `protobuf:"bytes,1,opt,name=vrf_seed,json=vrfSeed,proto3" json:"vrf_seed,omitempty"` VrfProof []byte `protobuf:"bytes,2,opt,name=vrf_proof,json=vrfProof,proto3" json:"vrf_proof,omitempty"` } @@ -455,9 +455,9 @@ func (m *Random) String() string { return proto.CompactTextString(m) func (*Random) ProtoMessage() {} func (*Random) Descriptor() ([]byte, []int) { return fileDescriptorBlock, []int{8} } -func (m *Random) GetVrfHash() []byte { +func (m *Random) GetVrfSeed() []byte { if m != nil { - return m.VrfHash + return m.VrfSeed } return nil } @@ -484,52 +484,53 @@ func init() { func init() { proto.RegisterFile("block.proto", fileDescriptorBlock) } var fileDescriptorBlock = []byte{ - // 749 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x5f, 0x8b, 0xeb, 0x44, - 0x14, 0x27, 0x6d, 0x9a, 0xb6, 0x27, 0xed, 0xb2, 0x8c, 0x8b, 0xc4, 0xaa, 0x6c, 0x89, 0x28, 0x45, - 0xb1, 0x85, 0x55, 0x58, 0x1f, 0x5d, 0xdd, 0x87, 0x55, 0x44, 0x96, 0xc1, 0x17, 0x41, 0x28, 0x93, - 0x64, 0x9a, 0x04, 0x93, 0x99, 0x30, 0x33, 0xad, 0xbb, 0x1f, 0xc1, 0x47, 0xbf, 0x87, 0x2f, 0xf7, - 0x1b, 0x5e, 0xe6, 0x4c, 0xd2, 0xa6, 0x7b, 0x17, 0x2e, 0xf7, 0x29, 0xf3, 0x3b, 0xbf, 0xf9, 0x9d, - 0x9c, 0xbf, 0x03, 0x61, 0x52, 0xc9, 0xf4, 0xef, 0x75, 0xa3, 0xa4, 0x91, 0x24, 0x48, 0xa5, 0xe2, - 0x4d, 0xb2, 0xb8, 0xcd, 0x4b, 0x53, 0xec, 0x93, 0x75, 0x2a, 0xeb, 0x8d, 0xe0, 0xc9, 0xbe, 0x62, - 0xba, 0x94, 0x9b, 0x5c, 0x7e, 0xdb, 0x82, 0x4d, 0x2a, 0xeb, 0x5a, 0x8a, 0x4d, 0xc6, 0xf2, 0x4d, - 0x93, 0xd8, 0x8f, 0x73, 0xb0, 0xf8, 0xe1, 0xfd, 0x42, 0xa1, 0xb9, 0xd0, 0x7b, 0x6d, 0x75, 0xda, - 0x30, 0xc3, 0x9d, 0x32, 0xfe, 0xcf, 0x83, 0xf1, 0x5d, 0x9a, 0xca, 0xbd, 0x30, 0x24, 0x82, 0x31, - 0xcb, 0x32, 0xc5, 0xb5, 0x8e, 0xbc, 0xa5, 0xb7, 0x9a, 0xd1, 0x0e, 0x5a, 0x26, 0x61, 0x15, 0x13, - 0x29, 0x8f, 0x06, 0x8e, 0x69, 0x21, 0xb9, 0x82, 0x91, 0x90, 0xd6, 0x3e, 0x5c, 0x7a, 0x2b, 0x9f, - 0x3a, 0x40, 0x3e, 0x85, 0xe9, 0x81, 0x29, 0xbd, 0x2d, 0x98, 0x2e, 0x22, 0x1f, 0x15, 0x13, 0x6b, - 0x78, 0x60, 0xba, 0x20, 0xd7, 0x10, 0x26, 0xa5, 0x32, 0xc5, 0xb6, 0xa9, 0x58, 0xca, 0xa3, 0x11, - 0xd2, 0x80, 0xa6, 0x47, 0x6b, 0x89, 0xbf, 0x07, 0xff, 0x9e, 0x19, 0x46, 0x08, 0xf8, 0xe6, 0xb9, - 0xe1, 0x18, 0xcc, 0x94, 0xe2, 0xd9, 0x46, 0xd2, 0xb0, 0xe7, 0x4a, 0xb2, 0xac, 0x8b, 0xa4, 0x85, - 0xf1, 0xff, 0x03, 0x08, 0xff, 0x50, 0x4c, 0x68, 0x96, 0x9a, 0x52, 0x0a, 0xab, 0xc6, 0xdf, 0xbb, - 0x54, 0xf0, 0x6c, 0x6d, 0x3b, 0x25, 0xeb, 0x56, 0x8a, 0x67, 0x72, 0x01, 0x03, 0x23, 0x31, 0xfc, - 0x19, 0x1d, 0x18, 0x69, 0x33, 0x3a, 0xb0, 0x6a, 0xcf, 0xdb, 0xb8, 0x1d, 0x38, 0xe5, 0x39, 0xea, - 0xe7, 0xf9, 0x19, 0x4c, 0x4d, 0x59, 0x73, 0x6d, 0x58, 0xdd, 0x44, 0xc1, 0xd2, 0x5b, 0x0d, 0xe9, - 0xc9, 0x40, 0x96, 0xe0, 0x67, 0xcc, 0xb0, 0x68, 0xbc, 0xf4, 0x56, 0xe1, 0xcd, 0x6c, 0xed, 0xba, - 0xbc, 0xb6, 0xb9, 0x51, 0x64, 0xc8, 0x27, 0x30, 0x49, 0x0b, 0x56, 0x8a, 0x6d, 0x99, 0x45, 0x93, - 0xa5, 0xb7, 0x9a, 0xd3, 0x31, 0xe2, 0x5f, 0x32, 0x5b, 0xc2, 0x9c, 0xe9, 0x6d, 0xa3, 0xca, 0x94, - 0x47, 0x53, 0x57, 0xc2, 0x9c, 0xe9, 0x47, 0x8b, 0x3b, 0xb2, 0x2a, 0xeb, 0xd2, 0x44, 0x70, 0x24, - 0x7f, 0xb3, 0x98, 0x5c, 0xc2, 0x90, 0x55, 0x79, 0x14, 0xa2, 0x3f, 0x7b, 0xb4, 0x69, 0xeb, 0x32, - 0x17, 0xd1, 0xcc, 0xa5, 0x6d, 0xcf, 0xf1, 0xbf, 0x43, 0x08, 0x7f, 0xb2, 0x33, 0xf8, 0xc0, 0x59, - 0xc6, 0xd5, 0xab, 0xe5, 0xba, 0x86, 0xb0, 0x61, 0x8a, 0x0b, 0xe3, 0x1a, 0xe9, 0xaa, 0x06, 0xce, - 0x84, 0xad, 0x5c, 0xc0, 0x24, 0x95, 0xa5, 0x48, 0x98, 0xee, 0xca, 0x75, 0xc4, 0xe7, 0xb5, 0x19, - 0xbd, 0xac, 0x4d, 0x3f, 0xf3, 0xe0, 0x3c, 0xf3, 0x36, 0xfe, 0xf1, 0xbb, 0xf1, 0x4f, 0x4e, 0xf1, - 0x93, 0xcf, 0x01, 0x70, 0x8e, 0xb7, 0x4a, 0x4a, 0xd3, 0x16, 0x68, 0x8a, 0x16, 0x2a, 0xa5, 0xb1, - 0xfe, 0xcd, 0x93, 0x76, 0xa4, 0x2b, 0xd0, 0xd8, 0x3c, 0x69, 0xa4, 0xae, 0x21, 0xe4, 0x07, 0x2e, - 0x4c, 0xcb, 0x86, 0x2e, 0x2b, 0x67, 0xc2, 0x0b, 0x77, 0x70, 0x71, 0xdc, 0x17, 0x77, 0x67, 0x86, - 0x1d, 0x5c, 0xac, 0x8f, 0xe6, 0x26, 0x59, 0xff, 0xdc, 0x9d, 0xad, 0x86, 0xce, 0xd3, 0x3e, 0x24, - 0x5f, 0x41, 0xa0, 0x98, 0xc8, 0x64, 0x1d, 0xcd, 0x51, 0x7a, 0xd1, 0x35, 0x9f, 0xa2, 0x95, 0xb6, - 0xec, 0xaf, 0xfe, 0x64, 0x78, 0xe9, 0xc7, 0x6f, 0x3c, 0x18, 0x61, 0x2f, 0xc8, 0x37, 0x10, 0x14, - 0xd8, 0x0f, 0xec, 0x43, 0x78, 0xf3, 0x51, 0xa7, 0xeb, 0xb5, 0x8a, 0xb6, 0x57, 0xc8, 0x2d, 0xcc, - 0xcc, 0x69, 0xe0, 0x75, 0x34, 0x58, 0x0e, 0xfb, 0x92, 0xde, 0x32, 0xd0, 0xb3, 0x8b, 0xe4, 0x6b, - 0x80, 0x8c, 0x37, 0x5c, 0x64, 0x5c, 0xa4, 0xcf, 0x38, 0xfa, 0xe1, 0x0d, 0xac, 0x33, 0x96, 0xe3, - 0x74, 0xe6, 0xb4, 0xc7, 0x92, 0x8f, 0x6d, 0x44, 0x65, 0x5e, 0x18, 0x6c, 0xb0, 0x4f, 0x5b, 0x14, - 0xff, 0x05, 0xd3, 0xdf, 0xb9, 0xc1, 0xb0, 0xf4, 0x71, 0xaf, 0xda, 0x4d, 0xc5, 0xbd, 0xba, 0x82, - 0x51, 0xc2, 0x4c, 0xea, 0xc6, 0xc6, 0xa7, 0x0e, 0x90, 0x2f, 0x21, 0xc0, 0x97, 0x4f, 0x47, 0x43, - 0x8c, 0x76, 0x7e, 0x96, 0x20, 0x6d, 0xc9, 0xf8, 0x4f, 0x98, 0x74, 0xde, 0x3f, 0xc0, 0xf9, 0x17, - 0x30, 0x42, 0x7d, 0x9b, 0xd2, 0x0b, 0xdf, 0x8e, 0x8b, 0x6f, 0x61, 0x7e, 0x2f, 0xff, 0x11, 0xf6, - 0xcd, 0x38, 0xfa, 0x7f, 0xed, 0xa1, 0xc0, 0x89, 0x1b, 0xf4, 0x36, 0xe6, 0x47, 0x08, 0x5c, 0xf7, - 0xec, 0x70, 0x1d, 0xd4, 0x6e, 0xdb, 0x53, 0x8d, 0x0f, 0x6a, 0x87, 0x1b, 0x61, 0x5f, 0x3e, 0xb5, - 0xdb, 0x36, 0x4a, 0xca, 0x5d, 0xab, 0xb6, 0x77, 0x1f, 0x2d, 0x4e, 0x02, 0x7c, 0x73, 0xbf, 0x7b, - 0x1b, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xa5, 0xbd, 0xd2, 0xfd, 0x05, 0x00, 0x00, + // 754 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x5f, 0x8b, 0xdb, 0x46, + 0x10, 0x47, 0xb6, 0x2c, 0xdb, 0x23, 0xfb, 0x38, 0xb6, 0x47, 0x51, 0xdd, 0x96, 0x33, 0x2a, 0x2d, + 0xa6, 0xa5, 0x36, 0x5c, 0x0b, 0xd7, 0xc7, 0x5e, 0x72, 0x0f, 0x97, 0x10, 0xc2, 0xb1, 0xc9, 0x4b, + 0x20, 0x60, 0x56, 0xd2, 0x5a, 0x12, 0x91, 0x76, 0x85, 0x76, 0xed, 0xdc, 0x7d, 0x84, 0x3c, 0xe6, + 0x7b, 0xe4, 0x25, 0xdf, 0x30, 0xec, 0xac, 0x64, 0xcb, 0x97, 0x83, 0x90, 0x27, 0xed, 0x6f, 0x7e, + 0x3b, 0xa3, 0xf9, 0xcd, 0x9f, 0x05, 0x3f, 0x2a, 0x64, 0xfc, 0x6e, 0x59, 0xd5, 0x52, 0x4b, 0xe2, + 0xc5, 0xb2, 0xe6, 0x55, 0x34, 0xbb, 0x4c, 0x73, 0x9d, 0x6d, 0xa3, 0x65, 0x2c, 0xcb, 0x95, 0xe0, + 0xd1, 0xb6, 0x60, 0x2a, 0x97, 0xab, 0x54, 0xfe, 0xdd, 0x80, 0x55, 0x2c, 0xcb, 0x52, 0x8a, 0x55, + 0xc2, 0xd2, 0x55, 0x15, 0x99, 0x8f, 0x0d, 0x30, 0xfb, 0xef, 0xdb, 0x8e, 0x42, 0x71, 0xa1, 0xb6, + 0xca, 0xf8, 0x29, 0xcd, 0x34, 0xb7, 0x9e, 0xe1, 0x47, 0x07, 0x86, 0x57, 0x71, 0x2c, 0xb7, 0x42, + 0x93, 0x00, 0x86, 0x2c, 0x49, 0x6a, 0xae, 0x54, 0xe0, 0xcc, 0x9d, 0xc5, 0x84, 0xb6, 0xd0, 0x30, + 0x11, 0x2b, 0x98, 0x88, 0x79, 0xd0, 0xb3, 0x4c, 0x03, 0xc9, 0x19, 0x0c, 0x84, 0x34, 0xf6, 0xfe, + 0xdc, 0x59, 0xb8, 0xd4, 0x02, 0xf2, 0x33, 0x8c, 0x77, 0xac, 0x56, 0xeb, 0x8c, 0xa9, 0x2c, 0x70, + 0xd1, 0x63, 0x64, 0x0c, 0x37, 0x4c, 0x65, 0xe4, 0x1c, 0xfc, 0x28, 0xaf, 0x75, 0xb6, 0xae, 0x0a, + 0x16, 0xf3, 0x60, 0x80, 0x34, 0xa0, 0xe9, 0xd6, 0x58, 0xc2, 0x7f, 0xc1, 0xbd, 0x66, 0x9a, 0x11, + 0x02, 0xae, 0xbe, 0xaf, 0x38, 0x26, 0x33, 0xa6, 0x78, 0x36, 0x99, 0x54, 0xec, 0xbe, 0x90, 0x2c, + 0x69, 0x33, 0x69, 0x60, 0xf8, 0xa9, 0x07, 0xfe, 0xeb, 0x9a, 0x09, 0xc5, 0x62, 0x9d, 0x4b, 0x61, + 0xbc, 0xf1, 0xf7, 0x56, 0x0a, 0x9e, 0x8d, 0x6d, 0x53, 0xcb, 0xb2, 0x71, 0xc5, 0x33, 0x39, 0x81, + 0x9e, 0x96, 0x98, 0xfe, 0x84, 0xf6, 0xb4, 0x34, 0x8a, 0x76, 0xac, 0xd8, 0xf2, 0x26, 0x6f, 0x0b, + 0x0e, 0x3a, 0x07, 0x5d, 0x9d, 0xbf, 0xc0, 0x58, 0xe7, 0x25, 0x57, 0x9a, 0x95, 0x55, 0xe0, 0xcd, + 0x9d, 0x45, 0x9f, 0x1e, 0x0c, 0x64, 0x0e, 0x6e, 0xc2, 0x34, 0x0b, 0x86, 0x73, 0x67, 0xe1, 0x5f, + 0x4c, 0x96, 0xb6, 0xcb, 0x4b, 0xa3, 0x8d, 0x22, 0x43, 0x7e, 0x82, 0x51, 0x9c, 0xb1, 0x5c, 0xac, + 0xf3, 0x24, 0x18, 0xcd, 0x9d, 0xc5, 0x94, 0x0e, 0x11, 0x3f, 0x4b, 0x4c, 0x09, 0x53, 0xa6, 0xd6, + 0x55, 0x9d, 0xc7, 0x3c, 0x18, 0xdb, 0x12, 0xa6, 0x4c, 0xdd, 0x1a, 0xdc, 0x92, 0x45, 0x5e, 0xe6, + 0x3a, 0x80, 0x3d, 0xf9, 0xc2, 0x60, 0x72, 0x0a, 0x7d, 0x56, 0xa4, 0x81, 0x8f, 0xf1, 0xcc, 0xd1, + 0xc8, 0x56, 0x79, 0x2a, 0x82, 0x89, 0x95, 0x6d, 0xce, 0xe1, 0x87, 0x3e, 0xf8, 0x4f, 0xcc, 0x0c, + 0xde, 0x70, 0x96, 0xf0, 0xfa, 0xd1, 0x72, 0x9d, 0x83, 0x5f, 0xb1, 0x9a, 0x0b, 0x6d, 0x1b, 0x69, + 0xab, 0x06, 0xd6, 0x84, 0xad, 0x9c, 0xc1, 0x28, 0x96, 0xb9, 0x88, 0x98, 0x6a, 0xcb, 0xb5, 0xc7, + 0xc7, 0xb5, 0x19, 0x3c, 0xac, 0x4d, 0x57, 0xb9, 0x77, 0xac, 0xbc, 0xc9, 0x7f, 0xf8, 0x75, 0xfe, + 0xa3, 0x43, 0xfe, 0xe4, 0x57, 0x00, 0x9c, 0xe3, 0x75, 0x2d, 0xa5, 0x6e, 0x0a, 0x34, 0x46, 0x0b, + 0x95, 0x52, 0x9b, 0xf8, 0xfa, 0x4e, 0x59, 0xd2, 0x16, 0x68, 0xa8, 0xef, 0x14, 0x52, 0xe7, 0xe0, + 0xf3, 0x1d, 0x17, 0xba, 0x61, 0x7d, 0xab, 0xca, 0x9a, 0xf0, 0xc2, 0x15, 0x9c, 0xec, 0xf7, 0xc5, + 0xde, 0x99, 0x60, 0x07, 0x67, 0xcb, 0xbd, 0xb9, 0x8a, 0x96, 0x4f, 0xdb, 0xb3, 0xf1, 0xa1, 0xd3, + 0xb8, 0x0b, 0xc9, 0x1f, 0xe0, 0xd5, 0x4c, 0x24, 0xb2, 0x0c, 0xa6, 0xe8, 0x7a, 0xd2, 0x36, 0x9f, + 0xa2, 0x95, 0x36, 0xec, 0x73, 0x77, 0xd4, 0x3f, 0x75, 0xc3, 0xcf, 0x0e, 0x0c, 0xb0, 0x17, 0xe4, + 0x2f, 0xf0, 0x32, 0xec, 0x07, 0xf6, 0xc1, 0xbf, 0xf8, 0xa1, 0xf5, 0xeb, 0xb4, 0x8a, 0x36, 0x57, + 0xc8, 0x25, 0x4c, 0xf4, 0x61, 0xe0, 0x55, 0xd0, 0x9b, 0xf7, 0xbb, 0x2e, 0x9d, 0x65, 0xa0, 0x47, + 0x17, 0xc9, 0x9f, 0x00, 0x09, 0xaf, 0xb8, 0x48, 0xb8, 0x88, 0xef, 0x71, 0xf4, 0xfd, 0x0b, 0x58, + 0x26, 0x2c, 0xc5, 0xe9, 0x4c, 0x69, 0x87, 0x25, 0x3f, 0x9a, 0x8c, 0xf2, 0x34, 0xd3, 0xd8, 0x60, + 0x97, 0x36, 0x28, 0x7c, 0x0b, 0xe3, 0x97, 0x5c, 0x63, 0x5a, 0x6a, 0xbf, 0x57, 0xcd, 0xa6, 0xe2, + 0x5e, 0x9d, 0xc1, 0x20, 0x62, 0x3a, 0xb6, 0x63, 0xe3, 0x52, 0x0b, 0xc8, 0xef, 0xe0, 0xe1, 0xcb, + 0xa7, 0x82, 0x3e, 0x66, 0x3b, 0x3d, 0x12, 0x48, 0x1b, 0x32, 0x7c, 0x03, 0xa3, 0x36, 0xfa, 0x77, + 0x04, 0xff, 0x0d, 0x06, 0xe8, 0xdf, 0x48, 0x7a, 0x10, 0xdb, 0x72, 0xe1, 0x25, 0x4c, 0xaf, 0xe5, + 0x7b, 0x61, 0xde, 0x8c, 0x7d, 0xfc, 0xc7, 0x1e, 0x0a, 0x9c, 0xb8, 0x5e, 0x67, 0x63, 0xfe, 0x07, + 0xcf, 0x76, 0xcf, 0x0c, 0xd7, 0xae, 0xde, 0xac, 0x15, 0xe7, 0x49, 0xfb, 0x52, 0xee, 0xea, 0xcd, + 0x2b, 0xce, 0x71, 0x6d, 0x0d, 0x55, 0xd5, 0x52, 0x6e, 0x1a, 0x6f, 0x73, 0xf7, 0xd6, 0xe0, 0xc8, + 0xc3, 0x37, 0xf7, 0x9f, 0x2f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb1, 0x18, 0x56, 0x0a, 0xfd, 0x05, + 0x00, 0x00, } diff --git a/core/pb/block.proto b/core/pb/block.proto index d7b5b00fd..9e1f0f714 100644 --- a/core/pb/block.proto +++ b/core/pb/block.proto @@ -93,6 +93,6 @@ message DownloadBlock { } message Random { - bytes vrf_hash = 1; + bytes vrf_seed = 1; bytes vrf_proof = 2; } \ No newline at end of file diff --git a/core/types.go b/core/types.go index c5c64e338..77b3e38e5 100644 --- a/core/types.go +++ b/core/types.go @@ -217,6 +217,8 @@ type Consensus interface { GenesisConsensusState(*BlockChain, *corepb.Genesis) (state.ConsensusState, error) CheckTimeout(*Block) bool CheckDoubleMint(*Block) bool + + NumberOfBlocksInDynasty() uint64 } // SyncService interface of sync service @@ -240,7 +242,7 @@ type AccountManager interface { SignHash(*Address, byteutils.Hash, keystore.Algorithm) ([]byte, error) SignBlock(*Address, *Block) error - GenerateBlockRand(*Address, []byteutils.Hash) ([]byte, []byte, error) + GenerateRandomSeed(*Address, ...[]byte) ([]byte, []byte, error) SignTransaction(*Address, *Transaction) error SignTransactionWithPassphrase(*Address, *Transaction, []byte) error diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index 9d1055e69..17d58a2c0 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -48,6 +48,7 @@ var NebDate = (function(Date) { throw new Error("Unsupported method!"); }, }); + // TODO: timezone/locale => 0 Object.setPrototypeOf(NebDate.prototype, Date.prototype); return NebDate; })(Date); diff --git a/rpc/admin_service.go b/rpc/admin_service.go index 73c4f929a..20d7ef6aa 100644 --- a/rpc/admin_service.go +++ b/rpc/admin_service.go @@ -136,10 +136,10 @@ func (s *AdminService) SignHash(ctx context.Context, req *rpcpb.SignHashRequest) return &rpcpb.SignHashResponse{Data: data}, nil } -// GenerateBlockRand generate block's rand info -func (s *AdminService) GenerateBlockRand(ctx context.Context, req *rpcpb.GenerateBlockRandRequest) (*rpcpb.GenerateBlockRandResponse, error) { +// GenerateRandomSeed generate block's rand info +func (s *AdminService) GenerateRandomSeed(ctx context.Context, req *rpcpb.GenerateRandomSeedRequest) (*rpcpb.GenerateRandomSeedResponse, error) { neb := s.server.Neblet() - hashes, err := neb.BlockChain().GetRecentNBlockHashBeforeInclusive(req.ParentHash, core.VRFInputParentHashNumber) + inputs, err := neb.BlockChain().GetInputForVRFSigner(req.ParentHash, req.Height) if err != nil { return nil, err } @@ -149,13 +149,13 @@ func (s *AdminService) GenerateBlockRand(ctx context.Context, req *rpcpb.Generat return nil, err } - vrfHash, vrfProof, err := neb.AccountManager().GenerateBlockRand(addr, hashes) + vrfSeed, vrfProof, err := neb.AccountManager().GenerateRandomSeed(addr, inputs...) if err != nil { return nil, err } - return &rpcpb.GenerateBlockRandResponse{ - VrfHash: vrfHash, + return &rpcpb.GenerateRandomSeedResponse{ + VrfSeed: vrfSeed, VrfProof: vrfProof, }, nil } diff --git a/rpc/pb/rpc.pb.go b/rpc/pb/rpc.pb.go index c05513ebe..4f31f9f50 100644 --- a/rpc/pb/rpc.pb.go +++ b/rpc/pb/rpc.pb.go @@ -37,8 +37,8 @@ It has these top-level messages: LockAccountResponse SignHashRequest SignHashResponse - GenerateBlockRandRequest - GenerateBlockRandResponse + GenerateRandomSeedRequest + GenerateRandomSeedResponse SignTransactionPassphraseRequest SignTransactionPassphraseResponse SendTransactionPassphraseRequest @@ -60,10 +60,8 @@ import _ "google.golang.org/genproto/googleapis/api/annotations" import consensuspb "github.com/nebulasio/go-nebulas/consensus/pb" import nebletpb "github.com/nebulasio/go-nebulas/neblet/pb" -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -1139,50 +1137,59 @@ func (m *SignHashResponse) GetData() []byte { return nil } -type GenerateBlockRandRequest struct { +type GenerateRandomSeedRequest struct { // miner address Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // parent hash of new block ParentHash []byte `protobuf:"bytes,2,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"` + // height of new block + Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` } -func (m *GenerateBlockRandRequest) Reset() { *m = GenerateBlockRandRequest{} } -func (m *GenerateBlockRandRequest) String() string { return proto.CompactTextString(m) } -func (*GenerateBlockRandRequest) ProtoMessage() {} -func (*GenerateBlockRandRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } +func (m *GenerateRandomSeedRequest) Reset() { *m = GenerateRandomSeedRequest{} } +func (m *GenerateRandomSeedRequest) String() string { return proto.CompactTextString(m) } +func (*GenerateRandomSeedRequest) ProtoMessage() {} +func (*GenerateRandomSeedRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } -func (m *GenerateBlockRandRequest) GetAddress() string { +func (m *GenerateRandomSeedRequest) GetAddress() string { if m != nil { return m.Address } return "" } -func (m *GenerateBlockRandRequest) GetParentHash() []byte { +func (m *GenerateRandomSeedRequest) GetParentHash() []byte { if m != nil { return m.ParentHash } return nil } -type GenerateBlockRandResponse struct { - VrfHash []byte `protobuf:"bytes,1,opt,name=vrf_hash,json=vrfHash,proto3" json:"vrf_hash,omitempty"` +func (m *GenerateRandomSeedRequest) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +type GenerateRandomSeedResponse struct { + VrfSeed []byte `protobuf:"bytes,1,opt,name=vrf_seed,json=vrfSeed,proto3" json:"vrf_seed,omitempty"` VrfProof []byte `protobuf:"bytes,2,opt,name=vrf_proof,json=vrfProof,proto3" json:"vrf_proof,omitempty"` } -func (m *GenerateBlockRandResponse) Reset() { *m = GenerateBlockRandResponse{} } -func (m *GenerateBlockRandResponse) String() string { return proto.CompactTextString(m) } -func (*GenerateBlockRandResponse) ProtoMessage() {} -func (*GenerateBlockRandResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } +func (m *GenerateRandomSeedResponse) Reset() { *m = GenerateRandomSeedResponse{} } +func (m *GenerateRandomSeedResponse) String() string { return proto.CompactTextString(m) } +func (*GenerateRandomSeedResponse) ProtoMessage() {} +func (*GenerateRandomSeedResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } -func (m *GenerateBlockRandResponse) GetVrfHash() []byte { +func (m *GenerateRandomSeedResponse) GetVrfSeed() []byte { if m != nil { - return m.VrfHash + return m.VrfSeed } return nil } -func (m *GenerateBlockRandResponse) GetVrfProof() []byte { +func (m *GenerateRandomSeedResponse) GetVrfProof() []byte { if m != nil { return m.VrfProof } @@ -1440,8 +1447,8 @@ func init() { proto.RegisterType((*LockAccountResponse)(nil), "rpcpb.LockAccountResponse") proto.RegisterType((*SignHashRequest)(nil), "rpcpb.SignHashRequest") proto.RegisterType((*SignHashResponse)(nil), "rpcpb.SignHashResponse") - proto.RegisterType((*GenerateBlockRandRequest)(nil), "rpcpb.GenerateBlockRandRequest") - proto.RegisterType((*GenerateBlockRandResponse)(nil), "rpcpb.GenerateBlockRandResponse") + proto.RegisterType((*GenerateRandomSeedRequest)(nil), "rpcpb.GenerateRandomSeedRequest") + proto.RegisterType((*GenerateRandomSeedResponse)(nil), "rpcpb.GenerateRandomSeedResponse") proto.RegisterType((*SignTransactionPassphraseRequest)(nil), "rpcpb.SignTransactionPassphraseRequest") proto.RegisterType((*SignTransactionPassphraseResponse)(nil), "rpcpb.SignTransactionPassphraseResponse") proto.RegisterType((*SendTransactionPassphraseRequest)(nil), "rpcpb.SendTransactionPassphraseRequest") @@ -1988,7 +1995,7 @@ type AdminServiceClient interface { SendTransaction(ctx context.Context, in *TransactionRequest, opts ...grpc.CallOption) (*SendTransactionResponse, error) // Sign sign msg SignHash(ctx context.Context, in *SignHashRequest, opts ...grpc.CallOption) (*SignHashResponse, error) - GenerateBlockRand(ctx context.Context, in *GenerateBlockRandRequest, opts ...grpc.CallOption) (*GenerateBlockRandResponse, error) + GenerateRandomSeed(ctx context.Context, in *GenerateRandomSeedRequest, opts ...grpc.CallOption) (*GenerateRandomSeedResponse, error) // Sign sign transaction SignTransactionWithPassphrase(ctx context.Context, in *SignTransactionPassphraseRequest, opts ...grpc.CallOption) (*SignTransactionPassphraseResponse, error) // SendTransactionWithPassphrase send transaction with passphrase @@ -2062,9 +2069,9 @@ func (c *adminServiceClient) SignHash(ctx context.Context, in *SignHashRequest, return out, nil } -func (c *adminServiceClient) GenerateBlockRand(ctx context.Context, in *GenerateBlockRandRequest, opts ...grpc.CallOption) (*GenerateBlockRandResponse, error) { - out := new(GenerateBlockRandResponse) - err := grpc.Invoke(ctx, "/rpcpb.AdminService/GenerateBlockRand", in, out, c.cc, opts...) +func (c *adminServiceClient) GenerateRandomSeed(ctx context.Context, in *GenerateRandomSeedRequest, opts ...grpc.CallOption) (*GenerateRandomSeedResponse, error) { + out := new(GenerateRandomSeedResponse) + err := grpc.Invoke(ctx, "/rpcpb.AdminService/GenerateRandomSeed", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -2131,7 +2138,7 @@ type AdminServiceServer interface { SendTransaction(context.Context, *TransactionRequest) (*SendTransactionResponse, error) // Sign sign msg SignHash(context.Context, *SignHashRequest) (*SignHashResponse, error) - GenerateBlockRand(context.Context, *GenerateBlockRandRequest) (*GenerateBlockRandResponse, error) + GenerateRandomSeed(context.Context, *GenerateRandomSeedRequest) (*GenerateRandomSeedResponse, error) // Sign sign transaction SignTransactionWithPassphrase(context.Context, *SignTransactionPassphraseRequest) (*SignTransactionPassphraseResponse, error) // SendTransactionWithPassphrase send transaction with passphrase @@ -2255,20 +2262,20 @@ func _AdminService_SignHash_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -func _AdminService_GenerateBlockRand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GenerateBlockRandRequest) +func _AdminService_GenerateRandomSeed_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateRandomSeedRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(AdminServiceServer).GenerateBlockRand(ctx, in) + return srv.(AdminServiceServer).GenerateRandomSeed(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/rpcpb.AdminService/GenerateBlockRand", + FullMethod: "/rpcpb.AdminService/GenerateRandomSeed", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AdminServiceServer).GenerateBlockRand(ctx, req.(*GenerateBlockRandRequest)) + return srv.(AdminServiceServer).GenerateRandomSeed(ctx, req.(*GenerateRandomSeedRequest)) } return interceptor(ctx, in, info, handler) } @@ -2392,8 +2399,8 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ Handler: _AdminService_SignHash_Handler, }, { - MethodName: "GenerateBlockRand", - Handler: _AdminService_GenerateBlockRand_Handler, + MethodName: "GenerateRandomSeed", + Handler: _AdminService_GenerateRandomSeed_Handler, }, { MethodName: "SignTransactionWithPassphrase", @@ -2423,149 +2430,149 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2292 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcb, 0x6f, 0x1b, 0xb9, - 0x19, 0x87, 0xfc, 0x94, 0x3e, 0xc9, 0xb6, 0x42, 0xbf, 0xc6, 0xf2, 0x23, 0x0e, 0xb3, 0xd8, 0xf5, - 0x06, 0x5d, 0x6b, 0xe3, 0x05, 0xb6, 0x45, 0x8a, 0x2d, 0x90, 0xa4, 0x59, 0x6f, 0x8a, 0x20, 0x70, - 0xc7, 0x49, 0xbb, 0x40, 0x9b, 0x0a, 0xd4, 0x88, 0x92, 0xa6, 0x3b, 0xe6, 0x4c, 0x49, 0xca, 0x89, - 0x73, 0x29, 0xb0, 0xf7, 0x9e, 0x0a, 0x14, 0x3d, 0xf4, 0xd6, 0xbf, 0xa8, 0xe8, 0xa1, 0x97, 0x1e, - 0xfb, 0x77, 0x14, 0x05, 0x39, 0x24, 0xe7, 0xa1, 0x91, 0xd5, 0xf4, 0xd0, 0x1b, 0x9f, 0xdf, 0xf7, - 0xf1, 0x7b, 0xfc, 0xf8, 0xe3, 0x0c, 0x34, 0x78, 0x12, 0x9c, 0x26, 0x3c, 0x96, 0x31, 0x5a, 0xe6, - 0x49, 0x90, 0xf4, 0x3b, 0x07, 0xa3, 0x38, 0x1e, 0x45, 0xb4, 0x4b, 0x92, 0xb0, 0x4b, 0x18, 0x8b, - 0x25, 0x91, 0x61, 0xcc, 0x44, 0xba, 0xa8, 0xf3, 0xa3, 0x51, 0x28, 0xc7, 0x93, 0xfe, 0x69, 0x10, - 0x5f, 0x75, 0x19, 0xed, 0x4f, 0x22, 0x22, 0xc2, 0xb8, 0x3b, 0x8a, 0x3f, 0x33, 0x9d, 0x6e, 0x10, - 0x33, 0x41, 0x99, 0x98, 0x88, 0x6e, 0xd2, 0xef, 0x0a, 0x49, 0x24, 0x35, 0x3b, 0xbf, 0x9c, 0xb7, - 0x93, 0xd1, 0x7e, 0x44, 0xa5, 0xda, 0x16, 0xc4, 0x6c, 0x18, 0x8e, 0xd2, 0x7d, 0xf8, 0x01, 0xb4, - 0x2f, 0x27, 0x7d, 0x11, 0xf0, 0xb0, 0x4f, 0x7d, 0xfa, 0xbb, 0x09, 0x15, 0x12, 0xed, 0xc0, 0x8a, - 0x8c, 0x93, 0x30, 0x10, 0x5e, 0xed, 0x78, 0xf1, 0xa4, 0xe1, 0x9b, 0x1e, 0xfe, 0x0a, 0xee, 0xe4, - 0xd6, 0x8a, 0x44, 0xd9, 0x82, 0xb6, 0x60, 0x59, 0x4f, 0x7b, 0xb5, 0xe3, 0xda, 0x49, 0xc3, 0x4f, - 0x3b, 0x08, 0xc1, 0xd2, 0x80, 0x48, 0xe2, 0x2d, 0xe8, 0x41, 0xdd, 0xc6, 0x08, 0xda, 0x2f, 0x63, - 0x76, 0x41, 0x38, 0xb9, 0x12, 0x46, 0x15, 0xfe, 0xcb, 0x82, 0x1a, 0x1c, 0xd0, 0xe7, 0x6c, 0x18, - 0x3b, 0x91, 0xeb, 0xb0, 0x10, 0x0e, 0x8c, 0xbc, 0x85, 0x70, 0x80, 0xf6, 0xa0, 0x1e, 0x8c, 0x49, - 0xc8, 0x7a, 0xe1, 0x40, 0x0b, 0x5c, 0xf3, 0x57, 0x75, 0xff, 0xf9, 0x00, 0x75, 0xa0, 0x1e, 0xc4, - 0x21, 0xeb, 0x13, 0x41, 0xbd, 0x45, 0xbd, 0xc1, 0xf5, 0xd1, 0x21, 0x40, 0x42, 0x29, 0xef, 0x05, - 0xf1, 0x84, 0x49, 0x6f, 0x49, 0x6f, 0x6c, 0xa8, 0x91, 0xa7, 0x6a, 0x00, 0x61, 0x68, 0x89, 0x1b, - 0x16, 0x8c, 0x79, 0xcc, 0xc2, 0xf7, 0x74, 0xe0, 0x2d, 0x1f, 0xd7, 0x4e, 0xea, 0x7e, 0x61, 0x0c, - 0xdd, 0x85, 0x66, 0x7f, 0x12, 0x7c, 0x47, 0x65, 0x4f, 0x84, 0xef, 0xa9, 0xb7, 0x72, 0x5c, 0x3b, - 0x59, 0xf6, 0x21, 0x1d, 0xba, 0x0c, 0xdf, 0x53, 0xf4, 0x29, 0xb4, 0xb5, 0x1f, 0x83, 0x38, 0xea, - 0x5d, 0x53, 0x2e, 0xc2, 0x98, 0x79, 0xa0, 0xed, 0xd8, 0xb0, 0xe3, 0xbf, 0x48, 0x87, 0xd1, 0x19, - 0x34, 0x79, 0x3c, 0x91, 0xb4, 0x27, 0x49, 0x3f, 0xa2, 0x5e, 0xf3, 0x78, 0xf1, 0xa4, 0x79, 0x76, - 0xe7, 0x54, 0xa7, 0xc5, 0xa9, 0xaf, 0x66, 0x5e, 0xa9, 0x09, 0x1f, 0xb8, 0x6b, 0xe3, 0x2f, 0x01, - 0xb2, 0x99, 0x29, 0xbf, 0x78, 0xb0, 0x4a, 0x06, 0x03, 0x4e, 0x85, 0xf0, 0x16, 0x74, 0xa0, 0x6c, - 0x17, 0xff, 0xa3, 0x06, 0x9b, 0xe7, 0x54, 0xbe, 0xa4, 0xfd, 0x4b, 0x95, 0x23, 0xce, 0xb3, 0x79, - 0x4f, 0xd6, 0x8a, 0x9e, 0x44, 0xb0, 0x24, 0x49, 0x18, 0xd9, 0x88, 0xa9, 0x36, 0x6a, 0xc3, 0x62, - 0x14, 0xf6, 0x8d, 0x63, 0x55, 0x53, 0xa5, 0xc6, 0x98, 0x86, 0xa3, 0x71, 0xea, 0xcf, 0x25, 0xdf, - 0xf4, 0x2a, 0xfd, 0xb0, 0x52, 0xed, 0x87, 0xb2, 0xdf, 0x57, 0x2b, 0xfc, 0xee, 0xc1, 0xaa, 0x95, - 0x52, 0xd7, 0x52, 0x6c, 0x17, 0x7f, 0x0e, 0xed, 0xc7, 0x81, 0x8e, 0xa8, 0x70, 0xa7, 0x3a, 0x80, - 0x86, 0x39, 0x38, 0xb5, 0x29, 0x9b, 0x0d, 0xe0, 0x9f, 0xc1, 0xce, 0x39, 0x95, 0x66, 0x93, 0x71, - 0x47, 0x9a, 0xe7, 0x39, 0xff, 0xa5, 0x4e, 0xb5, 0xdd, 0xdc, 0x31, 0x17, 0xf2, 0xc7, 0xc4, 0x6f, - 0x60, 0x77, 0x4a, 0x96, 0x31, 0xc2, 0x83, 0xd5, 0x3e, 0x89, 0x08, 0x0b, 0xa8, 0x15, 0x66, 0xba, - 0xaa, 0x42, 0x58, 0xac, 0xc6, 0x53, 0x59, 0x69, 0x47, 0xfb, 0xfb, 0x26, 0x49, 0xb3, 0x76, 0xcd, - 0xd7, 0x6d, 0xfc, 0x5b, 0x68, 0x3d, 0x25, 0x51, 0xe4, 0x64, 0xee, 0xc0, 0x0a, 0xa7, 0x62, 0x12, - 0x49, 0x23, 0xd2, 0xf4, 0x54, 0x5a, 0xd2, 0x77, 0x34, 0x50, 0xc9, 0x44, 0x39, 0x37, 0x21, 0x03, - 0x33, 0xf4, 0x8c, 0x73, 0x74, 0x0f, 0x5a, 0x54, 0xc8, 0xf0, 0x8a, 0x48, 0xda, 0x1b, 0x11, 0x61, - 0x22, 0xd8, 0xb4, 0x63, 0xe7, 0x44, 0xe0, 0x53, 0xd8, 0x7a, 0x72, 0xf3, 0x24, 0x8a, 0x83, 0xef, - 0xbe, 0xd1, 0x67, 0xcb, 0x15, 0xbf, 0x39, 0x7a, 0xad, 0x70, 0xf4, 0x1f, 0x00, 0x3a, 0xa7, 0xf2, - 0xa7, 0x37, 0x8c, 0x08, 0x79, 0x93, 0xb7, 0xf0, 0x2a, 0x64, 0x94, 0x3b, 0xa8, 0x48, 0x7b, 0xf8, - 0xdf, 0x35, 0x40, 0xaf, 0x38, 0x61, 0x82, 0x04, 0x0a, 0xdf, 0xac, 0x70, 0x04, 0x4b, 0x43, 0x1e, - 0x5f, 0x99, 0xe3, 0xe8, 0xb6, 0xca, 0x6a, 0x19, 0x9b, 0x33, 0x2c, 0xc8, 0x58, 0xb9, 0xeb, 0x9a, - 0x44, 0x13, 0x5b, 0xcf, 0x69, 0x27, 0x73, 0xe2, 0x52, 0xde, 0x89, 0xfb, 0xd0, 0x18, 0x11, 0xd1, - 0x4b, 0x78, 0x18, 0x50, 0x5d, 0xc0, 0x0d, 0xbf, 0x3e, 0x22, 0xe2, 0x42, 0xf5, 0xed, 0x64, 0x14, - 0x5e, 0x85, 0xd2, 0x24, 0xa3, 0x9a, 0x7c, 0xa1, 0xfa, 0xe8, 0x4c, 0x01, 0x07, 0x93, 0x9c, 0x04, - 0x52, 0x67, 0x60, 0xf3, 0x6c, 0xc7, 0x94, 0xe2, 0x53, 0x33, 0x6c, 0x6c, 0xf6, 0xdd, 0x3a, 0x75, - 0xd8, 0x7e, 0xc8, 0x08, 0xbf, 0xd1, 0x25, 0xde, 0xf2, 0x4d, 0xcf, 0x85, 0x72, 0xcb, 0x94, 0x8e, - 0x0a, 0xe5, 0x7b, 0xd8, 0x28, 0x09, 0x52, 0xdb, 0x45, 0x3c, 0xe1, 0x2e, 0x41, 0x4c, 0x4f, 0x45, - 0x33, 0x6d, 0xf5, 0xb4, 0x14, 0x13, 0xcd, 0x74, 0xe8, 0xd5, 0x4d, 0x42, 0x15, 0xc8, 0x0d, 0x27, - 0x4c, 0x3b, 0xd2, 0x82, 0x9c, 0xed, 0x2b, 0xdd, 0x84, 0x8f, 0x84, 0x76, 0x4b, 0xc3, 0xd7, 0x6d, - 0xdc, 0x85, 0xbd, 0x4b, 0xca, 0x06, 0x3e, 0x79, 0x5b, 0x1d, 0x02, 0x8d, 0xcc, 0x35, 0x7d, 0x84, - 0x14, 0x99, 0x7f, 0x0d, 0xbb, 0x6a, 0x43, 0x61, 0x75, 0x16, 0x60, 0xf9, 0x6e, 0x4c, 0xc4, 0xd8, - 0x1a, 0x9d, 0xf6, 0x54, 0xc1, 0x5b, 0xbf, 0xf4, 0x32, 0x10, 0xd2, 0x05, 0x6f, 0xc7, 0x1f, 0x1b, - 0x30, 0xea, 0xc1, 0xf6, 0x39, 0x95, 0x3a, 0xd5, 0x9e, 0xdc, 0x7c, 0x43, 0xc4, 0x38, 0x67, 0x4a, - 0x4e, 0xb2, 0x6e, 0xa3, 0x33, 0xd8, 0x1e, 0x4e, 0xa2, 0xa8, 0x37, 0x0c, 0xa3, 0xa8, 0x27, 0x33, - 0x83, 0xb4, 0xf0, 0xba, 0xbf, 0xa9, 0x26, 0xbf, 0x0e, 0xa3, 0x28, 0x67, 0x2b, 0xa6, 0xba, 0x2a, - 0xad, 0x82, 0xff, 0x26, 0x9b, 0xff, 0x27, 0x35, 0x0f, 0x61, 0xff, 0x9c, 0xca, 0xdc, 0xc8, 0xdc, - 0xd3, 0xe0, 0x7f, 0x2e, 0xc2, 0x9a, 0xb6, 0xcb, 0xf9, 0xb3, 0xea, 0xcc, 0x77, 0xa1, 0x99, 0x10, - 0x4e, 0x99, 0xec, 0xe9, 0x29, 0x93, 0x00, 0xe9, 0x90, 0xd2, 0x90, 0x3b, 0xc5, 0x62, 0xe1, 0x14, - 0xd5, 0x45, 0x91, 0xbf, 0x13, 0x97, 0x4b, 0x77, 0xe2, 0x01, 0x34, 0x64, 0x78, 0x45, 0x85, 0x24, - 0x57, 0x89, 0xae, 0x89, 0x45, 0x3f, 0x1b, 0x28, 0x5c, 0x0f, 0xab, 0xc5, 0xeb, 0xe1, 0x10, 0x40, - 0xd3, 0x8d, 0x1e, 0x8f, 0x63, 0x69, 0x40, 0xb9, 0xa1, 0x47, 0xfc, 0x38, 0x96, 0x6a, 0xa7, 0x7c, - 0x27, 0xd2, 0xc9, 0x46, 0x0a, 0x7f, 0xf2, 0x9d, 0xd0, 0x53, 0x0a, 0xac, 0xae, 0x29, 0x93, 0x66, - 0x16, 0x0c, 0x58, 0xe9, 0x21, 0xbd, 0xe0, 0x31, 0xac, 0x3b, 0x5a, 0x93, 0xae, 0x69, 0xea, 0x82, - 0xec, 0x9c, 0xba, 0xe1, 0xb4, 0x2c, 0xd3, 0xb6, 0xda, 0xe3, 0xaf, 0x05, 0xf9, 0xae, 0x72, 0x84, - 0x06, 0x1e, 0xaf, 0x95, 0x62, 0x86, 0xee, 0x28, 0xcd, 0xa1, 0xe8, 0x0d, 0x43, 0x46, 0xa2, 0x50, - 0xde, 0x78, 0x6b, 0x3a, 0xb4, 0x10, 0x8a, 0xaf, 0xcd, 0x08, 0xfa, 0x09, 0xb4, 0x72, 0xb1, 0x17, - 0xde, 0x40, 0xdf, 0xc9, 0x1d, 0x03, 0x04, 0x15, 0xe5, 0xe0, 0x17, 0xd6, 0xe3, 0x3f, 0x2d, 0xc2, - 0x66, 0x55, 0xd1, 0x54, 0x05, 0xd9, 0x03, 0xeb, 0xcb, 0x32, 0x87, 0xb1, 0xa0, 0xb8, 0x38, 0x05, - 0x8a, 0x4b, 0xd3, 0xa0, 0xb8, 0x5c, 0x09, 0x8a, 0x2b, 0xf9, 0xf8, 0x17, 0x62, 0xbc, 0x5a, 0x8e, - 0xb1, 0x05, 0xab, 0x7a, 0x06, 0x56, 0x0e, 0x13, 0x1a, 0x19, 0x26, 0x14, 0xa1, 0x15, 0x6e, 0x83, - 0xd6, 0x66, 0x09, 0x5a, 0xab, 0xa0, 0xa1, 0x55, 0x09, 0x0d, 0x1a, 0x12, 0x25, 0x91, 0x13, 0xa1, - 0x83, 0xb3, 0xec, 0x9b, 0x9e, 0x4a, 0x27, 0x25, 0x7f, 0x22, 0xe8, 0xc0, 0x5b, 0x4f, 0xd3, 0x69, - 0x44, 0xc4, 0x6b, 0x41, 0x07, 0xe8, 0x3e, 0xac, 0xe5, 0xee, 0xbe, 0x98, 0x7b, 0x1b, 0x7a, 0xbe, - 0x95, 0xdd, 0x7e, 0x31, 0xc7, 0x5f, 0xc0, 0x9d, 0x97, 0xf4, 0xad, 0xb9, 0xa7, 0x6d, 0x81, 0x1e, - 0x01, 0x24, 0x44, 0x88, 0x64, 0xcc, 0x55, 0x65, 0xd4, 0x6c, 0x95, 0xd9, 0x11, 0x7c, 0x0a, 0x28, - 0xbf, 0x29, 0xbb, 0xd7, 0xab, 0x49, 0x02, 0x8e, 0x60, 0xeb, 0x35, 0x53, 0xc5, 0x5d, 0xd2, 0x33, - 0x9b, 0x56, 0x14, 0x2d, 0x58, 0x28, 0x5b, 0xa0, 0x2a, 0x77, 0x30, 0xe1, 0xc4, 0x01, 0xfd, 0x92, - 0xef, 0xfa, 0xb8, 0x0b, 0xdb, 0x25, 0x6d, 0x95, 0x24, 0xa1, 0x6e, 0x49, 0x82, 0x3a, 0xce, 0x8b, - 0x0f, 0x30, 0x0e, 0x7f, 0x06, 0x9b, 0x2f, 0x3e, 0x40, 0xfc, 0xcf, 0x61, 0xe3, 0x32, 0x1c, 0xb1, - 0x3c, 0x02, 0xce, 0x3e, 0xb8, 0x2d, 0x88, 0x85, 0x34, 0xc1, 0x74, 0x41, 0xb4, 0x61, 0x91, 0x44, - 0x23, 0xc3, 0x7f, 0x54, 0x13, 0x7f, 0x0c, 0xed, 0x4c, 0x64, 0x56, 0x4a, 0x53, 0xd7, 0xd5, 0x6b, - 0xf0, 0xce, 0x29, 0xa3, 0x9c, 0x48, 0x9a, 0x82, 0x2b, 0x61, 0x83, 0xf9, 0x36, 0x54, 0xa0, 0x6c, - 0x2b, 0x8f, 0xb2, 0xf8, 0x12, 0xf6, 0x2a, 0xc4, 0x66, 0xcc, 0xf9, 0x9a, 0x0f, 0x7b, 0xae, 0xac, - 0x5b, 0xfe, 0xea, 0x35, 0x1f, 0x6a, 0x74, 0xde, 0x87, 0x86, 0x9a, 0x4a, 0x78, 0x1c, 0x0f, 0x8d, - 0x58, 0xb5, 0xf6, 0x42, 0xf5, 0xf1, 0xef, 0xe1, 0x58, 0x9d, 0x29, 0x87, 0x12, 0x17, 0x2e, 0xde, - 0xd6, 0xe6, 0x1f, 0x43, 0x33, 0x7f, 0x05, 0xd5, 0x34, 0xfa, 0xed, 0x55, 0xa1, 0x50, 0xca, 0x48, - 0xf2, 0xab, 0xe7, 0xe5, 0x14, 0xfe, 0x21, 0xdc, 0xbb, 0xc5, 0x80, 0x5b, 0xbc, 0xac, 0x2c, 0x2f, - 0x92, 0x82, 0xff, 0xb3, 0xe5, 0x5d, 0x68, 0x9f, 0x1b, 0xc0, 0x71, 0x86, 0x16, 0x50, 0xa9, 0x56, - 0x44, 0x25, 0x7c, 0x0f, 0x9a, 0xf3, 0x2e, 0xe4, 0x87, 0xd0, 0x3c, 0x27, 0xd9, 0xcb, 0xa1, 0x0d, - 0x8b, 0x8a, 0x1e, 0xa7, 0x2b, 0x54, 0x53, 0x8d, 0x64, 0x94, 0x5a, 0x35, 0xf1, 0x97, 0xb0, 0xfe, - 0x2c, 0xbd, 0xac, 0xec, 0xae, 0x8f, 0x60, 0x25, 0xbd, 0xbe, 0x34, 0xe9, 0x6d, 0x9e, 0xb5, 0xcc, - 0x81, 0xf5, 0x32, 0xdf, 0xcc, 0xe1, 0x87, 0xb0, 0xac, 0x07, 0x3e, 0xe0, 0x85, 0xfc, 0x31, 0xb4, - 0x2e, 0x12, 0x1e, 0x0f, 0x73, 0xec, 0x25, 0x0a, 0x85, 0xa4, 0xcc, 0x92, 0xaf, 0xb4, 0x87, 0x3f, - 0x81, 0x35, 0xb3, 0x6e, 0x4e, 0x91, 0x7e, 0x05, 0x77, 0xce, 0xa9, 0x7c, 0xaa, 0x1f, 0xfc, 0x6e, - 0xf1, 0x09, 0xac, 0xa4, 0x9f, 0x00, 0x4c, 0xbc, 0xda, 0xa7, 0xe9, 0xb7, 0x81, 0xf4, 0x92, 0x55, - 0x2b, 0xcd, 0xfc, 0xd9, 0xdf, 0x00, 0xe0, 0x71, 0x12, 0x5e, 0x52, 0x7e, 0xad, 0x50, 0xff, 0x0d, - 0x34, 0x73, 0x8f, 0x4a, 0xb4, 0x6b, 0x8e, 0x5d, 0x7e, 0xd4, 0x77, 0xec, 0x05, 0x5a, 0xf1, 0x02, - 0xc5, 0x7b, 0xdf, 0xff, 0xfd, 0x5f, 0x7f, 0x5c, 0xd8, 0x44, 0x77, 0xba, 0xd7, 0x0f, 0xbb, 0x13, - 0x41, 0x79, 0x97, 0xd1, 0xbe, 0xe6, 0x11, 0xe8, 0x37, 0xb0, 0xfb, 0x82, 0x48, 0x2a, 0xe4, 0x73, - 0xce, 0xa9, 0x7e, 0xef, 0xf5, 0xa3, 0xb4, 0x12, 0x67, 0xab, 0xda, 0x32, 0x13, 0x05, 0x92, 0x85, - 0xb7, 0xb4, 0x92, 0x75, 0xd4, 0x72, 0x4a, 0xd4, 0xdb, 0x95, 0xc3, 0x46, 0xe9, 0xf1, 0x86, 0x0e, - 0x33, 0x4b, 0x2b, 0x1e, 0x88, 0x9d, 0xa3, 0x59, 0xd3, 0x46, 0xcf, 0xb1, 0xd6, 0xd3, 0xc1, 0xdb, - 0x4e, 0x0f, 0x31, 0x6f, 0x53, 0xb5, 0xec, 0x51, 0xed, 0x01, 0xba, 0x80, 0x25, 0xf5, 0xa2, 0x43, - 0xb3, 0x6b, 0xa2, 0xb3, 0x69, 0xdf, 0x1d, 0xb9, 0x97, 0x1f, 0xf6, 0xb4, 0x64, 0x84, 0xd7, 0x9c, - 0xe4, 0x80, 0x44, 0x91, 0x92, 0xf8, 0x1e, 0xd0, 0x34, 0xb9, 0x47, 0xc7, 0x46, 0xc8, 0x4c, 0xde, - 0xef, 0xce, 0x32, 0x83, 0xe8, 0x63, 0xac, 0x35, 0x1e, 0xe0, 0x5d, 0xa7, 0x91, 0x93, 0xb7, 0xb9, - 0x72, 0x55, 0xba, 0xc7, 0xb0, 0x5e, 0x64, 0xf2, 0xe8, 0x20, 0xf3, 0xd0, 0x34, 0xc1, 0x9f, 0x11, - 0x9d, 0x69, 0x4d, 0xa3, 0xc2, 0x6e, 0xa5, 0x89, 0x41, 0xbb, 0x4c, 0xe9, 0xd1, 0xd1, 0xb4, 0xae, - 0x3c, 0xd7, 0x9f, 0xa1, 0xed, 0x23, 0xad, 0xed, 0x08, 0xef, 0x55, 0x69, 0xd3, 0xfb, 0x95, 0xbe, - 0xef, 0x6b, 0xfa, 0x91, 0x52, 0x70, 0x4c, 0x40, 0xc3, 0x44, 0x22, 0x9c, 0x69, 0x9d, 0x45, 0xfd, - 0x3b, 0xb7, 0x30, 0x46, 0xfc, 0xa9, 0xd6, 0x7f, 0x1f, 0x1f, 0xe5, 0xf5, 0x4f, 0xeb, 0x51, 0x46, - 0xf4, 0xa0, 0xe1, 0xbe, 0xaf, 0xb9, 0x94, 0x2f, 0x7f, 0x9d, 0xeb, 0x78, 0xd3, 0x13, 0x46, 0xd5, - 0xa1, 0x56, 0xb5, 0x8b, 0x91, 0x53, 0x25, 0xec, 0x9a, 0x47, 0xb5, 0x07, 0x9f, 0xd7, 0x4c, 0x01, - 0x5b, 0x50, 0x9d, 0x5d, 0x55, 0x76, 0xa2, 0x0c, 0xbf, 0xf8, 0x40, 0x6b, 0xd8, 0x41, 0x5b, 0xf9, - 0xc3, 0x38, 0x79, 0x6f, 0xa0, 0xf9, 0x2c, 0xfb, 0xc2, 0x70, 0x5b, 0xce, 0xa3, 0x4c, 0x81, 0x93, - 0x7d, 0x57, 0xcb, 0xde, 0xc3, 0x99, 0xec, 0xdc, 0xe7, 0x0a, 0xe5, 0x1e, 0xa2, 0xeb, 0x37, 0xc5, - 0x62, 0x93, 0x7e, 0x56, 0x4e, 0x3e, 0x18, 0xdb, 0x79, 0x34, 0xce, 0xc4, 0xdf, 0xd7, 0xe2, 0x0f, - 0xb1, 0x97, 0x37, 0x3d, 0x2f, 0x2c, 0x55, 0x01, 0xd9, 0x47, 0x0e, 0xb4, 0x6f, 0x13, 0xaa, 0xe2, - 0x3b, 0x49, 0x67, 0x2f, 0xcb, 0x8b, 0xd2, 0x47, 0x11, 0xbc, 0xaf, 0x55, 0x6d, 0xe3, 0xb6, 0x53, - 0x35, 0x48, 0x57, 0x3c, 0xaa, 0x3d, 0x38, 0xfb, 0x2b, 0x40, 0xeb, 0xf1, 0xe0, 0x2a, 0x64, 0x16, - 0x55, 0xbf, 0x85, 0xba, 0xfd, 0xa2, 0x35, 0x3f, 0x22, 0xe5, 0x6f, 0x5f, 0xb8, 0xa3, 0x75, 0x6d, - 0x21, 0x1d, 0x73, 0xa2, 0xe4, 0x3a, 0x0c, 0x42, 0x01, 0x40, 0x46, 0x68, 0x91, 0xcd, 0x9b, 0x29, - 0x62, 0xec, 0x8e, 0x32, 0xcd, 0x7e, 0x8b, 0x08, 0x57, 0x10, 0xdf, 0x65, 0xf4, 0xad, 0x72, 0x59, - 0x0c, 0x6b, 0x05, 0x5e, 0xea, 0xbc, 0x56, 0xc5, 0x8d, 0x3b, 0x07, 0xd5, 0x93, 0x55, 0x31, 0x2a, - 0x6a, 0x9b, 0xe8, 0x0d, 0x4a, 0xe1, 0x08, 0x9a, 0x39, 0x9e, 0xea, 0xb2, 0x6c, 0x9a, 0xeb, 0xba, - 0xb2, 0xac, 0xa0, 0xb5, 0xf8, 0x9e, 0x56, 0xb5, 0x8f, 0x77, 0xa6, 0x55, 0x59, 0x45, 0x0c, 0x36, - 0x4a, 0x60, 0x79, 0x5b, 0x4a, 0xcf, 0xc3, 0xd7, 0x0a, 0x4f, 0x96, 0xd0, 0xf5, 0x57, 0x50, 0xb7, - 0xf4, 0x17, 0xd9, 0x8f, 0x51, 0x25, 0x8a, 0xed, 0xf2, 0xa0, 0xcc, 0x93, 0xf1, 0x91, 0x16, 0xef, - 0xe1, 0xcd, 0x4c, 0xbc, 0x08, 0x47, 0xac, 0x3b, 0x36, 0x99, 0x7d, 0xad, 0x98, 0x40, 0x89, 0xdc, - 0xa2, 0xbb, 0x2e, 0x87, 0xab, 0xd9, 0x74, 0xe7, 0x78, 0xf6, 0x82, 0xd9, 0x7a, 0xfb, 0x6a, 0x11, - 0x27, 0x6c, 0xa0, 0xf4, 0xfe, 0xa1, 0x06, 0x87, 0x25, 0xfe, 0xf9, 0xcb, 0x50, 0x8e, 0x33, 0x2a, - 0x89, 0x3e, 0xc9, 0x1d, 0xe9, 0x36, 0xb2, 0xd9, 0x39, 0x99, 0xbf, 0xb0, 0x48, 0x32, 0xf0, 0x7a, - 0xd1, 0x19, 0xca, 0x9e, 0x3f, 0x2b, 0x7b, 0x8a, 0x21, 0x9a, 0x65, 0xcf, 0x1c, 0xf2, 0x3b, 0x37, - 0xe2, 0xa7, 0xda, 0x8a, 0x13, 0x7c, 0xbf, 0x32, 0xe2, 0x45, 0xad, 0xca, 0xb4, 0x4b, 0x80, 0x4b, - 0x49, 0xb8, 0xd4, 0xd4, 0x0e, 0x59, 0x5a, 0x90, 0x27, 0x84, 0xee, 0x8a, 0x2b, 0xb0, 0x3f, 0x8b, - 0x01, 0x78, 0x23, 0x53, 0x94, 0xa8, 0x05, 0x69, 0x52, 0x35, 0x1c, 0x03, 0x9c, 0x0d, 0x2f, 0x5e, - 0x06, 0x66, 0x45, 0xb2, 0x68, 0xb1, 0x0c, 0xe5, 0xe2, 0x3b, 0x72, 0xf2, 0xbe, 0x85, 0xba, 0xfd, - 0x79, 0x33, 0x1f, 0xba, 0xca, 0xbf, 0x79, 0xaa, 0xa0, 0x8b, 0xc5, 0x03, 0x1a, 0xb2, 0x61, 0xdc, - 0x5f, 0xd1, 0x7f, 0x0d, 0xbe, 0xf8, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xe8, 0xf0, 0x86, - 0x41, 0x1b, 0x00, 0x00, + // 2302 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0x5b, 0x6f, 0x1b, 0xb9, + 0xf5, 0x87, 0x2c, 0x5f, 0xa4, 0x23, 0xd9, 0x56, 0xe8, 0xdb, 0x58, 0xb1, 0x1d, 0x9b, 0x59, 0x6c, + 0xbc, 0xc1, 0x7f, 0xad, 0x8d, 0x17, 0xc8, 0xbf, 0x48, 0xb1, 0x05, 0x92, 0x34, 0xeb, 0x4d, 0x11, + 0x04, 0xee, 0x38, 0xdb, 0x2e, 0xd0, 0xa6, 0x02, 0x35, 0x43, 0x49, 0xd3, 0x1d, 0x73, 0xa6, 0x24, + 0xe5, 0xc4, 0x7e, 0x29, 0x90, 0xf7, 0x3e, 0x15, 0x28, 0xfa, 0xd0, 0x0f, 0xd1, 0xaf, 0x52, 0xf4, + 0xa1, 0x2f, 0x7d, 0xec, 0xe7, 0x28, 0x0a, 0x72, 0xc8, 0xb9, 0x69, 0x64, 0x6d, 0xfa, 0xd0, 0xb7, + 0x39, 0xbc, 0x9c, 0xfb, 0xf9, 0xf1, 0x90, 0x03, 0x4d, 0x1e, 0x7b, 0x27, 0x31, 0x8f, 0x64, 0x84, + 0x96, 0x78, 0xec, 0xc5, 0x83, 0xee, 0xde, 0x28, 0x8a, 0x46, 0x21, 0xed, 0x91, 0x38, 0xe8, 0x11, + 0xc6, 0x22, 0x49, 0x64, 0x10, 0x31, 0x91, 0x2c, 0xea, 0xfe, 0x68, 0x14, 0xc8, 0xf1, 0x64, 0x70, + 0xe2, 0x45, 0x97, 0x3d, 0x46, 0x07, 0x93, 0x90, 0x88, 0x20, 0xea, 0x8d, 0xa2, 0xcf, 0x0d, 0xd1, + 0xf3, 0x22, 0x26, 0x28, 0x13, 0x13, 0xd1, 0x8b, 0x07, 0x3d, 0x21, 0x89, 0xa4, 0x66, 0xe7, 0xe3, + 0x79, 0x3b, 0x19, 0x1d, 0x84, 0x54, 0xaa, 0x6d, 0x5e, 0xc4, 0x86, 0xc1, 0x28, 0xd9, 0x87, 0x1f, + 0x42, 0xe7, 0x62, 0x32, 0x10, 0x1e, 0x0f, 0x06, 0xd4, 0xa5, 0xbf, 0x9b, 0x50, 0x21, 0xd1, 0x36, + 0x2c, 0xcb, 0x28, 0x0e, 0x3c, 0xe1, 0xd4, 0x0e, 0xeb, 0xc7, 0x4d, 0xd7, 0x50, 0xf8, 0x2b, 0xb8, + 0x93, 0x5b, 0x2b, 0x62, 0xa5, 0x0b, 0xda, 0x84, 0x25, 0x3d, 0xed, 0xd4, 0x0e, 0x6b, 0xc7, 0x4d, + 0x37, 0x21, 0x10, 0x82, 0x45, 0x9f, 0x48, 0xe2, 0x2c, 0xe8, 0x41, 0xfd, 0x8d, 0x11, 0x74, 0x5e, + 0x47, 0xec, 0x9c, 0x70, 0x72, 0x29, 0x8c, 0x28, 0xfc, 0x97, 0x05, 0x35, 0xe8, 0xd3, 0x97, 0x6c, + 0x18, 0xa5, 0x2c, 0xd7, 0x60, 0x21, 0xf0, 0x0d, 0xbf, 0x85, 0xc0, 0x47, 0xbb, 0xd0, 0xf0, 0xc6, + 0x24, 0x60, 0xfd, 0xc0, 0xd7, 0x0c, 0x57, 0xdd, 0x15, 0x4d, 0xbf, 0xf4, 0x51, 0x17, 0x1a, 0x5e, + 0x14, 0xb0, 0x01, 0x11, 0xd4, 0xa9, 0xeb, 0x0d, 0x29, 0x8d, 0xf6, 0x01, 0x62, 0x4a, 0x79, 0xdf, + 0x8b, 0x26, 0x4c, 0x3a, 0x8b, 0x7a, 0x63, 0x53, 0x8d, 0x3c, 0x57, 0x03, 0x08, 0x43, 0x5b, 0x5c, + 0x33, 0x6f, 0xcc, 0x23, 0x16, 0xdc, 0x50, 0xdf, 0x59, 0x3a, 0xac, 0x1d, 0x37, 0xdc, 0xc2, 0x18, + 0xba, 0x07, 0xad, 0xc1, 0xc4, 0xfb, 0x9e, 0xca, 0xbe, 0x08, 0x6e, 0xa8, 0xb3, 0x7c, 0x58, 0x3b, + 0x5e, 0x72, 0x21, 0x19, 0xba, 0x08, 0x6e, 0x28, 0xfa, 0x0c, 0x3a, 0xda, 0x8f, 0x5e, 0x14, 0xf6, + 0xaf, 0x28, 0x17, 0x41, 0xc4, 0x1c, 0xd0, 0x7a, 0xac, 0xdb, 0xf1, 0x5f, 0x24, 0xc3, 0xe8, 0x14, + 0x5a, 0x3c, 0x9a, 0x48, 0xda, 0x97, 0x64, 0x10, 0x52, 0xa7, 0x75, 0x58, 0x3f, 0x6e, 0x9d, 0xde, + 0x39, 0xd1, 0x69, 0x71, 0xe2, 0xaa, 0x99, 0x37, 0x6a, 0xc2, 0x05, 0x9e, 0x7e, 0xe3, 0xc7, 0x00, + 0xd9, 0xcc, 0x94, 0x5f, 0x1c, 0x58, 0x21, 0xbe, 0xcf, 0xa9, 0x10, 0xce, 0x82, 0x0e, 0x94, 0x25, + 0xf1, 0x3f, 0x6a, 0xb0, 0x71, 0x46, 0xe5, 0x6b, 0x3a, 0xb8, 0x50, 0x39, 0x92, 0x7a, 0x36, 0xef, + 0xc9, 0x5a, 0xd1, 0x93, 0x08, 0x16, 0x25, 0x09, 0x42, 0x1b, 0x31, 0xf5, 0x8d, 0x3a, 0x50, 0x0f, + 0x83, 0x81, 0x71, 0xac, 0xfa, 0x54, 0xa9, 0x31, 0xa6, 0xc1, 0x68, 0x9c, 0xf8, 0x73, 0xd1, 0x35, + 0x54, 0xa5, 0x1f, 0x96, 0xab, 0xfd, 0x50, 0xf6, 0xfb, 0x4a, 0x85, 0xdf, 0x1d, 0x58, 0xb1, 0x5c, + 0x1a, 0x9a, 0x8b, 0x25, 0xf1, 0x17, 0xd0, 0x79, 0xea, 0xe9, 0x88, 0x8a, 0xd4, 0xaa, 0x3d, 0x68, + 0x1a, 0xc3, 0xa9, 0x4d, 0xd9, 0x6c, 0x00, 0xff, 0x0c, 0xb6, 0xcf, 0xa8, 0x34, 0x9b, 0x8c, 0x3b, + 0x92, 0x3c, 0xcf, 0xf9, 0x2f, 0x71, 0xaa, 0x25, 0x73, 0x66, 0x2e, 0xe4, 0xcd, 0xc4, 0x6f, 0x61, + 0x67, 0x8a, 0x97, 0x51, 0xc2, 0x81, 0x95, 0x01, 0x09, 0x09, 0xf3, 0xa8, 0x65, 0x66, 0x48, 0x55, + 0x21, 0x2c, 0x52, 0xe3, 0x09, 0xaf, 0x84, 0xd0, 0xfe, 0xbe, 0x8e, 0x93, 0xac, 0x5d, 0x75, 0xf5, + 0x37, 0xfe, 0x2d, 0xb4, 0x9f, 0x93, 0x30, 0x4c, 0x79, 0x6e, 0xc3, 0x32, 0xa7, 0x62, 0x12, 0x4a, + 0xc3, 0xd2, 0x50, 0x2a, 0x2d, 0xe9, 0x7b, 0xea, 0xa9, 0x64, 0xa2, 0x9c, 0x9b, 0x90, 0x81, 0x19, + 0x7a, 0xc1, 0x39, 0x3a, 0x82, 0x36, 0x15, 0x32, 0xb8, 0x24, 0x92, 0xf6, 0x47, 0x44, 0x98, 0x08, + 0xb6, 0xec, 0xd8, 0x19, 0x11, 0xf8, 0x04, 0x36, 0x9f, 0x5d, 0x3f, 0x0b, 0x23, 0xef, 0xfb, 0x6f, + 0xb4, 0x6d, 0xb9, 0xe2, 0x37, 0xa6, 0xd7, 0x0a, 0xa6, 0xff, 0x1f, 0xa0, 0x33, 0x2a, 0x7f, 0x7a, + 0xcd, 0x88, 0x90, 0xd7, 0x79, 0x0d, 0x2f, 0x03, 0x46, 0x79, 0x0a, 0x15, 0x09, 0x85, 0xff, 0x5d, + 0x03, 0xf4, 0x86, 0x13, 0x26, 0x88, 0xa7, 0xf0, 0xcd, 0x32, 0x47, 0xb0, 0x38, 0xe4, 0xd1, 0xa5, + 0x31, 0x47, 0x7f, 0xab, 0xac, 0x96, 0x91, 0xb1, 0x61, 0x41, 0x46, 0xca, 0x5d, 0x57, 0x24, 0x9c, + 0xd8, 0x7a, 0x4e, 0x88, 0xcc, 0x89, 0x8b, 0x79, 0x27, 0xde, 0x85, 0xe6, 0x88, 0x88, 0x7e, 0xcc, + 0x03, 0x8f, 0xea, 0x02, 0x6e, 0xba, 0x8d, 0x11, 0x11, 0xe7, 0x8a, 0xb6, 0x93, 0x61, 0x70, 0x19, + 0x48, 0x93, 0x8c, 0x6a, 0xf2, 0x95, 0xa2, 0xd1, 0xa9, 0x02, 0x0e, 0x26, 0x39, 0xf1, 0xa4, 0xce, + 0xc0, 0xd6, 0xe9, 0xb6, 0x29, 0xc5, 0xe7, 0x66, 0xd8, 0xe8, 0xec, 0xa6, 0xeb, 0x94, 0xb1, 0x83, + 0x80, 0x11, 0x7e, 0xad, 0x4b, 0xbc, 0xed, 0x1a, 0x2a, 0x0d, 0xe5, 0xa6, 0x29, 0x1d, 0x15, 0xca, + 0x1b, 0x58, 0x2f, 0x31, 0x52, 0xdb, 0x45, 0x34, 0xe1, 0x69, 0x82, 0x18, 0x4a, 0x45, 0x33, 0xf9, + 0xea, 0x6b, 0x2e, 0x26, 0x9a, 0xc9, 0xd0, 0x9b, 0xeb, 0x98, 0x2a, 0x90, 0x1b, 0x4e, 0x98, 0x76, + 0xa4, 0x05, 0x39, 0x4b, 0x2b, 0xd9, 0x84, 0x8f, 0x84, 0x76, 0x4b, 0xd3, 0xd5, 0xdf, 0xb8, 0x07, + 0xbb, 0x17, 0x94, 0xf9, 0x2e, 0x79, 0x57, 0x1d, 0x02, 0x8d, 0xcc, 0x35, 0x6d, 0x42, 0x82, 0xcc, + 0xbf, 0x86, 0x1d, 0xb5, 0xa1, 0xb0, 0x3a, 0x0b, 0xb0, 0x7c, 0x3f, 0x26, 0x62, 0x6c, 0x95, 0x4e, + 0x28, 0x55, 0xf0, 0xd6, 0x2f, 0xfd, 0x0c, 0x84, 0x74, 0xc1, 0xdb, 0xf1, 0xa7, 0x06, 0x8c, 0xfa, + 0xb0, 0x75, 0x46, 0xa5, 0x4e, 0xb5, 0x67, 0xd7, 0xdf, 0x10, 0x31, 0xce, 0xa9, 0x92, 0xe3, 0xac, + 0xbf, 0xd1, 0x29, 0x6c, 0x0d, 0x27, 0x61, 0xd8, 0x1f, 0x06, 0x61, 0xd8, 0x97, 0x99, 0x42, 0x9a, + 0x79, 0xc3, 0xdd, 0x50, 0x93, 0x5f, 0x07, 0x61, 0x98, 0xd3, 0x15, 0x53, 0x5d, 0x95, 0x56, 0xc0, + 0x0f, 0xc9, 0xe6, 0xff, 0x4a, 0xcc, 0x23, 0xb8, 0x7b, 0x46, 0x65, 0x6e, 0x64, 0xae, 0x35, 0xf8, + 0x9f, 0x75, 0x58, 0xd5, 0x7a, 0xa5, 0xfe, 0xac, 0xb2, 0xf9, 0x1e, 0xb4, 0x62, 0xc2, 0x29, 0x93, + 0x7d, 0x3d, 0x65, 0x12, 0x20, 0x19, 0x52, 0x12, 0x72, 0x56, 0xd4, 0x0b, 0x56, 0x54, 0x17, 0x45, + 0xfe, 0x4c, 0x5c, 0x2a, 0x9d, 0x89, 0x7b, 0xd0, 0x94, 0xc1, 0x25, 0x15, 0x92, 0x5c, 0xc6, 0xba, + 0x26, 0xea, 0x6e, 0x36, 0x50, 0x38, 0x1e, 0x56, 0x8a, 0xc7, 0xc3, 0x3e, 0x80, 0x6e, 0x37, 0xfa, + 0x3c, 0x8a, 0xa4, 0x01, 0xe5, 0xa6, 0x1e, 0x71, 0xa3, 0x48, 0xaa, 0x9d, 0xf2, 0xbd, 0x48, 0x26, + 0x9b, 0x09, 0xfc, 0xc9, 0xf7, 0x42, 0x4f, 0x29, 0xb0, 0xba, 0xa2, 0x4c, 0x9a, 0x59, 0x30, 0x60, + 0xa5, 0x87, 0xf4, 0x82, 0xa7, 0xb0, 0x96, 0xb6, 0x35, 0xc9, 0x9a, 0x96, 0x2e, 0xc8, 0xee, 0x49, + 0x3a, 0x9c, 0x94, 0x65, 0xf2, 0xad, 0xf6, 0xb8, 0xab, 0x5e, 0x9e, 0x54, 0x8e, 0xd0, 0xc0, 0xe3, + 0xb4, 0x13, 0xcc, 0xd0, 0x84, 0x92, 0x1c, 0x88, 0xfe, 0x30, 0x60, 0x24, 0x0c, 0xe4, 0xb5, 0xb3, + 0xaa, 0x43, 0x0b, 0x81, 0xf8, 0xda, 0x8c, 0xa0, 0x9f, 0x40, 0x3b, 0x17, 0x7b, 0xe1, 0xf8, 0xfa, + 0x4c, 0xee, 0x1a, 0x20, 0xa8, 0x28, 0x07, 0xb7, 0xb0, 0x1e, 0xff, 0xa9, 0x0e, 0x1b, 0x55, 0x45, + 0x53, 0x15, 0x64, 0x07, 0xac, 0x2f, 0xcb, 0x3d, 0x8c, 0x05, 0xc5, 0xfa, 0x14, 0x28, 0x2e, 0x4e, + 0x83, 0xe2, 0x52, 0x25, 0x28, 0x2e, 0xe7, 0xe3, 0x5f, 0x88, 0xf1, 0x4a, 0x39, 0xc6, 0x16, 0xac, + 0x1a, 0x19, 0x58, 0xa5, 0x98, 0xd0, 0xcc, 0x30, 0xa1, 0x08, 0xad, 0x70, 0x1b, 0xb4, 0xb6, 0x4a, + 0xd0, 0x5a, 0x05, 0x0d, 0xed, 0x4a, 0x68, 0xd0, 0x90, 0x28, 0x89, 0x9c, 0x08, 0x1d, 0x9c, 0x25, + 0xd7, 0x50, 0x2a, 0x9d, 0x14, 0xff, 0x89, 0xa0, 0xbe, 0xb3, 0x96, 0xa4, 0xd3, 0x88, 0x88, 0x6f, + 0x05, 0xf5, 0xd1, 0x7d, 0x58, 0xcd, 0x9d, 0x7d, 0x11, 0x77, 0xd6, 0xf5, 0x7c, 0x3b, 0x3b, 0xfd, + 0x22, 0x8e, 0xbf, 0x84, 0x3b, 0xaf, 0xe9, 0x3b, 0x73, 0x4e, 0xdb, 0x02, 0x3d, 0x00, 0x88, 0x89, + 0x10, 0xf1, 0x98, 0xab, 0xca, 0xa8, 0xd9, 0x2a, 0xb3, 0x23, 0xf8, 0x04, 0x50, 0x7e, 0x53, 0x76, + 0xae, 0x57, 0x37, 0x09, 0x38, 0x84, 0xcd, 0x6f, 0x99, 0x2a, 0xee, 0x92, 0x9c, 0xd9, 0x6d, 0x45, + 0x51, 0x83, 0x85, 0xb2, 0x06, 0xaa, 0x72, 0xfd, 0x09, 0x27, 0x29, 0xd0, 0x2f, 0xba, 0x29, 0x8d, + 0x7b, 0xb0, 0x55, 0x92, 0x56, 0xd9, 0x24, 0x34, 0x6c, 0x93, 0xa0, 0xcc, 0x79, 0xf5, 0x11, 0xca, + 0xe1, 0xcf, 0x61, 0xe3, 0xd5, 0x47, 0xb0, 0xff, 0x39, 0xac, 0x5f, 0x04, 0x23, 0x96, 0x47, 0xc0, + 0xd9, 0x86, 0xdb, 0x82, 0x58, 0x48, 0x12, 0x4c, 0x17, 0x44, 0x07, 0xea, 0x24, 0x1c, 0x99, 0xfe, + 0x47, 0x7d, 0xe2, 0x4f, 0xa1, 0x93, 0xb1, 0xcc, 0x4a, 0x69, 0xea, 0xb8, 0x62, 0xb0, 0x7b, 0x46, + 0x19, 0xe5, 0x0a, 0x7c, 0x08, 0xf3, 0xa3, 0xcb, 0x0b, 0x4a, 0xfd, 0xf9, 0x4a, 0x54, 0xc0, 0x6c, + 0xfb, 0x87, 0xc0, 0x2c, 0x7e, 0x03, 0xdd, 0x2a, 0x79, 0x59, 0x4f, 0x7d, 0xc5, 0x87, 0x7d, 0x41, + 0xa9, 0x6f, 0xb4, 0x5c, 0xb9, 0xe2, 0x43, 0xb5, 0x44, 0x95, 0x89, 0x9a, 0x8a, 0x79, 0x14, 0x0d, + 0x8d, 0x3c, 0xb5, 0xf6, 0x5c, 0xd1, 0xf8, 0xf7, 0x70, 0xa8, 0xac, 0xcd, 0xe1, 0xc7, 0x79, 0x9a, + 0x09, 0xd6, 0x98, 0x1f, 0x43, 0x2b, 0x7f, 0x38, 0xd5, 0x34, 0x2e, 0xee, 0x56, 0xe1, 0x53, 0xd2, + 0xab, 0xe4, 0x57, 0xcf, 0xcb, 0x36, 0xfc, 0xff, 0x70, 0x74, 0x8b, 0x02, 0xb7, 0xf8, 0x5f, 0x69, + 0x5e, 0x6c, 0x17, 0xfe, 0xc7, 0x9a, 0xf7, 0xa0, 0x73, 0x66, 0xa0, 0x28, 0x55, 0xb4, 0x80, 0x57, + 0xb5, 0x22, 0x5e, 0xe1, 0x23, 0x68, 0xcd, 0x3b, 0xaa, 0x1f, 0x41, 0xeb, 0x8c, 0x64, 0x77, 0x8a, + 0x0e, 0xd4, 0x55, 0xe3, 0x9c, 0xac, 0x50, 0x9f, 0x6a, 0x24, 0x6b, 0xb6, 0xd5, 0x27, 0x7e, 0x0c, + 0x6b, 0x2f, 0x92, 0x63, 0xcc, 0xee, 0xfa, 0x04, 0x96, 0x93, 0x83, 0x4d, 0xb7, 0xc3, 0xad, 0xd3, + 0xb6, 0x31, 0x58, 0x2f, 0x73, 0xcd, 0x1c, 0x7e, 0x04, 0x4b, 0x7a, 0xe0, 0x23, 0xee, 0xce, 0x9f, + 0x42, 0xfb, 0x3c, 0xe6, 0xd1, 0x30, 0xd7, 0xd7, 0x84, 0x81, 0x90, 0x94, 0xd9, 0xb6, 0x2c, 0xa1, + 0xf0, 0x03, 0x58, 0x35, 0xeb, 0xe6, 0x94, 0xef, 0x57, 0x70, 0xe7, 0x8c, 0xca, 0xe7, 0xfa, 0x29, + 0x20, 0x5d, 0x7c, 0x0c, 0xcb, 0xc9, 0xe3, 0x80, 0x89, 0x57, 0xe7, 0x24, 0x79, 0x35, 0x48, 0x8e, + 0x5f, 0xb5, 0xd2, 0xcc, 0x9f, 0xfe, 0x0d, 0x00, 0x9e, 0xc6, 0xc1, 0x05, 0xe5, 0x57, 0xea, 0x3c, + 0x78, 0x0b, 0xad, 0xdc, 0x75, 0x13, 0xed, 0x18, 0xb3, 0xcb, 0xd7, 0xfd, 0xae, 0x3d, 0x5a, 0x2b, + 0xee, 0xa6, 0x78, 0xf7, 0xc3, 0xdf, 0xff, 0xf5, 0xc7, 0x85, 0x0d, 0x74, 0xa7, 0x77, 0xf5, 0xa8, + 0x37, 0x11, 0x94, 0xf7, 0x18, 0x1d, 0xe8, 0x0e, 0x03, 0xfd, 0x06, 0x76, 0x5e, 0x11, 0x49, 0x85, + 0x7c, 0xc9, 0x39, 0xd5, 0x37, 0xc1, 0x41, 0x48, 0x75, 0x5f, 0x35, 0x5b, 0xd4, 0xa6, 0x99, 0x28, + 0xb4, 0x5f, 0x78, 0x53, 0x0b, 0x59, 0x43, 0xed, 0x54, 0x88, 0xba, 0xd5, 0x72, 0x58, 0x2f, 0x5d, + 0xeb, 0xd0, 0x7e, 0xa6, 0x69, 0xc5, 0xd5, 0xb1, 0x7b, 0x30, 0x6b, 0xda, 0xc8, 0x39, 0xd4, 0x72, + 0xba, 0x78, 0x2b, 0x95, 0x43, 0xcc, 0xad, 0x55, 0x2d, 0x7b, 0x52, 0x7b, 0x88, 0xce, 0x61, 0x51, + 0xdd, 0xf5, 0xd0, 0xec, 0x9a, 0xe8, 0x6e, 0xd8, 0x1b, 0x49, 0xee, 0x4e, 0x88, 0x1d, 0xcd, 0x19, + 0xe1, 0xd5, 0x94, 0xb3, 0x47, 0xc2, 0x50, 0x71, 0xbc, 0x01, 0x34, 0xdd, 0xf6, 0xa3, 0x43, 0xc3, + 0x64, 0xe6, 0x8d, 0x20, 0xb5, 0x65, 0xc6, 0x15, 0x00, 0x63, 0x2d, 0x71, 0x0f, 0xef, 0xa4, 0x12, + 0x39, 0x79, 0x97, 0x2b, 0x57, 0x25, 0x7b, 0x0c, 0x6b, 0xc5, 0x1e, 0x1f, 0xed, 0x65, 0x1e, 0x9a, + 0x6e, 0xfd, 0x67, 0x44, 0x67, 0x5a, 0xd2, 0xa8, 0xb0, 0x5b, 0x49, 0x62, 0xd0, 0x29, 0x37, 0xfb, + 0xe8, 0x60, 0x5a, 0x56, 0xfe, 0x16, 0x30, 0x43, 0xda, 0x27, 0x5a, 0xda, 0x01, 0xde, 0xad, 0x92, + 0xa6, 0xf7, 0x2b, 0x79, 0x1f, 0x6a, 0xfa, 0xfa, 0x52, 0x70, 0x8c, 0x47, 0x83, 0x58, 0x22, 0x9c, + 0x49, 0x9d, 0x75, 0x29, 0xe8, 0xde, 0xd2, 0x4b, 0xe2, 0xcf, 0xb4, 0xfc, 0xfb, 0xf8, 0x20, 0x2f, + 0x7f, 0x5a, 0x8e, 0x52, 0xa2, 0x0f, 0xcd, 0xf4, 0xe5, 0x2d, 0x4d, 0xf9, 0xf2, 0xbb, 0x5d, 0xd7, + 0x99, 0x9e, 0x30, 0xa2, 0xf6, 0xb5, 0xa8, 0x1d, 0x8c, 0x52, 0x51, 0xc2, 0xae, 0x79, 0x52, 0x7b, + 0xf8, 0x45, 0xcd, 0x14, 0xb0, 0x05, 0xd5, 0xd9, 0x55, 0x65, 0x27, 0xca, 0xf0, 0x8b, 0xf7, 0xb4, + 0x84, 0x6d, 0xb4, 0x99, 0x37, 0x26, 0xe5, 0xf7, 0x16, 0x5a, 0x2f, 0xb2, 0xb7, 0x87, 0xdb, 0x72, + 0x1e, 0x65, 0x02, 0x52, 0xde, 0xf7, 0x34, 0xef, 0x5d, 0x9c, 0xf1, 0xce, 0x3d, 0x64, 0x28, 0xf7, + 0x10, 0x5d, 0xbf, 0x09, 0x16, 0x9b, 0xf4, 0xb3, 0x7c, 0xf2, 0xc1, 0xd8, 0xca, 0xa3, 0x71, 0xc6, + 0xfe, 0xbe, 0x66, 0xbf, 0x8f, 0x9d, 0xbc, 0xea, 0x79, 0x66, 0x89, 0x08, 0xc8, 0x9e, 0x3f, 0xd0, + 0x5d, 0x9b, 0x50, 0x15, 0x2f, 0x28, 0xdd, 0xdd, 0x2c, 0x2f, 0x4a, 0xcf, 0x25, 0xf8, 0xae, 0x16, + 0xb5, 0x85, 0x3b, 0xa9, 0x28, 0x3f, 0x59, 0xf1, 0xa4, 0xf6, 0xf0, 0xf4, 0xaf, 0x00, 0xed, 0xa7, + 0xfe, 0x65, 0xc0, 0x2c, 0xaa, 0x7e, 0x07, 0x0d, 0xfb, 0xd6, 0x35, 0x3f, 0x22, 0xe5, 0x57, 0x31, + 0xdc, 0xd5, 0xb2, 0x36, 0x91, 0x8e, 0x39, 0x51, 0x7c, 0x53, 0x0c, 0x42, 0x1e, 0x40, 0xd6, 0xea, + 0x22, 0x9b, 0x37, 0x53, 0x2d, 0x73, 0x6a, 0xca, 0x74, 0x5f, 0x5c, 0x44, 0xb8, 0x02, 0xfb, 0x1e, + 0xa3, 0xef, 0x94, 0xcb, 0x22, 0x58, 0x2d, 0x74, 0xac, 0xa9, 0xd7, 0xaa, 0xba, 0xe6, 0xee, 0x5e, + 0xf5, 0x64, 0x55, 0x8c, 0x8a, 0xd2, 0x26, 0x7a, 0x83, 0x12, 0x38, 0x82, 0x56, 0xae, 0x83, 0x4d, + 0xb3, 0x6c, 0xba, 0x0b, 0x4e, 0xcb, 0xb2, 0xa2, 0xe1, 0xc5, 0x47, 0x5a, 0xd4, 0x5d, 0xbc, 0x3d, + 0x2d, 0xca, 0x0a, 0x62, 0xb0, 0x5e, 0x02, 0xcb, 0xdb, 0x52, 0x7a, 0x1e, 0xbe, 0x56, 0x78, 0xb2, + 0x84, 0xae, 0xbf, 0x82, 0x86, 0x6d, 0x8c, 0x91, 0x7d, 0xa6, 0x2a, 0x35, 0xdf, 0x69, 0x1e, 0x94, + 0x3b, 0x68, 0x7c, 0xa0, 0xd9, 0x3b, 0x78, 0x23, 0x63, 0x2f, 0x82, 0x11, 0xeb, 0x8d, 0x4d, 0x66, + 0x7f, 0xa8, 0x01, 0x9a, 0x6e, 0x6f, 0xd3, 0x73, 0x63, 0x66, 0xa7, 0xdd, 0x3d, 0xba, 0x65, 0x85, + 0x91, 0xfd, 0x40, 0xcb, 0x3e, 0xc2, 0x7b, 0x99, 0xec, 0xd1, 0xd4, 0x6a, 0xa5, 0xc4, 0x1f, 0x6a, + 0xb0, 0x5f, 0x6a, 0x46, 0x7f, 0x19, 0xc8, 0x71, 0xd6, 0x57, 0xa2, 0x07, 0x39, 0xfb, 0x6e, 0xeb, + 0x3c, 0xbb, 0xc7, 0xf3, 0x17, 0x16, 0x3b, 0x0e, 0xbc, 0x56, 0xf4, 0x8c, 0xd2, 0xe7, 0xcf, 0x4a, + 0x9f, 0x62, 0xbc, 0x66, 0xe9, 0x33, 0xa7, 0x13, 0x9e, 0x1b, 0xfe, 0x13, 0xad, 0xc5, 0x31, 0xbe, + 0x5f, 0x19, 0xfe, 0xa2, 0x54, 0xa5, 0xda, 0x05, 0xc0, 0x85, 0x24, 0x5c, 0xea, 0x3e, 0x0f, 0xd9, + 0x1e, 0x21, 0xdf, 0x1d, 0xa6, 0xe7, 0x5d, 0xa1, 0x15, 0xb4, 0x80, 0x80, 0xd7, 0x33, 0x41, 0xb1, + 0x5a, 0x90, 0x64, 0x58, 0x33, 0x6d, 0x07, 0x67, 0x63, 0x8d, 0x93, 0x21, 0x5b, 0xb1, 0x73, 0xb4, + 0xc0, 0x86, 0x36, 0xf2, 0x81, 0xb6, 0xfc, 0xbe, 0x83, 0x86, 0xfd, 0xc7, 0x33, 0x1f, 0xc7, 0xca, + 0x7f, 0x83, 0xaa, 0x70, 0x8c, 0x45, 0x3e, 0x0d, 0xd8, 0x30, 0x1a, 0x2c, 0xeb, 0x9f, 0x0b, 0x5f, + 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x9d, 0x00, 0x7f, 0x68, 0x1b, 0x00, 0x00, } diff --git a/rpc/pb/rpc.pb.gw.go b/rpc/pb/rpc.pb.gw.go index 797f1b102..25755278a 100644 --- a/rpc/pb/rpc.pb.gw.go +++ b/rpc/pb/rpc.pb.gw.go @@ -50,7 +50,7 @@ func request_ApiService_GetAccountState_0(ctx context.Context, marshaler runtime var protoReq GetAccountStateRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -63,7 +63,7 @@ func request_ApiService_Call_0(ctx context.Context, marshaler runtime.Marshaler, var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -76,7 +76,7 @@ func request_ApiService_SendRawTransaction_0(ctx context.Context, marshaler runt var protoReq SendRawTransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -89,7 +89,7 @@ func request_ApiService_GetBlockByHash_0(ctx context.Context, marshaler runtime. var protoReq GetBlockByHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -102,7 +102,7 @@ func request_ApiService_GetBlockByHeight_0(ctx context.Context, marshaler runtim var protoReq GetBlockByHeightRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -115,7 +115,7 @@ func request_ApiService_GetTransactionReceipt_0(ctx context.Context, marshaler r var protoReq GetTransactionByHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -128,7 +128,7 @@ func request_ApiService_Subscribe_0(ctx context.Context, marshaler runtime.Marsh var protoReq SubscribeRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -158,7 +158,7 @@ func request_ApiService_EstimateGas_0(ctx context.Context, marshaler runtime.Mar var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -171,7 +171,7 @@ func request_ApiService_GetEventsByHash_0(ctx context.Context, marshaler runtime var protoReq HashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -184,7 +184,7 @@ func request_ApiService_GetDynasty_0(ctx context.Context, marshaler runtime.Mars var protoReq ByBlockHeightRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -206,7 +206,7 @@ func request_AdminService_NewAccount_0(ctx context.Context, marshaler runtime.Ma var protoReq NewAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -219,7 +219,7 @@ func request_AdminService_UnlockAccount_0(ctx context.Context, marshaler runtime var protoReq UnlockAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -232,7 +232,7 @@ func request_AdminService_LockAccount_0(ctx context.Context, marshaler runtime.M var protoReq LockAccountRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -245,7 +245,7 @@ func request_AdminService_SendTransaction_0(ctx context.Context, marshaler runti var protoReq TransactionRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -258,7 +258,7 @@ func request_AdminService_SignHash_0(ctx context.Context, marshaler runtime.Mars var protoReq SignHashRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -267,15 +267,15 @@ func request_AdminService_SignHash_0(ctx context.Context, marshaler runtime.Mars } -func request_AdminService_GenerateBlockRand_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GenerateBlockRandRequest +func request_AdminService_GenerateRandomSeed_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateRandomSeedRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.GenerateBlockRand(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.GenerateRandomSeed(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } @@ -284,7 +284,7 @@ func request_AdminService_SignTransactionWithPassphrase_0(ctx context.Context, m var protoReq SignTransactionPassphraseRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -297,7 +297,7 @@ func request_AdminService_SendTransactionWithPassphrase_0(ctx context.Context, m var protoReq SendTransactionPassphraseRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -310,7 +310,7 @@ func request_AdminService_StartPprof_0(ctx context.Context, marshaler runtime.Ma var protoReq PprofRequest var metadata runtime.ServerMetadata - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -376,7 +376,7 @@ func RegisterApiServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ApiServiceClient) error { mux.Handle("GET", pattern_ApiService_GetNebState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -405,7 +405,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("GET", pattern_ApiService_LatestIrreversibleBlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -434,7 +434,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetAccountState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -463,7 +463,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_Call_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -492,7 +492,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_SendRawTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -521,7 +521,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetBlockByHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -550,7 +550,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetBlockByHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -579,7 +579,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetTransactionReceipt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -608,7 +608,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_Subscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -637,7 +637,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("GET", pattern_ApiService_GetGasPrice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -666,7 +666,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_EstimateGas_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -695,7 +695,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetEventsByHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -724,7 +724,7 @@ func RegisterApiServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) mux.Handle("POST", pattern_ApiService_GetDynasty_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -850,7 +850,7 @@ func RegisterAdminServiceHandler(ctx context.Context, mux *runtime.ServeMux, con func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AdminServiceClient) error { mux.Handle("GET", pattern_AdminService_Accounts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -879,7 +879,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_NewAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -908,7 +908,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_UnlockAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -937,7 +937,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_LockAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -966,7 +966,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SendTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -995,7 +995,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SignHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1023,8 +1023,8 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) - mux.Handle("POST", pattern_AdminService_GenerateBlockRand_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + mux.Handle("POST", pattern_AdminService_GenerateRandomSeed_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1041,19 +1041,19 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_AdminService_GenerateBlockRand_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_AdminService_GenerateRandomSeed_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_AdminService_GenerateBlockRand_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_AdminService_GenerateRandomSeed_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) mux.Handle("POST", pattern_AdminService_SignTransactionWithPassphrase_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1082,7 +1082,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_SendTransactionWithPassphrase_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1111,7 +1111,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("POST", pattern_AdminService_StartPprof_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1140,7 +1140,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("GET", pattern_AdminService_GetConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1169,7 +1169,7 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) mux.Handle("GET", pattern_AdminService_NodeInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(ctx) + ctx, cancel := context.WithCancel(req.Context()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan struct{}, closed <-chan bool) { @@ -1213,7 +1213,7 @@ var ( pattern_AdminService_SignHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "admin", "sign", "hash"}, "")) - pattern_AdminService_GenerateBlockRand_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "blockrand"}, "")) + pattern_AdminService_GenerateRandomSeed_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "generateRandomSeed"}, "")) pattern_AdminService_SignTransactionWithPassphrase_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "sign"}, "")) @@ -1239,7 +1239,7 @@ var ( forward_AdminService_SignHash_0 = runtime.ForwardResponseMessage - forward_AdminService_GenerateBlockRand_0 = runtime.ForwardResponseMessage + forward_AdminService_GenerateRandomSeed_0 = runtime.ForwardResponseMessage forward_AdminService_SignTransactionWithPassphrase_0 = runtime.ForwardResponseMessage diff --git a/rpc/pb/rpc.proto b/rpc/pb/rpc.proto index a4fefbbc2..1e1f2fbcc 100644 --- a/rpc/pb/rpc.proto +++ b/rpc/pb/rpc.proto @@ -174,9 +174,9 @@ service AdminService { }; } - rpc GenerateBlockRand(GenerateBlockRandRequest) returns (GenerateBlockRandResponse) { + rpc GenerateRandomSeed(GenerateRandomSeedRequest) returns (GenerateRandomSeedResponse) { option (google.api.http) = { - post: "/v1/admin/blockrand" + post: "/v1/admin/generateRandomSeed" body: "*" }; } @@ -554,15 +554,17 @@ message SignHashResponse { bytes data = 1; } -message GenerateBlockRandRequest { +message GenerateRandomSeedRequest { // miner address string address = 1; // parent hash of new block bytes parent_hash = 2; + // height of new block + uint64 height = 3; } -message GenerateBlockRandResponse { - bytes vrf_hash = 1; +message GenerateRandomSeedResponse { + bytes vrf_seed = 1; bytes vrf_proof = 2; } From a4f493c863b43d821fd5524f14f808482a4b1f85 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Thu, 3 May 2018 21:37:08 +0800 Subject: [PATCH 57/69] nvm: update date.js --- nf/nvm/v8/lib/date.js | 68 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index 17d58a2c0..5cd878473 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -43,12 +43,78 @@ var NebDate = (function(Date) { NebDate.parse = function(dateString) { return Date.parse(dateString); } + + NebDate.prototype.getTimezoneOffset = function() { + return 0; + } + NebDate.prototype.getDate = function() { + return this.getUTCDate(); + } + NebDate.prototype.getDay = function() { + return this.getUTCDay(); + } + NebDate.prototype.getFullYear = function() { + return this.getUTCFullYear(); + } + NebDate.prototype.getHours = function() { + return this.getUTCHours(); + } + NebDate.prototype.getMilliseconds = function() { + return this.getUTCMilliseconds(); + } + NebDate.prototype.getMinutes = function() { + return this.getUTCMinutes(); + } + NebDate.prototype.getMonth = function() { + return this.getUTCMonth(); + } + NebDate.prototype.getSeconds = function() { + return this.getUTCSeconds(); + }, + NebDate.prototype.getYear = function() { + throw new Error("Deprecated!"); + } + NebDate.prototype.setYear = function() { + throw new Error("Deprecated!"); + } + NebDate.prototype.setDate = function() { + return this.setUTCDate.apply(this, arguments); + } + NebDate.prototype.setFullYear = function() { + return this.setUTCFullYear.apply(this, arguments); + } + NebDate.prototype.setHours = function() { + return this.setUTCHours.apply(this, arguments); + } + NebDate.prototype.setMilliseconds = function() { + return this.setUTCMilliseconds.apply(this, arguments); + } + NebDate.prototype.setMinutes = function() { + return this.setUTCMinutes.apply(this, arguments); + } + NebDate.prototype.setMonth = function() { + return this.setUTCMonth.apply(this, arguments); + } + NebDate.prototype.setSeconds = function() { + return this.setUTCSeconds.apply(this, arguments); + } + NebDate.prototype.toString = function() { + // return UTC string + return this.toUTCString.apply(this, arguments); + } + NebDate.prototype.toDateString = function() { + throw new Error("Unsupported method!"); + } + NebDate.prototype.toTimeString = function() { + throw new Error("Unsupported method!"); + } + NebDate.prototype = new Proxy(NebDate.prototype, { getPrototypeOf: function(target) { throw new Error("Unsupported method!"); }, }); - // TODO: timezone/locale => 0 + Object.setPrototypeOf(NebDate.prototype, Date.prototype); return NebDate; })(Date); From 5710784f8491afb1c14e046b2db760848991008d Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Fri, 4 May 2018 01:36:49 +0800 Subject: [PATCH 58/69] date.js:add test cases --- core/block_pool.go | 4 +- core/blockchain.go | 3 +- nf/nvm/test/test_date.js | 120 ++++++++++++++++++++++++++++++++++++++- nf/nvm/v8/lib/date.js | 2 +- 4 files changed, 123 insertions(+), 6 deletions(-) diff --git a/core/block_pool.go b/core/block_pool.go index 69d83d600..093e3e5e6 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -554,7 +554,7 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( "blockHeight": lb.block.height, "targetHeight": lb.block.height - nob, "numOfBlocksInDynasty": nob, - }).Error("Block not found.") + }).Error("Block not found, unexpected error.") metricsUnexpectedBehavior.Update(1) return nil, nil, ErrNotBlockInCanonicalChain } @@ -570,7 +570,7 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( if !parentBlock.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "parent": parentBlock, - }).Error("Parent block has no random seed.") + }).Error("Parent block has no random seed, unexpected error.") metricsUnexpectedBehavior.Update(1) return nil, nil, ErrInvalidBlockRandom } diff --git a/core/blockchain.go b/core/blockchain.go index 7d1585550..250122781 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -497,7 +497,8 @@ func (bc *BlockChain) GetInputForVRFSigner(parentHash byteutils.Hash, height uin if !parent.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "parent": parent, - }).Info("Parent block has no random seed.") + }).Error("Parent block has no random seed, unexpected error.") + metricsUnexpectedBehavior.Update(1) return nil, ErrInvalidBlockRandom } out = append(out, parent.header.random.VrfSeed) diff --git a/nf/nvm/test/test_date.js b/nf/nvm/test/test_date.js index 98fc4baad..29353e1b0 100644 --- a/nf/nvm/test/test_date.js +++ b/nf/nvm/test/test_date.js @@ -22,6 +22,122 @@ Blockchain.block = { console.log(Date.now()); console.log(Date.UTC()); +console.log(Date.parse('01 Jan 1970 00:00:00 GMT')); -var date = new Date(); -console.log(date.getTime()); \ No newline at end of file +var date = new Date('August 19, 2017 23:15:30'); +var date2 = new Date('August 19, 2017 23:15:30'); +console.log(date.getTime()); +eq(date.getDate(), date.getUTCDate()); +eq(date.getDay(), date.getUTCDay()); +eq(date.getFullYear(), date.getUTCFullYear()); +eq(date.getHours(), date.getUTCHours()); +eq(date.getMilliseconds(), date.getUTCMilliseconds()); +eq(date.getMinutes(), date.getUTCMinutes()); +eq(date.getMonth(), date.getUTCMonth()); +eq(date.getSeconds(), date.getUTCSeconds()); +eq(date.toString(), date.toUTCString()); + +try { + date.getTimezoneOffset(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Unsupported method!") { + throw err; + } +} +try { + date.getYear(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Deprecated!") { + throw err; + } +} +try { + date.setYear(1999); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Deprecated!") { + throw err; + } +} +try { + date.toDateString(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Unsupported method!") { + throw err; + } +} +try { + date.toTimeString(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Unsupported method!") { + throw err; + } +} + +var tmp = new Date('August 19, 1975 23:15:30 UTC'); +if (tmp.toJSON() !== "1975-08-19T23:15:30.000Z") { + throw new Error("toJSON is not equal.") +} +try { + date.toLocaleDateString(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Unsupported method!") { + throw err; + } +} +try { + date.toLocaleTimeString(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Unsupported method!") { + throw err; + } +} + +try { + date.toLocaleString(); + throw new Error("should not be here."); +} catch(err) { + if (err != "Error: Unsupported method!") { + throw err; + } +} + +date.setDate(12); +date2.setUTCDate(12); +eq(date - date2, 0); + +date.setMonth(1); +date2.setUTCMonth(1); +eq(date - date2, 0); + +date.setFullYear(1999); +date2.setUTCFullYear(1999); +eq(date - date2, 0); + +date.setHours(22); +date2.setUTCHours(22); +eq(date - date2, 0); + +date.setMilliseconds(420); +date2.setUTCMilliseconds(420); +eq(date - date2, 0); + +date.setMinutes(12); +date2.setUTCMinutes(12); +eq(date - date2, 0); + +date.setSeconds(12); +date2.setUTCSeconds(12); +eq(date - date2, 0); + +function eq(a, b) { + if (a !== b) { + throw new Error("Not equal."); + } +} \ No newline at end of file diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index 5cd878473..0e9b9f4bd 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -45,7 +45,7 @@ var NebDate = (function(Date) { } NebDate.prototype.getTimezoneOffset = function() { - return 0; + throw new Error("Unsupported method!"); } NebDate.prototype.getDate = function() { return this.getUTCDate(); From 00ff407dabfe16b9aa622604aa92679828f37012 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Fri, 4 May 2018 16:02:25 +0800 Subject: [PATCH 59/69] nvm: rename vars, security enhance --- consensus/dpos/dpos.go | 6 +++--- core/block.go | 19 ++++++++++++------- core/block_pool.go | 4 ++-- core/blockchain.go | 4 ++-- core/compatibility.go | 11 +++++++---- nf/nvm/blockchain.go | 2 +- nf/nvm/context.go | 22 ++++++++++++---------- nf/nvm/engine_v8.go | 1 - nf/nvm/engine_v8_test.go | 11 ++++++++--- nf/nvm/test/contract_date_and_random.js | 3 ++- nf/nvm/test/test_date.js | 4 +--- nf/nvm/test/test_random_disable.js | 6 ++---- nf/nvm/test/test_random_enable.js | 6 ++---- nf/nvm/test/test_random_seed.js | 5 +---- nf/nvm/types.go | 3 ++- nf/nvm/v8/lib/blockchain.js | 19 +++++++++++++++++-- nf/nvm/v8/lib/date.js | 12 ++++++++++++ nf/nvm/v8/lib/execution_env.js | 2 +- nf/nvm/v8/lib/random.js | 4 ++-- 19 files changed, 89 insertions(+), 55 deletions(-) diff --git a/consensus/dpos/dpos.go b/consensus/dpos/dpos.go index 9b971bceb..fb0ccd7d3 100644 --- a/consensus/dpos/dpos.go +++ b/consensus/dpos/dpos.go @@ -378,10 +378,10 @@ func (dpos *Dpos) VerifyBlock(block *core.Block) error { } // check block random - if block.Height() >= core.RandomAvailableCompatibleHeight && !block.HasRandomSeed() { + if block.Height() >= core.RandomAvailableHeight && !block.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "blockHeight": block.Height(), - "compatibleHeight": core.RandomAvailableCompatibleHeight, + "compatibleHeight": core.RandomAvailableHeight, }).Debug("No random found in block header.") return core.ErrInvalidBlockRandom } @@ -479,7 +479,7 @@ func (dpos *Dpos) newBlock(tail *core.Block, consensusState state.ConsensusState adminService = rpcpb.NewAdminServiceClient(conn) } - if block.Height() >= core.RandomAvailableCompatibleHeight { + if block.Height() >= core.RandomAvailableHeight { dpos.generateRandomSeed(block, adminService) } diff --git a/core/block.go b/core/block.go index 4a5283fe1..29f28e83a 100644 --- a/core/block.go +++ b/core/block.go @@ -194,10 +194,10 @@ func (block *Block) FromProto(msg proto.Message) error { if err := block.header.FromProto(msg.Header); err != nil { return err } - if msg.Height >= RandomAvailableCompatibleHeight && !block.HasRandomSeed() { + if msg.Height >= RandomAvailableHeight && !block.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "blockHeight": msg.Height, - "compatibleHeight": RandomAvailableCompatibleHeight, + "compatibleHeight": RandomAvailableHeight, }).Debug("No random found in block header.") return ErrInvalidProtoToBlockHeader } @@ -383,15 +383,20 @@ func (block *Block) Transactions() Transactions { // RandomSeed block random seed (VRF) func (block *Block) RandomSeed() string { - if block.height >= RandomAvailableCompatibleHeight { + if block.height >= RandomAvailableHeight { return byteutils.Hex(block.header.random.VrfSeed) } return "" } -// SupportRandom check is random supported -func (block *Block) SupportRandom() bool { - return block.height >= RandomAvailableCompatibleHeight +// RandomAvailable check if Math.random available in contract +func (block *Block) RandomAvailable() bool { + return block.height >= RandomAvailableHeight +} + +// DateAvailable check if date available in contract +func (block *Block) DateAvailable() bool { + return block.height >= DateAvailableHeight } // LinkParentBlock link parent block, return true if hash is the same; false otherwise. @@ -790,7 +795,7 @@ func (block *Block) Seal() error { func (block *Block) String() string { random := "" - if block.height >= RandomAvailableCompatibleHeight && block.header.random != nil { + if block.height >= RandomAvailableHeight && block.header.random != nil { if block.header.random.VrfSeed != nil { random += "/vrf_seed/" + byteutils.Hex(block.header.random.VrfSeed) } diff --git a/core/block_pool.go b/core/block_pool.go index 093e3e5e6..0c47702bc 100644 --- a/core/block_pool.go +++ b/core/block_pool.go @@ -535,7 +535,7 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( } // verify vrf - if lb.block.height >= RandomAvailableCompatibleHeight { + if lb.block.height >= RandomAvailableHeight { // prepare vrf inputs inputs := make([][]byte, 0) @@ -566,7 +566,7 @@ func (lb *linkedBlock) travelToLinkAndReturnAllValidBlocks(parentBlock *Block) ( inputs = append(inputs, tmp.block.Hash()) } - if parentBlock.height >= RandomAvailableCompatibleHeight { + if parentBlock.height >= RandomAvailableHeight { if !parentBlock.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "parent": parentBlock, diff --git a/core/blockchain.go b/core/blockchain.go index 250122781..e6bfff777 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -468,7 +468,7 @@ func (bc *BlockChain) GetBlockOnCanonicalChainByHash(blockHash byteutils.Hash) * // GetInputForVRFSigner returns [ getBlock(block.height - 2 * dynasty.size).hash, block.parent.seed ] func (bc *BlockChain) GetInputForVRFSigner(parentHash byteutils.Hash, height uint64) (out [][]byte, err error) { - if parentHash == nil || height < RandomAvailableCompatibleHeight { + if parentHash == nil || height < RandomAvailableHeight { return nil, ErrInvalidArgument } @@ -493,7 +493,7 @@ func (bc *BlockChain) GetInputForVRFSigner(parentHash byteutils.Hash, height uin return nil, ErrNotBlockInCanonicalChain } - if parent.height >= RandomAvailableCompatibleHeight { + if parent.height >= RandomAvailableHeight { if !parent.HasRandomSeed() { logging.VLog().WithFields(logrus.Fields{ "parent": parent, diff --git a/core/compatibility.go b/core/compatibility.go index 5abed9c8b..9de84cb0a 100644 --- a/core/compatibility.go +++ b/core/compatibility.go @@ -19,9 +19,12 @@ package core const ( - // TransferFromContractEventCompatibleHeight record event 'TransferFromContractEvent' since this height - TransferFromContractEventCompatibleHeight uint64 = 200000 + // TransferFromContractEventRecordableHeight record event 'TransferFromContractEvent' since this height + TransferFromContractEventRecordableHeight uint64 = 200000 - // RandomAvailableCompatibleHeight make 'random' available in contract since this height - RandomAvailableCompatibleHeight uint64 = 200000 + // RandomAvailableHeight make 'Math.random' available in contract since this height + RandomAvailableHeight uint64 = 200000 + + // DateAvailableHeight make 'Date' available in contract since this height + DateAvailableHeight uint64 = 200000 ) diff --git a/nf/nvm/blockchain.go b/nf/nvm/blockchain.go index d5639346d..ce93099e0 100644 --- a/nf/nvm/blockchain.go +++ b/nf/nvm/blockchain.go @@ -181,7 +181,7 @@ func TransferFunc(handler unsafe.Pointer, to *C.char, v *C.char, gasCnt *C.size_ } } - if engine.ctx.block.Height() >= core.TransferFromContractEventCompatibleHeight { + if engine.ctx.block.Height() >= core.TransferFromContractEventRecordableHeight { cAddr, err := core.AddressParseFromBytes(engine.ctx.contract.Address()) if err != nil { logging.VLog().WithFields(logrus.Fields{ diff --git a/nf/nvm/context.go b/nf/nvm/context.go index 3101455d9..aa128c05d 100644 --- a/nf/nvm/context.go +++ b/nf/nvm/context.go @@ -32,11 +32,12 @@ type SerializableAccount struct { // SerializableBlock serializable block type SerializableBlock struct { - Timestamp int64 `json:"timestamp"` - Hash string `json:"hash"` - Height uint64 `json:"height"` - SupportRandom bool `json:"supportRandom"` - Seed string `json:"seed"` + Timestamp int64 `json:"timestamp"` + Hash string `json:"hash"` + Height uint64 `json:"height"` + RandomAvailable bool `json:"randomAvailable"` + DateAvailable bool `json:"dateAvailable"` + Seed string `json:"seed"` } // SerializableTransaction serializable transaction @@ -83,11 +84,12 @@ func toSerializableAccount(acc Account) *SerializableAccount { func toSerializableBlock(block Block) *SerializableBlock { sBlock := &SerializableBlock{ - Timestamp: block.Timestamp(), - Hash: block.Hash().String(), - Height: block.Height(), - SupportRandom: block.SupportRandom(), - Seed: block.RandomSeed(), + Timestamp: block.Timestamp(), + Hash: block.Hash().String(), + Height: block.Height(), + RandomAvailable: block.RandomAvailable(), + DateAvailable: block.DateAvailable(), + Seed: block.RandomSeed(), } return sBlock } diff --git a/nf/nvm/engine_v8.go b/nf/nvm/engine_v8.go index ba524ad6e..20dbd6aae 100644 --- a/nf/nvm/engine_v8.go +++ b/nf/nvm/engine_v8.go @@ -449,7 +449,6 @@ func (e *V8Engine) prepareRunnableContractScript(source, function, args string) } runnableSource = fmt.Sprintf(`Blockchain.blockParse("%s"); Blockchain.transactionParse("%s"); - Object.freeze(Blockchain); var __contract = require("%s"); var __instance = new __contract(); __instance["%s"].apply(__instance, JSON.parse("%s"));`, diff --git a/nf/nvm/engine_v8_test.go b/nf/nvm/engine_v8_test.go index 780c18f6e..f1b9e556e 100644 --- a/nf/nvm/engine_v8_test.go +++ b/nf/nvm/engine_v8_test.go @@ -81,8 +81,13 @@ func (block *testBlock) RandomSeed() string { return "59fc526072b09af8a8ca9732dae17132c4e9127e43cf2232" } -// SupportRandom mock -func (block *testBlock) SupportRandom() bool { +// RandomAvailable mock +func (block *testBlock) RandomAvailable() bool { + return true +} + +// DateAvailable +func (block *testBlock) DateAvailable() bool { return true } @@ -144,7 +149,7 @@ func TestRunScriptSource(t *testing.T) { {"test/test_bignumber_random.js", core.ErrExecutionFailed, "Error: BigNumber.random is not allowed in nvm."}, {"test/test_random_enable.js", nil, "\"\""}, {"test/test_random_disable.js", core.ErrExecutionFailed, "Error: Math.random func is not allowed in nvm."}, - {"test/test_random_seed.js", core.ErrExecutionFailed, "Error: random seed must be a string"}, + {"test/test_random_seed.js", core.ErrExecutionFailed, "Error: input seed must be a string"}, } for _, tt := range tests { diff --git a/nf/nvm/test/contract_date_and_random.js b/nf/nvm/test/contract_date_and_random.js index 7283a3bfc..2eb5ec442 100644 --- a/nf/nvm/test/contract_date_and_random.js +++ b/nf/nvm/test/contract_date_and_random.js @@ -60,7 +60,8 @@ Contract.prototype = { var r2 = Math.random(); Event.Trigger("random", { - "supportRandom": Blockchain.block.supportRandom, + "supportRandom": Blockchain.block.randomAvailable, + "supportDate": Blockchain.block.dateAvailable, "seed": Blockchain.block.seed, "defaultSeedRandom1": r1, "defaultSeedRandom2": r12, diff --git a/nf/nvm/test/test_date.js b/nf/nvm/test/test_date.js index 29353e1b0..c9a70a2ca 100644 --- a/nf/nvm/test/test_date.js +++ b/nf/nvm/test/test_date.js @@ -16,9 +16,7 @@ // along with the go-nebulas library. If not, see . // -Blockchain.block = { - timestamp: 10000000000 -}; +Blockchain.blockParse("{\"timestamp\":20000000000,\"dateAvailable\":true}"); console.log(Date.now()); console.log(Date.UTC()); diff --git a/nf/nvm/test/test_random_disable.js b/nf/nvm/test/test_random_disable.js index dd0cc17c4..c8ee5706e 100644 --- a/nf/nvm/test/test_random_disable.js +++ b/nf/nvm/test/test_random_disable.js @@ -16,8 +16,6 @@ // along with the go-nebulas library. If not, see . // -Blockchain.block = { - supportRandom: false, - seed: "test seed" -} +Blockchain.blockParse("{\"seed\":\"test seed\",\"randomAvailable\":false}"); + console.log(Math.random()); \ No newline at end of file diff --git a/nf/nvm/test/test_random_enable.js b/nf/nvm/test/test_random_enable.js index 8dd0bec79..b276ea7e8 100644 --- a/nf/nvm/test/test_random_enable.js +++ b/nf/nvm/test/test_random_enable.js @@ -16,8 +16,6 @@ // along with the go-nebulas library. If not, see . // -Blockchain.block = { - supportRandom: true, - seed: "seed" -} +Blockchain.blockParse("{\"seed\":\"seed\",\"randomAvailable\":true}"); + console.log(Math.random()); diff --git a/nf/nvm/test/test_random_seed.js b/nf/nvm/test/test_random_seed.js index d4cd34be5..fe1ed5172 100644 --- a/nf/nvm/test/test_random_seed.js +++ b/nf/nvm/test/test_random_seed.js @@ -16,8 +16,5 @@ // along with the go-nebulas library. If not, see . // -Blockchain.block = { - supportRandom: true, - seed: "null" -} +Blockchain.blockParse("{\"seed\":\"null\",\"randomAvailable\":false}"); console.log(Math.random.seed()); \ No newline at end of file diff --git a/nf/nvm/types.go b/nf/nvm/types.go index d6a5349e0..5571fe802 100644 --- a/nf/nvm/types.go +++ b/nf/nvm/types.go @@ -57,7 +57,8 @@ type Block interface { Height() uint64 // ToAdd: timestamp interface Timestamp() int64 RandomSeed() string - SupportRandom() bool + RandomAvailable() bool + DateAvailable() bool } // Transaction interface breaks cycle import dependency and hides unused services. diff --git a/nf/nvm/v8/lib/blockchain.js b/nf/nvm/v8/lib/blockchain.js index d515dee86..ac16173f4 100644 --- a/nf/nvm/v8/lib/blockchain.js +++ b/nf/nvm/v8/lib/blockchain.js @@ -29,7 +29,14 @@ Blockchain.prototype = { blockParse: function (str) { var block = JSON.parse(str); if (block != null) { - this.block = Object.freeze(block); + var fb = Object.freeze(block); + Object.defineProperty(this, "block", { + configurable: false, + enumerable: false, + get: function(){ + return fb; + } + }); } }, transactionParse: function (str) { @@ -41,7 +48,15 @@ Blockchain.prototype = { tx.gasPrice = new BigNumber(gasPrice); var gasLimit = tx.gasLimit === undefined || tx.gasLimit.length === 0 ? "0" : tx.gasLimit; tx.gasLimit = new BigNumber(gasLimit); - this.transaction = Object.freeze(tx); + + var ft = Object.freeze(tx); + Object.defineProperty(this, "transaction", { + configurable: false, + enumerable: false, + get: function(){ + return ft; + } + }); } }, transfer: function (address, value) { diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index 0e9b9f4bd..4f8954742 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -25,6 +25,9 @@ var NebDate = (function(Date) { if (!Blockchain.block) { throw new Error("'Blockchain.block' is not defined."); } + if (!Blockchain.block.dateAvailable) { + throw new Error("Date is not allowed in nvm."); + } var date = new(Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))))(); if (arguments.length == 0) { @@ -35,12 +38,21 @@ var NebDate = (function(Date) { return date; } NebDate.now = function() { + if (!Blockchain.block.dateAvailable) { + throw new Error("Date is not allowed in nvm."); + } return new NebDate().getTime(); } NebDate.UTC = function() { + if (!Blockchain.block.dateAvailable) { + throw new Error("Date is not allowed in nvm."); + } return Date.UTC.apply(null, arguments); } NebDate.parse = function(dateString) { + if (!Blockchain.block.dateAvailable) { + throw new Error("Date is not allowed in nvm."); + } return Date.parse(dateString); } diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index 85893735c..e16b3b240 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -110,5 +110,5 @@ const BigNumber = require('bignumber.js'); const Blockchain = require('blockchain.js'); const Event = require('event.js'); -var Date = require('date.js') +var Date = require('date.js'); Math.random = require('random.js'); \ No newline at end of file diff --git a/nf/nvm/v8/lib/random.js b/nf/nvm/v8/lib/random.js index 3bffdb7ee..528de24ac 100644 --- a/nf/nvm/v8/lib/random.js +++ b/nf/nvm/v8/lib/random.js @@ -107,7 +107,7 @@ module.exports = (function(){ throw new Error("'Blockchain.block' is undefined."); } - if (!Blockchain.block.supportRandom) { + if (!Blockchain.block.randomAvailable) { throw new Error("Math.random func is not allowed in nvm."); } @@ -125,7 +125,7 @@ module.exports = (function(){ } rand.seed = function(userseed) { if (typeof(userseed) !== 'string') { - throw new Error("random seed must be a string") + throw new Error("input seed must be a string") } checkCtx(); arng = new impl(Blockchain.block.seed + userseed); From f01eb1d116f2ca190bc53a4bae53c92cd107dda3 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 5 May 2018 03:13:03 +0800 Subject: [PATCH 60/69] compatibility code & return contract exe result --- core/blockchain.go | 2 - core/compatibility.go | 97 +++++++++- core/transaction.go | 82 +++++--- core/transaction_binary_payload.go | 2 +- neblet/neblet.go | 3 + rpc/api_service.go | 64 +++--- rpc/pb/rpc.pb.go | 300 +++++++++++++++-------------- rpc/pb/rpc.proto | 3 + 8 files changed, 352 insertions(+), 201 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index e6bfff777..ed8ae2624 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -74,8 +74,6 @@ type BlockChain struct { } const ( - // TestNetID chain id for test net. - TestNetID = 1 // EagleNebula chain id for 1.x EagleNebula = 1 << 4 diff --git a/core/compatibility.go b/core/compatibility.go index 9de84cb0a..3d0006f6c 100644 --- a/core/compatibility.go +++ b/core/compatibility.go @@ -18,13 +18,104 @@ package core +import ( + "github.com/nebulasio/go-nebulas/util/logging" + "github.com/sirupsen/logrus" +) + +const ( + // MainNetID mainnet id + MainNetID uint32 = 1 + + // TestNetID testnet id + TestNetID uint32 = 1001 +) + +// mainnet/testnet const ( + // DefaultTransferFromContractEventRecordableHeight + DefaultTransferFromContractEventRecordableHeight uint64 = 250000 + + // DefaultAcceptFuncAvailableHeight + DefaultAcceptFuncAvailableHeight uint64 = 250000 + + // DefaultRandomAvailableHeight + DefaultRandomAvailableHeight uint64 = 250000 + + // DefaultDateAvailableHeight + DefaultDateAvailableHeight uint64 = 250000 + + // DefaultRecordCallContractResultHeight + DefaultRecordCallContractResultHeight uint64 = 250000 +) + +// others, e.g. local/develop +const ( + // LocalTransferFromContractEventRecordableHeight + LocalTransferFromContractEventRecordableHeight uint64 = 0 + + // LocalAcceptFuncAvailableHeight + LocalAcceptFuncAvailableHeight uint64 = 0 + + // LocalRandomAvailableHeight + LocalRandomAvailableHeight uint64 = 0 + + // LocalDateAvailableHeight + LocalDateAvailableHeight uint64 = 0 + + // LocalRecordCallContractResultHeight + LocalRecordCallContractResultHeight uint64 = 0 +) + +var ( // TransferFromContractEventRecordableHeight record event 'TransferFromContractEvent' since this height - TransferFromContractEventRecordableHeight uint64 = 200000 + TransferFromContractEventRecordableHeight = DefaultTransferFromContractEventRecordableHeight + + // AcceptFuncAvailableHeight 'accept' func available since this height + AcceptFuncAvailableHeight = DefaultAcceptFuncAvailableHeight // RandomAvailableHeight make 'Math.random' available in contract since this height - RandomAvailableHeight uint64 = 200000 + RandomAvailableHeight = DefaultRandomAvailableHeight // DateAvailableHeight make 'Date' available in contract since this height - DateAvailableHeight uint64 = 200000 + DateAvailableHeight = DefaultDateAvailableHeight + + // RecordCallContractResultHeight record result of call contract to event `TopicTransactionExecutionResult` since this height + RecordCallContractResultHeight = DefaultRecordCallContractResultHeight ) + +// SetCompatibilityOptions set compatibility height according to chain_id +func SetCompatibilityOptions(chainID uint32) { + + if chainID == MainNetID || chainID == TestNetID { + logging.VLog().WithFields(logrus.Fields{ + "chain_id": chainID, + "TransferFromContractEventRecordableHeight": TransferFromContractEventRecordableHeight, + "AcceptFuncAvailableHeight": AcceptFuncAvailableHeight, + "RandomAvailableHeight": RandomAvailableHeight, + "DateAvailableHeight": DateAvailableHeight, + "RecordCallContractResultHeight": RecordCallContractResultHeight, + }).Info("Set compatibility options for mainnet/testnet.") + return + } + + TransferFromContractEventRecordableHeight = LocalTransferFromContractEventRecordableHeight + + AcceptFuncAvailableHeight = LocalAcceptFuncAvailableHeight + + RandomAvailableHeight = LocalRandomAvailableHeight + + DateAvailableHeight = LocalDateAvailableHeight + + RecordCallContractResultHeight = LocalRecordCallContractResultHeight + + logging.VLog().WithFields(logrus.Fields{ + "chain_id": chainID, + "TransferFromContractEventRecordableHeight": TransferFromContractEventRecordableHeight, + "AcceptFuncAvailableHeight": AcceptFuncAvailableHeight, + "RandomAvailableHeight": RandomAvailableHeight, + "DateAvailableHeight": DateAvailableHeight, + "RecordCallContractResultHeight": RecordCallContractResultHeight, + }).Info("Set compatibility options for local.") + +} diff --git a/core/transaction.go b/core/transaction.go index e921762df..62fddf97c 100644 --- a/core/transaction.go +++ b/core/transaction.go @@ -77,6 +77,15 @@ type TransactionEvent struct { Error string `json:"error"` } +// TransactionEventV2 add execution result +type TransactionEventV2 struct { + Hash string `json:"hash"` + Status int8 `json:"status"` + GasUsed string `json:"gas_used"` + Error string `json:"error"` + ExecuteResult string `json:"execute_result"` +} + // Transaction type is used to handle all transaction data. type Transaction struct { hash byteutils.Hash @@ -347,7 +356,8 @@ func (tx *Transaction) LoadPayload() (TxPayload, error) { return payload, err } -func submitTx(tx *Transaction, block *Block, ws WorldState, gas *util.Uint128, exeErr error, exeErrTy string) (bool, error) { +func submitTx(tx *Transaction, block *Block, ws WorldState, + gas *util.Uint128, exeErr error, exeErrTy string, exeResult string) (bool, error) { if exeErr != nil { logging.VLog().WithFields(logrus.Fields{ "err": exeErr, @@ -377,7 +387,7 @@ func submitTx(tx *Transaction, block *Block, ws WorldState, gas *util.Uint128, e metricsUnexpectedBehavior.Update(1) return true, err } - if err := tx.recordResultEvent(gas, exeErr, ws); err != nil { + if err := tx.recordResultEvent(gas, exeErr, ws, block, exeResult); err != nil { logging.VLog().WithFields(logrus.Fields{ "err": err, "tx": tx, @@ -437,7 +447,7 @@ func VerifyExecution(tx *Transaction, block *Block, ws WorldState) (bool, error) // step3. check payload vaild. payload, payloadErr := tx.LoadPayload() if payloadErr != nil { - return submitTx(tx, block, ws, gasUsed, payloadErr, "Failed to load payload.") + return submitTx(tx, block, ws, gasUsed, payloadErr, "Failed to load payload.", "") } // step4. calculate base gas of payload @@ -451,20 +461,20 @@ func VerifyExecution(tx *Transaction, block *Block, ws WorldState) (bool, error) "block": block, }).Error("Failed to add payload base gas, unexpected error") metricsUnexpectedBehavior.Update(1) - return submitTx(tx, block, ws, gasUsed, ErrGasCntOverflow, "Failed to add the count of base payload gas") + return submitTx(tx, block, ws, gasUsed, ErrGasCntOverflow, "Failed to add the count of base payload gas", "") } gasUsed = payloadGas if tx.gasLimit.Cmp(gasUsed) < 0 { - return submitTx(tx, block, ws, tx.gasLimit, ErrOutOfGasLimit, "Failed to check gasLimit >= txBaseGas + payloasBaseGas.") + return submitTx(tx, block, ws, tx.gasLimit, ErrOutOfGasLimit, "Failed to check gasLimit >= txBaseGas + payloasBaseGas.", "") } // step5. check balance >= limitedFee + value. and transfer minBalanceRequired, balanceErr := limitedFee.Add(tx.value) if balanceErr != nil { - return submitTx(tx, block, ws, gasUsed, ErrGasFeeOverflow, "Failed to add tx.value") + return submitTx(tx, block, ws, gasUsed, ErrGasFeeOverflow, "Failed to add tx.value", "") } if fromAcc.Balance().Cmp(minBalanceRequired) < 0 { - return submitTx(tx, block, ws, gasUsed, ErrInsufficientBalance, "Failed to check balance >= gasLimit * gasPrice + value") + return submitTx(tx, block, ws, gasUsed, ErrInsufficientBalance, "Failed to check balance >= gasLimit * gasPrice + value", "") } var transferSubErr, transferAddErr error transferSubErr = fromAcc.SubBalance(tx.value) @@ -481,7 +491,7 @@ func VerifyExecution(tx *Transaction, block *Block, ws WorldState) (bool, error) "block": block, }).Error("Failed to transfer value, unexpected error") metricsUnexpectedBehavior.Update(1) - return submitTx(tx, block, ws, gasUsed, ErrInvalidTransfer, "Failed to transfer tx.value") + return submitTx(tx, block, ws, gasUsed, ErrInvalidTransfer, "Failed to transfer tx.value", "") } // step6. calculate contract's limited gas @@ -494,23 +504,23 @@ func VerifyExecution(tx *Transaction, block *Block, ws WorldState) (bool, error) "block": block, }).Error("Failed to calculate payload's limit gas, unexpected error") metricsUnexpectedBehavior.Update(1) - return submitTx(tx, block, ws, tx.gasLimit, ErrOutOfGasLimit, "Failed to calculate payload's limit gas") + return submitTx(tx, block, ws, tx.gasLimit, ErrOutOfGasLimit, "Failed to calculate payload's limit gas", "") } // step7. execute contract. - gasExecution, _, exeErr := payload.Execute(contractLimitedGas, tx, block, ws) + gasExecution, exeResult, exeErr := payload.Execute(contractLimitedGas, tx, block, ws) // step8. calculate final gas. allGas, gasErr := gasUsed.Add(gasExecution) if gasErr != nil { - return submitTx(tx, block, ws, gasUsed, ErrGasCntOverflow, "Failed to add the fee of execution gas") + return submitTx(tx, block, ws, gasUsed, ErrGasCntOverflow, "Failed to add the fee of execution gas", "") } if tx.gasLimit.Cmp(allGas) < 0 { - return submitTx(tx, block, ws, tx.gasLimit, ErrOutOfGasLimit, "Failed to check gasLimit >= allGas") + return submitTx(tx, block, ws, tx.gasLimit, ErrOutOfGasLimit, "Failed to check gasLimit >= allGas", "") } // step9. over - return submitTx(tx, block, ws, allGas, exeErr, "Failed to execute payload") + return submitTx(tx, block, ws, allGas, exeErr, "Failed to execute payload", exeResult) } // simulateExecution simulate execution and return gasUsed, executionResult and executionErr, sysErr if occurred. @@ -555,7 +565,7 @@ func (tx *Transaction) simulateExecution(block *Block) (*SimulateResult, error) // try run smart contract if payload is. if tx.data.Type == TxPayloadCallType || tx.data.Type == TxPayloadDeployType || - (tx.data.Type == TxPayloadBinaryType && tx.to.Type() == ContractAddress) { + (tx.data.Type == TxPayloadBinaryType && tx.to.Type() == ContractAddress && block.height >= AcceptFuncAvailableHeight) { // transfer value to smart contract. toAcc, err := ws.GetOrCreateUserAccount(tx.to.address) @@ -614,22 +624,42 @@ func (tx *Transaction) recordGas(gasCnt *util.Uint128, ws WorldState) error { return ws.RecordGas(tx.from.String(), gasCost) } -func (tx *Transaction) recordResultEvent(gasUsed *util.Uint128, err error, ws WorldState) error { - txEvent := &TransactionEvent{ - Hash: tx.hash.String(), - GasUsed: gasUsed.String(), - Status: TxExecutionSuccess, - } +func (tx *Transaction) recordResultEvent(gasUsed *util.Uint128, err error, ws WorldState, block *Block, exeResult string) error { - if err != nil { - txEvent.Status = TxExecutionFailed - txEvent.Error = err.Error() - if len(txEvent.Error) > MaxEventErrLength { - txEvent.Error = txEvent.Error[:MaxEventErrLength] + var txData []byte + if block.height >= RecordCallContractResultHeight { + txEvent := &TransactionEventV2{ + Hash: tx.hash.String(), + GasUsed: gasUsed.String(), + Status: TxExecutionSuccess, + ExecuteResult: exeResult, + } + + if err != nil { + txEvent.Status = TxExecutionFailed + txEvent.Error = err.Error() + if len(txEvent.Error) > MaxEventErrLength { + txEvent.Error = txEvent.Error[:MaxEventErrLength] + } + } + txData, err = json.Marshal(txEvent) + } else { + txEvent := &TransactionEvent{ + Hash: tx.hash.String(), + GasUsed: gasUsed.String(), + Status: TxExecutionSuccess, + } + + if err != nil { + txEvent.Status = TxExecutionFailed + txEvent.Error = err.Error() + if len(txEvent.Error) > MaxEventErrLength { + txEvent.Error = txEvent.Error[:MaxEventErrLength] + } } + txData, err = json.Marshal(txEvent) } - txData, err := json.Marshal(txEvent) if err != nil { return err } diff --git a/core/transaction_binary_payload.go b/core/transaction_binary_payload.go index 4ad3d9521..28cb293b0 100644 --- a/core/transaction_binary_payload.go +++ b/core/transaction_binary_payload.go @@ -58,7 +58,7 @@ func (payload *BinaryPayload) Execute(limitedGas *util.Uint128, tx *Transaction, } // transfer to contract - if tx.to.Type() == ContractAddress { + if tx.to.Type() == ContractAddress && block.height >= AcceptFuncAvailableHeight { // payloadGasLimit <= 0, v8 engine not limit the execution instructions if limitedGas.Cmp(util.NewUint128()) <= 0 { return util.NewUint128(), "", ErrOutOfGasLimit diff --git a/neblet/neblet.go b/neblet/neblet.go index dc822bb46..600b43a07 100644 --- a/neblet/neblet.go +++ b/neblet/neblet.go @@ -87,6 +87,9 @@ func New(config *nebletpb.Config) (*Neblet, error) { logging.CLog().Error("Failed to find chain config in config file") return nil, ErrConfigShouldHasChain } + + core.SetCompatibilityOptions(config.Chain.ChainId) + var err error n.genesis, err = core.LoadGenesisConf(config.Chain.Genesis) if err != nil { diff --git a/rpc/api_service.go b/rpc/api_service.go index 73c5527e9..e29e1464f 100644 --- a/rpc/api_service.go +++ b/rpc/api_service.go @@ -410,9 +410,10 @@ func (s *APIService) GetTransactionReceipt(ctx context.Context, req *rpcpb.GetTr func (s *APIService) toTransactionResponse(tx *core.Transaction) (*rpcpb.TransactionResponse, error) { var ( - status int32 - gasUsed string - execute_error string + status int32 + gasUsed string + execute_error string + execute_result string ) neb := s.server.Neblet() event, err := neb.BlockChain().TailBlock().FetchExecutionResultEvent(tx.Hash()) @@ -421,33 +422,48 @@ func (s *APIService) toTransactionResponse(tx *core.Transaction) (*rpcpb.Transac } if event != nil { - txEvent := core.TransactionEvent{} - err := json.Unmarshal([]byte(event.Data), &txEvent) - if err != nil { - return nil, err + h := neb.BlockChain().TailBlock().Height() + if h >= core.RecordCallContractResultHeight { + txEvent2 := core.TransactionEventV2{} + + err := json.Unmarshal([]byte(event.Data), &txEvent2) + if err != nil { + return nil, err + } + status = int32(txEvent2.Status) + gasUsed = txEvent2.GasUsed + execute_error = txEvent2.Error + execute_result = txEvent2.ExecuteResult + } else { + txEvent := core.TransactionEvent{} + err := json.Unmarshal([]byte(event.Data), &txEvent) + if err != nil { + return nil, err + } + status = int32(txEvent.Status) + gasUsed = txEvent.GasUsed + execute_error = txEvent.Error } - status = int32(txEvent.Status) - gasUsed = txEvent.GasUsed - execute_error = txEvent.Error } else { status = core.TxExecutionPendding } resp := &rpcpb.TransactionResponse{ - ChainId: tx.ChainID(), - Hash: tx.Hash().String(), - From: tx.From().String(), - To: tx.To().String(), - Value: tx.Value().String(), - Nonce: tx.Nonce(), - Timestamp: tx.Timestamp(), - Type: tx.Type(), - Data: tx.Data(), - GasPrice: tx.GasPrice().String(), - GasLimit: tx.GasLimit().String(), - Status: status, - GasUsed: gasUsed, - ExecuteError: execute_error, + ChainId: tx.ChainID(), + Hash: tx.Hash().String(), + From: tx.From().String(), + To: tx.To().String(), + Value: tx.Value().String(), + Nonce: tx.Nonce(), + Timestamp: tx.Timestamp(), + Type: tx.Type(), + Data: tx.Data(), + GasPrice: tx.GasPrice().String(), + GasLimit: tx.GasLimit().String(), + Status: status, + GasUsed: gasUsed, + ExecuteError: execute_error, + ExecuteResult: execute_result, } if tx.Type() == core.TxPayloadDeployType { diff --git a/rpc/pb/rpc.pb.go b/rpc/pb/rpc.pb.go index 4f31f9f50..7f1464351 100644 --- a/rpc/pb/rpc.pb.go +++ b/rpc/pb/rpc.pb.go @@ -862,6 +862,8 @@ type TransactionResponse struct { GasUsed string `protobuf:"bytes,14,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` // contract execute error ExecuteError string `protobuf:"bytes,15,opt,name=execute_error,json=executeError,proto3" json:"execute_error,omitempty"` + // contract execute result + ExecuteResult string `protobuf:"bytes,16,opt,name=execute_result,json=executeResult,proto3" json:"execute_result,omitempty"` } func (m *TransactionResponse) Reset() { *m = TransactionResponse{} } @@ -974,6 +976,13 @@ func (m *TransactionResponse) GetExecuteError() string { return "" } +func (m *TransactionResponse) GetExecuteResult() string { + if m != nil { + return m.ExecuteResult + } + return "" +} + type NewAccountRequest struct { Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` } @@ -2430,149 +2439,150 @@ var _AdminService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2302 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0x5b, 0x6f, 0x1b, 0xb9, - 0xf5, 0x87, 0x2c, 0x5f, 0xa4, 0x23, 0xd9, 0x56, 0xe8, 0xdb, 0x58, 0xb1, 0x1d, 0x9b, 0x59, 0x6c, - 0xbc, 0xc1, 0x7f, 0xad, 0x8d, 0x17, 0xc8, 0xbf, 0x48, 0xb1, 0x05, 0x92, 0x34, 0xeb, 0x4d, 0x11, - 0x04, 0xee, 0x38, 0xdb, 0x2e, 0xd0, 0xa6, 0x02, 0x35, 0x43, 0x49, 0xd3, 0x1d, 0x73, 0xa6, 0x24, - 0xe5, 0xc4, 0x7e, 0x29, 0x90, 0xf7, 0x3e, 0x15, 0x28, 0xfa, 0xd0, 0x0f, 0xd1, 0xaf, 0x52, 0xf4, - 0xa1, 0x2f, 0x7d, 0xec, 0xe7, 0x28, 0x0a, 0x72, 0xc8, 0xb9, 0x69, 0x64, 0x6d, 0xfa, 0xd0, 0xb7, - 0x39, 0xbc, 0x9c, 0xfb, 0xf9, 0xf1, 0x90, 0x03, 0x4d, 0x1e, 0x7b, 0x27, 0x31, 0x8f, 0x64, 0x84, - 0x96, 0x78, 0xec, 0xc5, 0x83, 0xee, 0xde, 0x28, 0x8a, 0x46, 0x21, 0xed, 0x91, 0x38, 0xe8, 0x11, - 0xc6, 0x22, 0x49, 0x64, 0x10, 0x31, 0x91, 0x2c, 0xea, 0xfe, 0x68, 0x14, 0xc8, 0xf1, 0x64, 0x70, - 0xe2, 0x45, 0x97, 0x3d, 0x46, 0x07, 0x93, 0x90, 0x88, 0x20, 0xea, 0x8d, 0xa2, 0xcf, 0x0d, 0xd1, - 0xf3, 0x22, 0x26, 0x28, 0x13, 0x13, 0xd1, 0x8b, 0x07, 0x3d, 0x21, 0x89, 0xa4, 0x66, 0xe7, 0xe3, - 0x79, 0x3b, 0x19, 0x1d, 0x84, 0x54, 0xaa, 0x6d, 0x5e, 0xc4, 0x86, 0xc1, 0x28, 0xd9, 0x87, 0x1f, - 0x42, 0xe7, 0x62, 0x32, 0x10, 0x1e, 0x0f, 0x06, 0xd4, 0xa5, 0xbf, 0x9b, 0x50, 0x21, 0xd1, 0x36, - 0x2c, 0xcb, 0x28, 0x0e, 0x3c, 0xe1, 0xd4, 0x0e, 0xeb, 0xc7, 0x4d, 0xd7, 0x50, 0xf8, 0x2b, 0xb8, - 0x93, 0x5b, 0x2b, 0x62, 0xa5, 0x0b, 0xda, 0x84, 0x25, 0x3d, 0xed, 0xd4, 0x0e, 0x6b, 0xc7, 0x4d, - 0x37, 0x21, 0x10, 0x82, 0x45, 0x9f, 0x48, 0xe2, 0x2c, 0xe8, 0x41, 0xfd, 0x8d, 0x11, 0x74, 0x5e, - 0x47, 0xec, 0x9c, 0x70, 0x72, 0x29, 0x8c, 0x28, 0xfc, 0x97, 0x05, 0x35, 0xe8, 0xd3, 0x97, 0x6c, - 0x18, 0xa5, 0x2c, 0xd7, 0x60, 0x21, 0xf0, 0x0d, 0xbf, 0x85, 0xc0, 0x47, 0xbb, 0xd0, 0xf0, 0xc6, - 0x24, 0x60, 0xfd, 0xc0, 0xd7, 0x0c, 0x57, 0xdd, 0x15, 0x4d, 0xbf, 0xf4, 0x51, 0x17, 0x1a, 0x5e, - 0x14, 0xb0, 0x01, 0x11, 0xd4, 0xa9, 0xeb, 0x0d, 0x29, 0x8d, 0xf6, 0x01, 0x62, 0x4a, 0x79, 0xdf, - 0x8b, 0x26, 0x4c, 0x3a, 0x8b, 0x7a, 0x63, 0x53, 0x8d, 0x3c, 0x57, 0x03, 0x08, 0x43, 0x5b, 0x5c, - 0x33, 0x6f, 0xcc, 0x23, 0x16, 0xdc, 0x50, 0xdf, 0x59, 0x3a, 0xac, 0x1d, 0x37, 0xdc, 0xc2, 0x18, - 0xba, 0x07, 0xad, 0xc1, 0xc4, 0xfb, 0x9e, 0xca, 0xbe, 0x08, 0x6e, 0xa8, 0xb3, 0x7c, 0x58, 0x3b, - 0x5e, 0x72, 0x21, 0x19, 0xba, 0x08, 0x6e, 0x28, 0xfa, 0x0c, 0x3a, 0xda, 0x8f, 0x5e, 0x14, 0xf6, - 0xaf, 0x28, 0x17, 0x41, 0xc4, 0x1c, 0xd0, 0x7a, 0xac, 0xdb, 0xf1, 0x5f, 0x24, 0xc3, 0xe8, 0x14, - 0x5a, 0x3c, 0x9a, 0x48, 0xda, 0x97, 0x64, 0x10, 0x52, 0xa7, 0x75, 0x58, 0x3f, 0x6e, 0x9d, 0xde, - 0x39, 0xd1, 0x69, 0x71, 0xe2, 0xaa, 0x99, 0x37, 0x6a, 0xc2, 0x05, 0x9e, 0x7e, 0xe3, 0xc7, 0x00, - 0xd9, 0xcc, 0x94, 0x5f, 0x1c, 0x58, 0x21, 0xbe, 0xcf, 0xa9, 0x10, 0xce, 0x82, 0x0e, 0x94, 0x25, - 0xf1, 0x3f, 0x6a, 0xb0, 0x71, 0x46, 0xe5, 0x6b, 0x3a, 0xb8, 0x50, 0x39, 0x92, 0x7a, 0x36, 0xef, - 0xc9, 0x5a, 0xd1, 0x93, 0x08, 0x16, 0x25, 0x09, 0x42, 0x1b, 0x31, 0xf5, 0x8d, 0x3a, 0x50, 0x0f, - 0x83, 0x81, 0x71, 0xac, 0xfa, 0x54, 0xa9, 0x31, 0xa6, 0xc1, 0x68, 0x9c, 0xf8, 0x73, 0xd1, 0x35, - 0x54, 0xa5, 0x1f, 0x96, 0xab, 0xfd, 0x50, 0xf6, 0xfb, 0x4a, 0x85, 0xdf, 0x1d, 0x58, 0xb1, 0x5c, - 0x1a, 0x9a, 0x8b, 0x25, 0xf1, 0x17, 0xd0, 0x79, 0xea, 0xe9, 0x88, 0x8a, 0xd4, 0xaa, 0x3d, 0x68, - 0x1a, 0xc3, 0xa9, 0x4d, 0xd9, 0x6c, 0x00, 0xff, 0x0c, 0xb6, 0xcf, 0xa8, 0x34, 0x9b, 0x8c, 0x3b, - 0x92, 0x3c, 0xcf, 0xf9, 0x2f, 0x71, 0xaa, 0x25, 0x73, 0x66, 0x2e, 0xe4, 0xcd, 0xc4, 0x6f, 0x61, - 0x67, 0x8a, 0x97, 0x51, 0xc2, 0x81, 0x95, 0x01, 0x09, 0x09, 0xf3, 0xa8, 0x65, 0x66, 0x48, 0x55, - 0x21, 0x2c, 0x52, 0xe3, 0x09, 0xaf, 0x84, 0xd0, 0xfe, 0xbe, 0x8e, 0x93, 0xac, 0x5d, 0x75, 0xf5, - 0x37, 0xfe, 0x2d, 0xb4, 0x9f, 0x93, 0x30, 0x4c, 0x79, 0x6e, 0xc3, 0x32, 0xa7, 0x62, 0x12, 0x4a, - 0xc3, 0xd2, 0x50, 0x2a, 0x2d, 0xe9, 0x7b, 0xea, 0xa9, 0x64, 0xa2, 0x9c, 0x9b, 0x90, 0x81, 0x19, - 0x7a, 0xc1, 0x39, 0x3a, 0x82, 0x36, 0x15, 0x32, 0xb8, 0x24, 0x92, 0xf6, 0x47, 0x44, 0x98, 0x08, - 0xb6, 0xec, 0xd8, 0x19, 0x11, 0xf8, 0x04, 0x36, 0x9f, 0x5d, 0x3f, 0x0b, 0x23, 0xef, 0xfb, 0x6f, - 0xb4, 0x6d, 0xb9, 0xe2, 0x37, 0xa6, 0xd7, 0x0a, 0xa6, 0xff, 0x1f, 0xa0, 0x33, 0x2a, 0x7f, 0x7a, - 0xcd, 0x88, 0x90, 0xd7, 0x79, 0x0d, 0x2f, 0x03, 0x46, 0x79, 0x0a, 0x15, 0x09, 0x85, 0xff, 0x5d, - 0x03, 0xf4, 0x86, 0x13, 0x26, 0x88, 0xa7, 0xf0, 0xcd, 0x32, 0x47, 0xb0, 0x38, 0xe4, 0xd1, 0xa5, - 0x31, 0x47, 0x7f, 0xab, 0xac, 0x96, 0x91, 0xb1, 0x61, 0x41, 0x46, 0xca, 0x5d, 0x57, 0x24, 0x9c, - 0xd8, 0x7a, 0x4e, 0x88, 0xcc, 0x89, 0x8b, 0x79, 0x27, 0xde, 0x85, 0xe6, 0x88, 0x88, 0x7e, 0xcc, - 0x03, 0x8f, 0xea, 0x02, 0x6e, 0xba, 0x8d, 0x11, 0x11, 0xe7, 0x8a, 0xb6, 0x93, 0x61, 0x70, 0x19, - 0x48, 0x93, 0x8c, 0x6a, 0xf2, 0x95, 0xa2, 0xd1, 0xa9, 0x02, 0x0e, 0x26, 0x39, 0xf1, 0xa4, 0xce, - 0xc0, 0xd6, 0xe9, 0xb6, 0x29, 0xc5, 0xe7, 0x66, 0xd8, 0xe8, 0xec, 0xa6, 0xeb, 0x94, 0xb1, 0x83, - 0x80, 0x11, 0x7e, 0xad, 0x4b, 0xbc, 0xed, 0x1a, 0x2a, 0x0d, 0xe5, 0xa6, 0x29, 0x1d, 0x15, 0xca, - 0x1b, 0x58, 0x2f, 0x31, 0x52, 0xdb, 0x45, 0x34, 0xe1, 0x69, 0x82, 0x18, 0x4a, 0x45, 0x33, 0xf9, - 0xea, 0x6b, 0x2e, 0x26, 0x9a, 0xc9, 0xd0, 0x9b, 0xeb, 0x98, 0x2a, 0x90, 0x1b, 0x4e, 0x98, 0x76, - 0xa4, 0x05, 0x39, 0x4b, 0x2b, 0xd9, 0x84, 0x8f, 0x84, 0x76, 0x4b, 0xd3, 0xd5, 0xdf, 0xb8, 0x07, - 0xbb, 0x17, 0x94, 0xf9, 0x2e, 0x79, 0x57, 0x1d, 0x02, 0x8d, 0xcc, 0x35, 0x6d, 0x42, 0x82, 0xcc, - 0xbf, 0x86, 0x1d, 0xb5, 0xa1, 0xb0, 0x3a, 0x0b, 0xb0, 0x7c, 0x3f, 0x26, 0x62, 0x6c, 0x95, 0x4e, - 0x28, 0x55, 0xf0, 0xd6, 0x2f, 0xfd, 0x0c, 0x84, 0x74, 0xc1, 0xdb, 0xf1, 0xa7, 0x06, 0x8c, 0xfa, - 0xb0, 0x75, 0x46, 0xa5, 0x4e, 0xb5, 0x67, 0xd7, 0xdf, 0x10, 0x31, 0xce, 0xa9, 0x92, 0xe3, 0xac, - 0xbf, 0xd1, 0x29, 0x6c, 0x0d, 0x27, 0x61, 0xd8, 0x1f, 0x06, 0x61, 0xd8, 0x97, 0x99, 0x42, 0x9a, - 0x79, 0xc3, 0xdd, 0x50, 0x93, 0x5f, 0x07, 0x61, 0x98, 0xd3, 0x15, 0x53, 0x5d, 0x95, 0x56, 0xc0, - 0x0f, 0xc9, 0xe6, 0xff, 0x4a, 0xcc, 0x23, 0xb8, 0x7b, 0x46, 0x65, 0x6e, 0x64, 0xae, 0x35, 0xf8, - 0x9f, 0x75, 0x58, 0xd5, 0x7a, 0xa5, 0xfe, 0xac, 0xb2, 0xf9, 0x1e, 0xb4, 0x62, 0xc2, 0x29, 0x93, - 0x7d, 0x3d, 0x65, 0x12, 0x20, 0x19, 0x52, 0x12, 0x72, 0x56, 0xd4, 0x0b, 0x56, 0x54, 0x17, 0x45, - 0xfe, 0x4c, 0x5c, 0x2a, 0x9d, 0x89, 0x7b, 0xd0, 0x94, 0xc1, 0x25, 0x15, 0x92, 0x5c, 0xc6, 0xba, - 0x26, 0xea, 0x6e, 0x36, 0x50, 0x38, 0x1e, 0x56, 0x8a, 0xc7, 0xc3, 0x3e, 0x80, 0x6e, 0x37, 0xfa, - 0x3c, 0x8a, 0xa4, 0x01, 0xe5, 0xa6, 0x1e, 0x71, 0xa3, 0x48, 0xaa, 0x9d, 0xf2, 0xbd, 0x48, 0x26, - 0x9b, 0x09, 0xfc, 0xc9, 0xf7, 0x42, 0x4f, 0x29, 0xb0, 0xba, 0xa2, 0x4c, 0x9a, 0x59, 0x30, 0x60, - 0xa5, 0x87, 0xf4, 0x82, 0xa7, 0xb0, 0x96, 0xb6, 0x35, 0xc9, 0x9a, 0x96, 0x2e, 0xc8, 0xee, 0x49, - 0x3a, 0x9c, 0x94, 0x65, 0xf2, 0xad, 0xf6, 0xb8, 0xab, 0x5e, 0x9e, 0x54, 0x8e, 0xd0, 0xc0, 0xe3, - 0xb4, 0x13, 0xcc, 0xd0, 0x84, 0x92, 0x1c, 0x88, 0xfe, 0x30, 0x60, 0x24, 0x0c, 0xe4, 0xb5, 0xb3, - 0xaa, 0x43, 0x0b, 0x81, 0xf8, 0xda, 0x8c, 0xa0, 0x9f, 0x40, 0x3b, 0x17, 0x7b, 0xe1, 0xf8, 0xfa, - 0x4c, 0xee, 0x1a, 0x20, 0xa8, 0x28, 0x07, 0xb7, 0xb0, 0x1e, 0xff, 0xa9, 0x0e, 0x1b, 0x55, 0x45, - 0x53, 0x15, 0x64, 0x07, 0xac, 0x2f, 0xcb, 0x3d, 0x8c, 0x05, 0xc5, 0xfa, 0x14, 0x28, 0x2e, 0x4e, - 0x83, 0xe2, 0x52, 0x25, 0x28, 0x2e, 0xe7, 0xe3, 0x5f, 0x88, 0xf1, 0x4a, 0x39, 0xc6, 0x16, 0xac, - 0x1a, 0x19, 0x58, 0xa5, 0x98, 0xd0, 0xcc, 0x30, 0xa1, 0x08, 0xad, 0x70, 0x1b, 0xb4, 0xb6, 0x4a, - 0xd0, 0x5a, 0x05, 0x0d, 0xed, 0x4a, 0x68, 0xd0, 0x90, 0x28, 0x89, 0x9c, 0x08, 0x1d, 0x9c, 0x25, - 0xd7, 0x50, 0x2a, 0x9d, 0x14, 0xff, 0x89, 0xa0, 0xbe, 0xb3, 0x96, 0xa4, 0xd3, 0x88, 0x88, 0x6f, - 0x05, 0xf5, 0xd1, 0x7d, 0x58, 0xcd, 0x9d, 0x7d, 0x11, 0x77, 0xd6, 0xf5, 0x7c, 0x3b, 0x3b, 0xfd, - 0x22, 0x8e, 0xbf, 0x84, 0x3b, 0xaf, 0xe9, 0x3b, 0x73, 0x4e, 0xdb, 0x02, 0x3d, 0x00, 0x88, 0x89, - 0x10, 0xf1, 0x98, 0xab, 0xca, 0xa8, 0xd9, 0x2a, 0xb3, 0x23, 0xf8, 0x04, 0x50, 0x7e, 0x53, 0x76, - 0xae, 0x57, 0x37, 0x09, 0x38, 0x84, 0xcd, 0x6f, 0x99, 0x2a, 0xee, 0x92, 0x9c, 0xd9, 0x6d, 0x45, - 0x51, 0x83, 0x85, 0xb2, 0x06, 0xaa, 0x72, 0xfd, 0x09, 0x27, 0x29, 0xd0, 0x2f, 0xba, 0x29, 0x8d, - 0x7b, 0xb0, 0x55, 0x92, 0x56, 0xd9, 0x24, 0x34, 0x6c, 0x93, 0xa0, 0xcc, 0x79, 0xf5, 0x11, 0xca, - 0xe1, 0xcf, 0x61, 0xe3, 0xd5, 0x47, 0xb0, 0xff, 0x39, 0xac, 0x5f, 0x04, 0x23, 0x96, 0x47, 0xc0, - 0xd9, 0x86, 0xdb, 0x82, 0x58, 0x48, 0x12, 0x4c, 0x17, 0x44, 0x07, 0xea, 0x24, 0x1c, 0x99, 0xfe, - 0x47, 0x7d, 0xe2, 0x4f, 0xa1, 0x93, 0xb1, 0xcc, 0x4a, 0x69, 0xea, 0xb8, 0x62, 0xb0, 0x7b, 0x46, - 0x19, 0xe5, 0x0a, 0x7c, 0x08, 0xf3, 0xa3, 0xcb, 0x0b, 0x4a, 0xfd, 0xf9, 0x4a, 0x54, 0xc0, 0x6c, - 0xfb, 0x87, 0xc0, 0x2c, 0x7e, 0x03, 0xdd, 0x2a, 0x79, 0x59, 0x4f, 0x7d, 0xc5, 0x87, 0x7d, 0x41, - 0xa9, 0x6f, 0xb4, 0x5c, 0xb9, 0xe2, 0x43, 0xb5, 0x44, 0x95, 0x89, 0x9a, 0x8a, 0x79, 0x14, 0x0d, - 0x8d, 0x3c, 0xb5, 0xf6, 0x5c, 0xd1, 0xf8, 0xf7, 0x70, 0xa8, 0xac, 0xcd, 0xe1, 0xc7, 0x79, 0x9a, - 0x09, 0xd6, 0x98, 0x1f, 0x43, 0x2b, 0x7f, 0x38, 0xd5, 0x34, 0x2e, 0xee, 0x56, 0xe1, 0x53, 0xd2, - 0xab, 0xe4, 0x57, 0xcf, 0xcb, 0x36, 0xfc, 0xff, 0x70, 0x74, 0x8b, 0x02, 0xb7, 0xf8, 0x5f, 0x69, - 0x5e, 0x6c, 0x17, 0xfe, 0xc7, 0x9a, 0xf7, 0xa0, 0x73, 0x66, 0xa0, 0x28, 0x55, 0xb4, 0x80, 0x57, - 0xb5, 0x22, 0x5e, 0xe1, 0x23, 0x68, 0xcd, 0x3b, 0xaa, 0x1f, 0x41, 0xeb, 0x8c, 0x64, 0x77, 0x8a, - 0x0e, 0xd4, 0x55, 0xe3, 0x9c, 0xac, 0x50, 0x9f, 0x6a, 0x24, 0x6b, 0xb6, 0xd5, 0x27, 0x7e, 0x0c, - 0x6b, 0x2f, 0x92, 0x63, 0xcc, 0xee, 0xfa, 0x04, 0x96, 0x93, 0x83, 0x4d, 0xb7, 0xc3, 0xad, 0xd3, - 0xb6, 0x31, 0x58, 0x2f, 0x73, 0xcd, 0x1c, 0x7e, 0x04, 0x4b, 0x7a, 0xe0, 0x23, 0xee, 0xce, 0x9f, - 0x42, 0xfb, 0x3c, 0xe6, 0xd1, 0x30, 0xd7, 0xd7, 0x84, 0x81, 0x90, 0x94, 0xd9, 0xb6, 0x2c, 0xa1, - 0xf0, 0x03, 0x58, 0x35, 0xeb, 0xe6, 0x94, 0xef, 0x57, 0x70, 0xe7, 0x8c, 0xca, 0xe7, 0xfa, 0x29, - 0x20, 0x5d, 0x7c, 0x0c, 0xcb, 0xc9, 0xe3, 0x80, 0x89, 0x57, 0xe7, 0x24, 0x79, 0x35, 0x48, 0x8e, - 0x5f, 0xb5, 0xd2, 0xcc, 0x9f, 0xfe, 0x0d, 0x00, 0x9e, 0xc6, 0xc1, 0x05, 0xe5, 0x57, 0xea, 0x3c, - 0x78, 0x0b, 0xad, 0xdc, 0x75, 0x13, 0xed, 0x18, 0xb3, 0xcb, 0xd7, 0xfd, 0xae, 0x3d, 0x5a, 0x2b, - 0xee, 0xa6, 0x78, 0xf7, 0xc3, 0xdf, 0xff, 0xf5, 0xc7, 0x85, 0x0d, 0x74, 0xa7, 0x77, 0xf5, 0xa8, - 0x37, 0x11, 0x94, 0xf7, 0x18, 0x1d, 0xe8, 0x0e, 0x03, 0xfd, 0x06, 0x76, 0x5e, 0x11, 0x49, 0x85, - 0x7c, 0xc9, 0x39, 0xd5, 0x37, 0xc1, 0x41, 0x48, 0x75, 0x5f, 0x35, 0x5b, 0xd4, 0xa6, 0x99, 0x28, - 0xb4, 0x5f, 0x78, 0x53, 0x0b, 0x59, 0x43, 0xed, 0x54, 0x88, 0xba, 0xd5, 0x72, 0x58, 0x2f, 0x5d, - 0xeb, 0xd0, 0x7e, 0xa6, 0x69, 0xc5, 0xd5, 0xb1, 0x7b, 0x30, 0x6b, 0xda, 0xc8, 0x39, 0xd4, 0x72, - 0xba, 0x78, 0x2b, 0x95, 0x43, 0xcc, 0xad, 0x55, 0x2d, 0x7b, 0x52, 0x7b, 0x88, 0xce, 0x61, 0x51, - 0xdd, 0xf5, 0xd0, 0xec, 0x9a, 0xe8, 0x6e, 0xd8, 0x1b, 0x49, 0xee, 0x4e, 0x88, 0x1d, 0xcd, 0x19, - 0xe1, 0xd5, 0x94, 0xb3, 0x47, 0xc2, 0x50, 0x71, 0xbc, 0x01, 0x34, 0xdd, 0xf6, 0xa3, 0x43, 0xc3, - 0x64, 0xe6, 0x8d, 0x20, 0xb5, 0x65, 0xc6, 0x15, 0x00, 0x63, 0x2d, 0x71, 0x0f, 0xef, 0xa4, 0x12, - 0x39, 0x79, 0x97, 0x2b, 0x57, 0x25, 0x7b, 0x0c, 0x6b, 0xc5, 0x1e, 0x1f, 0xed, 0x65, 0x1e, 0x9a, - 0x6e, 0xfd, 0x67, 0x44, 0x67, 0x5a, 0xd2, 0xa8, 0xb0, 0x5b, 0x49, 0x62, 0xd0, 0x29, 0x37, 0xfb, - 0xe8, 0x60, 0x5a, 0x56, 0xfe, 0x16, 0x30, 0x43, 0xda, 0x27, 0x5a, 0xda, 0x01, 0xde, 0xad, 0x92, - 0xa6, 0xf7, 0x2b, 0x79, 0x1f, 0x6a, 0xfa, 0xfa, 0x52, 0x70, 0x8c, 0x47, 0x83, 0x58, 0x22, 0x9c, - 0x49, 0x9d, 0x75, 0x29, 0xe8, 0xde, 0xd2, 0x4b, 0xe2, 0xcf, 0xb4, 0xfc, 0xfb, 0xf8, 0x20, 0x2f, - 0x7f, 0x5a, 0x8e, 0x52, 0xa2, 0x0f, 0xcd, 0xf4, 0xe5, 0x2d, 0x4d, 0xf9, 0xf2, 0xbb, 0x5d, 0xd7, - 0x99, 0x9e, 0x30, 0xa2, 0xf6, 0xb5, 0xa8, 0x1d, 0x8c, 0x52, 0x51, 0xc2, 0xae, 0x79, 0x52, 0x7b, - 0xf8, 0x45, 0xcd, 0x14, 0xb0, 0x05, 0xd5, 0xd9, 0x55, 0x65, 0x27, 0xca, 0xf0, 0x8b, 0xf7, 0xb4, - 0x84, 0x6d, 0xb4, 0x99, 0x37, 0x26, 0xe5, 0xf7, 0x16, 0x5a, 0x2f, 0xb2, 0xb7, 0x87, 0xdb, 0x72, - 0x1e, 0x65, 0x02, 0x52, 0xde, 0xf7, 0x34, 0xef, 0x5d, 0x9c, 0xf1, 0xce, 0x3d, 0x64, 0x28, 0xf7, - 0x10, 0x5d, 0xbf, 0x09, 0x16, 0x9b, 0xf4, 0xb3, 0x7c, 0xf2, 0xc1, 0xd8, 0xca, 0xa3, 0x71, 0xc6, - 0xfe, 0xbe, 0x66, 0xbf, 0x8f, 0x9d, 0xbc, 0xea, 0x79, 0x66, 0x89, 0x08, 0xc8, 0x9e, 0x3f, 0xd0, - 0x5d, 0x9b, 0x50, 0x15, 0x2f, 0x28, 0xdd, 0xdd, 0x2c, 0x2f, 0x4a, 0xcf, 0x25, 0xf8, 0xae, 0x16, - 0xb5, 0x85, 0x3b, 0xa9, 0x28, 0x3f, 0x59, 0xf1, 0xa4, 0xf6, 0xf0, 0xf4, 0xaf, 0x00, 0xed, 0xa7, - 0xfe, 0x65, 0xc0, 0x2c, 0xaa, 0x7e, 0x07, 0x0d, 0xfb, 0xd6, 0x35, 0x3f, 0x22, 0xe5, 0x57, 0x31, - 0xdc, 0xd5, 0xb2, 0x36, 0x91, 0x8e, 0x39, 0x51, 0x7c, 0x53, 0x0c, 0x42, 0x1e, 0x40, 0xd6, 0xea, - 0x22, 0x9b, 0x37, 0x53, 0x2d, 0x73, 0x6a, 0xca, 0x74, 0x5f, 0x5c, 0x44, 0xb8, 0x02, 0xfb, 0x1e, - 0xa3, 0xef, 0x94, 0xcb, 0x22, 0x58, 0x2d, 0x74, 0xac, 0xa9, 0xd7, 0xaa, 0xba, 0xe6, 0xee, 0x5e, - 0xf5, 0x64, 0x55, 0x8c, 0x8a, 0xd2, 0x26, 0x7a, 0x83, 0x12, 0x38, 0x82, 0x56, 0xae, 0x83, 0x4d, - 0xb3, 0x6c, 0xba, 0x0b, 0x4e, 0xcb, 0xb2, 0xa2, 0xe1, 0xc5, 0x47, 0x5a, 0xd4, 0x5d, 0xbc, 0x3d, - 0x2d, 0xca, 0x0a, 0x62, 0xb0, 0x5e, 0x02, 0xcb, 0xdb, 0x52, 0x7a, 0x1e, 0xbe, 0x56, 0x78, 0xb2, - 0x84, 0xae, 0xbf, 0x82, 0x86, 0x6d, 0x8c, 0x91, 0x7d, 0xa6, 0x2a, 0x35, 0xdf, 0x69, 0x1e, 0x94, - 0x3b, 0x68, 0x7c, 0xa0, 0xd9, 0x3b, 0x78, 0x23, 0x63, 0x2f, 0x82, 0x11, 0xeb, 0x8d, 0x4d, 0x66, - 0x7f, 0xa8, 0x01, 0x9a, 0x6e, 0x6f, 0xd3, 0x73, 0x63, 0x66, 0xa7, 0xdd, 0x3d, 0xba, 0x65, 0x85, - 0x91, 0xfd, 0x40, 0xcb, 0x3e, 0xc2, 0x7b, 0x99, 0xec, 0xd1, 0xd4, 0x6a, 0xa5, 0xc4, 0x1f, 0x6a, - 0xb0, 0x5f, 0x6a, 0x46, 0x7f, 0x19, 0xc8, 0x71, 0xd6, 0x57, 0xa2, 0x07, 0x39, 0xfb, 0x6e, 0xeb, - 0x3c, 0xbb, 0xc7, 0xf3, 0x17, 0x16, 0x3b, 0x0e, 0xbc, 0x56, 0xf4, 0x8c, 0xd2, 0xe7, 0xcf, 0x4a, - 0x9f, 0x62, 0xbc, 0x66, 0xe9, 0x33, 0xa7, 0x13, 0x9e, 0x1b, 0xfe, 0x13, 0xad, 0xc5, 0x31, 0xbe, - 0x5f, 0x19, 0xfe, 0xa2, 0x54, 0xa5, 0xda, 0x05, 0xc0, 0x85, 0x24, 0x5c, 0xea, 0x3e, 0x0f, 0xd9, - 0x1e, 0x21, 0xdf, 0x1d, 0xa6, 0xe7, 0x5d, 0xa1, 0x15, 0xb4, 0x80, 0x80, 0xd7, 0x33, 0x41, 0xb1, - 0x5a, 0x90, 0x64, 0x58, 0x33, 0x6d, 0x07, 0x67, 0x63, 0x8d, 0x93, 0x21, 0x5b, 0xb1, 0x73, 0xb4, - 0xc0, 0x86, 0x36, 0xf2, 0x81, 0xb6, 0xfc, 0xbe, 0x83, 0x86, 0xfd, 0xc7, 0x33, 0x1f, 0xc7, 0xca, - 0x7f, 0x83, 0xaa, 0x70, 0x8c, 0x45, 0x3e, 0x0d, 0xd8, 0x30, 0x1a, 0x2c, 0xeb, 0x9f, 0x0b, 0x5f, - 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x9d, 0x00, 0x7f, 0x68, 0x1b, 0x00, 0x00, + // 2320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0x4f, 0x6f, 0x1b, 0xb9, + 0x15, 0x87, 0x2c, 0xff, 0x91, 0x9e, 0x64, 0x5b, 0xa1, 0xff, 0x8d, 0x15, 0xdb, 0x6b, 0x33, 0xdb, + 0x8d, 0x37, 0xe8, 0x5a, 0x1b, 0x2f, 0x90, 0x16, 0x29, 0xb6, 0x40, 0x92, 0x66, 0xbd, 0x29, 0x82, + 0xc0, 0x1d, 0x67, 0xdb, 0x05, 0xda, 0x54, 0xa0, 0x66, 0x28, 0x69, 0xba, 0x63, 0xce, 0x94, 0xa4, + 0x9c, 0xd8, 0x97, 0x02, 0xb9, 0xf7, 0xd4, 0x4b, 0x0f, 0xfd, 0x10, 0xfd, 0x02, 0xfd, 0x10, 0x45, + 0x0f, 0xbd, 0xf4, 0xd8, 0xcf, 0x51, 0x14, 0xe4, 0x90, 0xf3, 0x4f, 0x23, 0x6b, 0xd3, 0x43, 0x6f, + 0xf3, 0x1e, 0xc9, 0xf7, 0x1e, 0xdf, 0x9f, 0x1f, 0x1f, 0x39, 0xd0, 0xe4, 0xb1, 0x77, 0x12, 0xf3, + 0x48, 0x46, 0x68, 0x89, 0xc7, 0x5e, 0x3c, 0xe8, 0xee, 0x8d, 0xa2, 0x68, 0x14, 0xd2, 0x1e, 0x89, + 0x83, 0x1e, 0x61, 0x2c, 0x92, 0x44, 0x06, 0x11, 0x13, 0xc9, 0xa4, 0xee, 0x8f, 0x47, 0x81, 0x1c, + 0x4f, 0x06, 0x27, 0x5e, 0x74, 0xd9, 0x63, 0x74, 0x30, 0x09, 0x89, 0x08, 0xa2, 0xde, 0x28, 0xfa, + 0xcc, 0x10, 0x3d, 0x2f, 0x62, 0x82, 0x32, 0x31, 0x11, 0xbd, 0x78, 0xd0, 0x13, 0x92, 0x48, 0x6a, + 0x56, 0x3e, 0x9a, 0xb7, 0x92, 0xd1, 0x41, 0x48, 0xa5, 0x5a, 0xe6, 0x45, 0x6c, 0x18, 0x8c, 0x92, + 0x75, 0xf8, 0x01, 0x74, 0x2e, 0x26, 0x03, 0xe1, 0xf1, 0x60, 0x40, 0x5d, 0xfa, 0xfb, 0x09, 0x15, + 0x12, 0x6d, 0xc3, 0xb2, 0x8c, 0xe2, 0xc0, 0x13, 0x4e, 0xed, 0xb0, 0x7e, 0xdc, 0x74, 0x0d, 0x85, + 0xbf, 0x84, 0x3b, 0xb9, 0xb9, 0x22, 0x56, 0xb6, 0xa0, 0x4d, 0x58, 0xd2, 0xc3, 0x4e, 0xed, 0xb0, + 0x76, 0xdc, 0x74, 0x13, 0x02, 0x21, 0x58, 0xf4, 0x89, 0x24, 0xce, 0x82, 0x66, 0xea, 0x6f, 0x8c, + 0xa0, 0xf3, 0x2a, 0x62, 0xe7, 0x84, 0x93, 0x4b, 0x61, 0x54, 0xe1, 0xbf, 0x2c, 0x28, 0xa6, 0x4f, + 0x5f, 0xb0, 0x61, 0x94, 0x8a, 0x5c, 0x83, 0x85, 0xc0, 0x37, 0xf2, 0x16, 0x02, 0x1f, 0xed, 0x42, + 0xc3, 0x1b, 0x93, 0x80, 0xf5, 0x03, 0x5f, 0x0b, 0x5c, 0x75, 0x57, 0x34, 0xfd, 0xc2, 0x47, 0x5d, + 0x68, 0x78, 0x51, 0xc0, 0x06, 0x44, 0x50, 0xa7, 0xae, 0x17, 0xa4, 0x34, 0xda, 0x07, 0x88, 0x29, + 0xe5, 0x7d, 0x2f, 0x9a, 0x30, 0xe9, 0x2c, 0xea, 0x85, 0x4d, 0xc5, 0x79, 0xa6, 0x18, 0x08, 0x43, + 0x5b, 0x5c, 0x33, 0x6f, 0xcc, 0x23, 0x16, 0xdc, 0x50, 0xdf, 0x59, 0x3a, 0xac, 0x1d, 0x37, 0xdc, + 0x02, 0x0f, 0x7d, 0x04, 0xad, 0xc1, 0xc4, 0xfb, 0x8e, 0xca, 0xbe, 0x08, 0x6e, 0xa8, 0xb3, 0x7c, + 0x58, 0x3b, 0x5e, 0x72, 0x21, 0x61, 0x5d, 0x04, 0x37, 0x14, 0x7d, 0x0a, 0x1d, 0xed, 0x47, 0x2f, + 0x0a, 0xfb, 0x57, 0x94, 0x8b, 0x20, 0x62, 0x0e, 0x68, 0x3b, 0xd6, 0x2d, 0xff, 0x97, 0x09, 0x1b, + 0x9d, 0x42, 0x8b, 0x47, 0x13, 0x49, 0xfb, 0x92, 0x0c, 0x42, 0xea, 0xb4, 0x0e, 0xeb, 0xc7, 0xad, + 0xd3, 0x3b, 0x27, 0x3a, 0x2d, 0x4e, 0x5c, 0x35, 0xf2, 0x5a, 0x0d, 0xb8, 0xc0, 0xd3, 0x6f, 0xfc, + 0x08, 0x20, 0x1b, 0x99, 0xf2, 0x8b, 0x03, 0x2b, 0xc4, 0xf7, 0x39, 0x15, 0xc2, 0x59, 0xd0, 0x81, + 0xb2, 0x24, 0xfe, 0x67, 0x0d, 0x36, 0xce, 0xa8, 0x7c, 0x45, 0x07, 0x17, 0x2a, 0x47, 0x52, 0xcf, + 0xe6, 0x3d, 0x59, 0x2b, 0x7a, 0x12, 0xc1, 0xa2, 0x24, 0x41, 0x68, 0x23, 0xa6, 0xbe, 0x51, 0x07, + 0xea, 0x61, 0x30, 0x30, 0x8e, 0x55, 0x9f, 0x2a, 0x35, 0xc6, 0x34, 0x18, 0x8d, 0x13, 0x7f, 0x2e, + 0xba, 0x86, 0xaa, 0xf4, 0xc3, 0x72, 0xb5, 0x1f, 0xca, 0x7e, 0x5f, 0xa9, 0xf0, 0xbb, 0x03, 0x2b, + 0x56, 0x4a, 0x43, 0x4b, 0xb1, 0x24, 0xfe, 0x1c, 0x3a, 0x4f, 0x3c, 0x1d, 0x51, 0x91, 0xee, 0x6a, + 0x0f, 0x9a, 0x66, 0xe3, 0xd4, 0xa6, 0x6c, 0xc6, 0xc0, 0x3f, 0x87, 0xed, 0x33, 0x2a, 0xcd, 0x22, + 0xe3, 0x8e, 0x24, 0xcf, 0x73, 0xfe, 0x4b, 0x9c, 0x6a, 0xc9, 0xdc, 0x36, 0x17, 0xf2, 0xdb, 0xc4, + 0x6f, 0x60, 0x67, 0x4a, 0x96, 0x31, 0xc2, 0x81, 0x95, 0x01, 0x09, 0x09, 0xf3, 0xa8, 0x15, 0x66, + 0x48, 0x55, 0x21, 0x2c, 0x52, 0xfc, 0x44, 0x56, 0x42, 0x68, 0x7f, 0x5f, 0xc7, 0x49, 0xd6, 0xae, + 0xba, 0xfa, 0x1b, 0xff, 0x0e, 0xda, 0xcf, 0x48, 0x18, 0xa6, 0x32, 0xb7, 0x61, 0x99, 0x53, 0x31, + 0x09, 0xa5, 0x11, 0x69, 0x28, 0x95, 0x96, 0xf4, 0x1d, 0xf5, 0x54, 0x32, 0x51, 0xce, 0x4d, 0xc8, + 0xc0, 0xb0, 0x9e, 0x73, 0x8e, 0x8e, 0xa0, 0x4d, 0x85, 0x0c, 0x2e, 0x89, 0xa4, 0xfd, 0x11, 0x11, + 0x26, 0x82, 0x2d, 0xcb, 0x3b, 0x23, 0x02, 0x9f, 0xc0, 0xe6, 0xd3, 0xeb, 0xa7, 0x61, 0xe4, 0x7d, + 0xf7, 0xb5, 0xde, 0x5b, 0xae, 0xf8, 0xcd, 0xd6, 0x6b, 0x85, 0xad, 0xff, 0x10, 0xd0, 0x19, 0x95, + 0x3f, 0xbb, 0x66, 0x44, 0xc8, 0xeb, 0xbc, 0x85, 0x97, 0x01, 0xa3, 0x3c, 0x85, 0x8a, 0x84, 0xc2, + 0xff, 0xa9, 0x01, 0x7a, 0xcd, 0x09, 0x13, 0xc4, 0x53, 0xf8, 0x66, 0x85, 0x23, 0x58, 0x1c, 0xf2, + 0xe8, 0xd2, 0x6c, 0x47, 0x7f, 0xab, 0xac, 0x96, 0x91, 0xd9, 0xc3, 0x82, 0x8c, 0x94, 0xbb, 0xae, + 0x48, 0x38, 0xb1, 0xf5, 0x9c, 0x10, 0x99, 0x13, 0x17, 0xf3, 0x4e, 0xbc, 0x0b, 0xcd, 0x11, 0x11, + 0xfd, 0x98, 0x07, 0x1e, 0xd5, 0x05, 0xdc, 0x74, 0x1b, 0x23, 0x22, 0xce, 0x15, 0x6d, 0x07, 0xc3, + 0xe0, 0x32, 0x90, 0x26, 0x19, 0xd5, 0xe0, 0x4b, 0x45, 0xa3, 0x53, 0x05, 0x1c, 0x4c, 0x72, 0xe2, + 0x49, 0x9d, 0x81, 0xad, 0xd3, 0x6d, 0x53, 0x8a, 0xcf, 0x0c, 0xdb, 0xd8, 0xec, 0xa6, 0xf3, 0xd4, + 0x66, 0x07, 0x01, 0x23, 0xfc, 0x5a, 0x97, 0x78, 0xdb, 0x35, 0x54, 0x1a, 0xca, 0x4d, 0x53, 0x3a, + 0x2a, 0x94, 0x37, 0xb0, 0x5e, 0x12, 0xa4, 0x96, 0x8b, 0x68, 0xc2, 0xd3, 0x04, 0x31, 0x94, 0x8a, + 0x66, 0xf2, 0xd5, 0xd7, 0x52, 0x4c, 0x34, 0x13, 0xd6, 0xeb, 0xeb, 0x98, 0x2a, 0x90, 0x1b, 0x4e, + 0x98, 0x76, 0xa4, 0x05, 0x39, 0x4b, 0x2b, 0xdd, 0x84, 0x8f, 0x84, 0x76, 0x4b, 0xd3, 0xd5, 0xdf, + 0xb8, 0x07, 0xbb, 0x17, 0x94, 0xf9, 0x2e, 0x79, 0x5b, 0x1d, 0x02, 0x8d, 0xcc, 0x35, 0xbd, 0x85, + 0x04, 0x99, 0x7f, 0x03, 0x3b, 0x6a, 0x41, 0x61, 0x76, 0x16, 0x60, 0xf9, 0x6e, 0x4c, 0xc4, 0xd8, + 0x1a, 0x9d, 0x50, 0xaa, 0xe0, 0xad, 0x5f, 0xfa, 0x19, 0x08, 0xe9, 0x82, 0xb7, 0xfc, 0x27, 0x06, + 0x8c, 0xfa, 0xb0, 0x75, 0x46, 0xa5, 0x4e, 0xb5, 0xa7, 0xd7, 0x5f, 0x13, 0x31, 0xce, 0x99, 0x92, + 0x93, 0xac, 0xbf, 0xd1, 0x29, 0x6c, 0x0d, 0x27, 0x61, 0xd8, 0x1f, 0x06, 0x61, 0xd8, 0x97, 0x99, + 0x41, 0x5a, 0x78, 0xc3, 0xdd, 0x50, 0x83, 0x5f, 0x05, 0x61, 0x98, 0xb3, 0x15, 0x53, 0x5d, 0x95, + 0x56, 0xc1, 0xf7, 0xc9, 0xe6, 0xff, 0x49, 0xcd, 0x43, 0xb8, 0x7b, 0x46, 0x65, 0x8e, 0x33, 0x77, + 0x37, 0xf8, 0x5f, 0x75, 0x58, 0xd5, 0x76, 0xa5, 0xfe, 0xac, 0xda, 0xf3, 0x47, 0xd0, 0x8a, 0x09, + 0xa7, 0x4c, 0xf6, 0xf5, 0x90, 0x49, 0x80, 0x84, 0xa5, 0x34, 0xe4, 0x76, 0x51, 0x2f, 0xec, 0xa2, + 0xba, 0x28, 0xf2, 0x67, 0xe2, 0x52, 0xe9, 0x4c, 0xdc, 0x83, 0xa6, 0x0c, 0x2e, 0xa9, 0x90, 0xe4, + 0x32, 0xd6, 0x35, 0x51, 0x77, 0x33, 0x46, 0xe1, 0x78, 0x58, 0x29, 0x1e, 0x0f, 0xfb, 0x00, 0xba, + 0xdd, 0xe8, 0xf3, 0x28, 0x92, 0x06, 0x94, 0x9b, 0x9a, 0xe3, 0x46, 0x91, 0x54, 0x2b, 0xe5, 0x3b, + 0x91, 0x0c, 0x36, 0x13, 0xf8, 0x93, 0xef, 0x84, 0x1e, 0x52, 0x60, 0x75, 0x45, 0x99, 0x34, 0xa3, + 0x60, 0xc0, 0x4a, 0xb3, 0xf4, 0x84, 0x27, 0xb0, 0x96, 0xb6, 0x35, 0xc9, 0x9c, 0x96, 0x2e, 0xc8, + 0xee, 0x49, 0xca, 0x4e, 0xca, 0x32, 0xf9, 0x56, 0x6b, 0xdc, 0x55, 0x2f, 0x4f, 0x2a, 0x47, 0x68, + 0xe0, 0x71, 0xda, 0x09, 0x66, 0x68, 0x42, 0x69, 0x0e, 0x44, 0x7f, 0x18, 0x30, 0x12, 0x06, 0xf2, + 0xda, 0x59, 0xd5, 0xa1, 0x85, 0x40, 0x7c, 0x65, 0x38, 0xe8, 0xa7, 0xd0, 0xce, 0xc5, 0x5e, 0x38, + 0xbe, 0x3e, 0x93, 0xbb, 0x06, 0x08, 0x2a, 0xca, 0xc1, 0x2d, 0xcc, 0xc7, 0x7f, 0xab, 0xc3, 0x46, + 0x55, 0xd1, 0x54, 0x05, 0xd9, 0x01, 0xeb, 0xcb, 0x72, 0x0f, 0x63, 0x41, 0xb1, 0x3e, 0x05, 0x8a, + 0x8b, 0xd3, 0xa0, 0xb8, 0x54, 0x09, 0x8a, 0xcb, 0xf9, 0xf8, 0x17, 0x62, 0xbc, 0x52, 0x8e, 0xb1, + 0x05, 0xab, 0x46, 0x06, 0x56, 0x29, 0x26, 0x34, 0x33, 0x4c, 0x28, 0x42, 0x2b, 0xdc, 0x06, 0xad, + 0xad, 0x12, 0xb4, 0x56, 0x41, 0x43, 0xbb, 0x12, 0x1a, 0x34, 0x24, 0x4a, 0x22, 0x27, 0x42, 0x07, + 0x67, 0xc9, 0x35, 0x94, 0x4a, 0x27, 0x25, 0x7f, 0x22, 0xa8, 0xef, 0xac, 0x25, 0xe9, 0x34, 0x22, + 0xe2, 0x1b, 0x41, 0x7d, 0x74, 0x0f, 0x56, 0x73, 0x67, 0x5f, 0xc4, 0x9d, 0x75, 0x3d, 0xde, 0xce, + 0x4e, 0xbf, 0x88, 0xa3, 0x1f, 0xc0, 0x9a, 0x9d, 0x64, 0x0e, 0xd0, 0x8e, 0x9e, 0x65, 0x97, 0xba, + 0x9a, 0x89, 0xbf, 0x80, 0x3b, 0xaf, 0xe8, 0x5b, 0x73, 0x9c, 0xdb, 0x3a, 0x3e, 0x00, 0x88, 0x89, + 0x10, 0xf1, 0x98, 0xab, 0x02, 0xaa, 0xd9, 0x62, 0xb4, 0x1c, 0x7c, 0x02, 0x28, 0xbf, 0x28, 0x3b, + 0xfe, 0xab, 0x7b, 0x09, 0x1c, 0xc2, 0xe6, 0x37, 0x4c, 0x61, 0x40, 0x49, 0xcf, 0xec, 0xee, 0xa3, + 0x68, 0xc1, 0x42, 0xd9, 0x02, 0x55, 0xe0, 0xfe, 0x84, 0x93, 0xf4, 0x3c, 0x58, 0x74, 0x53, 0x1a, + 0xf7, 0x60, 0xab, 0xa4, 0xad, 0xb2, 0x97, 0x68, 0xd8, 0x5e, 0x42, 0x6d, 0xe7, 0xe5, 0x07, 0x18, + 0x87, 0x3f, 0x83, 0x8d, 0x97, 0x1f, 0x20, 0xfe, 0x17, 0xb0, 0x7e, 0x11, 0x8c, 0x58, 0x1e, 0x28, + 0x67, 0x6f, 0xdc, 0xd6, 0xcd, 0x42, 0x92, 0x87, 0xba, 0x6e, 0x3a, 0x50, 0x27, 0xe1, 0xc8, 0xb4, + 0x49, 0xea, 0x13, 0x7f, 0x02, 0x9d, 0x4c, 0x64, 0x56, 0x71, 0x53, 0xa7, 0x1a, 0x83, 0xdd, 0x33, + 0xca, 0x28, 0x57, 0x18, 0x45, 0x98, 0x1f, 0x5d, 0x5e, 0x50, 0xea, 0xcf, 0x37, 0xa2, 0x02, 0x8d, + 0xdb, 0xdf, 0x07, 0x8d, 0xf1, 0x6b, 0xe8, 0x56, 0xe9, 0xcb, 0x5a, 0xef, 0x2b, 0x3e, 0xec, 0x0b, + 0x4a, 0x7d, 0x63, 0xe5, 0xca, 0x15, 0x1f, 0xaa, 0x29, 0xaa, 0x9a, 0xd4, 0x50, 0xcc, 0xa3, 0x68, + 0x68, 0xf4, 0xa9, 0xb9, 0xe7, 0x8a, 0xc6, 0x7f, 0x80, 0x43, 0xb5, 0xdb, 0x1c, 0xcc, 0x9c, 0xa7, + 0x99, 0x60, 0x37, 0xf3, 0x13, 0x68, 0xe5, 0xcf, 0xb0, 0x9a, 0x86, 0xcf, 0xdd, 0x2a, 0x18, 0x4b, + 0x5a, 0x9a, 0xfc, 0xec, 0x79, 0xd9, 0x86, 0x7f, 0x04, 0x47, 0xb7, 0x18, 0x70, 0x8b, 0xff, 0x95, + 0xe5, 0xc5, 0xae, 0xe2, 0xff, 0x6c, 0x79, 0x0f, 0x3a, 0x67, 0x06, 0xb1, 0x52, 0x43, 0x0b, 0xb0, + 0x56, 0x2b, 0xc2, 0x1a, 0x3e, 0x82, 0xd6, 0xbc, 0x13, 0xfd, 0x21, 0xb4, 0xce, 0x48, 0x76, 0xf5, + 0xe8, 0x40, 0x5d, 0xf5, 0xd7, 0xc9, 0x0c, 0xf5, 0xa9, 0x38, 0x59, 0x4f, 0xae, 0x3e, 0xf1, 0x23, + 0x58, 0x7b, 0x9e, 0x9c, 0x76, 0x76, 0xd5, 0xc7, 0xb0, 0x9c, 0x9c, 0x7f, 0xba, 0x6b, 0x6e, 0x9d, + 0xb6, 0xcd, 0x86, 0xf5, 0x34, 0xd7, 0x8c, 0xe1, 0x87, 0xb0, 0xa4, 0x19, 0x1f, 0x70, 0xc5, 0xfe, + 0x04, 0xda, 0xe7, 0x31, 0x8f, 0x86, 0xb9, 0xf6, 0x27, 0x0c, 0x84, 0xa4, 0xcc, 0x76, 0x6f, 0x09, + 0x85, 0xef, 0xc3, 0xaa, 0x99, 0x37, 0xa7, 0x7c, 0xbf, 0x84, 0x3b, 0x67, 0x54, 0x3e, 0xd3, 0x2f, + 0x06, 0xe9, 0xe4, 0x63, 0x58, 0x4e, 0xde, 0x10, 0x4c, 0xbc, 0x3a, 0x27, 0xc9, 0xe3, 0x42, 0x72, + 0x4a, 0xab, 0x99, 0x66, 0xfc, 0xf4, 0xef, 0x00, 0xf0, 0x24, 0x0e, 0x2e, 0x28, 0xbf, 0x52, 0xc7, + 0xc6, 0x1b, 0x68, 0xe5, 0x6e, 0xa5, 0x68, 0xc7, 0x6c, 0xbb, 0xfc, 0x2a, 0xd0, 0xb5, 0x27, 0x70, + 0xc5, 0x15, 0x16, 0xef, 0xbe, 0xff, 0xc7, 0xbf, 0xff, 0xb4, 0xb0, 0x81, 0xee, 0xf4, 0xae, 0x1e, + 0xf6, 0x26, 0x82, 0xf2, 0x1e, 0xa3, 0x03, 0xdd, 0x88, 0xa0, 0xdf, 0xc2, 0xce, 0x4b, 0x22, 0xa9, + 0x90, 0x2f, 0x38, 0xa7, 0xfa, 0xc2, 0x38, 0x08, 0xa9, 0x6e, 0xbf, 0x66, 0xab, 0xda, 0x34, 0x03, + 0x85, 0x2e, 0x0d, 0x6f, 0x6a, 0x25, 0x6b, 0xa8, 0x9d, 0x2a, 0x51, 0x97, 0x5f, 0x0e, 0xeb, 0xa5, + 0xdb, 0x1f, 0xda, 0xcf, 0x2c, 0xad, 0xb8, 0x61, 0x76, 0x0f, 0x66, 0x0d, 0x1b, 0x3d, 0x87, 0x5a, + 0x4f, 0x17, 0x6f, 0xa5, 0x7a, 0x88, 0xb9, 0xdc, 0xaa, 0x69, 0x8f, 0x6b, 0x0f, 0xd0, 0x39, 0x2c, + 0xaa, 0x2b, 0x21, 0x9a, 0x5d, 0x13, 0xdd, 0x0d, 0x7b, 0x71, 0xc9, 0x5d, 0x1d, 0xb1, 0xa3, 0x25, + 0x23, 0xbc, 0x9a, 0x4a, 0xf6, 0x48, 0x18, 0x2a, 0x89, 0x37, 0x80, 0xa6, 0x6f, 0x07, 0xe8, 0xd0, + 0x08, 0x99, 0x79, 0x71, 0x48, 0xf7, 0x32, 0xe3, 0xa6, 0x80, 0xb1, 0xd6, 0xb8, 0x87, 0x77, 0x52, + 0x8d, 0x9c, 0xbc, 0xcd, 0x95, 0xab, 0xd2, 0x3d, 0x86, 0xb5, 0xe2, 0x55, 0x00, 0xed, 0x65, 0x1e, + 0x9a, 0xbe, 0x21, 0xcc, 0x88, 0xce, 0xb4, 0xa6, 0x51, 0x61, 0xb5, 0xd2, 0xc4, 0xa0, 0x53, 0xbe, + 0x13, 0xa0, 0x83, 0x69, 0x5d, 0xf9, 0xcb, 0xc2, 0x0c, 0x6d, 0x1f, 0x6b, 0x6d, 0x07, 0x78, 0xb7, + 0x4a, 0x9b, 0x5e, 0xaf, 0xf4, 0xbd, 0xaf, 0xe9, 0x5b, 0x4e, 0xc1, 0x31, 0x1e, 0x0d, 0x62, 0x89, + 0x70, 0xa6, 0x75, 0xd6, 0xdd, 0xa1, 0x7b, 0x4b, 0xcb, 0x89, 0x3f, 0xd5, 0xfa, 0xef, 0xe1, 0x83, + 0xbc, 0xfe, 0x69, 0x3d, 0xca, 0x88, 0x3e, 0x34, 0xd3, 0x07, 0xba, 0x34, 0xe5, 0xcb, 0xcf, 0x7b, + 0x5d, 0x67, 0x7a, 0xc0, 0xa8, 0xda, 0xd7, 0xaa, 0x76, 0x30, 0x4a, 0x55, 0x09, 0x3b, 0xe7, 0x71, + 0xed, 0xc1, 0xe7, 0x35, 0x53, 0xc0, 0x16, 0x54, 0x67, 0x57, 0x95, 0x1d, 0x28, 0xc3, 0x2f, 0xde, + 0xd3, 0x1a, 0xb6, 0xd1, 0x66, 0x7e, 0x33, 0xa9, 0xbc, 0x37, 0xd0, 0x7a, 0x9e, 0x3d, 0x51, 0xdc, + 0x96, 0xf3, 0x28, 0x53, 0x90, 0xca, 0xfe, 0x48, 0xcb, 0xde, 0xc5, 0x99, 0xec, 0xdc, 0x7b, 0x87, + 0x72, 0x0f, 0xd1, 0xf5, 0x9b, 0x60, 0xb1, 0x49, 0x3f, 0x2b, 0x27, 0x1f, 0x8c, 0xad, 0x3c, 0x1a, + 0x67, 0xe2, 0xef, 0x69, 0xf1, 0xfb, 0xd8, 0xc9, 0x9b, 0x9e, 0x17, 0x96, 0xa8, 0x80, 0xec, 0x95, + 0x04, 0xdd, 0xb5, 0x09, 0x55, 0xf1, 0xd0, 0xd2, 0xdd, 0xcd, 0xf2, 0xa2, 0xf4, 0xaa, 0x82, 0xef, + 0x6a, 0x55, 0x5b, 0xb8, 0x93, 0xaa, 0xf2, 0x93, 0x19, 0x8f, 0x6b, 0x0f, 0x4e, 0xff, 0x0a, 0xd0, + 0x7e, 0xe2, 0x5f, 0x06, 0xcc, 0xa2, 0xea, 0xb7, 0xd0, 0xb0, 0x4f, 0x62, 0xf3, 0x23, 0x52, 0x7e, + 0x3c, 0xc3, 0x5d, 0xad, 0x6b, 0x13, 0xe9, 0x98, 0x13, 0x25, 0x37, 0xc5, 0x20, 0xe4, 0x01, 0x64, + 0xad, 0x2e, 0xb2, 0x79, 0x33, 0xd5, 0x32, 0xa7, 0x5b, 0x99, 0xee, 0x8b, 0x8b, 0x08, 0x57, 0x10, + 0xdf, 0x63, 0xf4, 0xad, 0x72, 0x59, 0x04, 0xab, 0x85, 0x8e, 0x35, 0xf5, 0x5a, 0x55, 0xd7, 0xdc, + 0xdd, 0xab, 0x1e, 0xac, 0x8a, 0x51, 0x51, 0xdb, 0x44, 0x2f, 0x50, 0x0a, 0x47, 0xd0, 0xca, 0x75, + 0xb0, 0x69, 0x96, 0x4d, 0x77, 0xc1, 0x69, 0x59, 0x56, 0x34, 0xbc, 0xf8, 0x48, 0xab, 0xba, 0x8b, + 0xb7, 0xa7, 0x55, 0x59, 0x45, 0x0c, 0xd6, 0x4b, 0x60, 0x79, 0x5b, 0x4a, 0xcf, 0xc3, 0xd7, 0x0a, + 0x4f, 0x96, 0xd0, 0xf5, 0xd7, 0xd0, 0xb0, 0x8d, 0x31, 0xb2, 0xaf, 0x59, 0xa5, 0xe6, 0x3b, 0xcd, + 0x83, 0x72, 0x07, 0x8d, 0x0f, 0xb4, 0x78, 0x07, 0x6f, 0x64, 0xe2, 0x45, 0x30, 0x62, 0xbd, 0xb1, + 0xc9, 0xec, 0xf7, 0x35, 0x40, 0xd3, 0xed, 0x6d, 0x7a, 0x6e, 0xcc, 0xec, 0xb4, 0xbb, 0x47, 0xb7, + 0xcc, 0x30, 0xba, 0xef, 0x6b, 0xdd, 0x47, 0x78, 0x2f, 0xd3, 0x3d, 0x9a, 0x9a, 0xad, 0x8c, 0xf8, + 0x63, 0x0d, 0xf6, 0x4b, 0xcd, 0xe8, 0xaf, 0x02, 0x39, 0xce, 0xfa, 0x4a, 0x74, 0x3f, 0xb7, 0xbf, + 0xdb, 0x3a, 0xcf, 0xee, 0xf1, 0xfc, 0x89, 0xc5, 0x8e, 0x03, 0xaf, 0x15, 0x3d, 0xa3, 0xec, 0xf9, + 0xb3, 0xb2, 0xa7, 0x18, 0xaf, 0x59, 0xf6, 0xcc, 0xe9, 0x84, 0xe7, 0x86, 0xff, 0x44, 0x5b, 0x71, + 0x8c, 0xef, 0x55, 0x86, 0xbf, 0xa8, 0x55, 0x99, 0x76, 0x01, 0x70, 0x21, 0x09, 0x97, 0xba, 0xcf, + 0x43, 0xb6, 0x47, 0xc8, 0x77, 0x87, 0xe9, 0x79, 0x57, 0x68, 0x05, 0x2d, 0x20, 0xe0, 0xf5, 0x4c, + 0x51, 0xac, 0x26, 0x24, 0x19, 0xd6, 0x4c, 0xdb, 0xc1, 0xd9, 0x58, 0xe3, 0x64, 0xc8, 0x56, 0xec, + 0x1c, 0x2d, 0xb0, 0xa1, 0x8d, 0x7c, 0xa0, 0xad, 0xbc, 0x6f, 0xa1, 0x61, 0x7f, 0x05, 0xcd, 0xc7, + 0xb1, 0xf2, 0x4f, 0xa3, 0x2a, 0x1c, 0x63, 0x91, 0x4f, 0x03, 0x36, 0x8c, 0x06, 0xcb, 0xfa, 0x1f, + 0xc4, 0x17, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x42, 0xe3, 0x2b, 0x72, 0x8f, 0x1b, 0x00, 0x00, } diff --git a/rpc/pb/rpc.proto b/rpc/pb/rpc.proto index 1e1f2fbcc..b04d78f24 100644 --- a/rpc/pb/rpc.proto +++ b/rpc/pb/rpc.proto @@ -510,6 +510,9 @@ message TransactionResponse { // contract execute error string execute_error = 15; + + // contract execute result + string execute_result = 16; } message NewAccountRequest { From 1fff3771ea5ec05fd5a84c4cb6ae09f320a70061 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 5 May 2018 11:50:44 +0800 Subject: [PATCH 61/69] main: tweak log --- cmd/neb/main.go | 3 +++ cmd/network/main.go | 3 +++ core/blockchain.go | 4 ++-- neblet/neblet.go | 2 -- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/neb/main.go b/cmd/neb/main.go index f19505f2d..0c65227f6 100644 --- a/cmd/neb/main.go +++ b/cmd/neb/main.go @@ -27,6 +27,7 @@ import ( "syscall" "time" + "github.com/nebulasio/go-nebulas/core" "github.com/nebulasio/go-nebulas/neblet" "github.com/nebulasio/go-nebulas/util/logging" "github.com/urfave/cli" @@ -84,6 +85,8 @@ func neb(ctx *cli.Context) error { logging.Init(n.Config().App.LogFile, n.Config().App.LogLevel, n.Config().App.LogAge) + core.SetCompatibilityOptions(n.Config().Chain.ChainId) + // enable crash report if open the switch and configure the url if n.Config().App.EnableCrashReport && len(n.Config().App.CrashReportUrl) > 0 { InitCrashReporter(n.Config().App) diff --git a/cmd/network/main.go b/cmd/network/main.go index 29a1a9205..6ceb041bf 100644 --- a/cmd/network/main.go +++ b/cmd/network/main.go @@ -29,6 +29,7 @@ import ( "time" "github.com/libp2p/go-libp2p-interface-conn" + "github.com/nebulasio/go-nebulas/core" "github.com/nebulasio/go-nebulas/metrics" "github.com/nebulasio/go-nebulas/neblet" "github.com/nebulasio/go-nebulas/net" @@ -108,6 +109,8 @@ func run(mode, configPath string, packageSize, concurrentMessageCount, totalMess // init log. logging.Init(config.App.LogFile, config.App.LogLevel, config.App.LogAge) + core.SetCompatibilityOptions(config.Chain.ChainId) + // neblet. neblet, _ := neblet.New(config) netService, err := net.NewNebService(neblet) diff --git a/core/blockchain.go b/core/blockchain.go index ed8ae2624..213112c5d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -487,8 +487,8 @@ func (bc *BlockChain) GetInputForVRFSigner(parentHash byteutils.Hash, height uin } parent := bc.GetBlockOnCanonicalChainByHash(parentHash) - if parent == nil { - return nil, ErrNotBlockInCanonicalChain + if parent == nil || parent.height+1 != height { + return nil, ErrInvalidBlockHash } if parent.height >= RandomAvailableHeight { diff --git a/neblet/neblet.go b/neblet/neblet.go index 600b43a07..4538605d0 100644 --- a/neblet/neblet.go +++ b/neblet/neblet.go @@ -88,8 +88,6 @@ func New(config *nebletpb.Config) (*Neblet, error) { return nil, ErrConfigShouldHasChain } - core.SetCompatibilityOptions(config.Chain.ChainId) - var err error n.genesis, err = core.LoadGenesisConf(config.Chain.Genesis) if err != nil { From c5a61a0533dff8d18acc6a0068360c16db829ad5 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 5 May 2018 19:16:44 +0800 Subject: [PATCH 62/69] security enhance --- core/transaction.go | 7 ++++++ nf/nvm/context.go | 22 ++++++++--------- nf/nvm/test/contract_date_and_random.js | 2 -- nf/nvm/test/test_date.js | 2 +- nf/nvm/test/test_random_disable.js | 2 +- nf/nvm/test/test_random_enable.js | 2 +- nf/nvm/test/test_random_seed.js | 2 +- nf/nvm/v8/lib/date.js | 33 ++++++++++++++++--------- nf/nvm/v8/lib/random.js | 6 +---- 9 files changed, 43 insertions(+), 35 deletions(-) diff --git a/core/transaction.go b/core/transaction.go index 62fddf97c..4b22cb3c1 100644 --- a/core/transaction.go +++ b/core/transaction.go @@ -67,6 +67,9 @@ var ( // MaxEventErrLength Max error length in event MaxEventErrLength = 256 + + // MaxResultLength max execution result length + MaxResultLength = 256 ) // TransactionEvent transaction event @@ -628,6 +631,10 @@ func (tx *Transaction) recordResultEvent(gasUsed *util.Uint128, err error, ws Wo var txData []byte if block.height >= RecordCallContractResultHeight { + + if len(exeResult) > MaxResultLength { + exeResult = exeResult[:MaxResultLength] + } txEvent := &TransactionEventV2{ Hash: tx.hash.String(), GasUsed: gasUsed.String(), diff --git a/nf/nvm/context.go b/nf/nvm/context.go index aa128c05d..89136a3c0 100644 --- a/nf/nvm/context.go +++ b/nf/nvm/context.go @@ -32,12 +32,10 @@ type SerializableAccount struct { // SerializableBlock serializable block type SerializableBlock struct { - Timestamp int64 `json:"timestamp"` - Hash string `json:"hash"` - Height uint64 `json:"height"` - RandomAvailable bool `json:"randomAvailable"` - DateAvailable bool `json:"dateAvailable"` - Seed string `json:"seed"` + Timestamp int64 `json:"timestamp"` + Hash string `json:"hash"` + Height uint64 `json:"height"` + Seed string `json:"seed,omitempty"` } // SerializableTransaction serializable transaction @@ -84,12 +82,12 @@ func toSerializableAccount(acc Account) *SerializableAccount { func toSerializableBlock(block Block) *SerializableBlock { sBlock := &SerializableBlock{ - Timestamp: block.Timestamp(), - Hash: block.Hash().String(), - Height: block.Height(), - RandomAvailable: block.RandomAvailable(), - DateAvailable: block.DateAvailable(), - Seed: block.RandomSeed(), + Timestamp: block.Timestamp(), + Hash: "", + Height: block.Height(), + } + if block.RandomAvailable() { + sBlock.Seed = block.RandomSeed() } return sBlock } diff --git a/nf/nvm/test/contract_date_and_random.js b/nf/nvm/test/contract_date_and_random.js index 2eb5ec442..e5cad9212 100644 --- a/nf/nvm/test/contract_date_and_random.js +++ b/nf/nvm/test/contract_date_and_random.js @@ -60,8 +60,6 @@ Contract.prototype = { var r2 = Math.random(); Event.Trigger("random", { - "supportRandom": Blockchain.block.randomAvailable, - "supportDate": Blockchain.block.dateAvailable, "seed": Blockchain.block.seed, "defaultSeedRandom1": r1, "defaultSeedRandom2": r12, diff --git a/nf/nvm/test/test_date.js b/nf/nvm/test/test_date.js index c9a70a2ca..4ed43720c 100644 --- a/nf/nvm/test/test_date.js +++ b/nf/nvm/test/test_date.js @@ -16,7 +16,7 @@ // along with the go-nebulas library. If not, see . // -Blockchain.blockParse("{\"timestamp\":20000000000,\"dateAvailable\":true}"); +Blockchain.blockParse("{\"timestamp\":20000000000,\"seed\":\"\"}"); console.log(Date.now()); console.log(Date.UTC()); diff --git a/nf/nvm/test/test_random_disable.js b/nf/nvm/test/test_random_disable.js index c8ee5706e..c80bf29a0 100644 --- a/nf/nvm/test/test_random_disable.js +++ b/nf/nvm/test/test_random_disable.js @@ -16,6 +16,6 @@ // along with the go-nebulas library. If not, see . // -Blockchain.blockParse("{\"seed\":\"test seed\",\"randomAvailable\":false}"); +Blockchain.blockParse("{}"); console.log(Math.random()); \ No newline at end of file diff --git a/nf/nvm/test/test_random_enable.js b/nf/nvm/test/test_random_enable.js index b276ea7e8..890f9eedb 100644 --- a/nf/nvm/test/test_random_enable.js +++ b/nf/nvm/test/test_random_enable.js @@ -16,6 +16,6 @@ // along with the go-nebulas library. If not, see . // -Blockchain.blockParse("{\"seed\":\"seed\",\"randomAvailable\":true}"); +Blockchain.blockParse("{\"seed\":\"seed\"}"); console.log(Math.random()); diff --git a/nf/nvm/test/test_random_seed.js b/nf/nvm/test/test_random_seed.js index fe1ed5172..b07416b3e 100644 --- a/nf/nvm/test/test_random_seed.js +++ b/nf/nvm/test/test_random_seed.js @@ -16,5 +16,5 @@ // along with the go-nebulas library. If not, see . // -Blockchain.blockParse("{\"seed\":\"null\",\"randomAvailable\":false}"); +Blockchain.blockParse("{\"seed\":\"null\"}"); console.log(Math.random.seed()); \ No newline at end of file diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index 4f8954742..d7ed998cb 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -17,7 +17,16 @@ // -var NebDate = (function(Date) { +var NebDate = (function(ProtoDate) { + // compatibility + var Date = function() { + throw new Error("Date is not allowed in nvm."); + } + + function allow() { + return Blockchain.block.seed != null && typeof(Blockchain.block.seed) !== 'undefined'; + } + function NebDate() { if (!Blockchain) { throw new Error("'Blockchain' is not defined."); @@ -25,11 +34,11 @@ var NebDate = (function(Date) { if (!Blockchain.block) { throw new Error("'Blockchain.block' is not defined."); } - if (!Blockchain.block.dateAvailable) { + if (!allow()) { throw new Error("Date is not allowed in nvm."); } - var date = new(Function.prototype.bind.apply(Date, [Date].concat(Array.prototype.slice.call(arguments))))(); + var date = new(Function.prototype.bind.apply(ProtoDate, [ProtoDate].concat(Array.prototype.slice.call(arguments))))(); if (arguments.length == 0) { // unit of timestamp is second date.setTime(Blockchain.block.timestamp * 1000); @@ -38,22 +47,22 @@ var NebDate = (function(Date) { return date; } NebDate.now = function() { - if (!Blockchain.block.dateAvailable) { - throw new Error("Date is not allowed in nvm."); + if (!allow()) { + Date.now(); } return new NebDate().getTime(); } NebDate.UTC = function() { - if (!Blockchain.block.dateAvailable) { - throw new Error("Date is not allowed in nvm."); + if (!allow()) { + Date.UTC(); } - return Date.UTC.apply(null, arguments); + return ProtoDate.UTC.apply(null, arguments); } NebDate.parse = function(dateString) { - if (!Blockchain.block.dateAvailable) { - throw new Error("Date is not allowed in nvm."); + if (!allow()) { + Date.parse(dateString); } - return Date.parse(dateString); + return ProtoDate.parse(dateString); } NebDate.prototype.getTimezoneOffset = function() { @@ -127,7 +136,7 @@ var NebDate = (function(Date) { }, }); - Object.setPrototypeOf(NebDate.prototype, Date.prototype); + Object.setPrototypeOf(NebDate.prototype, ProtoDate.prototype); return NebDate; })(Date); diff --git a/nf/nvm/v8/lib/random.js b/nf/nvm/v8/lib/random.js index 528de24ac..26bb975e1 100644 --- a/nf/nvm/v8/lib/random.js +++ b/nf/nvm/v8/lib/random.js @@ -107,13 +107,9 @@ module.exports = (function(){ throw new Error("'Blockchain.block' is undefined."); } - if (!Blockchain.block.randomAvailable) { + if (Blockchain.block.seed == null || typeof(Blockchain.block.seed) === 'undefined') { throw new Error("Math.random func is not allowed in nvm."); } - - if (!Blockchain.block.seed) { - throw new Error("random seed is undefined."); - } } function rand() { From 721fa6f0a008abb3100b6876cd66f8d8f1800e71 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sat, 5 May 2018 21:13:44 +0800 Subject: [PATCH 63/69] nvm: update lib --- nf/nvm/v8/lib/blockchain.js | 5 +++-- nf/nvm/v8/lib/console.js | 2 ++ nf/nvm/v8/lib/date.js | 4 ++++ nf/nvm/v8/lib/event.js | 6 +++++- nf/nvm/v8/lib/execution_env.js | 1 + nf/nvm/v8/lib/random.js | 4 ++++ nf/nvm/v8/lib/storage.js | 8 ++++++-- 7 files changed, 25 insertions(+), 5 deletions(-) diff --git a/nf/nvm/v8/lib/blockchain.js b/nf/nvm/v8/lib/blockchain.js index ac16173f4..a3993cf8f 100644 --- a/nf/nvm/v8/lib/blockchain.js +++ b/nf/nvm/v8/lib/blockchain.js @@ -70,5 +70,6 @@ Blockchain.prototype = { return this.nativeBlockchain.verifyAddress(address); } }; - -module.exports = new Blockchain(); +var obj = new Blockchain(); +obj.toJSON = function() {return {};}; +module.exports = obj; diff --git a/nf/nvm/v8/lib/console.js b/nf/nvm/v8/lib/console.js index 7eef136e8..c42e26b08 100644 --- a/nf/nvm/v8/lib/console.js +++ b/nf/nvm/v8/lib/console.js @@ -52,5 +52,7 @@ function format(obj) { Console.prototype[val[0]] = log.bind(null, val[1]); }); +Console.toString = function() {return "";}; + module.exports = new Console(); module.exports.Console = Console; diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index d7ed998cb..ed9b05e85 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -65,6 +65,10 @@ var NebDate = (function(ProtoDate) { return ProtoDate.parse(dateString); } + NebDate.toString = function() { + return ""; + } + NebDate.prototype.getTimezoneOffset = function() { throw new Error("Unsupported method!"); } diff --git a/nf/nvm/v8/lib/event.js b/nf/nvm/v8/lib/event.js index 791830999..34f550f41 100644 --- a/nf/nvm/v8/lib/event.js +++ b/nf/nvm/v8/lib/event.js @@ -18,6 +18,10 @@ 'use strict'; -exports["Trigger"] = function (topic, data) { +function trigger(topic, data) { _native_event_trigger(topic, JSON.stringify(data)); }; + +trigger.toString = function() {return "";}; + +exports["Trigger"] = trigger; diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index e16b3b240..0c152470a 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -107,6 +107,7 @@ const ContractStorage = require('storage.js'); const LocalContractStorage = ContractStorage.lcs; const GlobalContractStorage = ContractStorage.gcs; const BigNumber = require('bignumber.js'); +BigNumber.toString = function() {return "";}; const Blockchain = require('blockchain.js'); const Event = require('event.js'); diff --git a/nf/nvm/v8/lib/random.js b/nf/nvm/v8/lib/random.js index 26bb975e1..d1df49e94 100644 --- a/nf/nvm/v8/lib/random.js +++ b/nf/nvm/v8/lib/random.js @@ -127,5 +127,9 @@ module.exports = (function(){ arng = new impl(Blockchain.block.seed + userseed); } + rand.toString = function() { + return ""; + } + return rand; })(); \ No newline at end of file diff --git a/nf/nvm/v8/lib/storage.js b/nf/nvm/v8/lib/storage.js index c0f57ce7f..aa1efb842 100644 --- a/nf/nvm/v8/lib/storage.js +++ b/nf/nvm/v8/lib/storage.js @@ -221,8 +221,12 @@ ContractStorage.prototype = { ContractStorage.prototype.put = ContractStorage.prototype.set; ContractStorage.prototype.delete = ContractStorage.prototype.del; -module.exports = Object.freeze({ +var Obj = { ContractStorage: ContractStorage, lcs: new ContractStorage(_native_storage_handlers.lcs), gcs: new ContractStorage(_native_storage_handlers.gcs) -}); +}; +Obj.toJSON = function() {return {}}; +Obj.lcs.toJSON = function() {return {}}; +Obj.gcs.toJSON = function() {return {}}; +module.exports = Object.freeze(Obj); \ No newline at end of file From 0e392322c38f9126199ae712d67294e00b213875 Mon Sep 17 00:00:00 2001 From: fengzi Date: Sat, 5 May 2018 21:24:01 +0800 Subject: [PATCH 64/69] nvm:context.go add parenthash of block --- nf/nvm/context.go | 10 ++++++---- nf/nvm/types.go | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nf/nvm/context.go b/nf/nvm/context.go index 89136a3c0..6af95ab82 100644 --- a/nf/nvm/context.go +++ b/nf/nvm/context.go @@ -32,10 +32,11 @@ type SerializableAccount struct { // SerializableBlock serializable block type SerializableBlock struct { - Timestamp int64 `json:"timestamp"` - Hash string `json:"hash"` - Height uint64 `json:"height"` - Seed string `json:"seed,omitempty"` + Timestamp int64 `json:"timestamp"` + Hash string `json:"hash"` + Height uint64 `json:"height"` + ParentHash string `json:"parentHash,omitempty"` + Seed string `json:"seed,omitempty"` } // SerializableTransaction serializable transaction @@ -88,6 +89,7 @@ func toSerializableBlock(block Block) *SerializableBlock { } if block.RandomAvailable() { sBlock.Seed = block.RandomSeed() + sBlock.ParentHash = block.ParentHash().String() } return sBlock } diff --git a/nf/nvm/types.go b/nf/nvm/types.go index 5571fe802..76154a129 100644 --- a/nf/nvm/types.go +++ b/nf/nvm/types.go @@ -54,6 +54,7 @@ const ( // Block interface breaks cycle import dependency and hides unused services. type Block interface { Hash() byteutils.Hash + ParentHash() byteutils.Hash Height() uint64 // ToAdd: timestamp interface Timestamp() int64 RandomSeed() string From 97a449d9d5c9507f28514c4d7209ad10ef0b45d5 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sun, 6 May 2018 01:54:39 +0800 Subject: [PATCH 65/69] update libs --- nf/nvm/v8/lib/blockchain.js | 12 +++++++---- nf/nvm/v8/lib/console.js | 2 -- nf/nvm/v8/lib/date.js | 4 ---- nf/nvm/v8/lib/event.js | 8 ++----- nf/nvm/v8/lib/execution_env.js | 2 +- nf/nvm/v8/lib/random.js | 4 ---- nf/nvm/v8/lib/storage.js | 38 +++++++++++++++++++++++++--------- 7 files changed, 39 insertions(+), 31 deletions(-) diff --git a/nf/nvm/v8/lib/blockchain.js b/nf/nvm/v8/lib/blockchain.js index a3993cf8f..529d1be22 100644 --- a/nf/nvm/v8/lib/blockchain.js +++ b/nf/nvm/v8/lib/blockchain.js @@ -19,7 +19,13 @@ 'use strict'; var Blockchain = function () { - this.nativeBlockchain = _native_blockchain; + Object.defineProperty(this, "nativeBlockchain", { + configurable: false, + enumerable: false, + get: function(){ + return _native_blockchain; + } + }); }; Blockchain.prototype = { @@ -70,6 +76,4 @@ Blockchain.prototype = { return this.nativeBlockchain.verifyAddress(address); } }; -var obj = new Blockchain(); -obj.toJSON = function() {return {};}; -module.exports = obj; +module.exports = new Blockchain(); diff --git a/nf/nvm/v8/lib/console.js b/nf/nvm/v8/lib/console.js index c42e26b08..7eef136e8 100644 --- a/nf/nvm/v8/lib/console.js +++ b/nf/nvm/v8/lib/console.js @@ -52,7 +52,5 @@ function format(obj) { Console.prototype[val[0]] = log.bind(null, val[1]); }); -Console.toString = function() {return "";}; - module.exports = new Console(); module.exports.Console = Console; diff --git a/nf/nvm/v8/lib/date.js b/nf/nvm/v8/lib/date.js index ed9b05e85..d7ed998cb 100644 --- a/nf/nvm/v8/lib/date.js +++ b/nf/nvm/v8/lib/date.js @@ -65,10 +65,6 @@ var NebDate = (function(ProtoDate) { return ProtoDate.parse(dateString); } - NebDate.toString = function() { - return ""; - } - NebDate.prototype.getTimezoneOffset = function() { throw new Error("Unsupported method!"); } diff --git a/nf/nvm/v8/lib/event.js b/nf/nvm/v8/lib/event.js index 34f550f41..13bdb68c1 100644 --- a/nf/nvm/v8/lib/event.js +++ b/nf/nvm/v8/lib/event.js @@ -18,10 +18,6 @@ 'use strict'; -function trigger(topic, data) { +exports["Trigger"] = function (topic, data) { _native_event_trigger(topic, JSON.stringify(data)); -}; - -trigger.toString = function() {return "";}; - -exports["Trigger"] = trigger; +}; \ No newline at end of file diff --git a/nf/nvm/v8/lib/execution_env.js b/nf/nvm/v8/lib/execution_env.js index 0c152470a..27a23767c 100644 --- a/nf/nvm/v8/lib/execution_env.js +++ b/nf/nvm/v8/lib/execution_env.js @@ -16,6 +16,7 @@ // along with the go-nebulas library. If not, see . // +Function.prototype.toString = function(){return "";}; const require = (function (global) { var PathRegexForNotLibFile = /^\.{0,2}\//; @@ -107,7 +108,6 @@ const ContractStorage = require('storage.js'); const LocalContractStorage = ContractStorage.lcs; const GlobalContractStorage = ContractStorage.gcs; const BigNumber = require('bignumber.js'); -BigNumber.toString = function() {return "";}; const Blockchain = require('blockchain.js'); const Event = require('event.js'); diff --git a/nf/nvm/v8/lib/random.js b/nf/nvm/v8/lib/random.js index d1df49e94..26bb975e1 100644 --- a/nf/nvm/v8/lib/random.js +++ b/nf/nvm/v8/lib/random.js @@ -127,9 +127,5 @@ module.exports = (function(){ arng = new impl(Blockchain.block.seed + userseed); } - rand.toString = function() { - return ""; - } - return rand; })(); \ No newline at end of file diff --git a/nf/nvm/v8/lib/storage.js b/nf/nvm/v8/lib/storage.js index aa1efb842..f4f7deaa4 100644 --- a/nf/nvm/v8/lib/storage.js +++ b/nf/nvm/v8/lib/storage.js @@ -79,7 +79,14 @@ var applyFieldDescriptor = function (obj, fieldName, descriptor) { }; var ContractStorage = function (handler) { - this.nativeStorage = new NativeStorage(handler); + var ns = new NativeStorage(handler); + Object.defineProperty(this, "nativeStorage", { + configurable: false, + enumerable: false, + get: function () { + return ns; + } + }); }; var StorageMap = function (contractStorage, fieldName, descriptor) { @@ -221,12 +228,23 @@ ContractStorage.prototype = { ContractStorage.prototype.put = ContractStorage.prototype.set; ContractStorage.prototype.delete = ContractStorage.prototype.del; -var Obj = { - ContractStorage: ContractStorage, - lcs: new ContractStorage(_native_storage_handlers.lcs), - gcs: new ContractStorage(_native_storage_handlers.gcs) -}; -Obj.toJSON = function() {return {}}; -Obj.lcs.toJSON = function() {return {}}; -Obj.gcs.toJSON = function() {return {}}; -module.exports = Object.freeze(Obj); \ No newline at end of file +var lcs = new ContractStorage(_native_storage_handlers.lcs); +var gcs = new ContractStorage(_native_storage_handlers.gcs); +var obj = {ContractStorage: ContractStorage}; +Object.defineProperty(obj, "lcs", { + configurable: false, + enumerable: false, + get: function () { + return lcs; + } +}); + +Object.defineProperty(obj, "gcs", { + configurable: false, + enumerable: false, + get: function () { + return gcs; + } +}); + +module.exports = Object.freeze(obj); \ No newline at end of file From 40b40e3cfa83d07aa7ba67b4b5283c974b90f08d Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sun, 6 May 2018 11:27:24 +0800 Subject: [PATCH 66/69] update libs --- nf/nvm/engine_v8_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nf/nvm/engine_v8_test.go b/nf/nvm/engine_v8_test.go index f1b9e556e..0820a6593 100644 --- a/nf/nvm/engine_v8_test.go +++ b/nf/nvm/engine_v8_test.go @@ -71,6 +71,10 @@ func (block *testBlock) Hash() byteutils.Hash { return []byte("59fc526072b09af8a8ca9732dae17132c4e9127e43cf2232") } +func (block *testBlock) ParentHash() byteutils.Hash { + return []byte("59fc526072b09af8a8ca9732dae17132c4e9127e43cf2232") +} + // Height mock func (block *testBlock) Height() uint64 { return 1 From c7cc3f2b4b163a5d1d856777c7b2ac4052914112 Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sun, 6 May 2018 11:45:59 +0800 Subject: [PATCH 67/69] update lib --- nf/nvm/context.go | 10 ++++------ nf/nvm/engine_v8_test.go | 4 ---- nf/nvm/types.go | 1 - 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/nf/nvm/context.go b/nf/nvm/context.go index 6af95ab82..89136a3c0 100644 --- a/nf/nvm/context.go +++ b/nf/nvm/context.go @@ -32,11 +32,10 @@ type SerializableAccount struct { // SerializableBlock serializable block type SerializableBlock struct { - Timestamp int64 `json:"timestamp"` - Hash string `json:"hash"` - Height uint64 `json:"height"` - ParentHash string `json:"parentHash,omitempty"` - Seed string `json:"seed,omitempty"` + Timestamp int64 `json:"timestamp"` + Hash string `json:"hash"` + Height uint64 `json:"height"` + Seed string `json:"seed,omitempty"` } // SerializableTransaction serializable transaction @@ -89,7 +88,6 @@ func toSerializableBlock(block Block) *SerializableBlock { } if block.RandomAvailable() { sBlock.Seed = block.RandomSeed() - sBlock.ParentHash = block.ParentHash().String() } return sBlock } diff --git a/nf/nvm/engine_v8_test.go b/nf/nvm/engine_v8_test.go index 0820a6593..f1b9e556e 100644 --- a/nf/nvm/engine_v8_test.go +++ b/nf/nvm/engine_v8_test.go @@ -71,10 +71,6 @@ func (block *testBlock) Hash() byteutils.Hash { return []byte("59fc526072b09af8a8ca9732dae17132c4e9127e43cf2232") } -func (block *testBlock) ParentHash() byteutils.Hash { - return []byte("59fc526072b09af8a8ca9732dae17132c4e9127e43cf2232") -} - // Height mock func (block *testBlock) Height() uint64 { return 1 diff --git a/nf/nvm/types.go b/nf/nvm/types.go index 76154a129..5571fe802 100644 --- a/nf/nvm/types.go +++ b/nf/nvm/types.go @@ -54,7 +54,6 @@ const ( // Block interface breaks cycle import dependency and hides unused services. type Block interface { Hash() byteutils.Hash - ParentHash() byteutils.Hash Height() uint64 // ToAdd: timestamp interface Timestamp() int64 RandomSeed() string From b2171e1a239b0d2e792a3c0baa714dcce96d9a5d Mon Sep 17 00:00:00 2001 From: fengzi Date: Sun, 6 May 2018 13:46:07 +0800 Subject: [PATCH 68/69] storage:rocks_stroage.go remove metrics --- common/mvccdb/mvccdb_test.go | 2 +- neblet/neblet.go | 2 +- storage/rocks_storage.go | 7 +++---- storage/rocks_storage_test.go | 6 +++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/common/mvccdb/mvccdb_test.go b/common/mvccdb/mvccdb_test.go index 48c35362a..12c944506 100644 --- a/common/mvccdb/mvccdb_test.go +++ b/common/mvccdb/mvccdb_test.go @@ -524,7 +524,7 @@ func TestMVCCDB_ParallelsExeTowTx(t *testing.T) { } func TestPerformance(t *testing.T) { - store, _ := storage.NewRocksStorage("test.db", false) + store, _ := storage.NewRocksStorage("test.db") defer os.RemoveAll("test.db") db, _ := NewMVCCDB(store, true) diff --git a/neblet/neblet.go b/neblet/neblet.go index 4538605d0..6c24ea42e 100644 --- a/neblet/neblet.go +++ b/neblet/neblet.go @@ -115,7 +115,7 @@ func (n *Neblet) Setup() { // storage // n.storage, err = storage.NewDiskStorage(n.config.Chain.Datadir) // n.storage, err = storage.NewMemoryStorage() - n.storage, err = storage.NewRocksStorage(n.config.Chain.Datadir, n.config.Stats.EnableMetrics) + n.storage, err = storage.NewRocksStorage(n.config.Chain.Datadir) if err != nil { logging.CLog().WithFields(logrus.Fields{ "dir": n.config.Chain.Datadir, diff --git a/storage/rocks_storage.go b/storage/rocks_storage.go index 63d459926..92ec584c4 100644 --- a/storage/rocks_storage.go +++ b/storage/rocks_storage.go @@ -24,7 +24,7 @@ type RocksStorage struct { } // NewRocksStorage init a storage -func NewRocksStorage(path string, enableMetrics bool) (*RocksStorage, error) { +func NewRocksStorage(path string) (*RocksStorage, error) { filter := gorocksdb.NewBloomFilter(10) bbto := gorocksdb.NewDefaultBlockBasedTableOptions() @@ -53,9 +53,8 @@ func NewRocksStorage(path string, enableMetrics bool) (*RocksStorage, error) { wo: gorocksdb.NewDefaultWriteOptions(), } - if enableMetrics { - go RecordMetrics(storage) - } + //go RecordMetrics(storage) + return storage, nil } diff --git a/storage/rocks_storage_test.go b/storage/rocks_storage_test.go index 283be16d2..20070222f 100644 --- a/storage/rocks_storage_test.go +++ b/storage/rocks_storage_test.go @@ -17,11 +17,11 @@ func TestNewRocksStorage(t *testing.T) { want *RocksStorage wantErr bool }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewRocksStorage(tt.args.path, false) + got, err := NewRocksStorage(tt.args.path) if (err != nil) != tt.wantErr { t.Errorf("NewRocksStorage() error = %v, wantErr %v", err, tt.wantErr) return @@ -32,7 +32,7 @@ func TestNewRocksStorage(t *testing.T) { }) } - s, err := NewRocksStorage("./rock.db/", false) + s, err := NewRocksStorage("./rock.db/") assert.Nil(t, err) key := []byte("key") From 40535a26aab65f951623bdaf7d0fb4bd48535a9d Mon Sep 17 00:00:00 2001 From: Yogi Xun Date: Sun, 6 May 2018 13:52:56 +0800 Subject: [PATCH 69/69] contract: update test cases --- .../contract/contract.feature.date.test.js | 29 ++++++++++++++++++- .../contract/contract.feature.random.test.js | 2 +- nf/nvm/test/contract_accept_func_with_args.js | 28 ++++++++++++++++++ nf/nvm/test/contract_date_and_random.js | 9 +++++- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/nebtestkit/cases/contract/contract.feature.date.test.js b/nebtestkit/cases/contract/contract.feature.date.test.js index fb618c0ee..4fba6e3d6 100644 --- a/nebtestkit/cases/contract/contract.feature.date.test.js +++ b/nebtestkit/cases/contract/contract.feature.date.test.js @@ -285,7 +285,15 @@ function runTest(testInput, testExpect, done) { } }); }).catch(function (err) { - console.log("send tx err"); + if (err.error && err.error.error && testExpect.eventErr) { + try { + expect(err.error.error).to.equal(testExpect.eventErr) + done(); + } catch (err) { + done(err); + } + return; + } done(err); }); } @@ -335,6 +343,25 @@ var caseGroup = { status: 1, equalBlockTime: false } + }, + { + "name": "0-3. test unsupported method", + "testInput": { + value: "0", + nonce: 1, + gasPrice: 1000000, + gasLimit: 2000000, + contract: { + function: "testDate2", + args: "" + } + }, + "testExpect": { + canExcuteTx: false, + toBalanceChange: "0", + status: 0, + eventErr: "Call: Error: Unsupported method!" + } } ] }; diff --git a/nebtestkit/cases/contract/contract.feature.random.test.js b/nebtestkit/cases/contract/contract.feature.random.test.js index dad9c35eb..9252ed3b8 100644 --- a/nebtestkit/cases/contract/contract.feature.random.test.js +++ b/nebtestkit/cases/contract/contract.feature.random.test.js @@ -322,7 +322,7 @@ var caseGroup = { canExcuteTx: false, toBalanceChange: "0", status: 0, - eventErr: "Call: Error: random seed must be a string" + eventErr: "Call: Error: input seed must be a string" } }, { diff --git a/nf/nvm/test/contract_accept_func_with_args.js b/nf/nvm/test/contract_accept_func_with_args.js index 7ab08cd57..87dcb602a 100644 --- a/nf/nvm/test/contract_accept_func_with_args.js +++ b/nf/nvm/test/contract_accept_func_with_args.js @@ -1,6 +1,34 @@ "use strict"; +var DepositeContent = function (text) { + if (text) { + var o = JSON.parse(text); + this.balance = new BigNumber(o.balance); + this.expiryHeight = new BigNumber(o.expiryHeight); + } else { + this.balance = new BigNumber(0); + this.expiryHeight = new BigNumber(0); + } +}; + +DepositeContent.prototype = { + toString: function () { + return JSON.stringify(this); + } +}; + +var BankVaultContract = function () { + LocalContractStorage.defineMapProperty(this, "bankVault", { + parse: function (text) { + return new DepositeContent(text); + }, + stringify: function (o) { + return o.toString(); + } + }); +}; + // save value to contract, only after height of block, users can takeout BankVaultContract.prototype = { init: function () { diff --git a/nf/nvm/test/contract_date_and_random.js b/nf/nvm/test/contract_date_and_random.js index e5cad9212..1e2a7c45b 100644 --- a/nf/nvm/test/contract_date_and_random.js +++ b/nf/nvm/test/contract_date_and_random.js @@ -22,7 +22,6 @@ Contract.prototype = { now: Date.now(), parse: Date.parse('04 Dec 1995 00:12:00 GMT'), getUTCDate: date.getUTCDate(), - timeZone: date.getTimezoneOffset(), toJSON: date.toJSON(), setFullYear: date2.toString(), height: Blockchain.block.height, @@ -51,6 +50,14 @@ Contract.prototype = { return data; }, + testDate2: function() { + var date = new Date(); + + Event.Trigger("Date.TZ", { + timezone: date.getTimezoneOffset() + }); + }, + testRandom: function(userseed) { var r1 = Math.random(); var r12 = Math.random();