/
blockchain.go
131 lines (113 loc) · 4.35 KB
/
blockchain.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (C) 2017, 2018, 2019 EGAAS S.A.
//
// This program 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 2 of the License, or (at
// your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package model
import (
"time"
)
// Block is model
type Block struct {
ID int64 `gorm:"primary_key;not_null"`
Hash []byte `gorm:"not null"`
RollbacksHash []byte `gorm:"not null"`
Data []byte `gorm:"not null"`
EcosystemID int64 `gorm:"not null"`
KeyID int64 `gorm:"not null"`
NodePosition int64 `gorm:"not null"`
Time int64 `gorm:"not null"`
Tx int32 `gorm:"not null"`
}
// TableName returns name of table
func (Block) TableName() string {
return "block_chain"
}
// Create is creating record of model
func (b *Block) Create(transaction *DbTransaction) error {
return GetDB(transaction).Create(b).Error
}
// Get is retrieving model from database
func (b *Block) Get(blockID int64) (bool, error) {
return isFound(DBConn.Where("id = ?", blockID).First(b))
}
// GetMaxBlock returns last block existence
func (b *Block) GetMaxBlock() (bool, error) {
return isFound(DBConn.Last(b))
}
// GetMaxForeignBlock returns last block generated not by key_id
func (b *Block) GetMaxForeignBlock(keyId int64) (bool, error) {
return isFound(DBConn.Order("id DESC").Where("key_id != ?", keyId).First(b))
}
// GetBlockchain is retrieving chain of blocks from database
func GetBlockchain(startBlockID int64, endblockID int64, order ordering) ([]Block, error) {
var err error
blockchain := new([]Block)
orderStr := "id " + string(order)
query := DBConn.Model(&Block{}).Order(orderStr)
if endblockID > 0 {
query = query.Where("id > ? AND id <= ?", startBlockID, endblockID).Find(&blockchain)
} else {
query = query.Where("id > ?", startBlockID).Find(&blockchain)
}
if query.Error != nil {
return nil, err
}
return *blockchain, nil
}
// GetBlocks is retrieving limited chain of blocks from database
func (b *Block) GetBlocks(startFromID int64, limit int32) ([]Block, error) {
var err error
blockchain := new([]Block)
if startFromID > 0 {
err = DBConn.Order("id desc").Limit(limit).Where("id > ?", startFromID).Find(&blockchain).Error
} else {
err = DBConn.Order("id desc").Limit(limit).Find(&blockchain).Error
}
return *blockchain, err
}
// GetBlocksFrom is retrieving ordered chain of blocks from database
func (b *Block) GetBlocksFrom(startFromID int64, ordering string, limit int32) ([]Block, error) {
var err error
blockchain := new([]Block)
if limit == 0 {
err = DBConn.Order("id "+ordering).Where("id > ?", startFromID).Find(&blockchain).Error
} else {
err = DBConn.Order("id "+ordering).Where("id > ?", startFromID).Limit(limit).Find(&blockchain).Error
}
return *blockchain, err
}
// GetReverseBlockchain returns records of blocks in reverse ordering
func (b *Block) GetReverseBlockchain(endBlockID int64, limit int32) ([]Block, error) {
var err error
blockchain := new([]Block)
err = DBConn.Model(&Block{}).Order("id DESC").Where("id <= ?", endBlockID).Limit(limit).Find(&blockchain).Error
return *blockchain, err
}
// GetNodeBlocksAtTime returns records of blocks for time interval and position of node
func (b *Block) GetNodeBlocksAtTime(from, to time.Time, node int64) ([]Block, error) {
var err error
blockchain := new([]Block)
err = DBConn.Model(&Block{}).Where("node_position = ? AND time BETWEEN ? AND ?", node, from.Unix(), to.Unix()).Find(&blockchain).Error
return *blockchain, err
}
// DeleteById is deleting block by ID
func (b *Block) DeleteById(transaction *DbTransaction, id int64) error {
return GetDB(transaction).Where("id = ?", id).Delete(Block{}).Error
}
func GetTxCount() (int64, error) {
var txCount int64
row := DBConn.Raw("SELECT SUM(tx) tx_count FROM block_chain").Select("tx_count").Row()
err := row.Scan(&txCount)
return txCount, err
}