#!/usr/contrib/bin/agent

 

# Multi-Bank: split merge close

 

include control/do

include log

 

proc Bcheck {billy banks} {

global agent bill

array set bank $banks

 

if {[llength [do_hack $billy]] != 4} {

return "err (Badly formed bill): $billy"}

if {[lindex $billy 1] != $agent(local-name)} {

if {[info exists bank([lindex $billy 1])]} {

return 1

} else {

return "err (Foreign Bill): $billy"}}

if {![info exists bill([lindex $billy 2])]} {

return "err (Counterfeit Bill): $billy"}

if {$bill([lindex $billy 2]) != [lindex $billy 3]} {

return "err (Wrong Number): $billy"}

return 0}

 

proc Bsplit {old amount} {

global agent bill

set error [Bcheck $old {}]

if {$error==0 && [lindex $old 3] >= $amount} {

set new [expr [lindex $old 3]-$amount]

unset bill([lindex $old 2])

set Nnew [random]

set Namount [random]

set bill($Nnew) $new

set bill($Namount) $amount

 

return [list [list $agent(actual-server) $agent(local-name) $Nnew $new] [list $agent(actual-server) $agent(local-name) $Namount $amount]]

 

} else {

return "$error"

}

}

 

proc Bmerge {old old2} {

global agent bill bank

set error [Bcheck $old {}]

set error2 [Bcheck $old2 [array get bank]]

if { $error==0 } {

switch -exact -- $error2 {

0 {

set new [expr [lindex $old 3]+[lindex $old2 3]]

unset bill([lindex $old 2])

unset bill([lindex $old2 2])

set Nnew [random]

set bill($Nnew) $new

return [list $agent(actual-server) $agent(local-name) $Nnew $new]}

1 {

set obank [lindex $old2 1]

agent_send "[lrange $old2 0 1]" "merge $bank($obank) $old2"

agent_receive code result -blocking

if {[lindex $result 0]=="err"} {

return "err (other bank say: $result): $old2"

} else {

set bank($obank) $result

return [Bnew [lindex $old2 3]]

}

}

default {

return "$error2"

}

}

} else {

return "$error"

}

}

 

proc Bnew {amount} {

global agent bill

set Nnew [random]

set bill($Nnew) $amount

return [list $agent(actual-server) $agent(local-name) $Nnew $amount]

}

 

proc bank {name maker amt lifetime} {

 

global bank

 

set bank("firstVirtual") 4

require wall $lifetime

agent_name $name

agent_event $maker bank [Bnew $amt]

 

do {

{"split %s %s" wallet amt} {

agent_send $sender [Bsplit $wallet $amt]}

{"merge %s %s" wal1 wal2} {

agent_send $sender [Bmerge $wal1 $wal2]}

{"close %s" wallet} {

agent_send $sender "ok"

agent_send $maker 0 DONE

break}

{"STOP"} {

agent_send $maker 0 DONE

break

}

error {"unexpected message %s" msg} {

agent_send $sender "what in hell does this mean? $msg"}

}

 

agent_end

}