Skip to content

Commit 1524dda

Browse files
authored
Merge pull request #99 from onflow/janezp/localnet-test-fixes
Review fixes for localnet integration test
2 parents d52ba1b + 5c4e4da commit 1524dda

5 files changed

Lines changed: 57 additions & 49 deletions

File tree

Makefile

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ go-build:
1919
go-test:
2020
go test -v github.com/onflow/rosetta/state/...
2121
go test -v github.com/onflow/rosetta/script/...
22+
# Compile (but don't run) the build-tagged localnet test so it can't rot.
23+
go test -tags localnet -run '^$$' github.com/onflow/rosetta/localnettest/...
2224

2325
# End-to-end localnet compatibility test (script/README.md). Requires a flow-go
2426
# localnet up at 127.0.0.1:4001, the flow CLI, jq, and python3 with click +
@@ -39,16 +41,9 @@ gen-originator-account:
3941
echo "Private Key: $$PRIVATE_KEY"; \
4042
address=$$(flow accounts create --sig-algo ECDSA_secp256k1 --key $$PUBLIC_FLOW_KEY $(FLOW_CLI_FLAGS) | grep "Address" | cut -d' ' -f2 | cut -c3-);\
4143
echo "Address created: $$address"; \
42-
jq --arg account_name "$(ACCOUNT_NAME)" '.accounts[$$account_name] = { \
43-
"address": "'$$address'", \
44-
"key": { \
45-
"type": "hex", \
46-
"index": 0, \
47-
"signatureAlgorithm": "ECDSA_secp256k1", \
48-
"hashAlgorithm": "SHA3_256", \
49-
"privateKey": "'$$PRIVATE_KEY'" \
50-
} \
51-
}' "${FLOW_JSON}" > flow.json.tmp && mv flow.json.tmp "${FLOW_JSON}" || { echo "Failed to update ${FLOW_JSON} with jq"; exit 1; }; \
44+
jq --arg account_name "$(ACCOUNT_NAME)" --arg address "$$address" --arg private_key "$$PRIVATE_KEY" \
45+
'.accounts[$$account_name] = {address: $$address, key: {type: "hex", index: 0, signatureAlgorithm: "ECDSA_secp256k1", hashAlgorithm: "SHA3_256", privateKey: $$private_key}}' \
46+
"${FLOW_JSON}" > flow.json.tmp && mv flow.json.tmp "${FLOW_JSON}" || { echo "Failed to update ${FLOW_JSON} with jq"; exit 1; }; \
5247
jq --arg address "$$address" '.originators += [$$address]' "${ROSETTA_ENV}.json" > env.json.tmp && mv env.json.tmp "${ROSETTA_ENV}.json"; \
5348
echo "$(ACCOUNT_NAME),$$KEYS,0x$$address" >> $(ACCOUNT_KEYS_FILENAME); \
5449
echo "Updated $(FLOW_JSON), $(ROSETTA_ENV).json and $(ACCOUNT_KEYS_FILENAME)";
@@ -88,7 +83,7 @@ rosetta-transfer-funds:
8883
echo "Payer address: $$PAYER_ADDRESS"; \
8984
RECIPIENT_ADDRESS=$$(grep '$(RECIPIENT_NAME)' $(ACCOUNT_KEYS_FILENAME) | cut -d ',' -f5); \
9085
echo "Recipient address: $$RECIPIENT_ADDRESS"; \
91-
TX_HASH=$$(python3 rosetta_handler.py rosetta-transfer-funds $(ROSETTA_HOST_URL) $$PAYER_ADDRESS $$PAYER_PUBLIC_KEY $$PAYER_PRIVATE_KEY $$RECIPIENT_ADDRESS $$AMOUNT); \
86+
TX_HASH=$$(python3 rosetta_handler.py rosetta-transfer-funds $(ROSETTA_HOST_URL) $$PAYER_ADDRESS $$PAYER_PUBLIC_KEY $$PAYER_PRIVATE_KEY $$RECIPIENT_ADDRESS $$AMOUNT) && \
9287
echo "Funding sent: $$TX_HASH";
9388

9489
# Use this target to verify that the accounts configured in the Rosetta environment JSON have the specified contracts deployed

indexdb/indexdb.go

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ var (
2525
ErrBlockNotIndexed = errors.New("indexdb: block not indexed")
2626
)
2727

28-
var (
29-
accountPrefix = []byte("a")
30-
blockPrefix = []byte("b")
31-
hash2HeightPrefix = []byte("c")
32-
height2HashPrefix = []byte("d")
33-
isProxyPrefix = []byte("p")
28+
const (
29+
accountPrefix byte = 'a'
30+
blockPrefix byte = 'b'
31+
hash2HeightPrefix byte = 'c'
32+
height2HashPrefix byte = 'd'
33+
isProxyPrefix byte = 'p'
3434
)
3535

3636
// NOTE(tav): We store the blockchain data within Badger using the following
@@ -88,9 +88,10 @@ func (s *Store) Accounts() (map[[8]byte]bool, error) {
8888
err := s.db.View(func(txn *badger.Txn) error {
8989
it := txn.NewIterator(badger.IteratorOptions{})
9090
defer it.Close()
91-
it.Seek(accountPrefix)
91+
prefix := []byte{accountPrefix}
92+
it.Seek(prefix)
9293
for {
93-
if !it.ValidForPrefix(accountPrefix) {
94+
if !it.ValidForPrefix(prefix) {
9495
break
9596
}
9697
key := it.Item().Key()
@@ -101,9 +102,10 @@ func (s *Store) Accounts() (map[[8]byte]bool, error) {
101102
}
102103
it = txn.NewIterator(badger.IteratorOptions{})
103104
defer it.Close()
104-
it.Seek(isProxyPrefix)
105+
prefix = []byte{isProxyPrefix}
106+
it.Seek(prefix)
105107
for {
106-
if !it.ValidForPrefix(isProxyPrefix) {
108+
if !it.ValidForPrefix(prefix) {
107109
break
108110
}
109111
key := it.Item().Key()
@@ -133,9 +135,10 @@ func (s *Store) AccountsInfo() (map[string]*AccountInfo, error) {
133135
err := s.db.View(func(txn *badger.Txn) error {
134136
it := txn.NewIterator(badger.IteratorOptions{})
135137
defer it.Close()
136-
it.Seek(accountPrefix)
138+
prefix := []byte{accountPrefix}
139+
it.Seek(prefix)
137140
for {
138-
if !it.ValidForPrefix(accountPrefix) {
141+
if !it.ValidForPrefix(prefix) {
139142
break
140143
}
141144
item := it.Item()
@@ -168,9 +171,10 @@ func (s *Store) AccountsInfo() (map[string]*AccountInfo, error) {
168171
err = s.db.View(func(txn *badger.Txn) error {
169172
it := txn.NewIterator(badger.IteratorOptions{})
170173
defer it.Close()
171-
it.Seek(isProxyPrefix)
174+
prefix := []byte{isProxyPrefix}
175+
it.Seek(prefix)
172176
for {
173-
if !it.ValidForPrefix(isProxyPrefix) {
177+
if !it.ValidForPrefix(prefix) {
174178
break
175179
}
176180
key := it.Item().Key()
@@ -312,7 +316,7 @@ func (s *Store) Genesis() *model.BlockMeta {
312316
// given height.
313317
func (s *Store) HasBalance(acct []byte, height uint64) (bool, error) {
314318
key := make([]byte, 1+8+8)
315-
key[0] = 'a' // accountPrefix
319+
key[0] = accountPrefix
316320
copy(key[1:9], acct)
317321
binary.BigEndian.PutUint64(key[9:], height)
318322
ok := false
@@ -341,7 +345,7 @@ func (s *Store) HashForHeight(height uint64) ([]byte, error) {
341345
var hash []byte
342346
heightEnc := make([]byte, 8)
343347
binary.BigEndian.PutUint64(heightEnc, height)
344-
key := append(height2HashPrefix, heightEnc...)
348+
key := append([]byte{height2HashPrefix}, heightEnc...)
345349
err := s.db.View(func(txn *badger.Txn) error {
346350
item, err := txn.Get(key)
347351
if err != nil {
@@ -367,7 +371,7 @@ func (s *Store) HashForHeight(height uint64) ([]byte, error) {
367371
// HeightForHash returns the block height for the given hash.
368372
func (s *Store) HeightForHash(hash []byte) (uint64, error) {
369373
height := uint64(0)
370-
key := append(hash2HeightPrefix, hash...)
374+
key := append([]byte{hash2HeightPrefix}, hash...)
371375
err := s.db.View(func(txn *badger.Txn) error {
372376
item, err := txn.Get(key)
373377
if err != nil {
@@ -427,7 +431,7 @@ func (s *Store) Index(ctx context.Context, height uint64, hash []byte, block *mo
427431
}
428432
if len(op.ProxyPublicKey) > 0 {
429433
key := make([]byte, 17)
430-
key[0] = 'p' // isProxyPrefix
434+
key[0] = isProxyPrefix
431435
copy(key[1:], op.Account)
432436
binary.BigEndian.PutUint64(key[9:], height)
433437
proxyAccts = append(proxyAccts, key)
@@ -444,7 +448,7 @@ func (s *Store) Index(ctx context.Context, height uint64, hash []byte, block *mo
444448
updates := make([]accountUpdate, len(accts))
445449
for acct, diff := range accts {
446450
key := make([]byte, 1+8+8)
447-
key[0] = 'a' // accountPrefix
451+
key[0] = accountPrefix
448452
copy(key[1:], acct)
449453
copy(key[9:], hval)
450454
updates[i] = accountUpdate{
@@ -453,13 +457,13 @@ func (s *Store) Index(ctx context.Context, height uint64, hash []byte, block *mo
453457
}
454458
i++
455459
}
456-
blockKey := append(blockPrefix, hval...)
460+
blockKey := append([]byte{blockPrefix}, hval...)
457461
blockValue, err := proto.Marshal(block)
458462
if err != nil {
459463
log.Fatalf("Failed to encode model.IndexedBlock: %s", err)
460464
}
461-
hash2heightKey := append(hash2HeightPrefix, hash...)
462-
height2hashKey := append(height2HashPrefix, hval...)
465+
hash2heightKey := append([]byte{hash2HeightPrefix}, hash...)
466+
height2hashKey := append([]byte{height2HashPrefix}, hval...)
463467
latest = &model.BlockMeta{
464468
Hash: hash,
465469
Height: height,
@@ -580,9 +584,10 @@ func (s *Store) PurgeProxyAccounts() {
580584
err := s.db.View(func(txn *badger.Txn) error {
581585
it := txn.NewIterator(badger.IteratorOptions{})
582586
defer it.Close()
583-
it.Seek(isProxyPrefix)
587+
prefix := []byte{isProxyPrefix}
588+
it.Seek(prefix)
584589
for {
585-
if !it.ValidForPrefix(isProxyPrefix) {
590+
if !it.ValidForPrefix(prefix) {
586591
break
587592
}
588593
key := it.Item().KeyCopy(nil)
@@ -598,7 +603,7 @@ func (s *Store) PurgeProxyAccounts() {
598603
err = s.db.View(func(txn *badger.Txn) error {
599604
it := txn.NewIterator(badger.IteratorOptions{})
600605
defer it.Close()
601-
prefix := accountPrefix
606+
prefix := []byte{accountPrefix}
602607
it.Seek(prefix)
603608
for {
604609
if !it.ValidForPrefix(prefix) {
@@ -643,7 +648,7 @@ func (s *Store) ResetTo(base uint64) error {
643648
delKeys := [][]byte{}
644649
err := s.db.View(func(txn *badger.Txn) error {
645650
it := txn.NewIterator(badger.IteratorOptions{})
646-
prefix := accountPrefix
651+
prefix := []byte{accountPrefix}
647652
it.Seek(prefix)
648653
for {
649654
if !it.ValidForPrefix(prefix) {
@@ -665,7 +670,7 @@ func (s *Store) ResetTo(base uint64) error {
665670
}
666671
err = s.db.View(func(txn *badger.Txn) error {
667672
it := txn.NewIterator(badger.IteratorOptions{})
668-
prefix := isProxyPrefix
673+
prefix := []byte{isProxyPrefix}
669674
it.Seek(prefix)
670675
for {
671676
if !it.ValidForPrefix(prefix) {
@@ -688,7 +693,7 @@ func (s *Store) ResetTo(base uint64) error {
688693
last := uint64(0)
689694
err = s.db.View(func(txn *badger.Txn) error {
690695
it := txn.NewIterator(badger.IteratorOptions{})
691-
prefix := height2HashPrefix
696+
prefix := []byte{height2HashPrefix}
692697
it.Seek(prefix)
693698
for {
694699
if !it.ValidForPrefix(prefix) {
@@ -701,7 +706,7 @@ func (s *Store) ResetTo(base uint64) error {
701706
height2HashKey := item.KeyCopy(nil)
702707
delKeys = append(delKeys, height2HashKey)
703708
blockKey := make([]byte, 9)
704-
blockKey[0] = 'b' // blockPrefix
709+
blockKey[0] = blockPrefix
705710
binary.BigEndian.PutUint64(blockKey[1:], height)
706711
delKeys = append(delKeys, blockKey)
707712
hash, err := item.ValueCopy(nil)
@@ -710,7 +715,7 @@ func (s *Store) ResetTo(base uint64) error {
710715
return err
711716
}
712717
hash2HeightKey := make([]byte, len(hash)+1)
713-
hash2HeightKey[0] = 'c' // hash2HeightPrefix
718+
hash2HeightKey[0] = hash2HeightPrefix
714719
copy(hash2HeightKey[1:], hash)
715720
delKeys = append(delKeys, hash2HeightKey)
716721
} else {
@@ -778,15 +783,15 @@ func (s *Store) SetGenesis(val *model.BlockMeta) error {
778783
}
779784
hval := make([]byte, 8)
780785
binary.BigEndian.PutUint64(hval, val.Height)
781-
blockKey := append(blockPrefix, hval...)
786+
blockKey := append([]byte{blockPrefix}, hval...)
782787
blockValue, err := proto.Marshal(&model.IndexedBlock{
783788
Timestamp: val.Timestamp,
784789
})
785790
if err != nil {
786791
log.Fatalf("Failed to encode model.IndexedBlock: %s", err)
787792
}
788-
hash2heightKey := append(hash2HeightPrefix, val.Hash...)
789-
height2hashKey := append(height2HashPrefix, hval...)
793+
hash2heightKey := append([]byte{hash2HeightPrefix}, val.Hash...)
794+
height2hashKey := append([]byte{height2HashPrefix}, hval...)
790795
err = s.db.Update(func(txn *badger.Txn) error {
791796
if err := txn.Set([]byte("genesis"), genesis); err != nil {
792797
return err
@@ -815,7 +820,7 @@ func (s *Store) SetGenesis(val *model.BlockMeta) error {
815820
func (s *Store) balanceByHeight(acct []byte, height uint64) (uint64, error) {
816821
balance := uint64(0)
817822
key := make([]byte, 1+8+8)
818-
key[0] = 'a'
823+
key[0] = accountPrefix
819824
copy(key[1:9], acct)
820825
binary.BigEndian.PutUint64(key[9:], height)
821826
err := s.db.View(func(txn *badger.Txn) error {
@@ -844,7 +849,7 @@ func (s *Store) balanceByHeight(acct []byte, height uint64) (uint64, error) {
844849
func (s *Store) blockByHeight(height uint64) (*model.IndexedBlock, error) {
845850
block := &model.IndexedBlock{}
846851
key := make([]byte, 9)
847-
key[0] = 'b'
852+
key[0] = blockPrefix
848853
binary.BigEndian.PutUint64(key[1:], height)
849854
err := s.db.View(func(txn *badger.Txn) error {
850855
item, err := txn.Get(key)

localnettest/localnet_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const (
3434
originatorName = "root-originator-1"
3535
derivedName = "derived-account-1"
3636
transferAmount = "50"
37+
// transferAmountUnits is transferAmount in Rosetta's smallest FLOW unit
38+
// (8 decimals).
39+
transferAmountUnits = 50 * 100_000_000
3740
)
3841

3942
// indexerFatalErrors are server log lines meaning the indexer is wedged and will
@@ -103,6 +106,9 @@ func TestLocalnetCompat(t *testing.T) {
103106

104107
t.Log("waiting for the transfer to be indexed (recipient balance increases)")
105108
after := waitForBalance(t, srv, base, cfg.Network, recipient, func(v uint64) bool { return v > before }, 3*time.Minute)
109+
if after-before != transferAmountUnits {
110+
t.Fatalf("recipient balance rose by %d, want exactly %d", after-before, uint64(transferAmountUnits))
111+
}
106112
t.Logf("recipient balance %d -> %d: Rosetta indexed the transfer — compatibility confirmed", before, after)
107113
}
108114

rosetta_handler.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,12 @@ def rosetta_create_derived_account(rosetta_host_url, root_originator_address, ro
151151
def rosetta_transfer_funds(rosetta_host_url, payer_address, payer_public_key,
152152
payer_private_key, recipient_address, amount, i=0):
153153
transaction = "transfer"
154+
# FLOW amounts use 8 decimals (UFix64), matching the "decimals": 8 currency
155+
# declared in the operations below.
154156
amount = float(amount)
155-
amount_sent = str(-1 * int(amount * 10 ** 7))
156-
amount_received = str(int(amount * 10 ** 7))
157+
smallest_unit = int(round(amount * 10 ** 8))
158+
amount_sent = str(-smallest_unit)
159+
amount_received = str(smallest_unit)
157160
operations = [
158161
{
159162
"type": transaction,

state/convert_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ func TestDeriveEventsHash(t *testing.T) {
160160
spork := Mainnet28_SporkVersion8.create(ctx)
161161
VerifyEventsHashForSpork(t, ctx, spork, 150_000_001, 150_000_011)
162162
})
163-
164163
}
165164

166165
func VerifyEventsHashForSpork(t *testing.T, ctx context.Context, spork *config.Spork, startHeight uint64, endHeight uint64) {

0 commit comments

Comments
 (0)