Improved the identity hash generation tool. The fastest quantity of goroutines is now identified and used.
This commit is contained in:
parent
35cda50ad7
commit
497f596b3b
4 changed files with 129 additions and 97 deletions
|
@ -6,6 +6,7 @@ Small and insignificant changes may not be included in this log.
|
||||||
|
|
||||||
## Unversioned Changes
|
## Unversioned Changes
|
||||||
|
|
||||||
|
* Improved the identity hash generation tool. The fastest quantity of goroutines is now identified and used. - *Simon Sarasova*
|
||||||
* Improved the creation procedures, encoding format, and graphical presentation of genetic analyses. Map lists have been replaced by custom objects. - *Simon Sarasova*
|
* Improved the creation procedures, encoding format, and graphical presentation of genetic analyses. Map lists have been replaced by custom objects. - *Simon Sarasova*
|
||||||
* Upgraded Circl to version 1.3.8. - *Simon Sarasova*
|
* Upgraded Circl to version 1.3.8. - *Simon Sarasova*
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,4 @@ Many other people have written code for modules which are imported by Seekia. Th
|
||||||
|
|
||||||
Name | Date Of First Commit | Number Of Commits
|
Name | Date Of First Commit | Number Of Commits
|
||||||
--- | --- | ---
|
--- | --- | ---
|
||||||
Simon Sarasova | June 13, 2023 | 248
|
Simon Sarasova | June 13, 2023 | 249
|
|
@ -26,6 +26,7 @@ import "math"
|
||||||
import "time"
|
import "time"
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
|
|
||||||
func setChooseNewIdentityHashPage(window fyne.Window, myIdentityType string, previousPage func(), onceCompletePage func()){
|
func setChooseNewIdentityHashPage(window fyne.Window, myIdentityType string, previousPage func(), onceCompletePage func()){
|
||||||
|
|
||||||
currentPage := func(){ setChooseNewIdentityHashPage(window, myIdentityType, previousPage, onceCompletePage) }
|
currentPage := func(){ setChooseNewIdentityHashPage(window, myIdentityType, previousPage, onceCompletePage) }
|
||||||
|
@ -59,7 +60,7 @@ func setChooseNewIdentityHashPage(window fyne.Window, myIdentityType string, pre
|
||||||
}
|
}
|
||||||
|
|
||||||
createCustomIdentityHashButton := getWidgetCentered(widget.NewButtonWithIcon("Create Custom", theme.SearchReplaceIcon(), func(){
|
createCustomIdentityHashButton := getWidgetCentered(widget.NewButtonWithIcon("Create Custom", theme.SearchReplaceIcon(), func(){
|
||||||
setCreateCustomIdentityHashPage(window, myIdentityType, currentPage, submitPageFunction)
|
setCreateCustomIdentityHashPage(window, myIdentityType, false, 0, 0, currentPage, submitPageFunction)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
selectRandomIdentityHashLabel := getLabelCentered("Select a random identity hash:")
|
selectRandomIdentityHashLabel := getLabelCentered("Select a random identity hash:")
|
||||||
|
@ -253,114 +254,145 @@ func setEnterMyNewSeedPhrasePage(window fyne.Window, myIdentityType string, newS
|
||||||
setPageContent(page, window)
|
setPageContent(page, window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Inputs:
|
||||||
|
// -fyne.Window
|
||||||
|
// -string: Identity Type ("Mate"/"Host"/"Moderator")
|
||||||
|
// -bool: Benchmark is done (is false if we need to perform the benchmark
|
||||||
|
// -int64: Hashes per second (is 0 if benchmark hasn't been performed)
|
||||||
|
// -int: Optimal number of goroutines
|
||||||
|
// -previousPage()
|
||||||
|
// func(string, func()): submitPage function = func(newSeedPhrase string, previousPage func())
|
||||||
|
func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, benchmarkIsDone bool, computerHashesPerSecond int64, optimalNumberOfGoroutines int, previousPage func(), submitPage func(string, func()) ){
|
||||||
|
|
||||||
// submitPage function = func(newSeedPhrase string, previousPage func())
|
if (benchmarkIsDone == false){
|
||||||
|
setLoadingScreen(window, "Create Custom Identity Hash", "Performing benchmark, this will take 4 seconds...")
|
||||||
|
|
||||||
func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, previousPage func(), submitPage func(string, func()) ){
|
// Output:
|
||||||
|
// -int64: Hashes per second
|
||||||
|
// -int: Optimal number of goroutines
|
||||||
|
// -error
|
||||||
|
performBenchmark := func()(int64, int, error){
|
||||||
|
|
||||||
setLoadingScreen(window, "Create Custom Identity Hash", "Loading...")
|
//TODO: Fix to retrieve language from settings
|
||||||
|
currentLanguage := "English"
|
||||||
|
currentLanguageWordList, err := wordLists.GetWordListFromLanguage(currentLanguage)
|
||||||
|
if (err != nil) { return 0, 0, err }
|
||||||
|
|
||||||
currentPage := func(){ setCreateCustomIdentityHashPage(window, identityType, previousPage, submitPage) }
|
optimalNumberOfGoroutines := 0
|
||||||
|
optimalNumberOfGoroutinesHashesPerSecond := int64(0)
|
||||||
|
|
||||||
// Output:
|
// We will try 1-8 goroutines to see which is the fastest
|
||||||
// -int64: Hashes per second
|
|
||||||
// -error
|
|
||||||
getIdentityHashGenerationSpeed := func()(int64, error){
|
|
||||||
|
|
||||||
//TODO: Fix to retrieve language from settings
|
for numberOfGoroutines:=1; numberOfGoroutines<=8; numberOfGoroutines++{
|
||||||
currentLanguage := "English"
|
|
||||||
currentLanguageWordList, err := wordLists.GetWordListFromLanguage(currentLanguage)
|
|
||||||
if (err != nil) { return 0, err }
|
|
||||||
|
|
||||||
// This counter will store the number of hashes we can compute in 1 second
|
// This counter will store the number of hashes we can compute in 1 second
|
||||||
var counterMutex sync.Mutex
|
var counterMutex sync.Mutex
|
||||||
counter := int64(0)
|
counter := int64(0)
|
||||||
|
|
||||||
// This bool keeps track of if the identity hash benchmark is happening
|
// This bool keeps track of if the identity hash benchmark is happening
|
||||||
var generateHashesStatusBoolMutex sync.RWMutex
|
var generateHashesStatusBoolMutex sync.RWMutex
|
||||||
generateHashesStatusBool := false
|
generateHashesStatusBool := false
|
||||||
|
|
||||||
var errorEncounteredMutex sync.Mutex
|
var errorEncounteredMutex sync.Mutex
|
||||||
var errorEncountered error
|
var errorEncountered error
|
||||||
|
|
||||||
setErrorEncounteredFunction := func(inputError error){
|
setErrorEncounteredFunction := func(inputError error){
|
||||||
|
|
||||||
errorEncounteredMutex.Lock()
|
errorEncounteredMutex.Lock()
|
||||||
errorEncountered = inputError
|
errorEncountered = inputError
|
||||||
errorEncounteredMutex.Unlock()
|
errorEncounteredMutex.Unlock()
|
||||||
|
|
||||||
generateHashesStatusBoolMutex.Lock()
|
generateHashesStatusBoolMutex.Lock()
|
||||||
generateHashesStatusBool = false
|
generateHashesStatusBool = false
|
||||||
generateHashesStatusBoolMutex.Unlock()
|
generateHashesStatusBoolMutex.Unlock()
|
||||||
}
|
|
||||||
|
|
||||||
var identityHashGenerationWaitgroup sync.WaitGroup
|
|
||||||
|
|
||||||
generateIdentityHashesFunction := func(){
|
|
||||||
|
|
||||||
subCounter := int64(0)
|
|
||||||
|
|
||||||
for{
|
|
||||||
|
|
||||||
_, newSeedPhraseHash, err := seedPhrase.GetNewSeedPhraseFromWordList(currentLanguageWordList)
|
|
||||||
if (err != nil) {
|
|
||||||
setErrorEncounteredFunction(err)
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentIdentityHashPrefix, err := identity.GetIdentityHash16CharacterPrefixFromSeedPhraseHash(newSeedPhraseHash)
|
var identityHashGenerationWaitgroup sync.WaitGroup
|
||||||
if (err != nil) {
|
|
||||||
setErrorEncounteredFunction(err)
|
generateIdentityHashesFunction := func(){
|
||||||
break
|
|
||||||
|
subCounter := int64(0)
|
||||||
|
|
||||||
|
for{
|
||||||
|
|
||||||
|
_, newSeedPhraseHash, err := seedPhrase.GetNewSeedPhraseFromWordList(currentLanguageWordList)
|
||||||
|
if (err != nil) {
|
||||||
|
setErrorEncounteredFunction(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIdentityHashPrefix, err := identity.GetIdentityHash16CharacterPrefixFromSeedPhraseHash(newSeedPhraseHash)
|
||||||
|
if (err != nil) {
|
||||||
|
setErrorEncounteredFunction(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have this check because we want to simulate how long it would take to check for a prefix
|
||||||
|
// The majority of the time is spent performing the hashing and ed25519 operations
|
||||||
|
strings.HasPrefix(currentIdentityHashPrefix, "seekia")
|
||||||
|
|
||||||
|
subCounter += 1
|
||||||
|
|
||||||
|
generateHashesStatusBoolMutex.RLock()
|
||||||
|
generatingStatus := generateHashesStatusBool
|
||||||
|
generateHashesStatusBoolMutex.RUnlock()
|
||||||
|
|
||||||
|
if (generatingStatus == false){
|
||||||
|
counterMutex.Lock()
|
||||||
|
counter += subCounter
|
||||||
|
counterMutex.Unlock()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
identityHashGenerationWaitgroup.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have this check because we want to simulate how long it would take to check for a prefix
|
generateHashesStatusBool = true
|
||||||
// The majority of the time is spent performing the hashing and ed25519 operations
|
|
||||||
strings.HasPrefix(currentIdentityHashPrefix, "seekia")
|
|
||||||
|
|
||||||
subCounter += 1
|
identityHashGenerationWaitgroup.Add(numberOfGoroutines)
|
||||||
|
|
||||||
generateHashesStatusBoolMutex.RLock()
|
for i:=0; i < numberOfGoroutines; i++{
|
||||||
generatingStatus := generateHashesStatusBool
|
|
||||||
generateHashesStatusBoolMutex.RUnlock()
|
|
||||||
|
|
||||||
if (generatingStatus == false){
|
go generateIdentityHashesFunction()
|
||||||
counterMutex.Lock()
|
}
|
||||||
counter += subCounter
|
|
||||||
counterMutex.Unlock()
|
// We run all goroutines for 1/2 of a second
|
||||||
break
|
time.Sleep(time.Second/2)
|
||||||
|
|
||||||
|
generateHashesStatusBoolMutex.Lock()
|
||||||
|
generateHashesStatusBool = false
|
||||||
|
generateHashesStatusBoolMutex.Unlock()
|
||||||
|
|
||||||
|
identityHashGenerationWaitgroup.Wait()
|
||||||
|
|
||||||
|
if (errorEncountered != nil){
|
||||||
|
return 0, 0, errorEncountered
|
||||||
|
}
|
||||||
|
|
||||||
|
currentGoroutinesNumberOfHashesPerSecond := counter*2
|
||||||
|
|
||||||
|
if (currentGoroutinesNumberOfHashesPerSecond > optimalNumberOfGoroutinesHashesPerSecond){
|
||||||
|
optimalNumberOfGoroutines = numberOfGoroutines
|
||||||
|
optimalNumberOfGoroutinesHashesPerSecond = currentGoroutinesNumberOfHashesPerSecond
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
identityHashGenerationWaitgroup.Done()
|
return optimalNumberOfGoroutinesHashesPerSecond, optimalNumberOfGoroutines, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
generateHashesStatusBool = true
|
optimalNumberOfGoroutinesHashesPerSecond, optimalNumberOfGoroutines, err := performBenchmark()
|
||||||
|
if (err != nil){
|
||||||
identityHashGenerationWaitgroup.Add(2)
|
setErrorEncounteredPage(window, err, previousPage)
|
||||||
|
return
|
||||||
go generateIdentityHashesFunction()
|
|
||||||
go generateIdentityHashesFunction()
|
|
||||||
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
|
|
||||||
generateHashesStatusBoolMutex.Lock()
|
|
||||||
generateHashesStatusBool = false
|
|
||||||
generateHashesStatusBoolMutex.Unlock()
|
|
||||||
|
|
||||||
identityHashGenerationWaitgroup.Wait()
|
|
||||||
|
|
||||||
if (errorEncountered != nil){
|
|
||||||
return 0, errorEncountered
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return counter, nil
|
setCreateCustomIdentityHashPage(window, identityType, true, optimalNumberOfGoroutinesHashesPerSecond, optimalNumberOfGoroutines, previousPage, submitPage)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hashGenerationSpeed, err := getIdentityHashGenerationSpeed()
|
currentPage := func(){
|
||||||
if (err != nil){
|
setCreateCustomIdentityHashPage(window, identityType, true, computerHashesPerSecond, optimalNumberOfGoroutines, previousPage, submitPage)
|
||||||
setErrorEncounteredPage(window, err, previousPage)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
title := getPageTitleCentered("Create Custom Identity Hash")
|
title := getPageTitleCentered("Create Custom Identity Hash")
|
||||||
|
@ -385,7 +417,7 @@ func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, pr
|
||||||
customPrefixEntryOnChangedFunction := func(newPrefix string){
|
customPrefixEntryOnChangedFunction := func(newPrefix string){
|
||||||
|
|
||||||
if (newPrefix == ""){
|
if (newPrefix == ""){
|
||||||
err = estimatedTimeLabelBinding.Set("")
|
err := estimatedTimeLabelBinding.Set("")
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
setErrorEncounteredPage(window, err, previousPage)
|
setErrorEncounteredPage(window, err, previousPage)
|
||||||
return
|
return
|
||||||
|
@ -400,7 +432,7 @@ func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, pr
|
||||||
|
|
||||||
prefixLength := len(newPrefix)
|
prefixLength := len(newPrefix)
|
||||||
if (prefixLength >= 13){
|
if (prefixLength >= 13){
|
||||||
err = estimatedTimeLabelBinding.Set("Prefix is too long.")
|
err := estimatedTimeLabelBinding.Set("Prefix is too long.")
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
setErrorEncounteredPage(window, err, previousPage)
|
setErrorEncounteredPage(window, err, previousPage)
|
||||||
return
|
return
|
||||||
|
@ -415,7 +447,7 @@ func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, pr
|
||||||
|
|
||||||
isBase32, invalidCharacter := encoding.VerifyStringContainsOnlyBase32Charset(newPrefix)
|
isBase32, invalidCharacter := encoding.VerifyStringContainsOnlyBase32Charset(newPrefix)
|
||||||
if (isBase32 == false){
|
if (isBase32 == false){
|
||||||
err = estimatedTimeLabelBinding.Set("Invalid character detected: " + invalidCharacter)
|
err := estimatedTimeLabelBinding.Set("Invalid character detected: " + invalidCharacter)
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
setErrorEncounteredPage(window, err, previousPage)
|
setErrorEncounteredPage(window, err, previousPage)
|
||||||
return
|
return
|
||||||
|
@ -432,7 +464,7 @@ func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, pr
|
||||||
numberOfBits := float64(numberOfCharacters * 5)
|
numberOfBits := float64(numberOfCharacters * 5)
|
||||||
numberOfRequiredHashes := math.Pow(2, numberOfBits)
|
numberOfRequiredHashes := math.Pow(2, numberOfBits)
|
||||||
|
|
||||||
estimatedTimeToGenerateInSeconds := numberOfRequiredHashes / float64(hashGenerationSpeed)
|
estimatedTimeToGenerateInSeconds := numberOfRequiredHashes / float64(computerHashesPerSecond)
|
||||||
|
|
||||||
estimatedTimeUnitsTranslated, err := helpers.ConvertUnixTimeDurationToUnitsTimeTranslated(int64(estimatedTimeToGenerateInSeconds), false)
|
estimatedTimeUnitsTranslated, err := helpers.ConvertUnixTimeDurationToUnitsTimeTranslated(int64(estimatedTimeToGenerateInSeconds), false)
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
|
@ -489,7 +521,7 @@ func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, pr
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyList := make([]string, 0)
|
emptyList := make([]string, 0)
|
||||||
setRunCustomIdentityHashGenerationPage(window, identityType, prefix, estimatedTimeUnitsTranslated, hashGenerationSpeed, emptyList, currentPage, submitPage)
|
setRunCustomIdentityHashGenerationPage(window, identityType, prefix, estimatedTimeUnitsTranslated, optimalNumberOfGoroutines, computerHashesPerSecond, emptyList, currentPage, submitPage)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
customPrefixEntrySection := getContainerCentered(container.NewGridWithColumns(1, enterDesiredPrefixText, customPrefixEntry, startGeneratingHashesButton))
|
customPrefixEntrySection := getContainerCentered(container.NewGridWithColumns(1, enterDesiredPrefixText, customPrefixEntry, startGeneratingHashesButton))
|
||||||
|
@ -499,13 +531,11 @@ func setCreateCustomIdentityHashPage(window fyne.Window, identityType string, pr
|
||||||
setPageContent(page, window)
|
setPageContent(page, window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: Update the estimated time every ~10 seconds
|
//TODO: Update the estimated time every ~10 seconds
|
||||||
//TODO: Figure out optimal number of goroutines to use for maximum speed
|
|
||||||
|
|
||||||
func setRunCustomIdentityHashGenerationPage(window fyne.Window, identityType string, desiredPrefix string, estimatedTimeRequired string, initialHashesPerSecond int64, seedPhrasesFoundList []string, previousPage func(), submitPage func(string, func()) ){
|
func setRunCustomIdentityHashGenerationPage(window fyne.Window, identityType string, desiredPrefix string, estimatedTimeRequired string, numberOfGoroutines int, initialHashesPerSecond int64, seedPhrasesFoundList []string, previousPage func(), submitPage func(string, func()) ){
|
||||||
|
|
||||||
currentPage := func(){setRunCustomIdentityHashGenerationPage(window, identityType, desiredPrefix, estimatedTimeRequired, initialHashesPerSecond, seedPhrasesFoundList, previousPage, submitPage)}
|
currentPage := func(){setRunCustomIdentityHashGenerationPage(window, identityType, desiredPrefix, estimatedTimeRequired, numberOfGoroutines, initialHashesPerSecond, seedPhrasesFoundList, previousPage, submitPage)}
|
||||||
|
|
||||||
appMemory.SetMemoryEntry("CurrentViewedPage", "RunCustomIdentityHashGeneration")
|
appMemory.SetMemoryEntry("CurrentViewedPage", "RunCustomIdentityHashGeneration")
|
||||||
|
|
||||||
|
@ -627,7 +657,7 @@ func setRunCustomIdentityHashGenerationPage(window fyne.Window, identityType str
|
||||||
|
|
||||||
retryButton := getWidgetCentered(widget.NewButtonWithIcon("Retry", theme.ViewRefreshIcon(), func(){
|
retryButton := getWidgetCentered(widget.NewButtonWithIcon("Retry", theme.ViewRefreshIcon(), func(){
|
||||||
emptyList := make([]string, 0)
|
emptyList := make([]string, 0)
|
||||||
setRunCustomIdentityHashGenerationPage(window, identityType, desiredPrefix, estimatedTimeRequired, initialHashesPerSecond, emptyList, previousPage, submitPage)
|
setRunCustomIdentityHashGenerationPage(window, identityType, desiredPrefix, estimatedTimeRequired, numberOfGoroutines, initialHashesPerSecond, emptyList, previousPage, submitPage)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
page := container.NewVBox(title, backButton, widget.NewSeparator(), doneDescription1, doneDescription2, widget.NewSeparator(), foundHashesGrid, retryButton)
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), doneDescription1, doneDescription2, widget.NewSeparator(), foundHashesGrid, retryButton)
|
||||||
|
@ -801,10 +831,11 @@ func setRunCustomIdentityHashGenerationPage(window fyne.Window, identityType str
|
||||||
|
|
||||||
setGenerateHashesStatusBool(true)
|
setGenerateHashesStatusBool(true)
|
||||||
|
|
||||||
generateHashesWaitgroup.Add(2)
|
generateHashesWaitgroup.Add(numberOfGoroutines)
|
||||||
|
|
||||||
go generateIdentityHashesFunction()
|
for i:=0; i < numberOfGoroutines; i++{
|
||||||
go generateIdentityHashesFunction()
|
go generateIdentityHashesFunction()
|
||||||
|
}
|
||||||
|
|
||||||
numberOfSecondsElapsed := 0
|
numberOfSecondsElapsed := 0
|
||||||
|
|
||||||
|
@ -882,7 +913,7 @@ func setRunCustomIdentityHashGenerationPage(window fyne.Window, identityType str
|
||||||
// We wait for all loops to exit
|
// We wait for all loops to exit
|
||||||
generateHashesWaitgroup.Wait()
|
generateHashesWaitgroup.Wait()
|
||||||
|
|
||||||
setRunCustomIdentityHashGenerationPage(window, identityType, desiredPrefix, estimatedTimeRequired, currentHashesPerSecond, seedPhrasesFoundList, previousPage, submitPage)
|
setRunCustomIdentityHashGenerationPage(window, identityType, desiredPrefix, estimatedTimeRequired, numberOfGoroutines, currentHashesPerSecond, seedPhrasesFoundList, previousPage, submitPage)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ func setChooseIdentityTypeForNewIdentityHashPage(window fyne.Window, previousPag
|
||||||
}
|
}
|
||||||
|
|
||||||
chooseIdentityTypeButton := widget.NewButton(identityType, func(){
|
chooseIdentityTypeButton := widget.NewButton(identityType, func(){
|
||||||
setCreateCustomIdentityHashPage(window, identityType, currentPage, submitPage)
|
setCreateCustomIdentityHashPage(window, identityType, false, 0, 0, currentPage, submitPage)
|
||||||
})
|
})
|
||||||
|
|
||||||
buttonWithIcon := container.NewGridWithColumns(1, identityTypeIcon, chooseIdentityTypeButton)
|
buttonWithIcon := container.NewGridWithColumns(1, identityTypeIcon, chooseIdentityTypeButton)
|
||||||
|
|
Loading…
Reference in a new issue