Skip to content

Commit 6ae9b34

Browse files
authoredFeb 10, 2022
Merge pull request #29 from everFinance/add-block-verify
Add block verify
2 parents 4e3eb0f + c431f10 commit 6ae9b34

File tree

7 files changed

+601
-26
lines changed

7 files changed

+601
-26
lines changed
 

‎README.md

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ fmt.Println(id, err) // {{id}}, nil
9393
- [x] GetBundle
9494
- [x] GetTxDataFromPeers
9595
- [x] BroadcastData
96+
- [x] GetUnconfirmedTx
97+
- [x] GetPendingTxIds
98+
- [x] GetBlockHashList
9699

97100
Initialize the instance:
98101

@@ -149,6 +152,7 @@ Package for Arweave develop toolkit.
149152
- [x] GetSignatureData
150153
- [x] VerifyTransaction
151154
- [x] NewBundle
155+
- [x] GenerateIndepHash
152156

153157
#### RSA Threshold Cryptography
154158

‎client.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,7 @@ func (c *Client) GetBlockByID(id string) (block *types.Block, err error) {
371371
if code != 200 {
372372
return nil, fmt.Errorf("get block by id error: %s", string(body))
373373
}
374-
block = &types.Block{}
375-
err = json.Unmarshal(body, block)
374+
block, err = utils.DecodeBlock(string(body))
376375
return
377376
}
378377

@@ -385,8 +384,7 @@ func (c *Client) GetBlockByHeight(height int64) (block *types.Block, err error)
385384
if code != 200 {
386385
return nil, fmt.Errorf("get block by height error: %s", string(body))
387386
}
388-
block = &types.Block{}
389-
err = json.Unmarshal(body, block)
387+
block, err = utils.DecodeBlock(string(body))
390388
return
391389
}
392390

@@ -527,3 +525,19 @@ func (c *Client) GetPendingTxIds() ([]string, error) {
527525
}
528526
return res, nil
529527
}
528+
529+
func (c *Client) GetBlockHashList() ([]string, error) {
530+
body, statusCode, err := c.httpGet("/hash_list")
531+
if statusCode != 200 {
532+
return nil, errors.New("get block hash list failed")
533+
}
534+
if err != nil {
535+
return nil, err
536+
}
537+
538+
res := make([]string, 0)
539+
if err := json.Unmarshal(body, &res); err != nil {
540+
return nil, err
541+
}
542+
return res, nil
543+
}

‎client_broadcast.go

-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ func (c *Client) GetTxDataFromPeers(txId string, peers ...string) ([]byte, error
5151
pNode.SetTempConnUrl("http://" + peer)
5252
data, err := pNode.DownloadChunkData(txId)
5353
if err != nil {
54-
log.Error("get tx data", "err", err, "peer", peer)
5554
continue
5655
}
5756
return data, nil
@@ -74,7 +73,6 @@ func (c *Client) GetBlockFromPeers(height int64, peers ...string) (*types.Block,
7473
pNode.SetTempConnUrl("http://" + peer)
7574
block, err := pNode.GetBlockByHeight(height)
7675
if err != nil {
77-
fmt.Printf("get block error:%v, peer: %s, height: %d\n", err, peer, height)
7876
continue
7977
}
8078
fmt.Printf("success get block; peer: %s\n", peer)
@@ -98,7 +96,6 @@ func (c *Client) GetTxFromPeers(arId string, peers ...string) (*types.Transactio
9896
pNode.SetTempConnUrl("http://" + peer)
9997
tx, err := pNode.GetTransactionByID(arId)
10098
if err != nil {
101-
fmt.Printf("get tx error:%v, peer: %s, arTx: %s\n", err, peer, arId)
10299
continue
103100
}
104101
fmt.Printf("success get tx; peer: %s, arTx: %s\n", peer, arId)
@@ -122,7 +119,6 @@ func (c *Client) GetUnconfirmedTxFromPeers(arId string, peers ...string) (*types
122119
pNode.SetTempConnUrl("http://" + peer)
123120
tx, err := pNode.GetUnconfirmedTx(arId)
124121
if err != nil {
125-
fmt.Printf("get tx error:%v, peer: %s, arTx: %s\n", err, peer, arId)
126122
continue
127123
}
128124
fmt.Printf("success get unconfirmed tx; peer: %s, arTx: %s\n", peer, arId)

‎types/block.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package types
2+
3+
type Block struct {
4+
Nonce string `json:"nonce"`
5+
PreviousBlock string `json:"previous_block"`
6+
Timestamp int64 `json:"timestamp"`
7+
LastRetarget int64 `json:"last_retarget"`
8+
Diff interface{} `json:"diff"`
9+
Height int64 `json:"height"`
10+
Hash string `json:"hash"`
11+
IndepHash string `json:"indep_hash"`
12+
Txs []string `json:"txs"`
13+
TxRoot string `json:"tx_root"`
14+
TxTree interface{} `json:"tx_tree"`
15+
HashList interface{} `json:"hash_list"`
16+
HashListMerkle string `json:"hash_list_merkle"`
17+
WalletList string `json:"wallet_list"`
18+
RewardAddr string `json:"reward_addr"`
19+
Tags []interface{} `json:"tags"`
20+
RewardPool interface{} `json:"reward_pool"` // always string
21+
WeaveSize interface{} `json:"weave_size"` // always string
22+
BlockSize interface{} `json:"block_size"` // always string
23+
CumulativeDiff interface{} `json:"cumulative_diff"`
24+
SizeTaggedTxs interface{} `json:"size_tagged_txs"`
25+
Poa POA `json:"poa"`
26+
UsdToArRate []string `json:"usd_to_ar_rate"`
27+
ScheduledUsdToArRate []string `json:"scheduled_usd_to_ar_rate"`
28+
Packing25Threshold string `json:"packing_2_5_threshold"`
29+
StrictDataSplitThreshold string `json:"strict_data_split_threshold"`
30+
}
31+
32+
type POA struct {
33+
Option string `json:"option"`
34+
TxPath string `json:"tx_path"`
35+
DataPath string `json:"data_path"`
36+
Chunk string `json:"chunk"`
37+
}

‎types/types.go

-18
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,6 @@ type NetworkInfo struct {
1212
NodeStateLatency int64 `json:"node_state_latency"`
1313
}
1414

15-
type Block struct {
16-
Nonce string `json:"nonce"`
17-
PreviousBlock string `json:"previous_block"`
18-
Timestamp int64 `json:"timestamp"`
19-
LastRetarget int64 `json:"last_retarget"`
20-
Diff interface{} `json:"diff"`
21-
Height int64 `json:"height"`
22-
Hash string `json:"hash"`
23-
IndepHash string `json:"indep_hash"`
24-
Txs []string `json:"txs"`
25-
WalletList string `json:"wallet_list"`
26-
RewardAddr string `json:"reward_addr"`
27-
Tags []interface{} `json:"tags"`
28-
RewardPool interface{} `json:"reward_pool"`
29-
WeaveSize interface{} `json:"weave_size"`
30-
BlockSize interface{} `json:"block_size"`
31-
}
32-
3315
type TransactionChunk struct {
3416
Chunk string `json:"chunk"`
3517
DataPath string `json:"data_path"`

‎utils/block.go

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package utils
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/everFinance/goar/types"
7+
"strings"
8+
)
9+
10+
const (
11+
height_2_0 = int64(422250)
12+
height_2_4 = int64(633720)
13+
height_2_5 = int64(812970)
14+
)
15+
16+
func GenerateIndepHash(b types.Block) string {
17+
if b.Height < height_2_0 { // not support arweave v1.0
18+
return b.IndepHash
19+
}
20+
21+
bds := generateBlockDataSegment(b)
22+
list := make([]interface{}, 0)
23+
list = append(list, Base64Encode(bds))
24+
list = append(list, b.Hash)
25+
list = append(list, b.Nonce)
26+
if b.Height >= height_2_4 {
27+
list = append(list, poaToList(b.Poa))
28+
}
29+
hash := DeepHash(list)
30+
return Base64Encode(hash[:])
31+
}
32+
33+
func generateBlockDataSegment(b types.Block) []byte {
34+
bdsBase := generateBlockDataSegmentBase(b)
35+
36+
list := make([]interface{}, 0)
37+
list = append(list, Base64Encode(bdsBase))
38+
list = append(list, Base64Encode([]byte(fmt.Sprintf("%d", b.Timestamp))))
39+
list = append(list, Base64Encode([]byte(fmt.Sprintf("%d", b.LastRetarget))))
40+
list = append(list, Base64Encode([]byte(fmt.Sprintf("%v", b.Diff))))
41+
list = append(list, Base64Encode([]byte(fmt.Sprintf("%v", b.CumulativeDiff))))
42+
list = append(list, Base64Encode([]byte(fmt.Sprintf("%v", b.RewardPool))))
43+
list = append(list, b.WalletList)
44+
list = append(list, b.HashListMerkle)
45+
hash := DeepHash(list)
46+
return hash[:]
47+
}
48+
49+
func generateBlockDataSegmentBase(b types.Block) []byte {
50+
props := make([]interface{}, 0)
51+
props = append(props, Base64Encode([]byte(fmt.Sprintf("%d", b.Height))))
52+
props = append(props, b.PreviousBlock)
53+
props = append(props, b.TxRoot)
54+
props = append(props, b.Txs)
55+
56+
props = append(props, Base64Encode([]byte(fmt.Sprintf("%v", b.BlockSize))))
57+
props = append(props, Base64Encode([]byte(fmt.Sprintf("%v", b.WeaveSize))))
58+
59+
if b.RewardAddr == "unclaimed" {
60+
props = append(props, Base64Encode([]byte("unclaimed")))
61+
} else {
62+
props = append(props, b.RewardAddr)
63+
}
64+
props = append(props, b.Tags)
65+
66+
endProps := make([]interface{}, 0)
67+
if b.Height >= height_2_4 {
68+
props2 := make([]interface{}, 0)
69+
if b.Height >= height_2_5 {
70+
RateDividend := b.UsdToArRate[0]
71+
RateDivisor := b.UsdToArRate[1]
72+
73+
ScheduledRateDividend := b.ScheduledUsdToArRate[0]
74+
ScheduledRateDivisor := b.ScheduledUsdToArRate[1]
75+
76+
props2 = append(props2, Base64Encode([]byte(fmt.Sprintf("%s", RateDividend))))
77+
props2 = append(props2, Base64Encode([]byte(fmt.Sprintf("%s", RateDivisor))))
78+
props2 = append(props2, Base64Encode([]byte(fmt.Sprintf("%s", ScheduledRateDividend))))
79+
props2 = append(props2, Base64Encode([]byte(fmt.Sprintf("%s", ScheduledRateDivisor))))
80+
81+
props2 = append(props2, Base64Encode([]byte(fmt.Sprintf("%s", b.Packing25Threshold))))
82+
props2 = append(props2, Base64Encode([]byte(fmt.Sprintf("%s", b.StrictDataSplitThreshold))))
83+
}
84+
endProps = append(props2, props...)
85+
} else {
86+
endProps = append(props, poaToList(b.Poa))
87+
}
88+
89+
hash := DeepHash(endProps)
90+
return hash[:]
91+
}
92+
93+
func poaToList(poa types.POA) []string {
94+
return []string{
95+
Base64Encode([]byte(poa.Option)),
96+
poa.TxPath,
97+
poa.DataPath,
98+
poa.Chunk,
99+
}
100+
}
101+
102+
func DecodeBlock(body string) (*types.Block, error) {
103+
b := &types.Block{}
104+
// json unmarshal exist number precision problem
105+
decoder := json.NewDecoder(strings.NewReader(body))
106+
decoder.UseNumber()
107+
err := decoder.Decode(b)
108+
if err != nil {
109+
return nil, err
110+
}
111+
formatBlockFields(b)
112+
return b, err
113+
}
114+
115+
func formatBlockFields(b *types.Block) {
116+
if _, ok := b.RewardPool.(string); !ok {
117+
by, _ := json.Marshal(b.RewardPool)
118+
b.RewardPool = string(by)
119+
}
120+
121+
if _, ok := b.WeaveSize.(string); !ok {
122+
by, _ := json.Marshal(b.WeaveSize)
123+
b.WeaveSize = string(by)
124+
}
125+
126+
if _, ok := b.BlockSize.(string); !ok {
127+
by, _ := json.Marshal(b.BlockSize)
128+
b.BlockSize = string(by)
129+
}
130+
}

‎utils/block_test.go

+412
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)