package Ġnet . cord a . node . services . vault Ċ Ċ import Ġnet . cord a . contracts . asset . Cash Ċ import Ġnet . cord a . contracts . asset . D UMMY _ C ASH _ IS SU ER Ċ import Ġnet . cord a . contracts . testing . fill With Some Test Cash Ċ import Ġnet . cord a . core . contracts .* Ċ import Ġnet . cord a . core . crypto . composite Ċ import Ġnet . cord a . core . node . services . States Not Available Exception Ċ import Ġnet . cord a . core . node . services . Tx Writable Storage Service Ċ import Ġnet . cord a . core . node . services . Vault Service Ċ import Ġnet . cord a . core . node . services . un consumed States Ċ import Ġnet . cord a . core . serialization . Opaque Bytes Ċ import Ġnet . cord a . core . transactions . Signed Transaction Ċ import Ġnet . cord a . core . utilities . D UMMY _ NOT ARY Ċ import Ġnet . cord a . core . utilities . Log Helper Ċ import Ġnet . cord a . node . utilities . configure Database Ċ import Ġnet . cord a . node . utilities . database Transaction Ċ import Ġnet . cord a . testing . BO C Ċ import Ġnet . cord a . testing . BO C _ KEY Ċ import Ġnet . cord a . testing . ME GA _ COR P Ċ import Ġnet . cord a . testing . ME GA _ COR P _ KEY Ċ import Ġnet . cord a . testing . node . Mock Services Ċ import Ġnet . cord a . testing . node . make Test DataSource Properties Ċ import Ġorg . assertj . core . api . Assertions . assertThat Ċ import Ġorg . assertj . core . api . Assertions . assertThat Exception OfType Ċ import Ġorg . jetbrains . ex posed . sql . Database Ċ import Ġorg . junit . After Ċ import Ġorg . junit . Before Ċ import Ġorg . junit . Test Ċ import Ġjava . io . Closeable Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . Executors Ċ import Ġkotlin . test . assertEquals Ċ import Ġkotlin . test . assertNull Ċ Ċ class ĠNode Vault Service Test Ġ{ ĊĠĠĠ Ġlateinit Ġvar Ġservices : ĠMock Services ĊĠĠĠ Ġval Ġvault : ĠVault Service Ġget () Ġ= Ġservices . vault Service ĊĠĠĠ Ġlateinit Ġvar ĠdataSource : ĠClose able ĊĠĠĠ Ġlateinit Ġvar Ġdatabase : ĠDatabase ĊĊĠĠĠ Ġ@ Before ĊĠĠĠ Ġfun ĠsetUp () Ġ{ ĊĠĠĠĠĠĠĠ ĠLog Helper . setLevel ( Node Vault Service :: class ) ĊĠĠĠĠĠĠĠ Ġval ĠdataSource Props Ġ= Ġmake Test DataSource Properties () ĊĠĠĠĠĠĠĠ Ġval ĠdataSource And Database Ġ= Ġconfigure Database ( dataSource Props ) ĊĠĠĠĠĠĠĠ ĠdataSource Ġ= ĠdataSource And Database . first ĊĠĠĠĠĠĠĠ Ġdatabase Ġ= ĠdataSource And Database . second ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices Ġ= Ġobject Ġ: ĠMock Services () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġvault Service : ĠVault Service Ġ= Ġmake Vault Service ( dataSource Props ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrecord Transactions ( tx s : ĠIterable < Signed Transaction >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( st x Ġin Ġt xs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstorage Service . validated Transactions . add Transaction ( st x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRef actored Ġto Ġuse Ġnotify All () Ġas Ġwe Ġhave Ġno Ġother Ġunit Ġtest Ġfor Ġthat Ġmethod Ġwith Ġmultiple Ġtransactions . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvault Service . notify All ( tx s . map Ġ{ Ġit . tx Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ After ĊĠĠĠ Ġfun ĠtearDown () Ġ{ ĊĠĠĠĠĠĠĠ ĠdataSource . close () ĊĠĠĠĠĠĠĠ ĠLog Helper . reset ( Node Vault Service :: class ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` states Ġnot Ġlocal Ġto Ġinstance `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw 1 Ġ= Ġservices . vault Service . un consumed States < Cash . State >() ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( w 1 ). has Size ( 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoriginal Storage Ġ= Ġservices . storage Service ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoriginal Vault Ġ= Ġservices . vault Service ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġservices 2 Ġ= Ġobject Ġ: ĠMock Services () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġvault Service : ĠVault Service Ġget () Ġ= Ġoriginal Vault ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġneed Ġto Ġbe Ġable Ġto Ġfind Ġthe Ġsame Ġtransactions Ġas Ġbefore , Ġtoo . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġstorage Service : ĠTx Writable Storage Service Ġget () Ġ= Ġoriginal Storage ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrecord Transactions ( tx s : ĠIterable < Signed Transaction >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( st x Ġin Ġt xs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstorage Service . validated Transactions . add Transaction ( st x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvault Service . notify ( st x . tx ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw 2 Ġ= Ġservices 2 . vault Service . un consumed States < Cash . State >() ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( w 2 ). has Size ( 3 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` states Ġfor Ġrefs `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw 1 Ġ= Ġservices . vault Service . un consumed States < Cash . State >(). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( w 1 ). has Size ( 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Refs Ġ= ĠlistOf ( w 1 [ 1 ]. ref , Ġw 1 [ 2 ]. ref ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġservices . vault Service . states For Refs ( state Refs ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( states ). has Size ( 2 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` states Ġsoft Ġlocking Ġreserve Ġand Ġrelease `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun consumed States Ġ= Ġservices . vault Service . un consumed States < Cash . State >(). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( un consumed States ). has Size ( 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ref sTo Soft Lock Ġ= Ġset Of ( un consumed States [ 1 ]. ref , Ġun consumed States [ 2 ]. ref ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsoft Ġlock Ġtwo Ġof Ġthe Ġthree Ġstates ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id Ġ= ĠUUID . randomUUID () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . soft Lock Reserve ( soft Lock Id , Ġstate Ref sTo Soft Lock ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġall Ġsoft locked Ġstates ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( services . vault Service . soft Locked States < Cash . State > ()). has Size ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmy Ġsoft locked Ġstates ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( services . vault Service . soft Locked States < Cash . State >( soft Lock Id )). has Size ( 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġexcluding Ġsoft locked Ġstates ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun locked States 1 Ġ= Ġservices . vault Service . un consumed States < Cash . State >( include Soft Locked States Ġ= Ġfalse ). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( unlocked States 1 ). has Size ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsoft Ġlock Ġrelease Ġone Ġof Ġthe Ġstates Ġexplicitly ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . soft Lock Release ( soft Lock Id , Ġset Of ( un consumed States [ 1 ]. ref )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun locked States 2 Ġ= Ġservices . vault Service . un consumed States < Cash . State >( include Soft Locked States Ġ= Ġfalse ). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( unlocked States 2 ). has Size ( 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsoft Ġlock Ġrelease Ġthe Ġrest Ġby Ġid ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . soft Lock Release ( soft Lock Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun locked States Ġ= Ġservices . vault Service . un consumed States < Cash . State >( include Soft Locked States Ġ= Ġfalse ). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( unlocked States ). has Size ( 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġshould Ġbe Ġback Ġto Ġoriginal Ġstates ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( unlocked States ). isEqualTo ( un consumed States ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` soft Ġlocking Ġattempt Ġconcurrent Ġreserve `() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġbackground Executor Ġ= ĠExec utors . new Fixed ThreadPool ( 2 ) ĊĠĠĠĠĠĠĠ Ġval Ġcount Down Ġ= ĠCount DownLatch ( 2 ) ĊĊĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id 1 Ġ= ĠUUID . randomUUID () ĊĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id 2 Ġ= ĠUUID . randomUUID () ĊĊĠĠĠĠĠĠĠ Ġval Ġvault States Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertNull ( vault . cash Balances [ USD ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġstate Ref sTo Soft Lock Ġ= Ġvault States . states . map Ġ{ Ġit . ref Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġprintln (" State ĠRe fs :: Ġ$ state Ref sTo Soft Lock ") ĊĊĠĠĠĠĠĠĠ Ġ// Ġ 1 st Ġtx Ġlocks Ġstates ĊĠĠĠĠĠĠĠ Ġbackground Executor . submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 1 , Ġstate Ref sTo Soft Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 1 )). has Size ( 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" SOFT ĠLOCK ĠSTAT ES Ġ# 1 Ġsucceeded ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" SOFT ĠLOCK ĠSTAT ES Ġ# 1 Ġfailed ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount Down . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġ 2 nd Ġtx Ġattempts Ġto Ġlock Ġsame Ġstates ĊĠĠĠĠĠĠĠ Ġbackground Executor . submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( 1 0 0 ) ĠĠ Ġ// Ġlet Ġ 1 st Ġthread Ġsoft Ġlock Ġthem Ġ 1 st ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 2 , Ġstate Ref sTo Soft Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 2 )). has Size ( 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" SOFT ĠLOCK ĠSTAT ES Ġ# 2 Ġsucceeded ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" SOFT ĠLOCK ĠSTAT ES Ġ# 2 Ġfailed ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount Down . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcount Down . await () ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlock States Id 1 Ġ= Ġvault . soft Locked States < Cash . State >( soft Lock Id 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" SOFT ĠLOCK Ġ# 1 Ġfinal Ġstates : Ġ$ lock States Id 1 ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( lock States Id 1 . size ). isIn ( 0 , Ġ 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlock States Id 2 Ġ= Ġvault . soft Locked States < Cash . State >( soft Lock Id 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" SOFT ĠLOCK Ġ# 2 Ġfinal Ġstates : Ġ$ lock States Id 2 ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( lock States Id 2 . size ). isIn ( 0 , Ġ 3 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` soft Ġlocking Ġpartial Ġreserve Ġstates Ġfails `() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id 1 Ġ= ĠUUID . randomUUID () ĊĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id 2 Ġ= ĠUUID . randomUUID () ĊĊĠĠĠĠĠĠĠ Ġval Ġvault States Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertNull ( vault . cash Balances [ USD ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġstate Ref sTo Soft Lock Ġ= Ġvault States . states . map Ġ{ Ġit . ref Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġprintln (" State ĠRe fs :: Ġ$ state Ref sTo Soft Lock ") ĊĊĠĠĠĠĠĠĠ Ġ// Ġlock Ġ 1 st Ġstate Ġwith ĠLock Id 1 ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 1 , Ġset Of ( state Ref sTo Soft Lock . first ())) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 1 )). has Size ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġattempt Ġto Ġlock Ġall Ġ 3 Ġstates Ġwith ĠLock Id 2 ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat Exception OfType ( States Not Available Exception :: class . java ). is Thrown By ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġvault . soft Lock Reserve ( soft Lock Id 2 , Ġstate Ref sTo Soft Lock ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). with Message Containing (" only Ġ 2 Ġrows Ġavailable "). with No Cause () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` attempt Ġto Ġlock Ġstates Ġalready Ġsoft Ġlocked Ġby Ġme `() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id 1 Ġ= ĠUUID . randomUUID () ĊĊĠĠĠĠĠĠĠ Ġval Ġvault States Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertNull ( vault . cash Balances [ USD ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġstate Ref sTo Soft Lock Ġ= Ġvault States . states . map Ġ{ Ġit . ref Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġprintln (" State ĠRe fs :: Ġ$ state Ref sTo Soft Lock ") ĊĊĠĠĠĠĠĠĠ Ġ// Ġlock Ġstates Ġwith ĠLock Id 1 ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 1 , Ġstate Ref sTo Soft Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 1 )). has Size ( 3 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġattempt Ġto Ġre lock Ġsame Ġstates Ġwith ĠLock Id 1 ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 1 , Ġstate Ref sTo Soft Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 1 )). has Size ( 3 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` lock Ġadditional Ġstates Ġto Ġsome Ġalready Ġsoft Ġlocked Ġby Ġme `() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġsoft Lock Id 1 Ġ= ĠUUID . randomUUID () ĊĊĠĠĠĠĠĠĠ Ġval Ġvault States Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertNull ( vault . cash Balances [ USD ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 3 , Ġ 3 , ĠRandom ( 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġstate Ref sTo Soft Lock Ġ= Ġvault States . states . map Ġ{ Ġit . ref Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġprintln (" State ĠRe fs :: Ġ$ state Ref sTo Soft Lock ") ĊĊĠĠĠĠĠĠĠ Ġ// Ġlock Ġstates Ġwith ĠLock Id 1 ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 1 , Ġset Of ( state Ref sTo Soft Lock . first ())) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 1 )). has Size ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġattempt Ġto Ġlock Ġall Ġstates Ġwith ĠLock Id 1 Ġ( including Ġpreviously Ġalready Ġlocked Ġone ) ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault . soft Lock Reserve ( soft Lock Id 1 , Ġstate Ref sTo Soft Lock ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( vault . soft Locked States < Cash . State >( soft Lock Id 1 )). has Size ( 3 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` un consumed States For S pending Ġexact Ġamount `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun consumed States Ġ= Ġservices . vault Service . un consumed States < Cash . State >(). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( un consumed States ). has Size ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspend able States USD Ġ= Ġ( services . vault Service Ġas ĠNode Vault Service ). un consumed States For S pending < Cash . State >( 1 0 0 . DO LL ARS , Ġlock Id Ġ= ĠUUID . randomUUID ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġspend able States USD . forEach (:: println ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD ). has Size ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 0 ]. state . data . amount . quantity ). isEqualTo ( 1 0 0 L * 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( services . vault Service . soft Locked States < Cash . State > ()). has Size ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` un consumed States For S pending Ġfrom Ġtwo Ġissuer Ġparties `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L ), Ġissued By Ġ= Ġ( D UMMY _ C ASH _ IS SU ER )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L ), Ġissued By Ġ= Ġ( BO C . ref ( 1 )), Ġissuer Key Ġ= ĠB OC _ KEY ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspend able States USD Ġ= Ġservices . vault Service . un consumed States For S pending < Cash . State >( 2 0 0 . DO LL ARS , Ġlock Id Ġ= ĠUUID . randomUUID (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġonly From Issuer Part ies Ġ= Ġset Of ( D UMMY _ C ASH _ IS SU ER . party , ĠB OC )). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġspend able States USD . forEach (:: println ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD ). has Size ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 0 ]. state . data . amount . token . issuer ). isEqualTo ( D UMMY _ C ASH _ IS SU ER ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 1 ]. state . data . amount . token . issuer ). isEqualTo ( BO C . ref ( 1 )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` un consumed States For S pending Ġfrom Ġspecific Ġissuer Ġparty Ġand Ġrefs `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L ), Ġissued By Ġ= Ġ( D UMMY _ C ASH _ IS SU ER )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L ), Ġissued By Ġ= Ġ( BO C . ref ( 1 )), Ġissuer Key Ġ= ĠB OC _ KEY , Ġref Ġ= ĠO pa que Bytes . of ( 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L ), Ġissued By Ġ= Ġ( BO C . ref ( 2 )), Ġissuer Key Ġ= ĠB OC _ KEY , Ġref Ġ= ĠO pa que Bytes . of ( 2 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L ), Ġissued By Ġ= Ġ( BO C . ref ( 3 )), Ġissuer Key Ġ= ĠB OC _ KEY , Ġref Ġ= ĠO pa que Bytes . of ( 3 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun consumed States Ġ= Ġservices . vault Service . un consumed States < Cash . State >(). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( un consumed States ). has Size ( 4 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspend able States USD Ġ= Ġservices . vault Service . un consumed States For S pending < Cash . State >( 2 0 0 . DO LL ARS , Ġlock Id Ġ= ĠUUID . randomUUID (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġonly From Issuer Part ies Ġ= Ġset Of ( BO C ), Ġwith Issuer Refs Ġ= Ġset Of ( Opaque Bytes . of ( 1 ), ĠO pa que Bytes . of ( 2 ))). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD ). has Size ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 0 ]. state . data . amount . token . issuer . party ). isEqualTo ( BO C ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 0 ]. state . data . amount . token . issuer . reference ). isEqualTo ( BO C . ref ( 1 ). reference ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 1 ]. state . data . amount . token . issuer . reference ). isEqualTo ( BO C . ref ( 2 ). reference ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` un consumed States For S pending Ġins ufficient Ġamount `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 , Ġ 1 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun consumed States Ġ= Ġservices . vault Service . un consumed States < Cash . State >(). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( un consumed States ). has Size ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspend able States USD Ġ= Ġ( services . vault Service Ġas ĠNode Vault Service ). un consumed States For S pending < Cash . State >( 1 1 0 . DO LL ARS , Ġlock Id Ġ= ĠUUID . randomUUID ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġspend able States USD . forEach (:: println ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD ). has Size ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( services . vault Service . soft Locked States < Cash . State > ()). has Size ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` un consumed States For S pending Ġsmall Ġamount `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 2 , Ġ 2 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun consumed States Ġ= Ġservices . vault Service . un consumed States < Cash . State >(). toList () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( un consumed States ). has Size ( 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspend able States USD Ġ= Ġ( services . vault Service Ġas ĠNode Vault Service ). un consumed States For S pending < Cash . State >( 1 . DO LL ARS , Ġlock Id Ġ= ĠUUID . randomUUID ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġspend able States USD . forEach (:: println ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD ). has Size ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( sp end able States USD [ 0 ]. state . data . amount . quantity ). is GreaterThan OrEqualTo ( 1 L * 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( services . vault Service . soft Locked States < Cash . State > ()). has Size ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` states Ġsoft Ġlocking Ġquery Ġgranularity `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . DO LL ARS , ĠD UMMY _ NOT ARY , Ġ 1 0 , Ġ 1 0 , ĠRandom ( 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . PO UN DS , ĠD UMMY _ NOT ARY , Ġ 1 0 , Ġ 1 0 , ĠRandom ( 0 L )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . fill With Some Test Cash ( 1 0 0 . SW ISS _ F RAN CS , ĠD UMMY _ NOT ARY , Ġ 1 0 , Ġ 1 0 , ĠRandom ( 0 L )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġall States Ġ= Ġservices . vault Service . un consumed States < Cash . State >() ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( all States ). has Size ( 3 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspend able States USD Ġ= Ġ( services . vault Service Ġas ĠNode Vault Service ). un consumed States For S pending < Cash . State >( 2 0 . DO LL ARS , Ġlock Id Ġ= ĠUUID . randomUUID ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspend able States USD . forEach (:: println ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnote Ġonly Ġ 3 Ġspend Ġattempts Ġsucceed Ġwith Ġa Ġtotal Ġof Ġ 8 Ġstates ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( services . vault Service . soft Locked States < Cash . State > ()). has Size ( 8 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġadd Note To Transaction () Ġ{ ĊĠĠĠĠĠĠĠ Ġdatabase Transaction ( database ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfresh Key Ġ= Ġservices . legal Identity Key ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIssue Ġa Ġtxn Ġto ĠSend Ġus Ġsome ĠMoney ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuseful TX Ġ= ĠTransaction Type . General . Builder ( null ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCash (). generate Issue ( this , Ġ 1 0 0 . DO LL ARS Ġ` iss ued Ġby ` ĠME GA _ COR P . ref ( 1 ), Ġfresh Key . public . composite , ĠD UMMY _ NOT ARY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsign With ( ME GA _ COR P _ KEY ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. to Signed Transaction () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . record Transactions ( listOf ( useful TX )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . add Note To Transaction ( useful TX . id , Ġ" USD ĠSample ĠNote Ġ 1 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . add Note To Transaction ( useful TX . id , Ġ" USD ĠSample ĠNote Ġ 2 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . add Note To Transaction ( useful TX . id , Ġ" USD ĠSample ĠNote Ġ 3 ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 3 , Ġservices . vault Service . getTransaction Notes ( useful TX . id ). count ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIssue Ġmore ĠMoney Ġ( GBP ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġanother TX Ġ= ĠTransaction Type . General . Builder ( null ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCash (). generate Issue ( this , Ġ 2 0 0 . PO UN DS Ġ` iss ued Ġby ` ĠME GA _ COR P . ref ( 1 ), Ġfresh Key . public . composite , ĠD UMMY _ NOT ARY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsign With ( ME GA _ COR P _ KEY ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. to Signed Transaction () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . record Transactions ( listOf ( another TX )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices . vault Service . add Note To Transaction ( another TX . id , Ġ" GP B ĠSample ĠNote Ġ 1 ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġservices . vault Service . getTransaction Notes ( another TX . id ). count ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ