From 8d67edc421bfd8f5c5acc37890746ff5e1ab5221 Mon Sep 17 00:00:00 2001 From: Ben Wilson Date: Wed, 23 Sep 2020 15:14:51 -0400 Subject: [PATCH] Started moving out of main --- .gitignore | 1 + go.mod | 7 +- go.sum | 16 ++ main.go | 366 +++--------------------------------- types.go => pkg/rpc/type.go | 20 +- zSendMany.go | 62 ------ 6 files changed, 55 insertions(+), 417 deletions(-) rename types.go => pkg/rpc/type.go (65%) delete mode 100644 zSendMany.go diff --git a/.gitignore b/.gitignore index 1e9c1ec..8680727 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env zfaucet eccfaucet +a_main-packr.go diff --git a/go.mod b/go.mod index d48c7ba..ea3b374 100644 --- a/go.mod +++ b/go.mod @@ -6,15 +6,16 @@ require ( github.com/doubtingben/zfaucet v0.0.0-20200722134018-70e63e333601 // indirect github.com/gobuffalo/packr v1.30.1 github.com/gobuffalo/packr/v2 v2.8.0 // indirect - github.com/karrick/godirwalk v1.15.6 // indirect + github.com/karrick/godirwalk v1.16.1 // indirect github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.7.1 github.com/muesli/cache2go v0.0.0-20200423001931-a100c5aac93f + github.com/rogpeppe/go-internal v1.6.2 // indirect github.com/sirupsen/logrus v1.6.0 // indirect github.com/spf13/cobra v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ybbus/jsonrpc v2.1.2+incompatible - golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 // indirect + golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 // indirect - golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 // indirect + golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d // indirect ) diff --git a/go.sum b/go.sum index c1a6436..770e530 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -81,6 +82,8 @@ github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0L github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/karrick/godirwalk v1.15.6 h1:Yf2mmR8TJy+8Fa0SuQVto5SYap6IF7lNVX4Jdl8G1qA= github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -114,9 +117,11 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -135,6 +140,8 @@ github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.0 h1:IZRgg4sfrDH7nsAD1Y/Nwj+GzIfEwpJSLjCaNC3SbsI= github.com/rogpeppe/go-internal v1.6.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= +github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -164,6 +171,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -185,6 +193,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -197,6 +207,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -225,6 +236,9 @@ golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666 h1:gVCS+QOncANNPlmlO1AhlU3ox golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 h1:X9xIZ1YU8bLZA3l6gqDUHSFiD0GFI9S548h6C8nDtOY= golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -235,6 +249,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -257,5 +272,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go index 65d1b3a..5d1ebbb 100644 --- a/main.go +++ b/main.go @@ -5,43 +5,33 @@ import ( "crypto/tls" "encoding/base64" "encoding/gob" - "encoding/json" - "errors" "flag" "fmt" - "html/template" "log" "net/http" "os" - "strconv" - "time" "github.com/gobuffalo/packr" "github.com/kelseyhightower/envconfig" - _ "github.com/lib/pq" "github.com/muesli/cache2go" "github.com/ybbus/jsonrpc" + "github.com/zcash-hackworks/eccfaucet/pkg/eccfaucet" + "github.com/zcash-hackworks/eccfaucet/pkg/rpc" ) -const tapAmount = 1.0 -const tapWaitMinutes = 2 -const opStatusWaitSeconds = 120 - -type TapRequest struct { - NetworkAddress string - WalletAddress string - RequestedAt time.Time -} type ECCfaucetConfig struct { - ListenPort string - ListenAddress string - RPCUser string - RPCPassword string - RPCHost string - RPCPort string - FundingAddress string - TLSCertFile string - TLSKeyFile string + ListenPort string + ListenAddress string + RPCUser string + RPCPassword string + RPCHost string + RPCPort string + FundingAddress string + TLSCertFile string + TLSKeyFile string + TapAmount float64 + TapWaitMinutes float64 + OpStatusWaitSeconds int } func (c *ECCfaucetConfig) checkConfig() error { @@ -64,172 +54,20 @@ func (c *ECCfaucetConfig) checkConfig() error { (c.TLSCertFile != "" && c.TLSKeyFile == "") { return fmt.Errorf("ECCFAUCET_TLSCERTFILE and ECCFAUCET_TLSKEYFILE are both required") } + c.TapAmount = 1.0 + c.TapWaitMinutes = 2 + c.OpStatusWaitSeconds = 120 return nil } -// ECCFaucet holds a zfaucet configuration -type ECCFaucet struct { - RPCConnetion jsonrpc.RPCClient - CurrentHeight int - UpdatedChainInfo time.Time - UpdatedWallet time.Time - Operations map[string]OperationStatus - ZcashdVersion string - ZcashNetwork string - FundingAddress string - TapRequests []*TapRequest - TapCache *cache2go.CacheTable - HomeHTML string -} - -type SendAmount struct { - Address string `json:"address"` - Amount float32 `json:"amount"` -} - -// TODO tag facet transactions, zaddr targets only -type SendAmountMemo struct { - SendAmount - Memo string -} - -func (z *ECCFaucet) ClearCache() { - for { - now := time.Now() - fmt.Printf("Clearing cache: %d\n", len(z.TapRequests)) - for _, t := range z.TapRequests { - fmt.Printf("Checking RemoteAddress: '%#v' - '%#v'\n", t.NetworkAddress, t.RequestedAt) - diff := now.Sub(t.RequestedAt) - if diff.Minutes() > tapWaitMinutes { - fmt.Printf("Old entry! : %#v\n", t) - } - } - time.Sleep(time.Second * 60 * tapWaitMinutes) - } -} - -func (z *ECCFaucet) UpdateZcashInfo() { - for { - z.UpdatedChainInfo = time.Now() - var blockChainInfo *GetBlockchainInfo - if err := z.RPCConnetion.CallFor(&blockChainInfo, "getblockchaininfo"); err != nil { - fmt.Printf("Failed to get blockchaininfo: %s\n", err) - } else { - z.CurrentHeight = blockChainInfo.Blocks - z.ZcashNetwork = blockChainInfo.Chain - } - var info *GetBlockInfo - if err := z.RPCConnetion.CallFor(&info, "getinfo"); err != nil { - fmt.Printf("Failed to get getinfo: %s\n", err) - } else { - z.ZcashdVersion = strconv.Itoa(info.Version) - } - fmt.Println("Updated Zcashd Info") - time.Sleep(time.Second * 30) - } -} - -func (z *ECCFaucet) WaitForOperation(opid string) (os OperationStatus, err error) { - var opStatus []struct { - CreationTime int `json:"creation_time"` - ID string `json:"id"` - Method string `json:"method"` - Result struct { - TxID string `json:"txid"` - } - Status string `json:"status"` - } - var parentList [][]string - var opList []string - opList = append(opList, opid) - parentList = append(parentList, opList) - fmt.Printf("opList: %s\n", opList) - fmt.Printf("parentList: %s\n", parentList) - // Wait for a few seconds for the operational status to become available - for i := 0; i < opStatusWaitSeconds; i++ { - if err := z.RPCConnetion.CallFor( - &opStatus, - "z_getoperationresult", - parentList, - ); err != nil { - return os, fmt.Errorf("failed to call z_getoperationresult: %s", err) - } else { - fmt.Printf("op: %s, i: %d, status: %#v\n", opid, i, opStatus) - if len(opStatus) > 0 { - fmt.Printf("opStatus: %#v\n", opStatus[0]) - //z.Operations[opid] = OperationStatus{ - os = OperationStatus{ - UpdatedAt: time.Now(), - TxID: opStatus[0].Result.TxID, - Status: opStatus[0].Status, - } - z.Operations[opid] = os - return os, nil - } - } - time.Sleep(time.Second * 1) - } - return os, errors.New("Timeout waiting for operations status") -} - -func (z *ECCFaucet) ValidateFundingAddress() (bool, error) { - if z.FundingAddress == "" { - return false, errors.New("FundingAddressis required") - } - return true, nil -} - -func (z *ECCFaucet) ZSendManyFaucet(remoteAddr string, remoteWallet string) (opStatus OperationStatus, err error) { - var op *string - amountEntry := SendAmount{ - Address: remoteWallet, - Amount: tapAmount, - } - fmt.Printf("ZSendManyFaucet sending: %#v\n", amountEntry) - fmt.Printf("ZSendManyFaucet from funding address: %s\n", z.FundingAddress) - // if err != nil { - // return opStatus, err - // } - // Call z_sendmany with a single entry entry list - if err := z.RPCConnetion.CallFor( - &op, - "z_sendmany", - z.FundingAddress, - []SendAmount{amountEntry}, - ); err != nil { - return opStatus, err - } - fmt.Printf("ZSendManyFaucet sent to %s: Address: %s %s\n", remoteWallet, remoteAddr, *op) - opStatus, err = z.WaitForOperation(*op) - if err != nil { - return opStatus, err - } - if opStatus.Status != "success" { - return opStatus, fmt.Errorf("Failed to send funds: %s", err) - } - tapRequest := &TapRequest{ - NetworkAddress: remoteAddr, - WalletAddress: remoteWallet, - RequestedAt: time.Now(), - } - z.TapCache.Add(remoteAddr, tapWaitMinutes*60*time.Second, tapRequest) - z.TapRequests = append(z.TapRequests, tapRequest) - return opStatus, err - -} - -type GetBlockInfo struct { - Version int -} - -func getBlockchainInfo(rpcClient jsonrpc.RPCClient) (blockChainInfo *GetBlockchainInfo, err error) { +func getBlockchainInfo(rpcClient jsonrpc.RPCClient) (blockChainInfo *rpc.GetBlockchainInfo, err error) { if err := rpcClient.CallFor(&blockChainInfo, "getblockchaininfo"); err != nil { return nil, err } return } -func getInfo(rpcClient jsonrpc.RPCClient) (info *GetBlockInfo, err error) { +func getInfo(rpcClient jsonrpc.RPCClient) (info *rpc.GetBlockInfo, err error) { if err := rpcClient.CallFor(&info, "getinfo"); err != nil { return nil, err } @@ -256,10 +94,13 @@ func main() { fmt.Printf("zfaucet: %#v\n", zConfig) basicAuth := base64.StdEncoding.EncodeToString([]byte(zConfig.RPCUser + ":" + zConfig.RPCPassword)) - var z ECCFaucet + var z eccfaucet.ECCFaucet z.TapCache = cache2go.Cache("tapRequests") z.FundingAddress = zConfig.FundingAddress - z.Operations = make(map[string]OperationStatus) + z.TapAmount = zConfig.TapAmount + z.TapWaitMinutes = zConfig.TapWaitMinutes + z.OpStatusWaitSeconds = zConfig.OpStatusWaitSeconds + z.Operations = make(map[string]eccfaucet.OperationStatus) z.RPCConnetion = jsonrpc.NewClientWithOpts("http://"+zConfig.RPCHost+":"+zConfig.RPCPort, &jsonrpc.RPCClientOpts{ CustomHeaders: map[string]string{ @@ -274,10 +115,10 @@ func main() { if err != nil { log.Fatal(err) } - homeHandler := http.HandlerFunc(z.home) - balanceHandler := http.HandlerFunc(z.balance) - opsStatusHandler := http.HandlerFunc(z.opsStatus) - addressHandler := http.HandlerFunc(z.addresses) + homeHandler := http.HandlerFunc(z.Home) + balanceHandler := http.HandlerFunc(z.Balance) + opsStatusHandler := http.HandlerFunc(z.OpsStatus) + addressHandler := http.HandlerFunc(z.Addresses) mux := http.NewServeMux() mux.Handle("/", homeHandler) mux.Handle("/balance", z.OKMiddleware(balanceHandler)) @@ -311,157 +152,6 @@ func main() { log.Fatal(err) } -// OperationStatus describes an rpc response -type OperationStatus struct { - UpdatedAt time.Time - Status string - TxID string - result interface{} -} - -// home is the default request handler -func (z *ECCFaucet) home(w http.ResponseWriter, r *http.Request) { - // tData is the html template data - tData := struct { - Z *ECCFaucet - Msg string - }{ - z, - "", - } - switch r.Method { - case http.MethodPost: - res, err := z.TapCache.Value(r.RemoteAddr) - if err == nil { - fmt.Println("Found value in cache:", res.Data().(*TapRequest).NetworkAddress) - tData.Msg = fmt.Sprintf("You may only tap the faucet every %d minutes\nPlease try again later\n", tapWaitMinutes) - break - } else { - fmt.Println("Error retrieving value from cache:", err) - } - if err := checkFaucetAddress(r.FormValue("address")); err != nil { - tData.Msg = fmt.Sprintf("Invalid address: %s", err) - break - } - opStatus, err := z.ZSendManyFaucet(r.RemoteAddr, r.FormValue("address")) - if err != nil { - tData.Msg = fmt.Sprintf("Failed to send funds: %s", err) - break - } - tData.Msg = fmt.Sprintf("Successfully submitted operation, transaction: %s", opStatus.TxID) - } - w.Header().Set("Content-Type", "text/html") - tmpl, err := template.New("name").Parse(z.HomeHTML) - if err != nil { - http.Error(w, err.Error(), 500) - } - tmpl.Execute(w, tData) -} - -// OKMiddleware determines if a request is allowed before execution -func (z *ECCFaucet) OKMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Our middleware logic goes here... - next.ServeHTTP(w, r) - }) -} - -// Balance -func (z *ECCFaucet) balance(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var totalBalance *z_gettotalbalance - if err := z.RPCConnetion.CallFor(&totalBalance, "z_gettotalbalance"); err != nil { - http.Error(w, err.Error(), 500) - return - } - out, err := json.Marshal(totalBalance) - if err != nil { - http.Error(w, err.Error(), 500) - return - } - fmt.Fprintf(w, string(out)) -} - -// opsStatus -func (z *ECCFaucet) opsStatus(w http.ResponseWriter, r *http.Request) { - // tData is the html template data - tData := struct { - Z *ECCFaucet - Ops *[]string - Type string - }{ - z, - nil, - "opsStatus", - } - if err := z.RPCConnetion.CallFor(&tData.Ops, "z_listoperationids"); err != nil { - http.Error(w, err.Error(), 500) - return - } - w.Header().Set("Content-Type", "text/html") - tmpl, err := template.New("name").Parse(z.HomeHTML) - if err != nil { - http.Error(w, err.Error(), 500) - } - tmpl.Execute(w, tData) -} - -// addresses -func (z *ECCFaucet) addresses(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var addresses []WalletAddress - var zlist *[]string - var taddrs []interface{} - // Z addresses - if err := z.RPCConnetion.CallFor(&zlist, "z_listaddresses"); err != nil { - http.Error(w, err.Error(), 500) - return - } - for _, zaddr := range *zlist { - entry := WalletAddress{ - Address: zaddr, - } - entry.Notes = append(entry.Notes, "z address") - addresses = append(addresses, entry) - - } - // T addresses - if err := z.RPCConnetion.CallFor(&taddrs, "listaddressgroupings"); err != nil { - http.Error(w, fmt.Sprintf("Problem calling listaddressgroupings: %s", err.Error()), 500) - return - } - fmt.Printf("T addresses:\n%#v\n", taddrs) - // TODO: fix this mess - for _, a := range taddrs { - switch aResult := a.(type) { - case []interface{}: - for _, b := range aResult { - switch bResult := b.(type) { - case []interface{}: - for _, x := range bResult { - switch x.(type) { - case string: - taddr := fmt.Sprintf("%v", x) - fmt.Printf("Adding T Address: %s\n", taddr) - entry := WalletAddress{ - Address: taddr, - } - entry.Notes = append(entry.Notes, "t address") - addresses = append(addresses, entry) - } - } - } - } - } - } - out, err := json.Marshal(addresses) - if err != nil { - http.Error(w, err.Error(), 500) - return - } - fmt.Fprintf(w, string(out)) -} - // GetBytes returns a byte slice from an interface func GetBytes(key interface{}) ([]byte, error) { var buf bytes.Buffer diff --git a/types.go b/pkg/rpc/type.go similarity index 65% rename from types.go rename to pkg/rpc/type.go index dcbe19e..e10e536 100644 --- a/types.go +++ b/pkg/rpc/type.go @@ -1,7 +1,10 @@ -package main +package rpc + +// GetBlockInfo is the important getblockinfo response data +type GetBlockInfo struct { + Version int +} -// GetBlockchainInfo return the zcashd rpc `getblockchaininfo` status -// https://zcash-rpc.github.io/getblockchaininfo.html type GetBlockchainInfo struct { Chain string `json:"chain"` Blocks int `json:"blocks"` @@ -17,14 +20,3 @@ type SoftFork struct { ID string `json:"id"` Version int `json:"version"` } - -type z_gettotalbalance struct { - Transparent string - Private string - Total string -} - -type WalletAddress struct { - Address string - Notes []string -} diff --git a/zSendMany.go b/zSendMany.go deleted file mode 100644 index b470105..0000000 --- a/zSendMany.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "net/http" - "regexp" -) - -func zSendManyHTTPPost(r *http.Request) (opid string, err error) { - fmt.Printf("zSendManyHTTPPost address: %s\n", r.FormValue("address")) - switch { - case r.FormValue("address") == "": - fmt.Println("address blank case") - return "", errors.New("Form field value required: address") - case isTestnetTransparent(r.FormValue("address")): - fmt.Println("Address is a transparent testnet address") - - return r.FormValue("address"), nil - - default: - fmt.Println("address default case") - return "", errors.New("A valid address is required") - } -} - -func isTestnetTransparent(addr string) bool { - //TODO Check length and encoding - matched, _ := regexp.MatchString(`^tm`, addr) - return matched -} - -func isTestnetSaplingZaddr(addr string) bool { - //TODO Check length and encoding - matched, _ := regexp.MatchString(`^ztestsapling`, addr) - return matched -} - -func checkSourceAddress(rAddress string) error { - - return nil -} -func checkFaucetAddress(checkAddr string) error { - switch { - case checkAddr == "": - fmt.Println("address blank case") - return errors.New("Form field value required: address") - case isTestnetTransparent(checkAddr): - fmt.Println("Address is a testnet transparent address") - return nil - case isTestnetSaplingZaddr(checkAddr): - fmt.Println("Address is a testnet sapling address") - return nil - default: - fmt.Println("address default case") - return errors.New("A valid address is required") - } -} - -func zSendManyFaucet(addr string) (opid string, err error) { - return "000-test-opid-string-000", nil -}