Skip to content

Commit 33a4d3a

Browse files
committed
feat: ini config
1 parent d41953f commit 33a4d3a

File tree

2 files changed

+181
-15
lines changed

2 files changed

+181
-15
lines changed

cmd/sequence/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/0xsequence/ethkit/go-ethereum/common"
1313
"github.com/0xsequence/go-sequence/core"
1414
v3 "github.com/0xsequence/go-sequence/core/v3"
15+
"github.com/davecgh/go-spew/spew"
1516
"github.com/spf13/cobra"
1617
)
1718

@@ -373,6 +374,9 @@ func calculateImageHash(params *ConfigImageHashParams) (string, error) {
373374
return "", fmt.Errorf("failed to decode wallet config: %w", err)
374375
}
375376

377+
log.Printf("Decoded config: %+v", config)
378+
spew.Dump(config)
379+
376380
imageHash := config.ImageHash()
377381
return "0x" + common.Bytes2Hex(imageHash.Bytes()), nil
378382
}

core/v3/v3.go

Lines changed: 177 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,8 +1716,9 @@ func (l *signatureTreeSapientCompactLeaf) write(writer io.Writer) error {
17161716
type WalletConfig struct {
17171717
Threshold_ uint16 `json:"threshold" toml:"threshold"`
17181718
// WARNING: contract code is uint64
1719-
Checkpoint_ uint64 `json:"checkpoint" toml:"checkpoint"`
1720-
Tree WalletConfigTree `json:"tree" toml:"tree"`
1719+
Checkpoint_ uint64 `json:"checkpoint" toml:"checkpoint"`
1720+
Tree WalletConfigTree `json:"tree" toml:"tree"`
1721+
Checkpointer common.Address `json:"checkpointer,omitempty" toml:"checkpointer,omitempty"`
17211722
}
17221723

17231724
func (c *WalletConfig) Threshold() uint16 {
@@ -1747,18 +1748,22 @@ func (c *WalletConfig) IsUsable() error {
17471748
}
17481749

17491750
func (c *WalletConfig) ImageHash() core.ImageHash {
1750-
imageHash := c.Tree.ImageHash()
1751-
threshold := common.BigToHash(new(big.Int).SetUint64(uint64(c.Threshold_)))
1752-
checkpoint := common.BigToHash(new(big.Int).SetUint64(uint64(c.Checkpoint_)))
1751+
treeHash := c.Tree.ImageHash().Bytes()
1752+
1753+
thresholdBytes := common.BigToHash(new(big.Int).SetUint64(uint64(c.Threshold_))).Bytes()
1754+
checkpointBytes := common.BigToHash(new(big.Int).SetUint64(c.Checkpoint_)).Bytes()
1755+
1756+
checkpointerBytes := make([]byte, 32)
1757+
copy(checkpointerBytes[12:], c.Checkpointer.Bytes())
1758+
1759+
root := crypto.Keccak256Hash(treeHash, thresholdBytes)
1760+
1761+
root = crypto.Keccak256Hash(root.Bytes(), checkpointBytes)
1762+
1763+
root = crypto.Keccak256Hash(root.Bytes(), checkpointerBytes)
17531764

17541765
return core.ImageHash{
1755-
Hash: crypto.Keccak256Hash(
1756-
crypto.Keccak256Hash(
1757-
imageHash.Bytes(),
1758-
threshold.Bytes(),
1759-
).Bytes(),
1760-
checkpoint.Bytes(),
1761-
),
1766+
Hash: root,
17621767
Preimage: c,
17631768
}
17641769
}
@@ -1881,6 +1886,10 @@ func DecodeWalletConfigTree(object any) (WalletConfigTree, error) {
18811886
return decodeWalletConfigTreeNestedLeaf(object_)
18821887
} else if hasKeys(object_, []string{"subdigest"}) {
18831888
return decodeWalletConfigTreeSubdigestLeaf(object_)
1889+
} else if hasKeys(object_, []string{"weight", "address", "imageHash"}) {
1890+
return decodeWalletConfigTreeSapientSignerLeaf(object_)
1891+
} else if hasKeys(object_, []string{"digest"}) {
1892+
return decodeWalletConfigTreeAnyAddressSubdigestLeaf(object_)
18841893
}
18851894
return nil, fmt.Errorf("unknown wallet config tree type")
18861895
}
@@ -2025,9 +2034,15 @@ func decodeWalletConfigTreeAddressLeaf(object any) (*WalletConfigTreeAddressLeaf
20252034
}
20262035

20272036
func (l *WalletConfigTreeAddressLeaf) ImageHash() core.ImageHash {
2028-
var hash common.Hash
2029-
hash.SetBytes(l.Address.Bytes())
2030-
hash[common.HashLength-common.AddressLength-1] = l.Weight
2037+
weight := new(big.Int).SetUint64(uint64(l.Weight))
2038+
weightBytes := make([]byte, 32)
2039+
weight.FillBytes(weightBytes)
2040+
2041+
hash := crypto.Keccak256Hash(
2042+
[]byte("Sequence signer:\n"),
2043+
l.Address.Bytes(),
2044+
weightBytes,
2045+
)
20312046
return core.ImageHash{Hash: hash, Preimage: l}
20322047
}
20332048

@@ -2277,6 +2292,153 @@ func (l WalletConfigTreeSubdigestLeaf) buildSignatureTree(signerSignatures map[c
22772292
return signatureTreeSubdigestLeaf{l.Subdigest}
22782293
}
22792294

2295+
type WalletConfigTreeSapientSignerLeaf struct {
2296+
Weight uint8 `json:"weight" toml:"weight"`
2297+
Address common.Address `json:"address" toml:"address"`
2298+
ImageHash_ core.ImageHash `json:"imageHash" toml:"imageHash"`
2299+
}
2300+
2301+
func decodeWalletConfigTreeSapientSignerLeaf(object any) (*WalletConfigTreeSapientSignerLeaf, error) {
2302+
object_, ok := object.(map[string]any)
2303+
if !ok {
2304+
return nil, fmt.Errorf("wallet config tree sapient signer leaf must be an object")
2305+
}
2306+
2307+
weight, ok := object_["weight"]
2308+
if !ok {
2309+
return nil, fmt.Errorf(`missing required "weight" property`)
2310+
}
2311+
weight_, err := toUint8(weight)
2312+
if err != nil {
2313+
return nil, fmt.Errorf("unable to convert weight: %w", err)
2314+
}
2315+
2316+
address, ok := object_["address"]
2317+
if !ok {
2318+
return nil, fmt.Errorf(`missing required "address" property`)
2319+
}
2320+
address_, ok := address.(string)
2321+
if !ok {
2322+
return nil, fmt.Errorf("address must be a string")
2323+
}
2324+
if !common.IsHexAddress(address_) {
2325+
return nil, fmt.Errorf(`"%v" is not a valid address`, address_)
2326+
}
2327+
2328+
imageHash, ok := object_["imageHash"]
2329+
if !ok {
2330+
return nil, fmt.Errorf(`missing required "imageHash" property`)
2331+
}
2332+
imageHash_, ok := imageHash.(string)
2333+
if !ok {
2334+
return nil, fmt.Errorf("imageHash must be a string")
2335+
}
2336+
imageHashBytes, err := hexutil.Decode(imageHash_)
2337+
if err != nil || len(imageHashBytes) != 32 {
2338+
return nil, fmt.Errorf(`"%v" is not a valid 32-byte hash`, imageHash_)
2339+
}
2340+
2341+
return &WalletConfigTreeSapientSignerLeaf{
2342+
Weight: weight_,
2343+
Address: common.HexToAddress(address_),
2344+
ImageHash_: core.ImageHash{Hash: common.BytesToHash(imageHashBytes)},
2345+
}, nil
2346+
}
2347+
2348+
func (l *WalletConfigTreeSapientSignerLeaf) ImageHash() core.ImageHash {
2349+
weight := new(big.Int).SetUint64(uint64(l.Weight))
2350+
weightBytes := make([]byte, 32)
2351+
weight.FillBytes(weightBytes)
2352+
2353+
hash := crypto.Keccak256Hash(
2354+
[]byte("Sequence sapient config:\n"),
2355+
l.Address.Bytes(),
2356+
weightBytes,
2357+
l.ImageHash_.Bytes(),
2358+
)
2359+
return core.ImageHash{Hash: hash, Preimage: l}
2360+
}
2361+
2362+
func (l *WalletConfigTreeSapientSignerLeaf) maxWeight() *big.Int {
2363+
return new(big.Int).SetUint64(uint64(l.Weight))
2364+
}
2365+
2366+
func (l *WalletConfigTreeSapientSignerLeaf) readSignersIntoMap(signers map[common.Address]uint16) {
2367+
signers[l.Address] = uint16(l.Weight)
2368+
}
2369+
2370+
func (l *WalletConfigTreeSapientSignerLeaf) unverifiedWeight(signers map[common.Address]uint16) *big.Int {
2371+
if _, ok := signers[l.Address]; ok {
2372+
return new(big.Int).SetUint64(uint64(l.Weight))
2373+
}
2374+
return new(big.Int)
2375+
}
2376+
2377+
func (l *WalletConfigTreeSapientSignerLeaf) buildSignatureTree(signerSignatures map[common.Address]signerSignature) signatureTree {
2378+
if signature, ok := signerSignatures[l.Address]; ok {
2379+
return &signatureTreeSapientLeaf{
2380+
Weight: l.Weight,
2381+
Address: l.Address,
2382+
Signature: signature.signature,
2383+
}
2384+
}
2385+
return &signatureTreeAddressLeaf{Weight: l.Weight, Address: l.Address}
2386+
}
2387+
2388+
type WalletConfigTreeAnyAddressSubdigestLeaf struct {
2389+
Digest core.Subdigest `json:"digest" toml:"digest"`
2390+
}
2391+
2392+
func decodeWalletConfigTreeAnyAddressSubdigestLeaf(object any) (WalletConfigTreeAnyAddressSubdigestLeaf, error) {
2393+
object_, ok := object.(map[string]any)
2394+
if !ok {
2395+
return WalletConfigTreeAnyAddressSubdigestLeaf{}, fmt.Errorf("wallet config tree any address subdigest leaf must be an object")
2396+
}
2397+
2398+
digest, ok := object_["digest"]
2399+
if !ok {
2400+
return WalletConfigTreeAnyAddressSubdigestLeaf{}, fmt.Errorf(`missing required "digest" property`)
2401+
}
2402+
digest_, ok := digest.(string)
2403+
if !ok {
2404+
return WalletConfigTreeAnyAddressSubdigestLeaf{}, fmt.Errorf("digest must be a string")
2405+
}
2406+
digestBytes, err := hexutil.Decode(digest_)
2407+
if err != nil || len(digestBytes) != 32 {
2408+
return WalletConfigTreeAnyAddressSubdigestLeaf{}, fmt.Errorf(`"%v" is not a valid 32-byte hash`, digest_)
2409+
}
2410+
2411+
return WalletConfigTreeAnyAddressSubdigestLeaf{
2412+
Digest: core.Subdigest{Hash: common.BytesToHash(digestBytes)},
2413+
}, nil
2414+
}
2415+
2416+
func (l WalletConfigTreeAnyAddressSubdigestLeaf) ImageHash() core.ImageHash {
2417+
hash := crypto.Keccak256Hash(
2418+
[]byte("Sequence any address subdigest:\n"),
2419+
l.Digest.Bytes(),
2420+
)
2421+
return core.ImageHash{
2422+
Hash: hash,
2423+
Preimage: &l,
2424+
}
2425+
}
2426+
2427+
func (l WalletConfigTreeAnyAddressSubdigestLeaf) maxWeight() *big.Int {
2428+
return new(big.Int).Set(maxUint256)
2429+
}
2430+
2431+
func (l WalletConfigTreeAnyAddressSubdigestLeaf) readSignersIntoMap(signers map[common.Address]uint16) {
2432+
}
2433+
2434+
func (l WalletConfigTreeAnyAddressSubdigestLeaf) unverifiedWeight(signers map[common.Address]uint16) *big.Int {
2435+
return new(big.Int).Set(maxUint256)
2436+
}
2437+
2438+
func (l WalletConfigTreeAnyAddressSubdigestLeaf) buildSignatureTree(signerSignatures map[common.Address]signerSignature) signatureTree {
2439+
return &signatureTreeAnyAddressSubdigestLeaf{l.Digest}
2440+
}
2441+
22802442
func ecrecover(subdigest core.Subdigest, signature []byte) (common.Address, error) {
22812443
if len(signature) != crypto.SignatureLength {
22822444
return common.Address{}, fmt.Errorf("invalid signature length %v, expected %v", len(signature), crypto.SignatureLength)

0 commit comments

Comments
 (0)