Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing pow check for user profile creation #1711

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ba61f6b
Add cathash images
axpoems Feb 25, 2024
afac04a
Misc improvements in cathash
djing-chan Feb 27, 2024
e710c0a
Remove unused code
axpoems Feb 27, 2024
a094aee
Add missing license headers
axpoems Feb 27, 2024
0e763d0
Refactor: rename robohash to cathash
axpoems Feb 27, 2024
383c3e5
Add comments to understand better how the handle is encoded
axpoems Feb 27, 2024
931c17a
Prepare cathash image set
axpoems Feb 27, 2024
ddf36ae
Reduce visibility of methods. Move package scope method up.
HenrikJannsen Feb 28, 2024
a6c1209
Remove Handle and HandleFactory.
HenrikJannsen Feb 28, 2024
49c3101
Replace #ITEM# with NUM
HenrikJannsen Feb 28, 2024
967cc76
Reduce visibility of methods. Move package scope method up.
HenrikJannsen Feb 28, 2024
4d344c8
Remove VariableSizeHashing
HenrikJannsen Feb 28, 2024
ff59130
Cleanups, Renamings
HenrikJannsen Feb 28, 2024
a3d3d21
Remove comment for dev testing
HenrikJannsen Feb 28, 2024
9754d4d
Reduce visibility of methods. Move package scope method up.
HenrikJannsen Feb 28, 2024
f1870ec
Remove Handle and HandleFactory.
HenrikJannsen Feb 28, 2024
c77eb23
Replace #ITEM# with NUM
HenrikJannsen Feb 28, 2024
f3ad800
Reduce visibility of methods. Move package scope method up.
HenrikJannsen Feb 28, 2024
76d0619
Remove VariableSizeHashing
HenrikJannsen Feb 28, 2024
49cb0f0
Cleanups, Renamings
HenrikJannsen Feb 28, 2024
18dc6ee
Remove comment for dev testing
HenrikJannsen Feb 28, 2024
194f091
Merge remote-tracking branch 'HenrikJannsen/bisq-avatar-improvements'…
djing-chan Feb 29, 2024
dff65a8
Refactor: Move NymIdGenerator into bisq.user.profile
djing-chan Feb 28, 2024
657f301
Move mintNymProofOfWork method to UserIdentityService
djing-chan Feb 28, 2024
caf0920
Refactor: Move NymIdGenerator into bisq.user.identity
djing-chan Feb 28, 2024
d4fa397
Add solution (counter) of PoW to nym and icon generation
djing-chan Feb 28, 2024
0912c2f
Combine powSolution with pubKeyHash for input for nym and catHash
djing-chan Feb 28, 2024
e8232a9
Add verification of user profiles pow
djing-chan Feb 28, 2024
811457e
Use solution as byte array instead of counter as long
djing-chan Feb 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler)

userService = new UserService(UserService.Config.from(getConfig("user")),
persistenceService,
securityService,
identityService,
networkService,
bondedRolesService,
securityService.getHashCashProofOfWorkService());
bondedRolesService);

settingsService = new SettingsService(persistenceService);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.components.cathash;

import bisq.common.util.MathUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BucketConfig {
static final String DIGIT = "#";

private static final int BG0_COUNT = 16;
private static final int BG1_COUNT = 16;
private static final int EARS0_COUNT = 16;
private static final int EARS1_COUNT = 3;
private static final int FACE0_COUNT = 16;
private static final int FACE1_COUNT = 9;
private static final int EYES0_COUNT = 16;
private static final int NOSE0_COUNT = 6;
private static final int WHISKERS0_COUNT = 7;

private static final int[] BUCKET_SIZES = new int[]{BG0_COUNT, BG1_COUNT, EARS0_COUNT, EARS1_COUNT, FACE0_COUNT,
FACE1_COUNT, EYES0_COUNT, NOSE0_COUNT, WHISKERS0_COUNT};

private static final String[] PATH_TEMPLATES;

static {
String postFix = ".png";
PATH_TEMPLATES = new String[]{
"bg0/" + DIGIT + postFix,
"bg1/" + DIGIT + postFix,
"ears0/" + DIGIT + postFix,
"ears1/" + DIGIT + postFix,
"face0/" + DIGIT + postFix,
"face1/" + DIGIT + postFix,
"eyes0/" + DIGIT + postFix,
"nose0/" + DIGIT + postFix,
"whiskers0/" + DIGIT + postFix
};

long numCombinations = getNumCombinations();
log.info("Number of combinations: 2^{} = {}", MathUtils.getLog2(numCombinations), numCombinations);
}

static int[] getBucketSizes() {
return BUCKET_SIZES;
}

static String[] getPathTemplates() {
return PATH_TEMPLATES;
}

static long getNumCombinations() {
long result = 1;
for (int bucketSize : BUCKET_SIZES) {
result *= bucketSize;
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.components.cathash;

import java.math.BigInteger;

public class BucketEncoder {
/**
* @param input A BigInteger input that is to be split up deterministically in buckets according to the bucketSizes array.
* @return buckets
*/
static int[] encode(BigInteger input, int[] bucketSizes) {
int currentBucket = 0;
int[] result = new int[bucketSizes.length];
while (currentBucket < bucketSizes.length) {
int bucketSize = bucketSizes[currentBucket];
BigInteger[] divisorReminder = input.divideAndRemainder(BigInteger.valueOf(bucketSize));
input = divisorReminder[0];
long reminder = divisorReminder[1].longValue();
result[currentBucket] = (int) Math.abs(reminder % bucketSize);
currentBucket++;
}
return result;
}

static String[] toPaths(int[] buckets, String[] pathTemplates) {
String[] paths = new String[buckets.length];
for (int facet = 0; facet < buckets.length; facet++) {
int bucketValue = buckets[facet];
paths[facet] = generatePath(pathTemplates[facet], bucketValue);
}
return paths;
}

private static String generatePath(String pathTemplate, int index) {
return pathTemplate.replaceAll(BucketConfig.DIGIT, String.format("%02d", index));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,43 @@

package bisq.desktop.components.cathash;

import bisq.common.data.ByteArray;
import bisq.common.util.ByteArrayUtils;
import bisq.desktop.common.utils.ImageUtil;
import bisq.user.profile.UserProfile;
import javafx.scene.image.Image;
import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;
import java.util.concurrent.ConcurrentHashMap;

// Derived from https://github.com/neuhalje/android-robohash
// Number of combinations: 3 * 15 * 15 * 15 * 15 * 15 * 15 = 34171875 (2 ^ 25)
@Slf4j
public class CatHash {
private static final int SIZE = 300;
private static final int MAX_CACHE_SIZE = 10000;
private static final HandleFactory HANDLE_FACTORY = new HandleFactory();
private static final ConcurrentHashMap<ByteArray, Image> CACHE = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<BigInteger, Image> CACHE = new ConcurrentHashMap<>();

public static Image getImage(byte[] pubKeyHash) {
return getImage(new ByteArray(pubKeyHash), true);
public static Image getImage(UserProfile userProfile) {
return getImage(userProfile.getPubKeyHash(), userProfile.getProofOfWork().getSolution(), true);
}

public static Image getImage(byte[] pubKeyHash, boolean useCache) {
return getImage(new ByteArray(pubKeyHash), useCache);
public static Image getImage(byte[] pubKeyHash, byte[] powSolution) {
return getImage(pubKeyHash, powSolution, true);
}

private static Image getImage(ByteArray pubKeyHash, boolean useCache) {
if (useCache && CACHE.containsKey(pubKeyHash)) {
return CACHE.get(pubKeyHash);
public static Image getImage(byte[] pubKeyHash, byte[] powSolution, boolean useCache) {
byte[] combined = ByteArrayUtils.concat(powSolution, pubKeyHash);
BigInteger input = new BigInteger(combined);
if (useCache && CACHE.containsKey(input)) {
return CACHE.get(input);
}
BigInteger bigInteger = new BigInteger(pubKeyHash.getBytes());
Configuration configuration = new Configuration();
VariableSizeHashing hashing = new VariableSizeHashing(configuration.getBucketSizes());
byte[] data = hashing.createBuckets(bigInteger);
Handle handle = HANDLE_FACTORY.calculateHandle(data);
Image image = imageForHandle(handle, configuration);

int[] buckets = BucketEncoder.encode(input, BucketConfig.getBucketSizes());
String[] paths = BucketEncoder.toPaths(buckets, BucketConfig.getPathTemplates());
Image image = ImageUtil.composeImage(paths, SIZE, SIZE);
if (useCache && CACHE.size() < MAX_CACHE_SIZE) {
CACHE.put(pubKeyHash, image);
CACHE.put(input, image);
}
return image;
}

private static Image imageForHandle(Handle handle, Configuration configuration) {
long ts = System.currentTimeMillis();
byte[] bucketValues = handle.bucketValues();
String[] paths = configuration.convertToFacetParts(bucketValues);
log.debug("Generated paths for CatHash image in {} ms", System.currentTimeMillis() - ts); // typically <1ms
return ImageUtil.composeImage(paths, configuration.width(), configuration.height());
}
}

This file was deleted.

This file was deleted.

Loading
Loading