Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit fb84757

Browse files
Merge pull request #73 from ava-labs/activity-reward
Activity reward + Faster Genesis Handling
2 parents 7d87959 + 09b504b commit fb84757

File tree

10 files changed

+67
-17
lines changed

10 files changed

+67
-17
lines changed

chain/activity.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import (
99

1010
type Activity struct {
1111
Tmstmp int64 `serialize:"true" json:"timestamp"`
12-
Sender string `serialize:"true" json:"sender"`
1312
TxID ids.ID `serialize:"true" json:"txId"`
1413
Typ string `serialize:"true" json:"type"`
14+
Sender string `serialize:"true" json:"sender,omitempty"` // empty when reward
1515
Space string `serialize:"true" json:"space,omitempty"`
1616
Key string `serialize:"true" json:"key,omitempty"`
1717
To string `serialize:"true" json:"to,omitempty"` // common.Address will be 0x000 when not populated

chain/block.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ type StatelessBlock struct {
4040
t time.Time
4141
bytes []byte
4242

43+
Winners map[ids.ID]*Activity
44+
4345
vm VM
4446
children []*StatelessBlock
4547
onAcceptDB *versiondb.Database
@@ -90,6 +92,7 @@ func ParseStatefulBlock(
9092
bytes: source,
9193
st: status,
9294
vm: vm,
95+
Winners: map[ids.ID]*Activity{},
9396
}
9497
id, err := ids.ToID(crypto.Keccak256(b.bytes))
9598
if err != nil {
@@ -106,6 +109,7 @@ func ParseStatefulBlock(
106109
}
107110

108111
func (b *StatelessBlock) init() error {
112+
b.Winners = map[ids.ID]*Activity{}
109113
bytes, err := Marshal(b.StatefulBlock)
110114
if err != nil {
111115
return err

chain/builder.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func BuildBlock(vm VM, preferred ids.ID) (snowman.Block, error) {
4545
return nil, err
4646
}
4747

48+
b.Winners = map[ids.ID]*Activity{}
4849
b.Txs = []*Transaction{}
4950
units := uint64(0)
5051
for units < g.TargetUnits && mempool.Len() > 0 {

chain/decoder.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ const (
2121
Delete = "delete"
2222
Move = "move"
2323
Transfer = "transfer"
24+
25+
// Non-user created event
26+
Reward = "reward"
2427
)
2528

2629
type Input struct {

chain/genesis.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ package chain
66
import (
77
"encoding/json"
88
"fmt"
9+
"time"
910

1011
"github.com/ava-labs/avalanchego/database"
12+
"github.com/ava-labs/avalanchego/database/versiondb"
1113
"github.com/ava-labs/avalanchego/utils/units"
1214
"github.com/ethereum/go-ethereum/common"
1315
"github.com/ethereum/go-ethereum/crypto"
@@ -118,36 +120,44 @@ func (g *Genesis) Verify() error {
118120
return nil
119121
}
120122

121-
func (g *Genesis) Load(db database.KeyValueWriter, airdropData []byte) error {
123+
func (g *Genesis) Load(db database.Database, airdropData []byte) error {
124+
start := time.Now()
125+
defer func() {
126+
log.Debug("loaded genesis allocations", "t", time.Since(start))
127+
}()
128+
129+
vdb := versiondb.New(db)
122130
if len(g.AirdropHash) > 0 {
123131
h := common.BytesToHash(crypto.Keccak256(airdropData)).Hex()
124132
if g.AirdropHash != h {
125133
return fmt.Errorf("expected standard allocation %s but got %s", g.AirdropHash, h)
126134
}
127135

128-
standardAllocation := []*Airdrop{}
129-
if err := json.Unmarshal(airdropData, &standardAllocation); err != nil {
136+
airdrop := []*Airdrop{}
137+
if err := json.Unmarshal(airdropData, &airdrop); err != nil {
130138
return err
131139
}
132140

133-
for _, alloc := range standardAllocation {
134-
if err := SetBalance(db, alloc.Address, g.AirdropUnits); err != nil {
141+
for _, alloc := range airdrop {
142+
if err := SetBalance(vdb, alloc.Address, g.AirdropUnits); err != nil {
135143
return fmt.Errorf("%w: addr=%s, bal=%d", err, alloc.Address, g.AirdropUnits)
136144
}
137145
}
138146
log.Debug(
139147
"applied airdrop allocation",
140-
"hash", h, "addrs", len(standardAllocation), "balance", g.AirdropUnits,
148+
"hash", h, "addrs", len(airdrop), "balance", g.AirdropUnits,
141149
)
142150
}
143151

144152
// Do custom allocation last in case an address shows up in standard
145153
// allocation
146154
for _, alloc := range g.CustomAllocation {
147-
if err := SetBalance(db, alloc.Address, alloc.Balance); err != nil {
155+
if err := SetBalance(vdb, alloc.Address, alloc.Balance); err != nil {
148156
return fmt.Errorf("%w: addr=%s, bal=%d", err, alloc.Address, alloc.Balance)
149157
}
150158
log.Debug("applied custom allocation", "addr", alloc.Address, "balance", alloc.Balance)
151159
}
152-
return nil
160+
161+
// Commit as a batch to improve speed
162+
return vdb.Commit()
153163
}

chain/storage.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,9 @@ func ModifyBalance(db database.KeyValueReaderWriter, address common.Address, add
592592
return n, SetBalance(db, address, n)
593593
}
594594

595-
func ApplyReward(db database.Database, blkID ids.ID, txID ids.ID, sender common.Address, reward uint64) error {
595+
func ApplyReward(
596+
db database.Database, blkID ids.ID, txID ids.ID, sender common.Address, reward uint64,
597+
) (common.Address, bool, error) {
596598
seed := [64]byte{}
597599
copy(seed[:], blkID[:])
598600
copy(seed[32:], txID[:])
@@ -612,26 +614,26 @@ func ApplyReward(db database.Database, blkID ids.ID, txID ids.ID, sender common.
612614

613615
var i SpaceInfo
614616
if _, err := Unmarshal(cursor.Value(), &i); err != nil {
615-
return err
617+
return common.Address{}, false, err
616618
}
617619
space := string(curKey[2:])
618620

619621
// Do not give sender their funds back
620622
if bytes.Equal(i.Owner[:], sender[:]) {
621623
log.Debug("skipping reward: same owner", "space", space, "owner", i.Owner)
622-
return nil
624+
return common.Address{}, false, nil
623625
}
624626

625627
// Distribute reward
626628
if _, err := ModifyBalance(db, i.Owner, true, reward); err != nil {
627-
return err
629+
return common.Address{}, false, err
628630
}
629631

630632
log.Debug("rewarded space owner", "space", space, "owner", i.Owner, "amount", reward)
631-
return nil
633+
return i.Owner, true, nil
632634
}
633635

634636
// No reward applied
635637
log.Debug("skipping reward: no valid space")
636-
return nil
638+
return common.Address{}, false, nil
637639
}

chain/tx.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,20 @@ func (t *Transaction) Execute(g *Genesis, db database.Database, blk *StatelessBl
129129
return nil
130130
}
131131
rewardAmount := t.FeeUnits(g) * blk.Price * g.LotteryRewardMultipler / g.LotteryRewardDivisor
132-
return ApplyReward(db, blk.ID(), t.ID(), t.sender, rewardAmount)
132+
recipient, distributed, err := ApplyReward(db, blk.ID(), t.ID(), t.sender, rewardAmount)
133+
if err != nil {
134+
return err
135+
}
136+
if distributed {
137+
blk.Winners[t.ID()] = &Activity{
138+
Tmstmp: blk.Tmstmp,
139+
Typ: Reward,
140+
TxID: t.ID(),
141+
To: recipient.Hex(),
142+
Units: rewardAmount,
143+
}
144+
}
145+
return nil
133146
}
134147

135148
func (t *Transaction) Activity() *Activity {

scripts/run.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ EOF
8080

8181
echo "creating VM genesis file"
8282
rm -f /tmp/spacesvm.genesis
83-
/tmp/spaces-cli genesis 1 /tmp/allocations.json --genesis-file /tmp/spacesvm.genesis
83+
/tmp/spaces-cli genesis 1 /tmp/allocations.json \
84+
--genesis-file /tmp/spacesvm.genesis \
85+
--airdrop-hash 0xccbf8e430b30d08b5b3342208781c40b373d1b5885c1903828f367230a2568da \
86+
--airdrop-units 10000
8487

8588
echo "building runner"
8689
pushd ./tests/runner

tests/integration/integration_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,16 @@ var _ = ginkgo.Describe("[ClaimTx]", func() {
458458
}
459459
gomega.Ω(found).To(gomega.BeTrue())
460460
})
461+
462+
ginkgo.By("ensure all activity accounted for", func() {
463+
activity, err := instances[0].cli.RecentActivity()
464+
gomega.Ω(err).To(gomega.BeNil())
465+
466+
a0 := activity[0]
467+
gomega.Ω(a0.Typ).To(gomega.Equal("reward"))
468+
gomega.Ω(a0.To).To(gomega.Equal(sender.Hex()))
469+
gomega.Ω(len(a0.Sender)).To(gomega.Equal(0))
470+
})
461471
})
462472

463473
ginkgo.It("fail Gossip ClaimTx to a stale node when missing previous blocks", func() {

vm/chain_vm.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ func (vm *VM) Accepted(b *chain.StatelessBlock) {
5858
activity.Tmstmp = b.Tmstmp
5959
vm.activityCache[vm.activityCacheCursor%cs] = activity
6060
vm.activityCacheCursor++
61+
if reward, ok := b.Winners[tx.ID()]; ok {
62+
vm.activityCache[vm.activityCacheCursor%cs] = reward
63+
vm.activityCacheCursor++
64+
}
6165
}
6266
}
6367

0 commit comments

Comments
 (0)