diff --git a/README.md b/README.md index 9ba7e82..46061d0 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ rpcallowip=127.0.0.1 "port": "3021", "genesisTx": "7c27ade2c28e67ed3077f8f77b8ea6d36d4f5eba04c099be3c9faa9a4a04c046", "genesisBlock": "beed44fa5e96150d95d56ebd5d2625781825a9407a5215dd7eda723373a0a1d7", - "startFromBlock": 160, + "startFromBlock": 0, "server": { "serverIP": "127.0.0.1", "serverPort": "3014", @@ -68,10 +68,16 @@ Wait until the entire blockchain is downloaded. ./goBlockchainDataAnalysis -explore ``` - 3.1. The next runs, once the database have data, can just run: + 3.1. The next runs, once the database have data and just need to add last blocks added in the blockchain, can just run: +``` +./goBlockchainDataAnalysis -continue +``` + + 3.2. If don't want to fill the database, can just run: ``` ./goBlockchainDataAnalysis ``` + Webapp will run on 127.0.0.1:8080 4. ADDITIONAL - Run the webserver, directly from the /web directory diff --git a/exploreBlockchain.go b/exploreBlockchain.go index fd109d9..5a2998a 100644 --- a/exploreBlockchain.go +++ b/exploreBlockchain.go @@ -25,7 +25,6 @@ func explore(client *btcrpcclient.Client, blockHash string) { check(err) block, err := client.GetBlockVerbose(bh) check(err) - if block.Height > config.StartFromBlock { var newBlock BlockModel newBlock.Hash = block.Hash @@ -176,7 +175,7 @@ func explore(client *btcrpcclient.Client, blockHash string) { blockHash = block.NextHash } - fmt.Print("realBlocks (blocks with Fee and Amount values): ") + fmt.Print("realBlocks added (blocks with Fee and Amount values): ") fmt.Println(realBlocks) fmt.Println("reached the end of blockchain") } diff --git a/main.go b/main.go index d00eac7..6311baa 100644 --- a/main.go +++ b/main.go @@ -4,12 +4,13 @@ import ( "log" "net/http" "os" + "strconv" "time" mgo "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" "github.com/btcsuite/btcrpcclient" - "github.com/fatih/color" "github.com/gorilla/handlers" ) @@ -61,7 +62,7 @@ func main() { for label, amount := range accounts { log.Printf("%s: %s", label, amount) } - color.Blue("starting to explore blockchain") + log.Println("starting to explore blockchain") start := time.Now() explore(client, config.GenesisBlock) log.Println("blockchain exploration finished, time:") @@ -74,6 +75,27 @@ func main() { } log.Printf("Block count: %d", blockCount) } + if os.Args[1] == "-continue" { + // create new client instance + client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{ + HTTPPostMode: true, + DisableTLS: true, + Host: config.Host + ":" + config.Port, + User: config.User, + Pass: config.Pass, + }, nil) + check(err) + //get last block stored in mongodb + lastBlock := BlockModel{} + err = blockCollection.Find(bson.M{}).Sort("-$natural").One(&lastBlock) + check(err) + log.Println("Getting last block stored in MongoDB. Hash: " + string(lastBlock.Hash) + ", BlockHeight: " + strconv.FormatInt(lastBlock.Height, 10)) + log.Println("continuing blockchain exploration since last block in mongodb") + start := time.Now() + explore(client, string(lastBlock.Hash)) + log.Println("blockchain exploration finished, time:") + log.Println(time.Since(start)) + } } //run thw webserver go webserver() diff --git a/mongoModels.go b/mongoModels.go index 8536350..beb1db8 100644 --- a/mongoModels.go +++ b/mongoModels.go @@ -92,6 +92,11 @@ type ChartAnalysisResp struct { Labels []string `json:"labels"` Data []int `json:"data"` } +type ChartSeriesAnalysisResp struct { + Labels []string `json:"labels"` + Data [][]int `json:"data"` + Series []int `json:"series"` +} type DateCountModel struct { Time int64 `json:"time"` Date string `json:"date"` diff --git a/screenshots/goBlockchainDataAnalysis00.png b/screenshots/goBlockchainDataAnalysis00.png index ab7153a..be076dd 100644 Binary files a/screenshots/goBlockchainDataAnalysis00.png and b/screenshots/goBlockchainDataAnalysis00.png differ diff --git a/screenshots/goBlockchainDataAnalysis04.png b/screenshots/goBlockchainDataAnalysis04.png index a62c4f8..d3eb94c 100644 Binary files a/screenshots/goBlockchainDataAnalysis04.png and b/screenshots/goBlockchainDataAnalysis04.png differ diff --git a/serverRoutes.go b/serverRoutes.go index c0529c4..39740e9 100644 --- a/serverRoutes.go +++ b/serverRoutes.go @@ -76,6 +76,12 @@ var routes = Routes{ "/last7day", GetLast7DayAnalysis, }, + Route{ + "GetLast7DayHourAnalysis", + "Get", + "/last7dayhour", + GetLast7DayHourAnalysis, + }, } //ROUTES @@ -318,3 +324,49 @@ func GetLast7DayAnalysis(w http.ResponseWriter, r *http.Request) { check(err) fmt.Fprintln(w, string(jsonResp)) } + +func GetLast7DayHourAnalysis(w http.ResponseWriter, r *http.Request) { + ipFilter(w, r) + + var resp ChartSeriesAnalysisResp + + for i := 0; i < 7; i++ { + fromDate := time.Now().AddDate(0, 0, -i-1) + toDate := time.Now().AddDate(0, 0, -i) + txs := []TxModel{} + err := txCollection.Find(bson.M{ + "datet": bson.M{ + "$gt": fromDate, + "$lt": toDate, + }, + }).Sort("-$natural").All(&txs) + check(err) + + //generate map with 24 hours + hourFrequencies := map24hours() + for _, tx := range txs { + hourFrequencies[tx.Date.Hour]++ + } + var hourCount []ChartCountModel + for hour, frequency := range hourFrequencies { + hourCount = append(hourCount, ChartCountModel{hour, frequency}) + } + //sort by hour + sort.Slice(hourCount, func(i, j int) bool { + return hourCount[i].Elem < hourCount[j].Elem + }) + var dayData []int + for _, d := range hourCount { + dayData = append(dayData, d.Count) + } + resp.Series = append(resp.Series, txs[0].Date.Day) + resp.Data = append(resp.Data, dayData) + } + hourLabels := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"} + resp.Labels = hourLabels + + //convert []resp struct to json + jsonResp, err := json.Marshal(resp) + check(err) + fmt.Fprintln(w, string(jsonResp)) +} diff --git a/web/views/dateAnalysis/dateAnalysis.html b/web/views/dateAnalysis/dateAnalysis.html index 9d7e0c4..0f27ce5 100644 --- a/web/views/dateAnalysis/dateAnalysis.html +++ b/web/views/dateAnalysis/dateAnalysis.html @@ -1,11 +1,11 @@