Skip to content

Commit ed52492

Browse files
committed
assets: implement asset deposit key reveal
With this commit, the client can now reveal the keys of asset deposits to the server. This allows the server to sweep the deposits as needed, without requiring further interaction with the client.
1 parent 00469c8 commit ed52492

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

assets/deposit/manager.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,3 +1212,76 @@ func (m *Manager) publishPendingWithdrawals(ctx context.Context) error {
12121212

12131213
return nil
12141214
}
1215+
1216+
// RevealDepositKeys reveals the internal keys for the given deposit IDs to
1217+
// the swap server.
1218+
func (m *Manager) RevealDepositKeys(ctx context.Context,
1219+
depositIDs []string) error {
1220+
1221+
done, err := m.scheduleNextCall()
1222+
if err != nil {
1223+
return err
1224+
}
1225+
defer done()
1226+
1227+
// First check that all requested deposits are in the required state and
1228+
// collect the keys.
1229+
keys := make(map[string][]byte, len(depositIDs))
1230+
for _, depositID := range depositIDs {
1231+
d, ok := m.deposits[depositID]
1232+
if !ok {
1233+
log.Warnf("Can't reveal key for deposit %v as it is "+
1234+
"not active", depositID)
1235+
}
1236+
1237+
if d.State != StateConfirmed && d.State != StateKeyRevealed {
1238+
return fmt.Errorf("deposit %v key cannot be revealed",
1239+
depositID)
1240+
}
1241+
1242+
internalPubKey, internalPrivKey, err := DeriveSharedDepositKey(
1243+
ctx, m.signer, d.FunderScriptKey,
1244+
)
1245+
if err != nil {
1246+
return err
1247+
}
1248+
1249+
if !d.FunderInternalKey.IsEqual(internalPubKey) {
1250+
log.Errorf("Funder internal key %x does not match "+
1251+
"expected %x for deposit %v",
1252+
d.FunderInternalKey.SerializeCompressed(),
1253+
internalPubKey.SerializeCompressed(), depositID)
1254+
1255+
return fmt.Errorf("funder internal key mismatch")
1256+
}
1257+
1258+
keys[depositID] = internalPrivKey.Serialize()
1259+
}
1260+
1261+
// Update the deposit state before we actually push the keys to the
1262+
// server. Otherwise we may fail to update the state in our database,
1263+
// despite the server accepting the keys.
1264+
for depositID := range keys {
1265+
d := m.deposits[depositID]
1266+
d.State = StateKeyRevealed
1267+
err = m.handleDepositStateUpdate(ctx, d)
1268+
if err != nil {
1269+
return err
1270+
}
1271+
1272+
log.Infof("Revealing deposit key for %v: pub=%x", depositID,
1273+
d.FunderInternalKey.SerializeCompressed())
1274+
}
1275+
1276+
// Now push the keys to the server.
1277+
_, err = m.depositServiceClient.PushAssetDepositKeys(
1278+
ctx, &swapserverrpc.PushAssetDepositKeysReq{
1279+
DepositKeys: keys,
1280+
},
1281+
)
1282+
if err != nil {
1283+
return err
1284+
}
1285+
1286+
return err
1287+
}

assets/deposit/server.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,18 @@ func (s *Server) RevealAssetDepositKey(ctx context.Context,
140140
in *looprpc.RevealAssetDepositKeyRequest) (
141141
*looprpc.RevealAssetDepositKeyResponse, error) {
142142

143-
return nil, status.Error(codes.Unimplemented, "unimplemented")
143+
if s.manager == nil {
144+
return nil, ErrAssetDepositsUnavailable
145+
}
146+
147+
err := s.manager.RevealDepositKeys(
148+
ctx, []string{in.DepositId},
149+
)
150+
if err != nil {
151+
return nil, status.Error(codes.Internal, err.Error())
152+
}
153+
154+
return &looprpc.RevealAssetDepositKeyResponse{}, nil
144155
}
145156

146157
// WithdrawAssetDeposits is the rpc endpoint for loop clients to withdraw their

0 commit comments

Comments
 (0)