diff --git a/common/darkside.go b/common/darkside.go index 57c89ce..8473e49 100644 --- a/common/darkside.go +++ b/common/darkside.go @@ -17,6 +17,7 @@ import ( ) type darksideState struct { + inited bool startHeight int saplingActivation int branchID string @@ -30,11 +31,12 @@ type darksideState struct { var state darksideState func DarksideIsEnabled() bool { - return state.chainName != "" + return state.inited } func DarksideInit() { state = darksideState{ + inited: true, startHeight: -1, saplingActivation: -1, branchID: "2bb40e60", // Blossom @@ -170,9 +172,25 @@ func DarksideSetBlocksURL(url string) error { return nil } -func DarksideSendTransaction(txbytes []byte) { +func DarksideSendTransaction(txHex []byte) ([]byte, error) { + // Need to parse the transaction to return its hash, plus it's + // good error checking. + txbytes, err := hex.DecodeString(string(txHex)) + if err != nil { + return nil, err + } + tx := parser.NewTransaction() + rest, err := tx.ParseFromSlice(txbytes) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, errors.New("transaction serialization is too long") + } state.incomingTransactions = append(state.incomingTransactions, txbytes) + return tx.GetDisplayHash(), nil } + func darksideRawRequest(method string, params []json.RawMessage) (json.RawMessage, error) { if time.Now().Sub(state.serverStart).Minutes() >= 30 { Log.Fatal("Shutting down darksidewalletd to prevent accidental deployment in production.") diff --git a/docs/darksidewalletd.md b/docs/darksidewalletd.md index ed57894..2c5cb5e 100644 --- a/docs/darksidewalletd.md +++ b/docs/darksidewalletd.md @@ -13,6 +13,16 @@ same darksidewalletd at the same time. Darksidewalletd should only be used for testing, and therefore is hard-coded to shut down after 30 minutes of operation to prevent accidental deployment as a server. +## Security warning + +Leaving darksidewalletd running puts your machine at greater risk because (a) it +may be possible to use file: paths with `DarksideSetBlocksURL` to read arbitrary +files on your system, and (b) also using `DarksideSetBlocksURL`, someone can +force your system to make a web request to an arbitrary URL (which could have +your system download questionable material, perform attacks on other systems, +etc.). The maximum 30-minute run time limit built into darksidewalletd mitigates +these risks, but users should still be cautious. + ## Dependencies Lightwalletd and most dependencies of lightwalletd, including Go version 1.11 or @@ -111,8 +121,8 @@ You can get the same effect slightly less efficiently by submitting 1000-1007 (t is, resubmitting the original 1000-1002 followed by the new 1003-1007). If you first submit 1000-1005, then 1001-1002, the result will be 1000-1002 -(1003-1005 are dropped; it's not possible to "insert" blocks into an range). -Likewise, first submit 1005-1008, then 1000-1006, the result is only 1000-1006. As +(1003-1005 are dropped; it's not possible to "insert" blocks into a range). +Likewise, first submit 1005-1008, then 1000-1006, the result is only 1000-1006. An easy way to state it is that all earlier blocks beyond the end of the extent of the range being submitted now are dropped. But blocks before the start of the range being submitted now are preserved if doing so doesn't create a gap. diff --git a/frontend/service.go b/frontend/service.go index 0393249..b19fc2c 100644 --- a/frontend/service.go +++ b/frontend/service.go @@ -18,7 +18,6 @@ import ( "time" "github.com/zcash/lightwalletd/common" - "github.com/zcash/lightwalletd/parser" "github.com/zcash/lightwalletd/walletrpc" ) @@ -221,21 +220,13 @@ func (s *LwdStreamer) SendTransaction(ctx context.Context, rawtx *walletrpc.RawT // "hex" (string) The transaction hash in hex if common.DarksideIsEnabled() { - txbytes, err := hex.DecodeString(string(rawtx.Data)) - common.DarksideSendTransaction(txbytes) - // Need to parse the transaction to return its hash, plus it's - // good error checking. - tx := parser.NewTransaction() - rest, err := tx.ParseFromSlice(txbytes) + txid, err := common.DarksideSendTransaction(rawtx.Data) if err != nil { return nil, err } - if len(rest) != 0 { - return nil, errors.New("transaction serialization is too long") - } return &walletrpc.SendResponse{ ErrorCode: 0, - ErrorMessage: hex.EncodeToString(tx.GetDisplayHash()), + ErrorMessage: hex.EncodeToString(txid), }, nil } // Construct raw JSON-RPC params diff --git a/utils/submitblocks.sh b/utils/submitblocks.sh index c3a9a70..b3a5347 100755 --- a/utils/submitblocks.sh +++ b/utils/submitblocks.sh @@ -4,7 +4,7 @@ # e.g. ./submitblocks.sh 1000 blocks.txt # set -e -test $# -ne 2 && { echo usage: $0 start-height blocks-file;exit 1;} +test $# -ne 2 && { echo usage: $0 sapling-height blocks-file;exit 1;} JSON="{\"saplingActivation\": $1, \"branchID\": \"2bb40e60\", \"chainName\": \"main\"}" grpcurl -plaintext -d "$JSON" localhost:9067 cash.z.wallet.sdk.rpc.DarksideStreamer/SetMetaState