This repository has been archived by the owner on May 13, 2022. It is now read-only.
/
mock.go
129 lines (112 loc) · 2.99 KB
/
mock.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
package dump
import (
bin "encoding/binary"
"fmt"
"io"
"math/rand"
"github.com/hyperledger/burrow/acm"
"github.com/hyperledger/burrow/binary"
"github.com/hyperledger/burrow/crypto"
"github.com/hyperledger/burrow/execution/exec"
"github.com/hyperledger/burrow/execution/names"
"github.com/hyperledger/burrow/genesis"
)
type MockSource struct {
Accounts int
MaxStorage int
Names int
Events int
*Mockchain
rand *rand.Rand
}
var _ Source = &MockSource{}
func NewMockSource(accounts, maxStorage, names, events int) *MockSource {
return &MockSource{
Accounts: accounts,
MaxStorage: maxStorage,
Names: names,
Events: events,
Mockchain: NewMockchain("Mockchain", 0),
rand: rand.New(rand.NewSource(2323524)),
}
}
func (m *MockSource) Recv() (*Dump, error) {
row := Dump{Height: m.LastBlockHeight()}
// In order to create the same state as from a real dump we need to honour the dump order:
// [accounts[storage...]...][names...][events...]
if m.Accounts > 0 {
var addr crypto.Address
bin.BigEndian.PutUint64(addr[:], uint64(m.Accounts))
row.Account = &acm.Account{
Address: addr,
Balance: m.rand.Uint64(),
}
if m.Accounts%2 > 0 {
row.Account.EVMCode = make([]byte, m.rand.Intn(10000))
m.rand.Read(row.Account.EVMCode)
}
m.Accounts--
if m.MaxStorage > 0 {
// We don't send empty storage
storagelen := 1 + m.rand.Intn(m.MaxStorage)
row.AccountStorage = &AccountStorage{
Address: addr,
Storage: make([]*Storage, storagelen),
}
for i := 0; i < storagelen; i++ {
var key binary.Word256
// Put account index in first 8 bytes
copy(key[:8], addr[:8])
// Put storage index in last 8 bytes
bin.BigEndian.PutUint64(key[24:], uint64(i))
row.AccountStorage.Storage[i] = &Storage{Key: key, Value: key[:]}
}
}
} else if m.Accounts == 0 {
// Finally send the global permissions account (makes for easier equality checks with genesis state dump)
row.Account = genesis.DefaultPermissionsAccount
m.Accounts--
} else if m.Names > 0 {
row.Name = &names.Entry{
Name: fmt.Sprintf("name%d", m.Names),
Data: fmt.Sprintf("data%x", m.Names),
Owner: crypto.ZeroAddress,
Expires: 1337,
}
m.Names--
} else if m.Events > 0 {
datalen := 1 + m.rand.Intn(10)
data := make([]byte, datalen*32)
topiclen := 1 + m.rand.Intn(5)
topics := make([]binary.Word256, topiclen)
row.EVMEvent = &EVMEvent{
ChainID: m.ChainID(),
Event: &exec.LogEvent{
Address: crypto.ZeroAddress,
Data: data,
Topics: topics,
},
}
m.Events--
} else {
return nil, io.EOF
}
return &row, nil
}
type Mockchain struct {
chainID string
lastBlockHeight uint64
}
var _ Blockchain = &Mockchain{}
func NewMockchain(chainID string, lastBlockHeight uint64) *Mockchain {
return &Mockchain{
chainID: chainID,
lastBlockHeight: lastBlockHeight,
}
}
func (mc *Mockchain) ChainID() string {
return mc.chainID
}
func (mc *Mockchain) LastBlockHeight() uint64 {
return mc.lastBlockHeight
}