Improved the identity hash generation tool. The fastest quantity of goroutines is now identified and used.

This commit is contained in:
Simon Sarasova 2024-06-03 02:42:45 +00:00
parent 35cda50ad7
commit 497f596b3b
No known key found for this signature in database
GPG key ID: EEDA4103C9C36944
4 changed files with 129 additions and 97 deletions

View file

@ -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*

View file

@ -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

View file

@ -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
} }

View file

@ -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)