diff --git a/doc/diagrams/.gitignore b/doc/diagrams/.gitignore new file mode 100644 index 0000000..0e77146 --- /dev/null +++ b/doc/diagrams/.gitignore @@ -0,0 +1,2 @@ +*.aux +*.log diff --git a/doc/diagrams/class-diagram.pdf b/doc/diagrams/class-diagram.pdf new file mode 100644 index 0000000..9c89b0f Binary files /dev/null and b/doc/diagrams/class-diagram.pdf differ diff --git a/doc/diagrams/class-diagram.tex b/doc/diagrams/class-diagram.tex new file mode 100644 index 0000000..828fbc2 --- /dev/null +++ b/doc/diagrams/class-diagram.tex @@ -0,0 +1,231 @@ +\documentclass[tikz]{standalone} + +\usepackage{etoolbox} + +\usetikzlibrary{ + arrows.meta, + backgrounds, + calc, + fit, + positioning, + shadows, + shapes.multipart, +} + + +\begin{document} + +\definecolor{umlbgleft}{HTML}{F9D4A8} +\definecolor{umlbgright}{HTML}{FEF8D2} +\definecolor{umlifaceoutline}{HTML}{76907C} +\definecolor{umlifacebgleft}{HTML}{C0D2C4} +\definecolor{umlifacebgright}{HTML}{FAFCFB} +\definecolor{umlificonoutline}{HTML}{76907C} +\definecolor{umloutline}{HTML}{968255} +\definecolor{umlpkgbgleft}{HTML}{D5DEFF} +\definecolor{umlpkgbgright}{HTML}{F4F8FF} +\definecolor{umlpkgoutline}{HTML}{8B90A9} +\definecolor{umltypefg}{HTML}{606060} +\definecolor{nonuml}{HTML}{606060} + +\newcommand\TallStrut{\vrule height 10pt depth 10pt width 0pt} + +\newcommand*\Param[2]{#1 : \textcolor{umltypefg}{#2}} +\newcommand*\Op[3]{% + #1(\notblank{#2}{~}{}#2\notblank{#2}{~}{})% + \notblank{#3}{~:~\textcolor{umltypefg}{#3}}{}% +} +\newcommand\Ellipsis{~~~~\textcolor{nonuml}{[...]}} +\newcommand*\Multiplicity[2]{~[#1..#2]} +\newcommand\Any{*} +\newcommand*\Stereo[1]{«#1»} + +\begin{tikzpicture}[ + basic/.style={ + draw=umloutline, + shading=axis,left color=umlbgleft,right color=umlbgright, + drop shadow, + font=\bfseries\large, + }, + basictitle/.style={component,minimum height=4ex}, + basicbox/.style={component,inner sep=1em}, + basicsimple/.style={ + basicbox, + text width=8em,text centered,minimum height=8ex, + }, + classsimple/.style={basic,font=\bfseries\large,inner sep=1em}, + classabstractsimple/.style={classsimple,font=\bfseries\itshape\large}, + class/.style args={#1/#2}{ + basic,rectangle split,rectangle split parts=2, + node contents={% + \nodepart[align=center]{one}\TallStrut\raisebox{-.5ex}{\bfseries#1}% + \nodepart{two}\texttt{#2}% + }, + }, + classabstract/.style args={#1/#2}{class={\textit{#1}/#2}}, + iface/.style args={#1/#2}{ + basic, + draw=umlifaceoutline, + shading=axis,left color=umlifacebgleft, + right color=umlifacebgright, + rectangle split,rectangle split parts=2, + node contents={% + \nodepart[align=center]{one}{% + \bfseries\TallStrut\raisebox{-.5ex}{#1}% + }% + \nodepart{two}{\ttfamily#2}% + }, + }, + ifacesimple/.style={ + basic, + draw=umloutline, + shading=axis, + left color=umlifacebgleft,right color=umlifacebgright, + inner sep=1em, + }, + folder/.style={ + basic, + draw=umlpkgoutline, + left color=umlpkgbgleft,right color=umlpkgbgright, + inner sep=1em, + append after command={ + \pgfextra{ + \draw[ + umlpkgoutline, + fill=umlpkgbgleft, + drop shadow, + ] + ($(\tikzlastnode.north west)+(.5\pgflinewidth,-\pgflinewidth)$) + rectangle + ($(\tikzlastnode.north)+(-5em,+1.5em)$); + } + }, + }, + ificon/.pic={ + \draw[ + umlificonoutline, + shading=axis, + left color=umlifacebgleft,right color=umlifacebgright, + ] (0,0) circle (8pt); + }, + dep/.style={ + ->,dashed,thick,>={Straight Barb[length=.5em,width=.75em]} + }, + impl/.style={dep,>={Triangle[open,length=.75em,width=.75em]}}, + ext/.style={impl,solid}, + assoc/.style={->,>={Straight Barb[length=.5em,width=.75em]}}, + comp/.style={ + assoc, + {Diamond[length=1em,width=.5em]}-{Straight Barb[length=.5em,width=.75em]} + }, + rellab/.style={font=\ttfamily\large}, +] + \node (iregistry) [ + iface=RegistryInterface/{% + \Op{create}{% + \Param{entity}{SerializableEntity}% + }{void} \\ + \Op{read}{% + \Param{entity}{SerializableEntity}% + }{void} \\ + \Op{update}{% + \Param{entity}{SerializableEntity}% + }{void} \\ + \Op{delete}{% + \Param{entity}{SerializableEntity}% + }{void} \\ + },text width=28em, + ]; + \pic at ($(iregistry.north east)+(-1.2em,-1.4em)$) {ificon}; + + \node[right=32em of iregistry.north,anchor=north] (ientity) [ + iface=SerializableEntityInterface/{% + \Op{getType}{}{String} \\ + \Op{getKeyParts}{}{String\Multiplicity{1}{\Any}} \\ + \Op{toBuffer}{}{byte\Multiplicity{1}{\Any}} \\ + \Op{fromBuffer}{% + \Param{buffer}{byte\Multiplicity{1}{\Any}}% + }{void} \\ + \Op{toJson}{}{String} \\ + \Op{fromJson}{\Param{json}{String}}{void} \\ + },text width=26em, + ]; + \pic at ($(ientity.north east)+(-1.2em,-1.4em)$) {ificon}; + + \node[below=of iregistry] (registry) [classsimple] {Registry}; + + \node[below=of registry] (ctxwreg) [ + class=ContextWithRegistry/{% + \Op{+getRegistry}{}{Registry}% + }]; + + \node[below=4em of ientity] (entitybase) + [classabstractsimple] {SerializableEntityBase}; + \node[below=of ctxwreg,xshift=12em] (mwbase) + [classabstractsimple] {ChaincodeStubMiddlewareBase}; + + \node[below=15em of ctxwreg] (ctx) + [class=Context/\Op{getStub}{}{ChaincodeStub},text width=17em]; + + \node[below=of ctx] (icontract) + [ifacesimple,text width=16em,text centered] + {ContractInterface}; + \pic at ($(icontract.north east)+(-1.2em,-1.4em)$) {ificon}; + + \node[below=18em of entitybase] (istub) [ + iface=ChaincodeStub/{% + \Op{getState}{% + \Param{key}{String} + }{byte\Multiplicity{0}{\Any}} \\ + \Op{putState}{% + \Param{key}{String}, + \Param{value}{byte\Multiplicity{0}{\Any}}% + }{void} \\ + \Ellipsis + },text width=32em, + ]; + \pic at ($(istub.north east)+(-1.2em,-1.4em)$) {ificon}; + + \coordinate[above=4em of iregistry] (fitcftsrg); + \begin{scope}[on background layer] + \node (pkgftsrg) [ + folder, + fit=(fitcftsrg)(iregistry)(registry)(ctxwreg)(mwbase)(ientity)(entitybase) + ] {}; + \end{scope} + \node[font=\large\bfseries\ttfamily] + at ($(pkgftsrg.north)+(0,-1em)$) + {hu.bme.mit.ftsrg.chaincode.dataaccess}; + + \coordinate[above=2em of istub] (fitcfabric); + \begin{scope}[on background layer] + \node (pkgfabric) [ + folder, + fit=(fitcfabric)(ctx)(icontract)(istub) + ] {}; + \end{scope} + \node[font=\large\bfseries\ttfamily] + at ($(pkgfabric.north)+(0,-1em)$) + {org.hyperledger.fabric}; + + \node[classsimple,left=15em of ctxwreg] (cc) {MyChaincode}; + + \draw[impl] (registry) -- (iregistry); + \draw[ext] (ctxwreg) -- (ctx); + \draw[comp] (ctxwreg) + -- node[right,rellab,pos=.65] {-registry} (registry); + \draw[comp,transform canvas={yshift=-1em}] (ctx.east |- istub) + -- node[below,rellab,pos=.7] {-stub} (istub); + \draw[dep] (iregistry) -- ++(-12em,-12em) -- (ctx); + \draw[dep] (iregistry.east |- ientity) -- (ientity); + \draw[impl] (mwbase) |- (istub); + \draw[assoc] (mwbase) + -| node[right,rellab,pos=.95] {\#next} (istub); + \coordinate (chelper1) at ($(ctxwreg.south east)+(-2em,0)$); + \draw[dep] (chelper1) -- (chelper1 |- mwbase.north); + \draw[impl] (entitybase) -- (ientity); + \draw[dep] (cc) -- node[above,rellab,midway] {\Stereo{use}} (ctxwreg); + \draw[impl] (cc) |- (icontract); +\end{tikzpicture} + +\end{document} diff --git a/doc/diagrams/sequence-diagram.pdf b/doc/diagrams/sequence-diagram.pdf new file mode 100644 index 0000000..5fbc48c Binary files /dev/null and b/doc/diagrams/sequence-diagram.pdf differ diff --git a/doc/diagrams/sequence-diagram.tex b/doc/diagrams/sequence-diagram.tex new file mode 100644 index 0000000..b8cb5b4 --- /dev/null +++ b/doc/diagrams/sequence-diagram.tex @@ -0,0 +1,166 @@ +\documentclass[tikz]{standalone} + +\usetikzlibrary{ + arrows.meta, + calc, + fit, + positioning, + shadows, + shapes.multipart, +} + + +\begin{document} + +\definecolor{umlactivationbg}{HTML}{C4E1D5} +\definecolor{umlactorbgleft}{HTML}{CEE6DC} +\definecolor{umlactorbgright}{HTML}{F6FEFB} +\definecolor{umlactoroutline}{HTML}{000000} +\definecolor{umlifacebgleft}{HTML}{C0D2C4} +\definecolor{umlifacebgright}{HTML}{FAFCFB} +\definecolor{umlificonoutline}{HTML}{76907C} + +\newcommand\TallStrut{\vrule height 10pt depth 10pt width 0pt} + +\newcommand*\Actor[2][]{#1~:~#2} +\newcommand*\Stereo[1]{«#1»} + +\begin{tikzpicture}[ + actor/.style={ + draw=umlactoroutline, + shading=axis, + left color=umlactorbgleft,right color=umlactorbgright, + drop shadow, + font=\bfseries\Large, + node contents={\TallStrut\raisebox{-.5ex}{#1}}, + minimum height=4em, + }, + ificon/.pic={ + \draw[ + umlificonoutline, + shading=axis, + left color=umlifacebgleft,right color=umlifacebgright, + ] (0,0) circle (8pt); + }, + activation/.style={ + draw=black,fill=umlactivationbg, + inner xsep=.5em,inner ysep=0, + node contents={}, + }, + port/.style={ + draw,fill=black, + minimum width=1em,minimum height=1em, + node contents={} + }, + life/.style=loosely dashed, + longdashed/.style={dash pattern={on 8pt off 5pt}}, + msg/.style={ + -{Triangle[width=1em,length=1em]}, + shorten >=.5em,shorten <=.5em, + }, + reply/.style={ + msg,longdashed, + -{Straight Barb[width=1em,length=1em]}, + }, + msgcreate/.style=reply, + msglab/.style={font=\ttfamily\Large}, +] + + \node (cc) [actor={\Actor{MyChaincode}}]; + \node (ctx) + [actor={\Actor[ctx]{ContextWithRegistry}},right=of cc]; + \node (ent) + [actor={\Actor[ent]{Entity}},right=-6em of ctx,yshift=-12em]; + \node (reg) [actor={\Actor[reg]{Registry}},right=8em of ctx]; + \node (stub) [ + actor={\Actor[interceptor]{ChaincodeStub}}, + right=12em of reg, + text width=25em,text centered, + ]; + \pic at ($(stub.north east)+(-1.4em,-1.8em)$) {ificon}; + \node (fabstub) [ + actor={\Actor[fabricStub]{ChaincodeStub}}, + right=6em of stub, + text width=24em,text centered, + ]; + \pic at ($(fabstub.north east)+(-1.4em,-1.8em)$) {ificon}; + + \coordinate (cbot) at ($(cc)+(0,-45em)$); + \foreach \a in {cc,ctx,ent,reg,stub,fabstub} + \draw[life] (\a) -- (\a |- cbot); + + \node (in) [port,left=16em of cc,yshift=-4em]; + + \coordinate (ccact1start) at (in.east -| cc); + \coordinate (ccact1end) at ($(cc.south)+(0,-42em)$); + \node (ccact1) [activation,fit=(ccact1start)(ccact1end)]; + \draw[msg,shorten <=0em] (in) + -- node[above,msglab] {invokeTx(ctx=ctx,parameters)} + (in -| ccact1); + + \coordinate (ctxact1start) at ($(ctx.south)+(0,-5em)$); + \coordinate (ctxact1end) at ($(ctxact1start)+(0,-2em)$); + \node (ctxact1) [activation,fit=(ctxact1start)(ctxact1end)]; + \draw[msg] (ccact1 |- ctxact1start) + -- node[above,msglab] {getRegistry()} (ctxact1start); + \draw[reply] (ctxact1end) + -- node[above,msglab] {reg} (ctxact1end -| ccact1); + + \draw[msgcreate] (ccact1 |- ent) + -- node[above,msglab] {\Stereo{create}} (ent); + + \coordinate (regact1start) at ($(reg.south)+(0,-15em)$); + \coordinate (regact1end) at ($(regact1start)+(0,-24em)$); + \node (regact1) [activation,fit=(regact1start)(regact1end)]; + \draw[msg] (ccact1 |- regact1start) + -- node[above,msglab] {create(ctx=ctx, entity=ent)} + (regact1start); + + \coordinate (ctxact2start) at ($(ctx.south)+(0,-18em)$); + \coordinate (ctxact2end) at ($(ctxact2start)+(0,-2em)$); + \node (ctxact1) [activation,fit=(ctxact2start)(ctxact2end)]; + \draw[msg] (regact1 |- ctxact2start) + -- node[above,msglab] {getStub()} (ctxact2start); + \draw[reply] (ctxact2end) + -- node[above,msglab] {interceptor} (ctxact2end -| regact1); + + \coordinate (entact1start) at ($(ent.south)+(0,-10em)$); + \coordinate (entact1end) at ($(entact1start)+(0,-2em)$); + \node (entact1) [activation,fit=(entact1start)(entact1end)]; + \draw[msg] (regact1 |- entact1start) + -- node[above,msglab] {getKeyParts()} (entact1start); + \draw[reply] (entact1end) + -- node[above,msglab] {keyParts} (entact1end -| regact1); + + \coordinate (entact2start) at ($(ent.south)+(0,-14em)$); + \coordinate (entact2end) at ($(entact2start)+(0,-2em)$); + \node (entact2) [activation,fit=(entact2start)(entact2end)]; + \draw[msg] (regact1 |- entact2start) + -- node[above,msglab] {toBuffer()} (entact2start); + \draw[reply] (entact2end) + -- node[above,msglab] {buffer} (entact2end -| regact1); + + \coordinate (stubact1start) at ($(stub.south)+(0,-30em)$); + \coordinate (stubact1end) at ($(stubact1start)+(0,-6em)$); + \node (stubact1) [activation,fit=(stubact1start)(stubact1end)]; + \draw[msg] (regact1 |- stubact1start) + -- node[above,msglab] {putState(key=keyParts,value=buffer)} + (stubact1start); + \draw[reply] (stubact1end) -- (stubact1end -| regact1); + + \coordinate (fabstubact1start) at ($(fabstub.south)+(0,-32em)$); + \coordinate (fabstubact1end) at ($(fabstubact1start)+(0,-2em)$); + \node (fabstubact1) [ + activation,fit=(fabstubact1start)(fabstubact1end), + ]; + \draw[msg] (stubact1 |- fabstubact1start) + -- node[above,msglab] {putState(key=keyParts,value=buffer)} + (fabstubact1start); + \draw[reply] (fabstubact1end) -- (fabstubact1end -| stubact1); + + \draw[reply] (regact1end) -- (regact1end -| ccact1); + + \draw[reply] (ccact1end) -- (ccact1end -| in) node[port,solid]; +\end{tikzpicture} + +\end{document}