Commit 48437bbb authored by Christopher Schinnerl's avatar Christopher Schinnerl

address Luke's comment

parent 8e067b43
Pipeline #46689967 passed with stages
in 44 minutes and 7 seconds
......@@ -201,7 +201,7 @@ func SignTransaction(txn *types.Transaction, seed modules.Seed, toSign []crypto.
var keyIndex uint64
const keysPerBatch = 1000
for len(keys) < 1e6 {
for _, sk := range generateKeys(seed, keyIndex, keyIndex+keysPerBatch, false) {
for _, sk := range generateKeys(seed, keyIndex, keyIndex+keysPerBatch) {
keys[sk.UnlockConditions.UnlockHash()] = sk
}
keyIndex += keysPerBatch
......
......@@ -71,7 +71,7 @@ func (s *seedScanner) numKeys() uint64 {
// generateKeys generates n additional keys from the seedScanner's seed.
func (s *seedScanner) generateKeys(n uint64) {
initialProgress := s.numKeys()
for i, k := range generateKeys(s.seed, initialProgress, n, false) {
for i, k := range generateKeys(s.seed, initialProgress, n) {
s.keys[k.UnlockConditions.UnlockHash()] = initialProgress + uint64(i)
}
}
......
......@@ -44,15 +44,8 @@ func generateSpendableKey(seed modules.Seed, index uint64) spendableKey {
}
}
// generateKeys generates n keys from seed, starting from index start. If
// reverse is set to true, it will start with index start and move towards
// index 0. If n is too big and would result in a negative index, it will
// return fewer than n spendable keys without throwing an error.
func generateKeys(seed modules.Seed, start, n uint64, reverse bool) []spendableKey {
// Make sure that we don't generate below index 0.
if reverse && n > start+1 {
n = start + 1
}
// generateKeys generates n keys from seed, starting from index start.
func generateKeys(seed modules.Seed, start, n uint64) []spendableKey {
// generate in parallel, one goroutine per core.
keys := make([]spendableKey, n)
var wg sync.WaitGroup
......@@ -60,17 +53,11 @@ func generateKeys(seed modules.Seed, start, n uint64, reverse bool) []spendableK
for cpu := 0; cpu < runtime.NumCPU(); cpu++ {
go func(offset uint64) {
defer wg.Done()
var index uint64
for i := offset; i < n; i += uint64(runtime.NumCPU()) {
// NOTE: don't bother trying to optimize generateSpendableKey;
// profiling shows that ed25519 key generation consumes far
// more CPU time than encoding or hashing.
if reverse {
index = start - i
} else {
index = start + i
}
keys[i] = generateSpendableKey(seed, index)
keys[i] = generateSpendableKey(seed, start+i)
}
}(uint64(cpu))
}
......@@ -112,7 +99,7 @@ func (w *Wallet) regenerateLookahead(start uint64) {
maxKeys := maxLookahead(start)
existingKeys := uint64(len(w.lookahead))
for i, k := range generateKeys(w.primarySeed, start+existingKeys, maxKeys-existingKeys, false) {
for i, k := range generateKeys(w.primarySeed, start+existingKeys, maxKeys-existingKeys) {
w.lookahead[k.UnlockConditions.UnlockHash()] = start + existingKeys + uint64(i)
}
}
......@@ -120,7 +107,7 @@ func (w *Wallet) regenerateLookahead(start uint64) {
// integrateSeed generates n spendableKeys from the seed and loads them into
// the wallet.
func (w *Wallet) integrateSeed(seed modules.Seed, n uint64) {
for _, sk := range generateKeys(seed, 0, n, false) {
for _, sk := range generateKeys(seed, 0, n) {
w.keys[sk.UnlockConditions.UnlockHash()] = sk
}
}
......@@ -143,7 +130,7 @@ func (w *Wallet) nextPrimarySeedAddresses(tx *bolt.Tx, n uint64) ([]types.Unlock
// Integrate the next keys into the wallet, and return the unlock
// conditions. Also remove new keys from the future keys and update them
// according to new progress
spendableKeys := generateKeys(w.primarySeed, progress, n, false)
spendableKeys := generateKeys(w.primarySeed, progress, n)
ucs := make([]types.UnlockConditions, 0, len(spendableKeys))
for _, spendableKey := range spendableKeys {
w.keys[spendableKey.UnlockConditions.UnlockHash()] = spendableKey
......
......@@ -3,7 +3,6 @@ package wallet
import (
"bytes"
"path/filepath"
"reflect"
"testing"
"gitlab.com/NebulousLabs/Sia/build"
......@@ -511,23 +510,9 @@ func TestSweepSeedCoinsAndFunds(t *testing.T) {
// TestGenerateKeys tests that the generateKeys function correctly generates a
// key for every index specified.
func TestGenerateKeys(t *testing.T) {
keys := generateKeys(modules.Seed{}, 1000, 4000, false)
keysReverse := generateKeys(modules.Seed{}, 4999, 4000, true)
for i, k := range keys {
for i, k := range generateKeys(modules.Seed{}, 1000, 4000) {
if len(k.UnlockConditions.PublicKeys) == 0 {
t.Errorf("index %v was skipped", i)
}
if !reflect.DeepEqual(keys[i], keysReverse[len(keysReverse)-i-1]) {
t.Fatal("keys are not equal")
}
}
// This should only return 1 key. The one at index 0.
keys = generateKeys(modules.Seed{}, 0, 2, true)
if len(keys) != 1 {
t.Fatalf("should've returned 1 key but was %v", len(keys))
}
expectedKey := generateKeys(modules.Seed{}, 0, 1, false)[0]
if keys[0].UnlockConditions.UnlockHash() != expectedKey.UnlockConditions.UnlockHash() {
t.Fatalf("key should be the one generated at index 0")
}
}
......@@ -46,7 +46,7 @@ func (w *Wallet) advanceSeedLookahead(index uint64) (bool, error) {
newProgress := index + 1
// Add spendable keys and remove them from lookahead
spendableKeys := generateKeys(w.primarySeed, progress, newProgress-progress, false)
spendableKeys := generateKeys(w.primarySeed, progress, newProgress-progress)
for _, key := range spendableKeys {
w.keys[key.UnlockConditions.UnlockHash()] = key
delete(w.lookahead, key.UnlockConditions.UnlockHash())
......
......@@ -157,11 +157,16 @@ func (w *Wallet) LastAddresses(n uint64) ([]types.UnlockHash, error) {
if err != nil {
return []types.UnlockHash{}, err
}
// At most seedProgess addresses can be requested.
if n > seedProgress {
n = seedProgress
}
start := seedProgress - n
// Generate the keys.
keys := generateKeys(w.primarySeed, seedProgress-1, n, true)
uhs := make([]types.UnlockHash, len(keys))
for i := range keys {
uhs[i] = keys[i].UnlockConditions.UnlockHash()
keys := generateKeys(w.primarySeed, start, n)
uhs := make([]types.UnlockHash, 0, len(keys))
for i := len(keys) - 1; i >= 0; i-- {
uhs = append(uhs, keys[i].UnlockConditions.UnlockHash())
}
return uhs, nil
}
......
......@@ -376,7 +376,7 @@ func TestAdvanceLookaheadNoRescan(t *testing.T) {
// choose 10 keys in the lookahead and remember them
var receivingAddresses []types.UnlockHash
for _, sk := range generateKeys(wt.wallet.primarySeed, progress, 10, false) {
for _, sk := range generateKeys(wt.wallet.primarySeed, progress, 10) {
sco := types.SiacoinOutput{
UnlockHash: sk.UnlockConditions.UnlockHash(),
Value: types.NewCurrency64(1e3),
......
......@@ -532,6 +532,10 @@ func TestWalletLastAddresses(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if len(addresses) != len(wlag.Addresses) {
t.Fatalf("Expected %v addresses but got %v",
len(addresses), len(wlag.Addresses))
}
// Make sure the returned addresses are the same and have the reversed
// order of the created ones.
for i := range wag.Addresses {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment