Skip to content

Commit 10de06a

Browse files
committed
Add chain_code setup instructions and integrate chain_code into configuration
1 parent 902c868 commit 10de06a

6 files changed

Lines changed: 93 additions & 9 deletions

File tree

INSTALLATION.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,29 @@ Detailed steps can be found in [SETUP.md](SETUP.md).
5656

5757
---
5858

59+
## chain_code setup (required)
60+
61+
Generate one 32-byte hex chain code and set it in all configs:
62+
63+
```bash
64+
cd /home/carmy/Documents/works/mpcium
65+
CC=$(openssl rand -hex 32) && echo "$CC" > .chain_code
66+
sed -i -E "s|^([[:space:]]*chain_code:).*|\1 \"$CC\"|" config.yaml
67+
for n in node0 node1 node2; do
68+
sed -i -E "s|^([[:space:]]*chain_code:).*|\1 \"$CC\"|" "$n/config.yaml"
69+
done
70+
```
71+
72+
Start nodes normally (no env export needed):
73+
74+
```bash
75+
cd node0 && mpcium start -n node0
76+
```
77+
78+
Repeat for `node1` and `node2`. The value must be exactly 64 hex chars (32 bytes).
79+
80+
---
81+
5982
## Production Deployment (High Security)
6083

6184
1. Use production-grade **NATS** and **Consul** clusters.

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ The application uses a YAML configuration file (`config.yaml`) with the followin
133133
- `event_initiator_pubkey`: Public key of the event initiator
134134
- `max_concurrent_keygen`: Maximum concurrent key generation operations
135135

136+
#### chain_code (required)
137+
- Mpcium derives child keys using a master chain code.
138+
- Provide a single 32-byte hex value in `config.yaml` under `chain_code`, and use the same value for all nodes.
139+
- Example to generate once and set:
140+
```bash
141+
CC=$(openssl rand -hex 32)
142+
sed -i -E "s|^([[:space:]]*chain_code:).*|\1 \"$CC\"|" config.yaml
143+
for n in node0 node1 node2; do
144+
sed -i -E "s|^([[:space:]]*chain_code:).*|\1 \"$CC\"|" "$n/config.yaml"
145+
done
146+
```
147+
136148
## Installation
137149

138150
- **Local Development**: For quick setup and testing, see [INSTALLATION.md](./INSTALLATION.md)

cmd/mpcium/main.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ func runNode(ctx context.Context, c *cli.Command) error {
203203
peerNodeIDs := GetPeerIDs(peers)
204204
peerRegistry := mpc.NewRegistry(nodeID, peerNodeIDs, consulClient.KV(), directMessaging, pubsub, identityStore)
205205

206-
ckd, err := mpc.NewCKD()
206+
chainCodeHex := viper.GetString("chain_code")
207+
ckd, err := mpc.NewCKDFromHex(chainCodeHex)
207208
if err != nil {
208209
logger.Fatal("Failed to create ckd store", err)
209210
}
@@ -449,6 +450,14 @@ func checkRequiredConfigValues(appConfig *config.AppConfig) {
449450
if viper.GetString("event_initiator_pubkey") == "" {
450451
logger.Fatal("Event initiator public key is required", nil)
451452
}
453+
454+
chainCode := strings.TrimSpace(viper.GetString("chain_code"))
455+
if chainCode == "" {
456+
logger.Fatal("chain_code is required in config.yaml", nil)
457+
}
458+
if len(chainCode) != 64 { // 32 bytes hex
459+
logger.Fatal("chain_code must be 32-byte hex (64 chars)", nil)
460+
}
452461
}
453462

454463
func NewConsulClient(addr string) *api.Client {

pkg/config/init.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type AppConfig struct {
1717

1818
Environment string `mapstructure:"environment"`
1919
BadgerPassword string `mapstructure:"badger_password"`
20+
ChainCodeHex string `mapstructure:"chain_code"`
2021
}
2122

2223
// Implement masking serializer AppConfig

pkg/mpc/ckd.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,35 @@ type CKD struct {
3333
mu sync.RWMutex
3434
}
3535

36-
// NewCKD loads chain code from environment variable CHAIN_CODE (hex-encoded).
37-
func NewCKD() (*CKD, error) {
38-
envVal := os.Getenv("CHAIN_CODE")
39-
if envVal == "" {
40-
return nil, fmt.Errorf("CHAIN_CODE not set in environment")
36+
// NewCKDFromHex creates CKD from a hex-encoded chain code string (32 bytes).
37+
func NewCKDFromHex(hexStr string) (*CKD, error) {
38+
if hexStr == "" {
39+
return nil, fmt.Errorf("chain code is empty")
4140
}
4241

43-
code, err := hex.DecodeString(envVal)
42+
code, err := hex.DecodeString(hexStr)
4443
if err != nil {
45-
return nil, fmt.Errorf("invalid CHAIN_CODE hex: %w", err)
44+
return nil, fmt.Errorf("invalid chain code hex: %w", err)
4645
}
4746
if len(code) != chainCodeLength {
4847
return nil, fmt.Errorf("%w: got %d, want %d", ErrInvalidChainCode, len(code), chainCodeLength)
4948
}
5049

51-
logger.Info("Loaded static chain code from environment")
50+
logger.Info("Loaded static chain code from config")
5251

5352
return &CKD{masterChainCode: code}, nil
5453
}
5554

55+
// NewCKD loads chain code from environment variable CHAIN_CODE (hex-encoded).
56+
// Deprecated: prefer NewCKDFromHex with config-provided value.
57+
func NewCKD() (*CKD, error) {
58+
envVal := os.Getenv("CHAIN_CODE")
59+
if envVal == "" {
60+
return nil, fmt.Errorf("CHAIN_CODE not set in environment")
61+
}
62+
return NewCKDFromHex(envVal)
63+
}
64+
5665
// GetMasterChainCode returns a copy of the chain code.
5766
func (c *CKD) GetMasterChainCode() []byte {
5867
c.mu.RLock()

setup_identities.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,36 @@ for i in $(seq 0 $((NUM_NODES-1))); do
3030
( cd "node$i" && mpcium-cli generate-identity --node "node$i" )
3131
done
3232

33+
# Generate a single chain_code if not present and set it in configs
34+
if [ ! -f .chain_code ]; then
35+
echo "🔐 Generating chain_code (32-byte hex) ..."
36+
CC=$(openssl rand -hex 32)
37+
echo "$CC" > .chain_code
38+
else
39+
CC=$(cat .chain_code)
40+
fi
41+
42+
if [ -z "$CC" ]; then
43+
echo "❌ Failed to determine chain_code"
44+
exit 1
45+
fi
46+
47+
echo "📝 Setting chain_code in root config.yaml ..."
48+
if grep -q '^\s*chain_code:' config.yaml; then
49+
sed -i -E "s|^([[:space:]]*chain_code:).*|\1 \"$CC\"|" config.yaml
50+
else
51+
printf '\nchain_code: "%s"\n' "$CC" >> config.yaml
52+
fi
53+
54+
echo "📦 Distributing chain_code to node configs ..."
55+
for i in $(seq 0 $((NUM_NODES-1))); do
56+
if grep -q '^\s*chain_code:' "node$i/config.yaml"; then
57+
sed -i -E "s|^([[:space:]]*chain_code:).*|\1 \"$CC\"|" "node$i/config.yaml"
58+
else
59+
printf '\nchain_code: "%s"\n' "$CC" >> "node$i/config.yaml"
60+
fi
61+
done
62+
3363
# Distribute identity files to all nodes
3464
echo "🔄 Distributing identity files across nodes..."
3565
for i in $(seq 0 $((NUM_NODES-1))); do

0 commit comments

Comments
 (0)